[BACK]Return to usbdi_util.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / usb

Annotation of src/sys/dev/usb/usbdi_util.c, Revision 1.72

1.72    ! manu        1: /*     $NetBSD: usbdi_util.c,v 1.71 2018/07/24 03:58:36 msaitoh Exp $  */
1.1       augustss    2:
                      3: /*
1.57      mrg         4:  * Copyright (c) 1998, 2012 The NetBSD Foundation, Inc.
1.1       augustss    5:  * All rights reserved.
                      6:  *
1.5       augustss    7:  * This code is derived from software contributed to The NetBSD Foundation
1.30      augustss    8:  * by Lennart Augustsson (lennart@augustsson.net) at
1.57      mrg         9:  * Carlstedt Research & Technology and Matthew R. Green (mrg@eterna.com.au).
1.1       augustss   10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     21:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     22:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     23:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     24:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     25:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     26:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     27:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     28:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     29:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     30:  * POSSIBILITY OF SUCH DAMAGE.
                     31:  */
1.36      lukem      32:
                     33: #include <sys/cdefs.h>
1.72    ! manu       34: __KERNEL_RCSID(0, "$NetBSD: usbdi_util.c,v 1.71 2018/07/24 03:58:36 msaitoh Exp $");
1.63      skrll      35:
                     36: #ifdef _KERNEL_OPT
                     37: #include "opt_usb.h"
                     38: #endif
1.1       augustss   39:
                     40: #include <sys/param.h>
                     41: #include <sys/systm.h>
                     42: #include <sys/kernel.h>
1.65      skrll      43: #include <sys/kmem.h>
1.1       augustss   44: #include <sys/proc.h>
1.14      augustss   45: #include <sys/device.h>
1.57      mrg        46: #include <sys/bus.h>
1.1       augustss   47:
                     48: #include <dev/usb/usb.h>
                     49: #include <dev/usb/usbhid.h>
                     50: #include <dev/usb/usbdi.h>
1.57      mrg        51: #include <dev/usb/usbdivar.h>
1.1       augustss   52: #include <dev/usb/usbdi_util.h>
1.72    ! manu       53: #include <dev/usb/usb_quirks.h>
1.63      skrll      54: #include <dev/usb/usbhist.h>
1.1       augustss   55:
1.65      skrll      56: #define        DPRINTF(FMT,A,B,C,D)    USBHIST_LOGN(usbdebug,1,FMT,A,B,C,D)
                     57: #define        DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(usbdebug,N,FMT,A,B,C,D)
1.1       augustss   58:
                     59: usbd_status
1.65      skrll      60: usbd_get_desc(struct usbd_device *dev, int type, int index, int len, void *desc)
1.1       augustss   61: {
                     62:        usb_device_request_t req;
1.72    ! manu       63:        usbd_status err;
1.1       augustss   64:
1.65      skrll      65:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                     66:
1.70      pgoyette   67:        DPRINTFN(3,"type=%jd, index=%jd, len=%jd", type, index, len, 0);
1.26      augustss   68:
1.72    ! manu       69:        /*
        !            70:         * Provide hard-coded configuration descriptors
        !            71:         * for devices that may corrupt it. This cannot
        !            72:         * be done for device descriptors which are used
        !            73:         * to identify the device.
        !            74:         */
        !            75:        if (type != UDESC_DEVICE &&
        !            76:            dev->ud_quirks->uq_flags & UQ_DESC_CORRUPT) {
        !            77:                err = usbd_get_desc_fake(dev, type, index, len, desc);
        !            78:                goto out;
        !            79:        }
        !            80:
1.1       augustss   81:        req.bmRequestType = UT_READ_DEVICE;
                     82:        req.bRequest = UR_GET_DESCRIPTOR;
                     83:        USETW2(req.wValue, type, index);
                     84:        USETW(req.wIndex, 0);
                     85:        USETW(req.wLength, len);
1.72    ! manu       86:        err = usbd_do_request(dev, &req, desc);
        !            87:
        !            88: out:
        !            89:        return err;
1.1       augustss   90: }
                     91:
                     92: usbd_status
1.65      skrll      93: usbd_get_config_desc(struct usbd_device *dev, int confidx,
1.31      augustss   94:                     usb_config_descriptor_t *d)
1.1       augustss   95: {
1.65      skrll      96:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1.23      augustss   97:        usbd_status err;
1.9       augustss   98:
1.70      pgoyette   99:        DPRINTFN(3, "confidx=%jd", confidx, 0, 0, 0);
1.40      augustss  100:        err = usbd_get_desc(dev, UDESC_CONFIG, confidx,
1.26      augustss  101:                            USB_CONFIG_DESCRIPTOR_SIZE, d);
1.23      augustss  102:        if (err)
1.65      skrll     103:                return err;
1.9       augustss  104:        if (d->bDescriptorType != UDESC_CONFIG) {
1.70      pgoyette  105:                DPRINTFN(1, "confidx=%jd, bad desc len=%d type=%d",
1.65      skrll     106:                    confidx, d->bLength, d->bDescriptorType, 0);
                    107:                return USBD_INVAL;
1.9       augustss  108:        }
1.65      skrll     109:        return USBD_NORMAL_COMPLETION;
1.1       augustss  110: }
                    111:
                    112: usbd_status
1.65      skrll     113: usbd_get_config_desc_full(struct usbd_device *dev, int conf, void *d, int size)
1.4       augustss  114: {
1.65      skrll     115:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    116:
1.70      pgoyette  117:        DPRINTFN(3, "conf=%jd", conf, 0, 0, 0);
1.65      skrll     118:        return usbd_get_desc(dev, UDESC_CONFIG, conf, size, d);
1.4       augustss  119: }
                    120:
                    121: usbd_status
1.65      skrll     122: usbd_get_bos_desc(struct usbd_device *dev, int confidx,
1.64      skrll     123:                     usb_bos_descriptor_t *d)
                    124: {
1.65      skrll     125:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1.64      skrll     126:        usbd_status err;
                    127:
1.70      pgoyette  128:        DPRINTFN(3, "confidx=%jd", confidx, 0, 0, 0);
1.64      skrll     129:        err = usbd_get_desc(dev, UDESC_BOS, confidx,
                    130:                            USB_BOS_DESCRIPTOR_SIZE, d);
                    131:        if (err)
1.69      skrll     132:                return err;
1.64      skrll     133:        if (d->bDescriptorType != UDESC_BOS) {
1.70      pgoyette  134:                DPRINTFN(1, "confidx=%jd, bad desc len=%d type=%d",
1.65      skrll     135:                    confidx, d->bLength, d->bDescriptorType, 0);
                    136:                return USBD_INVAL;
1.64      skrll     137:        }
1.65      skrll     138:        return USBD_NORMAL_COMPLETION;
1.64      skrll     139: }
                    140:
                    141: usbd_status
1.65      skrll     142: usbd_get_bos_desc_full(struct usbd_device *dev, int conf, void *d, int size)
1.64      skrll     143: {
1.65      skrll     144:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    145:
1.70      pgoyette  146:        DPRINTFN(3, "conf=%jd", conf, 0, 0, 0);
1.65      skrll     147:        return usbd_get_desc(dev, UDESC_BOS, conf, size, d);
1.64      skrll     148: }
                    149:
                    150: usbd_status
1.65      skrll     151: usbd_get_device_desc(struct usbd_device *dev, usb_device_descriptor_t *d)
1.1       augustss  152: {
1.65      skrll     153:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    154:
1.69      skrll     155:        return usbd_get_desc(dev, UDESC_DEVICE,
                    156:                             0, USB_DEVICE_DESCRIPTOR_SIZE, d);
1.1       augustss  157: }
                    158:
                    159: usbd_status
1.65      skrll     160: usbd_get_device_status(struct usbd_device *dev, usb_status_t *st)
1.1       augustss  161: {
1.65      skrll     162:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1.1       augustss  163:        usb_device_request_t req;
                    164:
                    165:        req.bmRequestType = UT_READ_DEVICE;
                    166:        req.bRequest = UR_GET_STATUS;
                    167:        USETW(req.wValue, 0);
                    168:        USETW(req.wIndex, 0);
                    169:        USETW(req.wLength, sizeof(usb_status_t));
1.65      skrll     170:        return usbd_do_request(dev, &req, st);
1.40      augustss  171: }
1.1       augustss  172:
                    173: usbd_status
1.65      skrll     174: usbd_get_hub_status(struct usbd_device *dev, usb_hub_status_t *st)
1.1       augustss  175: {
1.65      skrll     176:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1.1       augustss  177:        usb_device_request_t req;
                    178:
1.70      pgoyette  179:        DPRINTF("dev %#jx", (uintptr_t)dev, 0, 0, 0);
1.1       augustss  180:        req.bmRequestType = UT_READ_CLASS_DEVICE;
                    181:        req.bRequest = UR_GET_STATUS;
                    182:        USETW(req.wValue, 0);
                    183:        USETW(req.wIndex, 0);
                    184:        USETW(req.wLength, sizeof(usb_hub_status_t));
1.65      skrll     185:        return usbd_do_request(dev, &req, st);
1.40      augustss  186: }
1.1       augustss  187:
                    188: usbd_status
1.65      skrll     189: usbd_set_address(struct usbd_device *dev, int addr)
1.1       augustss  190: {
1.65      skrll     191:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1.1       augustss  192:        usb_device_request_t req;
                    193:
1.70      pgoyette  194:        DPRINTF("dev %#jx addr %jd", (uintptr_t)dev, addr, 0, 0);
1.1       augustss  195:        req.bmRequestType = UT_WRITE_DEVICE;
                    196:        req.bRequest = UR_SET_ADDRESS;
                    197:        USETW(req.wValue, addr);
                    198:        USETW(req.wIndex, 0);
                    199:        USETW(req.wLength, 0);
                    200:        return usbd_do_request(dev, &req, 0);
                    201: }
                    202:
                    203: usbd_status
1.65      skrll     204: usbd_get_port_status(struct usbd_device *dev, int port, usb_port_status_t *ps)
1.1       augustss  205: {
1.65      skrll     206:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1.1       augustss  207:        usb_device_request_t req;
                    208:
1.70      pgoyette  209:        DPRINTF("dev %#jx port %jd", (uintptr_t)dev, port, 0, 0);
1.1       augustss  210:        req.bmRequestType = UT_READ_CLASS_OTHER;
                    211:        req.bRequest = UR_GET_STATUS;
                    212:        USETW(req.wValue, 0);
                    213:        USETW(req.wIndex, port);
1.65      skrll     214:        USETW(req.wLength, sizeof(*ps));
                    215:        return usbd_do_request(dev, &req, ps);
                    216: }
                    217:
                    218: /* USB 3.1 10.16.2.6, 10.16.2.6.3 */
                    219: usbd_status
                    220: usbd_get_port_status_ext(struct usbd_device *dev, int port,
                    221:     usb_port_status_ext_t *pse)
                    222: {
                    223:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    224:        usb_device_request_t req;
                    225:
1.70      pgoyette  226:        DPRINTF("dev %#jx port %jd", (uintptr_t)dev, port, 0, 0);
1.65      skrll     227:        req.bmRequestType = UT_READ_CLASS_OTHER;
                    228:        req.bRequest = UR_GET_STATUS;
                    229:        USETW2(req.wValue, 0, UR_PST_EXT_PORT_STATUS);
                    230:        USETW(req.wIndex, port);
                    231:        USETW(req.wLength, sizeof(*pse));
1.69      skrll     232:        return usbd_do_request(dev, &req, pse);
1.16      augustss  233: }
                    234:
                    235: usbd_status
1.65      skrll     236: usbd_clear_hub_feature(struct usbd_device *dev, int sel)
1.16      augustss  237: {
1.65      skrll     238:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1.16      augustss  239:        usb_device_request_t req;
                    240:
1.70      pgoyette  241:        DPRINTF("dev %#jx sel %jd", (uintptr_t)dev, sel, 0, 0);
1.16      augustss  242:        req.bmRequestType = UT_WRITE_CLASS_DEVICE;
                    243:        req.bRequest = UR_CLEAR_FEATURE;
                    244:        USETW(req.wValue, sel);
                    245:        USETW(req.wIndex, 0);
                    246:        USETW(req.wLength, 0);
1.65      skrll     247:        return usbd_do_request(dev, &req, 0);
1.16      augustss  248: }
                    249:
                    250: usbd_status
1.65      skrll     251: usbd_set_hub_feature(struct usbd_device *dev, int sel)
1.16      augustss  252: {
1.65      skrll     253:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1.16      augustss  254:        usb_device_request_t req;
                    255:
1.70      pgoyette  256:        DPRINTF("dev %#jx sel %jd", (uintptr_t)dev, sel, 0, 0);
1.16      augustss  257:        req.bmRequestType = UT_WRITE_CLASS_DEVICE;
                    258:        req.bRequest = UR_SET_FEATURE;
                    259:        USETW(req.wValue, sel);
                    260:        USETW(req.wIndex, 0);
                    261:        USETW(req.wLength, 0);
1.65      skrll     262:        return usbd_do_request(dev, &req, 0);
1.1       augustss  263: }
                    264:
                    265: usbd_status
1.65      skrll     266: usbd_clear_port_feature(struct usbd_device *dev, int port, int sel)
1.1       augustss  267: {
1.65      skrll     268:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1.1       augustss  269:        usb_device_request_t req;
                    270:
1.70      pgoyette  271:        DPRINTF("dev %#jx port %jd sel %jd", (uintptr_t)dev, port, sel, 0);
1.1       augustss  272:        req.bmRequestType = UT_WRITE_CLASS_OTHER;
                    273:        req.bRequest = UR_CLEAR_FEATURE;
                    274:        USETW(req.wValue, sel);
                    275:        USETW(req.wIndex, port);
                    276:        USETW(req.wLength, 0);
1.65      skrll     277:        return usbd_do_request(dev, &req, 0);
1.1       augustss  278: }
                    279:
                    280: usbd_status
1.65      skrll     281: usbd_set_port_feature(struct usbd_device *dev, int port, int sel)
1.1       augustss  282: {
1.65      skrll     283:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1.1       augustss  284:        usb_device_request_t req;
                    285:
1.70      pgoyette  286:        DPRINTF("dev %#jx port %jd sel %.d", (uintptr_t)dev, sel, 0, 0);
1.1       augustss  287:        req.bmRequestType = UT_WRITE_CLASS_OTHER;
                    288:        req.bRequest = UR_SET_FEATURE;
                    289:        USETW(req.wValue, sel);
                    290:        USETW(req.wIndex, port);
                    291:        USETW(req.wLength, 0);
1.65      skrll     292:        return usbd_do_request(dev, &req, 0);
1.1       augustss  293: }
                    294:
1.39      augustss  295: usbd_status
1.65      skrll     296: usbd_set_port_u1_timeout(struct usbd_device *dev, int port, int timeout)
                    297: {
                    298:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    299:        usb_device_request_t req;
                    300:
1.70      pgoyette  301:        DPRINTF("dev %#jx port %jd timeout %.d", (uintptr_t)dev, port,
                    302:            timeout, 0);
1.65      skrll     303:        req.bmRequestType = UT_WRITE_CLASS_OTHER;
                    304:        req.bRequest = UR_SET_FEATURE;
                    305:        USETW(req.wValue, UHF_PORT_U1_TIMEOUT);
                    306:        USETW2(req.wIndex, timeout, port);
                    307:        USETW(req.wLength, 0);
                    308:        return usbd_do_request(dev, &req, 0);
                    309: }
                    310:
                    311: usbd_status
                    312: usbd_set_port_u2_timeout(struct usbd_device *dev, int port, int timeout)
                    313: {
                    314:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    315:        usb_device_request_t req;
                    316:
1.70      pgoyette  317:        DPRINTF("dev %#jx port %jd timeout %jd", (uintptr_t)dev, port,
                    318:            timeout, 0);
1.65      skrll     319:        req.bmRequestType = UT_WRITE_CLASS_OTHER;
                    320:        req.bRequest = UR_SET_FEATURE;
                    321:        USETW(req.wValue, UHF_PORT_U2_TIMEOUT);
                    322:        USETW2(req.wIndex, timeout, port);
                    323:        USETW(req.wLength, 0);
                    324:        return usbd_do_request(dev, &req, 0);
                    325: }
                    326:
                    327: usbd_status
                    328: usbd_get_protocol(struct usbd_interface *iface, uint8_t *report)
1.39      augustss  329: {
                    330:        usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
1.65      skrll     331:        struct usbd_device *dev;
1.39      augustss  332:        usb_device_request_t req;
                    333:
1.65      skrll     334:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    335:
1.39      augustss  336:        if (id == NULL)
1.65      skrll     337:                return USBD_IOERROR;
1.70      pgoyette  338:        DPRINTFN(4, "iface=%#jx, endpt=%jd", (uintptr_t)iface,
                    339:            id->bInterfaceNumber, 0, 0);
1.68      maya      340:
1.39      augustss  341:        usbd_interface2device_handle(iface, &dev);
                    342:        req.bmRequestType = UT_READ_CLASS_INTERFACE;
                    343:        req.bRequest = UR_GET_PROTOCOL;
                    344:        USETW(req.wValue, 0);
                    345:        USETW(req.wIndex, id->bInterfaceNumber);
                    346:        USETW(req.wLength, 1);
1.65      skrll     347:        return usbd_do_request(dev, &req, report);
1.39      augustss  348: }
1.1       augustss  349:
                    350: usbd_status
1.65      skrll     351: usbd_set_protocol(struct usbd_interface *iface, int report)
1.1       augustss  352: {
                    353:        usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
1.65      skrll     354:        struct usbd_device *dev;
1.1       augustss  355:        usb_device_request_t req;
                    356:
1.65      skrll     357:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    358:
1.67      maya      359:        if (id == NULL)
                    360:                return USBD_IOERROR;
1.70      pgoyette  361:        DPRINTFN(4, "iface=%#jx, report=%jd, endpt=%jd", (uintptr_t)iface,
                    362:            report, id->bInterfaceNumber, 0);
1.67      maya      363:
1.37      augustss  364:        usbd_interface2device_handle(iface, &dev);
1.1       augustss  365:        req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
                    366:        req.bRequest = UR_SET_PROTOCOL;
                    367:        USETW(req.wValue, report);
                    368:        USETW(req.wIndex, id->bInterfaceNumber);
                    369:        USETW(req.wLength, 0);
1.65      skrll     370:        return usbd_do_request(dev, &req, 0);
1.1       augustss  371: }
                    372:
                    373: usbd_status
1.65      skrll     374: usbd_set_report(struct usbd_interface *iface, int type, int id, void *data,
1.31      augustss  375:                int len)
1.1       augustss  376: {
                    377:        usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
1.65      skrll     378:        struct usbd_device *dev;
1.1       augustss  379:        usb_device_request_t req;
                    380:
1.65      skrll     381:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    382:
1.70      pgoyette  383:        DPRINTFN(4, "len=%jd", len, 0, 0, 0);
1.23      augustss  384:        if (ifd == NULL)
1.65      skrll     385:                return USBD_IOERROR;
1.37      augustss  386:        usbd_interface2device_handle(iface, &dev);
1.1       augustss  387:        req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
                    388:        req.bRequest = UR_SET_REPORT;
1.2       augustss  389:        USETW2(req.wValue, type, id);
                    390:        USETW(req.wIndex, ifd->bInterfaceNumber);
                    391:        USETW(req.wLength, len);
1.65      skrll     392:        return usbd_do_request(dev, &req, data);
1.3       augustss  393: }
                    394:
                    395: usbd_status
1.65      skrll     396: usbd_get_report(struct usbd_interface *iface, int type, int id, void *data,
1.31      augustss  397:                int len)
1.2       augustss  398: {
                    399:        usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
1.65      skrll     400:        struct usbd_device *dev;
1.2       augustss  401:        usb_device_request_t req;
                    402:
1.65      skrll     403:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    404:
1.70      pgoyette  405:        DPRINTFN(4, "len=%jd", len, 0, 0, 0);
1.28      augustss  406:        if (ifd == NULL)
1.65      skrll     407:                return USBD_IOERROR;
1.37      augustss  408:        usbd_interface2device_handle(iface, &dev);
1.2       augustss  409:        req.bmRequestType = UT_READ_CLASS_INTERFACE;
                    410:        req.bRequest = UR_GET_REPORT;
1.1       augustss  411:        USETW2(req.wValue, type, id);
                    412:        USETW(req.wIndex, ifd->bInterfaceNumber);
                    413:        USETW(req.wLength, len);
1.65      skrll     414:        return usbd_do_request(dev, &req, data);
1.1       augustss  415: }
                    416:
                    417: usbd_status
1.65      skrll     418: usbd_set_idle(struct usbd_interface *iface, int duration, int id)
1.1       augustss  419: {
                    420:        usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
1.65      skrll     421:        struct usbd_device *dev;
1.1       augustss  422:        usb_device_request_t req;
                    423:
1.65      skrll     424:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    425:
1.70      pgoyette  426:        DPRINTFN(4, "duration %jd id %jd", duration, id, 0, 0);
1.23      augustss  427:        if (ifd == NULL)
1.65      skrll     428:                return USBD_IOERROR;
1.37      augustss  429:        usbd_interface2device_handle(iface, &dev);
1.1       augustss  430:        req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
                    431:        req.bRequest = UR_SET_IDLE;
                    432:        USETW2(req.wValue, duration, id);
                    433:        USETW(req.wIndex, ifd->bInterfaceNumber);
                    434:        USETW(req.wLength, 0);
1.65      skrll     435:        return usbd_do_request(dev, &req, 0);
1.1       augustss  436: }
                    437:
                    438: usbd_status
1.65      skrll     439: usbd_get_report_descriptor(struct usbd_device *dev, int ifcno,
1.31      augustss  440:                           int size, void *d)
1.1       augustss  441: {
1.65      skrll     442:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1.1       augustss  443:        usb_device_request_t req;
                    444:
1.70      pgoyette  445:        DPRINTF("dev %#jx ifcno %jd size %jd", (uintptr_t)dev, ifcno, size, 0);
1.1       augustss  446:        req.bmRequestType = UT_READ_INTERFACE;
                    447:        req.bRequest = UR_GET_DESCRIPTOR;
1.35      augustss  448:        USETW2(req.wValue, UDESC_REPORT, 0); /* report id should be 0 */
1.6       augustss  449:        USETW(req.wIndex, ifcno);
1.1       augustss  450:        USETW(req.wLength, size);
1.65      skrll     451:        return usbd_do_request(dev, &req, d);
1.1       augustss  452: }
                    453:
                    454: usb_hid_descriptor_t *
1.65      skrll     455: usbd_get_hid_descriptor(struct usbd_interface *ifc)
1.1       augustss  456: {
                    457:        usb_interface_descriptor_t *idesc = usbd_get_interface_descriptor(ifc);
1.65      skrll     458:        struct usbd_device *dev;
1.1       augustss  459:        usb_config_descriptor_t *cdesc;
                    460:        usb_hid_descriptor_t *hd;
                    461:        char *p, *end;
                    462:
1.23      augustss  463:        if (idesc == NULL)
1.65      skrll     464:                return NULL;
1.41      augustss  465:        usbd_interface2device_handle(ifc, &dev);
1.1       augustss  466:        cdesc = usbd_get_config_descriptor(dev);
                    467:
                    468:        p = (char *)idesc + idesc->bLength;
                    469:        end = (char *)cdesc + UGETW(cdesc->wTotalLength);
                    470:
                    471:        for (; p < end; p += hd->bLength) {
                    472:                hd = (usb_hid_descriptor_t *)p;
                    473:                if (p + hd->bLength <= end && hd->bDescriptorType == UDESC_HID)
1.65      skrll     474:                        return hd;
1.1       augustss  475:                if (hd->bDescriptorType == UDESC_INTERFACE)
                    476:                        break;
                    477:        }
1.65      skrll     478:        return NULL;
1.1       augustss  479: }
                    480:
                    481: usbd_status
1.65      skrll     482: usbd_read_report_desc(struct usbd_interface *ifc, void **descp, int *sizep)
1.1       augustss  483: {
1.6       augustss  484:        usb_interface_descriptor_t *id;
1.1       augustss  485:        usb_hid_descriptor_t *hid;
1.65      skrll     486:        struct usbd_device *dev;
1.23      augustss  487:        usbd_status err;
1.1       augustss  488:
1.37      augustss  489:        usbd_interface2device_handle(ifc, &dev);
1.6       augustss  490:        id = usbd_get_interface_descriptor(ifc);
1.23      augustss  491:        if (id == NULL)
1.65      skrll     492:                return USBD_INVAL;
1.1       augustss  493:        hid = usbd_get_hid_descriptor(ifc);
1.25      augustss  494:        if (hid == NULL)
1.65      skrll     495:                return USBD_IOERROR;
1.1       augustss  496:        *sizep = UGETW(hid->descrs[0].wDescriptorLength);
1.65      skrll     497:        *descp = kmem_alloc(*sizep, KM_SLEEP);
1.35      augustss  498:        err = usbd_get_report_descriptor(dev, id->bInterfaceNumber,
                    499:                                         *sizep, *descp);
1.23      augustss  500:        if (err) {
1.65      skrll     501:                kmem_free(*descp, *sizep);
1.34      augustss  502:                *descp = NULL;
1.65      skrll     503:                return err;
1.1       augustss  504:        }
1.65      skrll     505:        return USBD_NORMAL_COMPLETION;
1.7       augustss  506: }
                    507:
1.40      augustss  508: usbd_status
1.65      skrll     509: usbd_get_config(struct usbd_device *dev, uint8_t *conf)
1.7       augustss  510: {
1.65      skrll     511:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1.7       augustss  512:        usb_device_request_t req;
                    513:
1.70      pgoyette  514:        DPRINTF("dev %#jx", (uintptr_t)dev, 0, 0, 0);
1.7       augustss  515:        req.bmRequestType = UT_READ_DEVICE;
                    516:        req.bRequest = UR_GET_CONFIG;
                    517:        USETW(req.wValue, 0);
                    518:        USETW(req.wIndex, 0);
                    519:        USETW(req.wLength, 1);
1.65      skrll     520:        return usbd_do_request(dev, &req, conf);
1.1       augustss  521: }
1.10      augustss  522:
                    523: usbd_status
1.65      skrll     524: usbd_bulk_transfer(struct usbd_xfer *xfer, struct usbd_pipe *pipe,
                    525:     uint16_t flags, uint32_t timeout, void *buf, uint32_t *size)
1.10      augustss  526: {
1.23      augustss  527:        usbd_status err;
1.10      augustss  528:
1.63      skrll     529:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    530:
1.65      skrll     531:        usbd_setup_xfer(xfer, 0, buf, *size, flags, timeout, NULL);
1.70      pgoyette  532:        DPRINTFN(1, "start transfer %jd bytes", *size, 0, 0, 0);
1.61      skrll     533:        err = usbd_sync_transfer_sig(xfer);
1.57      mrg       534:
                    535:        usbd_get_xfer_status(xfer, NULL, NULL, size, NULL);
1.70      pgoyette  536:        DPRINTFN(1, "transferred %jd", *size, 0, 0, 0);
1.23      augustss  537:        if (err) {
1.10      augustss  538:                usbd_clear_endpoint_stall(pipe);
                    539:        }
1.70      pgoyette  540:        USBHIST_LOG(usbdebug, "<- done xfer %#jx err %d", (uintptr_t)xfer,
                    541:            err, 0, 0);
1.61      skrll     542:
1.65      skrll     543:        return err;
1.10      augustss  544: }
                    545:
1.42      augustss  546: usbd_status
1.65      skrll     547: usbd_intr_transfer(struct usbd_xfer *xfer, struct usbd_pipe *pipe,
                    548:     uint16_t flags, uint32_t timeout, void *buf, uint32_t *size)
1.42      augustss  549: {
                    550:        usbd_status err;
                    551:
1.63      skrll     552:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    553:
1.65      skrll     554:        usbd_setup_xfer(xfer, 0, buf, *size, flags, timeout, NULL);
1.61      skrll     555:
1.70      pgoyette  556:        DPRINTFN(1, "start transfer %jd bytes", *size, 0, 0, 0);
1.57      mrg       557:        err = usbd_sync_transfer_sig(xfer);
1.61      skrll     558:
1.57      mrg       559:        usbd_get_xfer_status(xfer, NULL, NULL, size, NULL);
1.61      skrll     560:
1.70      pgoyette  561:        DPRINTFN(1, "transferred %jd", *size, 0, 0, 0);
1.42      augustss  562:        if (err) {
                    563:                usbd_clear_endpoint_stall(pipe);
                    564:        }
1.70      pgoyette  565:        USBHIST_LOG(usbdebug, "<- done xfer %#jx err %jd", (uintptr_t)xfer,
                    566:            err, 0, 0);
1.63      skrll     567:
1.65      skrll     568:        return err;
1.42      augustss  569: }
                    570:
1.14      augustss  571: void
1.57      mrg       572: usb_detach_wait(device_t dv, kcondvar_t *cv, kmutex_t *lock)
                    573: {
1.65      skrll     574:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    575:
1.70      pgoyette  576:        DPRINTFN(1, "waiting for dv %#jx", (uintptr_t)dv, 0, 0, 0);
1.57      mrg       577:        if (cv_timedwait(cv, lock, hz * 60))    // dv, PZERO, "usbdet", hz * 60
1.71      msaitoh   578:                aprint_error_dev(dv, "usb_detach_wait: didn't detach\n");
1.65      skrll     579:        DPRINTFN(1, "done", 0, 0, 0, 0);
1.57      mrg       580: }
                    581:
                    582: void
                    583: usb_detach_broadcast(device_t dv, kcondvar_t *cv)
                    584: {
1.65      skrll     585:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    586:
1.70      pgoyette  587:        DPRINTFN(1, "for dv %#jx", (uintptr_t)dv, 0, 0, 0);
1.57      mrg       588:        cv_broadcast(cv);
                    589: }
                    590:
                    591: void
1.56      mrg       592: usb_detach_waitold(device_t dv)
1.14      augustss  593: {
1.65      skrll     594:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    595:
1.70      pgoyette  596:        DPRINTFN(1, "waiting for dv %#jx", (uintptr_t)dv, 0, 0, 0);
1.57      mrg       597:        if (tsleep(dv, PZERO, "usbdet", hz * 60)) /* XXXSMP ok */
1.71      msaitoh   598:                aprint_error_dev(dv, "usb_detach_waitold: didn't detach\n");
1.65      skrll     599:        DPRINTFN(1, "done", 0, 0, 0, 0);
1.40      augustss  600: }
1.14      augustss  601:
                    602: void
1.56      mrg       603: usb_detach_wakeupold(device_t dv)
1.14      augustss  604: {
1.65      skrll     605:        USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
                    606:
1.70      pgoyette  607:        DPRINTFN(1, "for dv %#jx", (uintptr_t)dv, 0, 0, 0);
1.57      mrg       608:        wakeup(dv); /* XXXSMP ok */
1.40      augustss  609: }
1.38      augustss  610:
1.48      drochner  611: const usb_cdc_descriptor_t *
1.65      skrll     612: usb_find_desc(struct usbd_device *dev, int type, int subtype)
1.38      augustss  613: {
1.41      augustss  614:        usbd_desc_iter_t iter;
1.48      drochner  615:        const usb_cdc_descriptor_t *desc;
1.41      augustss  616:
                    617:        usb_desc_iter_init(dev, &iter);
                    618:        for (;;) {
1.48      drochner  619:                desc = (const usb_cdc_descriptor_t *)usb_desc_iter_next(&iter);
1.41      augustss  620:                if (!desc || (desc->bDescriptorType == type &&
1.48      drochner  621:                              (subtype == USBD_CDCSUBTYPE_ANY ||
1.41      augustss  622:                               subtype == desc->bDescriptorSubtype)))
                    623:                        break;
1.38      augustss  624:        }
1.41      augustss  625:        return desc;
1.38      augustss  626: }
1.43      itohy     627:
                    628: /* same as usb_find_desc(), but searches only in the specified interface. */
1.48      drochner  629: const usb_cdc_descriptor_t *
1.65      skrll     630: usb_find_desc_if(struct usbd_device *dev, int type, int subtype,
1.43      itohy     631:                 usb_interface_descriptor_t *id)
                    632: {
                    633:        usbd_desc_iter_t iter;
1.48      drochner  634:        const usb_cdc_descriptor_t *desc;
1.43      itohy     635:
1.54      christos  636:        if (id == NULL)
                    637:                return usb_find_desc(dev, type, subtype);
                    638:
1.43      itohy     639:        usb_desc_iter_init(dev, &iter);
                    640:
                    641:        iter.cur = (void *)id;          /* start from the interface desc */
                    642:        usb_desc_iter_next(&iter);      /* and skip it */
                    643:
1.48      drochner  644:        while ((desc = (const usb_cdc_descriptor_t *)usb_desc_iter_next(&iter))
                    645:               != NULL) {
1.43      itohy     646:                if (desc->bDescriptorType == UDESC_INTERFACE) {
                    647:                        /* we ran into the next interface --- not found */
                    648:                        return NULL;
                    649:                }
                    650:                if (desc->bDescriptorType == type &&
1.48      drochner  651:                    (subtype == USBD_CDCSUBTYPE_ANY ||
1.43      itohy     652:                     subtype == desc->bDescriptorSubtype))
                    653:                        break;
                    654:        }
                    655:        return desc;
                    656: }

CVSweb <webmaster@jp.NetBSD.org>