[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     ! 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