[BACK]Return to usbdi_util.c CVS log [TXT][DIR] Up to [local] / sys / dev / usb

Annotation of sys/dev/usb/usbdi_util.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: usbdi_util.c,v 1.24 2007/06/18 11:53:11 mbalmer Exp $ */
                      2: /*     $NetBSD: usbdi_util.c,v 1.40 2002/07/11 21:14:36 augustss Exp $ */
                      3: /*     $FreeBSD: src/sys/dev/usb/usbdi_util.c,v 1.14 1999/11/17 22:33:50 n_hibma Exp $ */
                      4:
                      5: /*
                      6:  * Copyright (c) 1998 The NetBSD Foundation, Inc.
                      7:  * All rights reserved.
                      8:  *
                      9:  * This code is derived from software contributed to The NetBSD Foundation
                     10:  * by Lennart Augustsson (lennart@augustsson.net) at
                     11:  * Carlstedt Research & Technology.
                     12:  *
                     13:  * Redistribution and use in source and binary forms, with or without
                     14:  * modification, are permitted provided that the following conditions
                     15:  * are met:
                     16:  * 1. Redistributions of source code must retain the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer.
                     18:  * 2. Redistributions in binary form must reproduce the above copyright
                     19:  *    notice, this list of conditions and the following disclaimer in the
                     20:  *    documentation and/or other materials provided with the distribution.
                     21:  * 3. All advertising materials mentioning features or use of this software
                     22:  *    must display the following acknowledgement:
                     23:  *        This product includes software developed by the NetBSD
                     24:  *        Foundation, Inc. and its contributors.
                     25:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     26:  *    contributors may be used to endorse or promote products derived
                     27:  *    from this software without specific prior written permission.
                     28:  *
                     29:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     30:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     31:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     32:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     33:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     34:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     35:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     36:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     37:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     38:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     39:  * POSSIBILITY OF SUCH DAMAGE.
                     40:  */
                     41:
                     42: #include <sys/param.h>
                     43: #include <sys/systm.h>
                     44: #include <sys/kernel.h>
                     45: #include <sys/malloc.h>
                     46: #include <sys/proc.h>
                     47: #include <sys/device.h>
                     48:
                     49: #include <dev/usb/usb.h>
                     50: #include <dev/usb/usbhid.h>
                     51:
                     52: #include <dev/usb/usbdi.h>
                     53: #include <dev/usb/usbdi_util.h>
                     54:
                     55: #ifdef USB_DEBUG
                     56: #define DPRINTF(x)     do { if (usbdebug) printf x; } while (0)
                     57: #define DPRINTFN(n,x)  do { if (usbdebug>(n)) printf x; } while (0)
                     58: extern int usbdebug;
                     59: #else
                     60: #define DPRINTF(x)
                     61: #define DPRINTFN(n,x)
                     62: #endif
                     63:
                     64: usbd_status
                     65: usbd_get_desc(usbd_device_handle dev, int type, int index, int len, void *desc)
                     66: {
                     67:        usb_device_request_t req;
                     68:
                     69:        DPRINTFN(3,("usbd_get_desc: type=%d, index=%d, len=%d\n", type, index,
                     70:            len));
                     71:
                     72:        req.bmRequestType = UT_READ_DEVICE;
                     73:        req.bRequest = UR_GET_DESCRIPTOR;
                     74:        USETW2(req.wValue, type, index);
                     75:        USETW(req.wIndex, 0);
                     76:        USETW(req.wLength, len);
                     77:        return (usbd_do_request(dev, &req, desc));
                     78: }
                     79:
                     80: usbd_status
                     81: usbd_get_config_desc(usbd_device_handle dev, int confidx,
                     82:     usb_config_descriptor_t *d)
                     83: {
                     84:        usbd_status err;
                     85:
                     86:        DPRINTFN(3,("usbd_get_config_desc: confidx=%d\n", confidx));
                     87:        err = usbd_get_desc(dev, UDESC_CONFIG, confidx,
                     88:            USB_CONFIG_DESCRIPTOR_SIZE, d);
                     89:        if (err)
                     90:                return (err);
                     91:        if (d->bDescriptorType != UDESC_CONFIG) {
                     92:                DPRINTFN(-1,("usbd_get_config_desc: confidx=%d, bad desc "
                     93:                    "len=%d type=%d\n", confidx, d->bLength,
                     94:                    d->bDescriptorType));
                     95:                return (USBD_INVAL);
                     96:        }
                     97:        return (USBD_NORMAL_COMPLETION);
                     98: }
                     99:
                    100: usbd_status
                    101: usbd_get_config_desc_full(usbd_device_handle dev, int conf, void *d, int size)
                    102: {
                    103:        DPRINTFN(3,("usbd_get_config_desc_full: conf=%d\n", conf));
                    104:        return (usbd_get_desc(dev, UDESC_CONFIG, conf, size, d));
                    105: }
                    106:
                    107: usbd_status
                    108: usbd_get_device_desc(usbd_device_handle dev, usb_device_descriptor_t *d)
                    109: {
                    110:        DPRINTFN(3,("usbd_get_device_desc:\n"));
                    111:        return (usbd_get_desc(dev, UDESC_DEVICE, 0, USB_DEVICE_DESCRIPTOR_SIZE,
                    112:            d));
                    113: }
                    114:
                    115: usbd_status
                    116: usbd_get_device_status(usbd_device_handle dev, usb_status_t *st)
                    117: {
                    118:        usb_device_request_t req;
                    119:
                    120:        req.bmRequestType = UT_READ_DEVICE;
                    121:        req.bRequest = UR_GET_STATUS;
                    122:        USETW(req.wValue, 0);
                    123:        USETW(req.wIndex, 0);
                    124:        USETW(req.wLength, sizeof(usb_status_t));
                    125:        return (usbd_do_request(dev, &req, st));
                    126: }
                    127:
                    128: usbd_status
                    129: usbd_get_hub_status(usbd_device_handle dev, usb_hub_status_t *st)
                    130: {
                    131:        usb_device_request_t req;
                    132:
                    133:        req.bmRequestType = UT_READ_CLASS_DEVICE;
                    134:        req.bRequest = UR_GET_STATUS;
                    135:        USETW(req.wValue, 0);
                    136:        USETW(req.wIndex, 0);
                    137:        USETW(req.wLength, sizeof(usb_hub_status_t));
                    138:        return (usbd_do_request(dev, &req, st));
                    139: }
                    140:
                    141: usbd_status
                    142: usbd_set_address(usbd_device_handle dev, int addr)
                    143: {
                    144:        usb_device_request_t req;
                    145:
                    146:        req.bmRequestType = UT_WRITE_DEVICE;
                    147:        req.bRequest = UR_SET_ADDRESS;
                    148:        USETW(req.wValue, addr);
                    149:        USETW(req.wIndex, 0);
                    150:        USETW(req.wLength, 0);
                    151:        return usbd_do_request(dev, &req, 0);
                    152: }
                    153:
                    154: usbd_status
                    155: usbd_get_port_status(usbd_device_handle dev, int port, usb_port_status_t *ps)
                    156: {
                    157:        usb_device_request_t req;
                    158:
                    159:        req.bmRequestType = UT_READ_CLASS_OTHER;
                    160:        req.bRequest = UR_GET_STATUS;
                    161:        USETW(req.wValue, 0);
                    162:        USETW(req.wIndex, port);
                    163:        USETW(req.wLength, sizeof *ps);
                    164:        return (usbd_do_request(dev, &req, ps));
                    165: }
                    166:
                    167: usbd_status
                    168: usbd_clear_hub_feature(usbd_device_handle dev, int sel)
                    169: {
                    170:        usb_device_request_t req;
                    171:
                    172:        req.bmRequestType = UT_WRITE_CLASS_DEVICE;
                    173:        req.bRequest = UR_CLEAR_FEATURE;
                    174:        USETW(req.wValue, sel);
                    175:        USETW(req.wIndex, 0);
                    176:        USETW(req.wLength, 0);
                    177:        return (usbd_do_request(dev, &req, 0));
                    178: }
                    179:
                    180: usbd_status
                    181: usbd_set_hub_feature(usbd_device_handle dev, int sel)
                    182: {
                    183:        usb_device_request_t req;
                    184:
                    185:        req.bmRequestType = UT_WRITE_CLASS_DEVICE;
                    186:        req.bRequest = UR_SET_FEATURE;
                    187:        USETW(req.wValue, sel);
                    188:        USETW(req.wIndex, 0);
                    189:        USETW(req.wLength, 0);
                    190:        return (usbd_do_request(dev, &req, 0));
                    191: }
                    192:
                    193: usbd_status
                    194: usbd_clear_port_feature(usbd_device_handle dev, int port, int sel)
                    195: {
                    196:        usb_device_request_t req;
                    197:
                    198:        req.bmRequestType = UT_WRITE_CLASS_OTHER;
                    199:        req.bRequest = UR_CLEAR_FEATURE;
                    200:        USETW(req.wValue, sel);
                    201:        USETW(req.wIndex, port);
                    202:        USETW(req.wLength, 0);
                    203:        return (usbd_do_request(dev, &req, 0));
                    204: }
                    205:
                    206: usbd_status
                    207: usbd_set_port_feature(usbd_device_handle dev, int port, int sel)
                    208: {
                    209:        usb_device_request_t req;
                    210:
                    211:        req.bmRequestType = UT_WRITE_CLASS_OTHER;
                    212:        req.bRequest = UR_SET_FEATURE;
                    213:        USETW(req.wValue, sel);
                    214:        USETW(req.wIndex, port);
                    215:        USETW(req.wLength, 0);
                    216:        return (usbd_do_request(dev, &req, 0));
                    217: }
                    218:
                    219: usbd_status
                    220: usbd_get_protocol(usbd_interface_handle iface, u_int8_t *report)
                    221: {
                    222:        usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
                    223:        usbd_device_handle dev;
                    224:        usb_device_request_t req;
                    225:
                    226:        DPRINTFN(4, ("usbd_get_protocol: iface=%p, endpt=%d\n", iface,
                    227:            id->bInterfaceNumber));
                    228:        if (id == NULL)
                    229:                return (USBD_IOERROR);
                    230:        usbd_interface2device_handle(iface, &dev);
                    231:        req.bmRequestType = UT_READ_CLASS_INTERFACE;
                    232:        req.bRequest = UR_GET_PROTOCOL;
                    233:        USETW(req.wValue, 0);
                    234:        USETW(req.wIndex, id->bInterfaceNumber);
                    235:        USETW(req.wLength, 1);
                    236:        return (usbd_do_request(dev, &req, report));
                    237: }
                    238:
                    239: usbd_status
                    240: usbd_set_protocol(usbd_interface_handle iface, int report)
                    241: {
                    242:        usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
                    243:        usbd_device_handle dev;
                    244:        usb_device_request_t req;
                    245:
                    246:        DPRINTFN(4, ("usbd_set_protocol: iface=%p, report=%d, endpt=%d\n",
                    247:            iface, report, id->bInterfaceNumber));
                    248:        if (id == NULL)
                    249:                return (USBD_IOERROR);
                    250:        usbd_interface2device_handle(iface, &dev);
                    251:        req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
                    252:        req.bRequest = UR_SET_PROTOCOL;
                    253:        USETW(req.wValue, report);
                    254:        USETW(req.wIndex, id->bInterfaceNumber);
                    255:        USETW(req.wLength, 0);
                    256:        return (usbd_do_request(dev, &req, 0));
                    257: }
                    258:
                    259: usbd_status
                    260: usbd_set_report(usbd_interface_handle iface, int type, int id, void *data,
                    261:     int len)
                    262: {
                    263:        usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
                    264:        usbd_device_handle dev;
                    265:        usb_device_request_t req;
                    266:
                    267:        DPRINTFN(4, ("usbd_set_report: len=%d\n", len));
                    268:        if (ifd == NULL)
                    269:                return (USBD_IOERROR);
                    270:        usbd_interface2device_handle(iface, &dev);
                    271:        req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
                    272:        req.bRequest = UR_SET_REPORT;
                    273:        USETW2(req.wValue, type, id);
                    274:        USETW(req.wIndex, ifd->bInterfaceNumber);
                    275:        USETW(req.wLength, len);
                    276:        return (usbd_do_request(dev, &req, data));
                    277: }
                    278:
                    279: usbd_status
                    280: usbd_set_report_async(usbd_interface_handle iface, int type, int id,
                    281:     void *data, int len)
                    282: {
                    283:        usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
                    284:        usbd_device_handle dev;
                    285:        usb_device_request_t req;
                    286:
                    287:        DPRINTFN(4, ("usbd_set_report_async: len=%d\n", len));
                    288:        if (ifd == NULL)
                    289:                return (USBD_IOERROR);
                    290:        usbd_interface2device_handle(iface, &dev);
                    291:        req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
                    292:        req.bRequest = UR_SET_REPORT;
                    293:        USETW2(req.wValue, type, id);
                    294:        USETW(req.wIndex, ifd->bInterfaceNumber);
                    295:        USETW(req.wLength, len);
                    296:        return (usbd_do_request_async(dev, &req, data));
                    297: }
                    298:
                    299: usbd_status
                    300: usbd_get_report(usbd_interface_handle iface, int type, int id, void *data,
                    301:     int len)
                    302: {
                    303:        usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
                    304:        usbd_device_handle dev;
                    305:        usb_device_request_t req;
                    306:
                    307:        DPRINTFN(4, ("usbd_get_report: len=%d\n", len));
                    308:        if (ifd == NULL)
                    309:                return (USBD_IOERROR);
                    310:        usbd_interface2device_handle(iface, &dev);
                    311:        req.bmRequestType = UT_READ_CLASS_INTERFACE;
                    312:        req.bRequest = UR_GET_REPORT;
                    313:        USETW2(req.wValue, type, id);
                    314:        USETW(req.wIndex, ifd->bInterfaceNumber);
                    315:        USETW(req.wLength, len);
                    316:        return (usbd_do_request(dev, &req, data));
                    317: }
                    318:
                    319: usbd_status
                    320: usbd_set_idle(usbd_interface_handle iface, int duration, int id)
                    321: {
                    322:        usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
                    323:        usbd_device_handle dev;
                    324:        usb_device_request_t req;
                    325:
                    326:        DPRINTFN(4, ("usbd_set_idle: %d %d\n", duration, id));
                    327:        if (ifd == NULL)
                    328:                return (USBD_IOERROR);
                    329:        usbd_interface2device_handle(iface, &dev);
                    330:        req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
                    331:        req.bRequest = UR_SET_IDLE;
                    332:        USETW2(req.wValue, duration, id);
                    333:        USETW(req.wIndex, ifd->bInterfaceNumber);
                    334:        USETW(req.wLength, 0);
                    335:        return (usbd_do_request(dev, &req, 0));
                    336: }
                    337:
                    338: usbd_status
                    339: usbd_get_report_descriptor(usbd_device_handle dev, int ifcno, int size,
                    340:     void *d)
                    341: {
                    342:        usb_device_request_t req;
                    343:
                    344:        req.bmRequestType = UT_READ_INTERFACE;
                    345:        req.bRequest = UR_GET_DESCRIPTOR;
                    346:        USETW2(req.wValue, UDESC_REPORT, 0); /* report id should be 0 */
                    347:        USETW(req.wIndex, ifcno);
                    348:        USETW(req.wLength, size);
                    349:        return (usbd_do_request(dev, &req, d));
                    350: }
                    351:
                    352: usb_hid_descriptor_t *
                    353: usbd_get_hid_descriptor(usbd_interface_handle ifc)
                    354: {
                    355:        usb_interface_descriptor_t *idesc = usbd_get_interface_descriptor(ifc);
                    356:        usbd_device_handle dev;
                    357:        usb_config_descriptor_t *cdesc;
                    358:        usb_hid_descriptor_t *hd;
                    359:        char *p, *end;
                    360:
                    361:        if (idesc == NULL)
                    362:                return (0);
                    363:        usbd_interface2device_handle(ifc, &dev);
                    364:        cdesc = usbd_get_config_descriptor(dev);
                    365:
                    366:        p = (char *)idesc + idesc->bLength;
                    367:        end = (char *)cdesc + UGETW(cdesc->wTotalLength);
                    368:
                    369:        for (; p < end; p += hd->bLength) {
                    370:                hd = (usb_hid_descriptor_t *)p;
                    371:                if (p + hd->bLength <= end && hd->bDescriptorType == UDESC_HID)
                    372:                        return (hd);
                    373:                if (hd->bDescriptorType == UDESC_INTERFACE)
                    374:                        break;
                    375:        }
                    376:        return (0);
                    377: }
                    378:
                    379: usbd_status
                    380: usbd_read_report_desc(usbd_interface_handle ifc, void **descp, int *sizep,
                    381:     int mem)
                    382: {
                    383:        usb_interface_descriptor_t *id;
                    384:        usb_hid_descriptor_t *hid;
                    385:        usbd_device_handle dev;
                    386:        usbd_status err;
                    387:
                    388:        usbd_interface2device_handle(ifc, &dev);
                    389:        id = usbd_get_interface_descriptor(ifc);
                    390:        if (id == NULL)
                    391:                return (USBD_INVAL);
                    392:        hid = usbd_get_hid_descriptor(ifc);
                    393:        if (hid == NULL)
                    394:                return (USBD_IOERROR);
                    395:        *sizep = UGETW(hid->descrs[0].wDescriptorLength);
                    396:        *descp = malloc(*sizep, mem, M_NOWAIT);
                    397:        if (*descp == NULL)
                    398:                return (USBD_NOMEM);
                    399:        err = usbd_get_report_descriptor(dev, id->bInterfaceNumber, *sizep,
                    400:            *descp);
                    401:        if (err) {
                    402:                free(*descp, mem);
                    403:                *descp = NULL;
                    404:                return (err);
                    405:        }
                    406:        return (USBD_NORMAL_COMPLETION);
                    407: }
                    408:
                    409: usbd_status
                    410: usbd_get_config(usbd_device_handle dev, u_int8_t *conf)
                    411: {
                    412:        usb_device_request_t req;
                    413:
                    414:        req.bmRequestType = UT_READ_DEVICE;
                    415:        req.bRequest = UR_GET_CONFIG;
                    416:        USETW(req.wValue, 0);
                    417:        USETW(req.wIndex, 0);
                    418:        USETW(req.wLength, 1);
                    419:        return (usbd_do_request(dev, &req, conf));
                    420: }
                    421:
                    422: void usbd_bulk_transfer_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
                    423:     usbd_status status);
                    424: void
                    425: usbd_bulk_transfer_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
                    426:     usbd_status status)
                    427: {
                    428:        wakeup(xfer);
                    429: }
                    430:
                    431: usbd_status
                    432: usbd_bulk_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
                    433:     u_int16_t flags, u_int32_t timeout, void *buf, u_int32_t *size, char *lbl)
                    434: {
                    435:        usbd_status err;
                    436:        int s, error;
                    437:
                    438:        usbd_setup_xfer(xfer, pipe, 0, buf, *size, flags, timeout,
                    439:            usbd_bulk_transfer_cb);
                    440:        DPRINTFN(1, ("usbd_bulk_transfer: start transfer %d bytes\n", *size));
                    441:        s = splusb();           /* don't want callback until tsleep() */
                    442:        err = usbd_transfer(xfer);
                    443:        if (err != USBD_IN_PROGRESS) {
                    444:                splx(s);
                    445:                return (err);
                    446:        }
                    447:        error = tsleep((caddr_t)xfer, PZERO | PCATCH, lbl, 0);
                    448:        splx(s);
                    449:        if (error) {
                    450:                DPRINTF(("usbd_bulk_transfer: tsleep=%d\n", error));
                    451:                usbd_abort_pipe(pipe);
                    452:                return (USBD_INTERRUPTED);
                    453:        }
                    454:        usbd_get_xfer_status(xfer, NULL, NULL, size, &err);
                    455:        DPRINTFN(1,("usbd_bulk_transfer: transferred %d\n", *size));
                    456:        if (err) {
                    457:                DPRINTF(("usbd_bulk_transfer: error=%d\n", err));
                    458:                usbd_clear_endpoint_stall(pipe);
                    459:        }
                    460:        return (err);
                    461: }
                    462:
                    463: void usbd_intr_transfer_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
                    464:     usbd_status status);
                    465: void
                    466: usbd_intr_transfer_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
                    467:     usbd_status status)
                    468: {
                    469:        wakeup(xfer);
                    470: }
                    471:
                    472: usbd_status
                    473: usbd_intr_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
                    474:     u_int16_t flags, u_int32_t timeout, void *buf, u_int32_t *size, char *lbl)
                    475: {
                    476:        usbd_status err;
                    477:        int s, error;
                    478:
                    479:        usbd_setup_xfer(xfer, pipe, 0, buf, *size, flags, timeout,
                    480:            usbd_intr_transfer_cb);
                    481:        DPRINTFN(1, ("usbd_intr_transfer: start transfer %d bytes\n", *size));
                    482:        s = splusb();           /* don't want callback until tsleep() */
                    483:        err = usbd_transfer(xfer);
                    484:        if (err != USBD_IN_PROGRESS) {
                    485:                splx(s);
                    486:                return (err);
                    487:        }
                    488:        error = tsleep(xfer, PZERO | PCATCH, lbl, 0);
                    489:        splx(s);
                    490:        if (error) {
                    491:                DPRINTF(("usbd_intr_transfer: tsleep=%d\n", error));
                    492:                usbd_abort_pipe(pipe);
                    493:                return (USBD_INTERRUPTED);
                    494:        }
                    495:        usbd_get_xfer_status(xfer, NULL, NULL, size, &err);
                    496:        DPRINTFN(1,("usbd_intr_transfer: transferred %d\n", *size));
                    497:        if (err) {
                    498:                DPRINTF(("usbd_intr_transfer: error=%d\n", err));
                    499:                usbd_clear_endpoint_stall(pipe);
                    500:        }
                    501:        return (err);
                    502: }
                    503:
                    504: void
                    505: usb_detach_wait(struct device *dv)
                    506: {
                    507:        DPRINTF(("usb_detach_wait: waiting for %s\n", dv->dv_xname));
                    508:        if (tsleep(dv, PZERO, "usbdet", hz * 60))
                    509:                printf("usb_detach_wait: %s didn't detach\n", dv->dv_xname);
                    510:        DPRINTF(("usb_detach_wait: %s done\n", dv->dv_xname));
                    511: }
                    512:
                    513: void
                    514: usb_detach_wakeup(struct device *dv)
                    515: {
                    516:        DPRINTF(("usb_detach_wakeup: for %s\n", dv->dv_xname));
                    517:        wakeup(dv);
                    518: }
                    519:
                    520: usb_descriptor_t *
                    521: usb_find_desc(usbd_device_handle dev, int type)
                    522: {
                    523:        usb_descriptor_t *desc;
                    524:        usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
                    525:         uByte *p = (uByte *)cd;
                    526:         uByte *end = p + UGETW(cd->wTotalLength);
                    527:
                    528:        while (p < end) {
                    529:                desc = (usb_descriptor_t *)p;
                    530:                if (desc->bDescriptorType == type)
                    531:                        return (desc);
                    532:                p += desc->bLength;
                    533:        }
                    534:
                    535:        return (NULL);
                    536: }

CVSweb