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

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

1.1       nbrk        1: /*     $OpenBSD: usb_subr.c,v 1.57 2007/07/21 16:28:50 deraadt Exp $ */
                      2: /*     $NetBSD: usb_subr.c,v 1.103 2003/01/10 11:19:13 augustss Exp $  */
                      3: /*     $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 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/device.h>
                     47: #include <sys/selinfo.h>
                     48: #include <sys/proc.h>
                     49:
                     50: #include <machine/bus.h>
                     51:
                     52: #include <dev/usb/usb.h>
                     53:
                     54: #include <dev/usb/usbdi.h>
                     55: #include <dev/usb/usbdi_util.h>
                     56: #include <dev/usb/usbdivar.h>
                     57: #include <dev/usb/usbdevs.h>
                     58: #include <dev/usb/usb_quirks.h>
                     59:
                     60: #ifdef USB_DEBUG
                     61: #define DPRINTF(x)     do { if (usbdebug) printf x; } while (0)
                     62: #define DPRINTFN(n,x)  do { if (usbdebug>(n)) printf x; } while (0)
                     63: extern int usbdebug;
                     64: #else
                     65: #define DPRINTF(x)
                     66: #define DPRINTFN(n,x)
                     67: #endif
                     68:
                     69: usbd_status    usbd_set_config(usbd_device_handle, int);
                     70: void           usbd_devinfo(usbd_device_handle, int, char *, size_t);
                     71: void           usbd_devinfo_vp(usbd_device_handle, char *, char *,
                     72:                            int);
                     73: char           *usbd_get_string(usbd_device_handle, int, char *);
                     74: int            usbd_getnewaddr(usbd_bus_handle);
                     75: int            usbd_print(void *, const char *);
                     76: int            usbd_submatch(struct device *, void *, void *);
                     77: void           usbd_free_iface_data(usbd_device_handle, int);
                     78: void           usbd_kill_pipe(usbd_pipe_handle);
                     79: usbd_status    usbd_probe_and_attach(struct device *,
                     80:                            usbd_device_handle, int, int);
                     81:
                     82: u_int32_t      usb_cookie_no = 0;
                     83:
                     84: #ifdef USBVERBOSE
                     85: #include <dev/usb/usbdevs_data.h>
                     86: #endif /* USBVERBOSE */
                     87:
                     88: const char * const usbd_error_strs[] = {
                     89:        "NORMAL_COMPLETION",
                     90:        "IN_PROGRESS",
                     91:        "PENDING_REQUESTS",
                     92:        "NOT_STARTED",
                     93:        "INVAL",
                     94:        "NOMEM",
                     95:        "CANCELLED",
                     96:        "BAD_ADDRESS",
                     97:        "IN_USE",
                     98:        "NO_ADDR",
                     99:        "SET_ADDR_FAILED",
                    100:        "NO_POWER",
                    101:        "TOO_DEEP",
                    102:        "IOERROR",
                    103:        "NOT_CONFIGURED",
                    104:        "TIMEOUT",
                    105:        "SHORT_XFER",
                    106:        "STALLED",
                    107:        "INTERRUPTED",
                    108:        "XXX",
                    109: };
                    110:
                    111: const char *
                    112: usbd_errstr(usbd_status err)
                    113: {
                    114:        static char buffer[5];
                    115:
                    116:        if (err < USBD_ERROR_MAX)
                    117:                return (usbd_error_strs[err]);
                    118:        else {
                    119:                snprintf(buffer, sizeof(buffer), "%d", err);
                    120:                return (buffer);
                    121:        }
                    122: }
                    123:
                    124: usbd_status
                    125: usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid,
                    126:     usb_string_descriptor_t *sdesc, int *sizep)
                    127: {
                    128:        usb_device_request_t req;
                    129:        usbd_status err;
                    130:        int actlen;
                    131:
                    132:        req.bmRequestType = UT_READ_DEVICE;
                    133:        req.bRequest = UR_GET_DESCRIPTOR;
                    134:        USETW2(req.wValue, UDESC_STRING, sindex);
                    135:        USETW(req.wIndex, langid);
                    136:        USETW(req.wLength, 1);  /* only size byte first */
                    137:        err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
                    138:            &actlen, USBD_DEFAULT_TIMEOUT);
                    139:        if (err)
                    140:                return (err);
                    141:
                    142:        if (actlen < 1)
                    143:                return (USBD_SHORT_XFER);
                    144:
                    145:        USETW(req.wLength, sdesc->bLength);     /* the whole string */
                    146:        err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
                    147:            &actlen, USBD_DEFAULT_TIMEOUT);
                    148:        if (err)
                    149:                return (err);
                    150:
                    151:        if (actlen != sdesc->bLength) {
                    152:                DPRINTFN(-1, ("usbd_get_string_desc: expected %d, got %d\n",
                    153:                    sdesc->bLength, actlen));
                    154:        }
                    155:
                    156:        *sizep = actlen;
                    157:        return (USBD_NORMAL_COMPLETION);
                    158: }
                    159:
                    160: char *
                    161: usbd_get_string(usbd_device_handle dev, int si, char *buf)
                    162: {
                    163:        int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE;
                    164:        usb_string_descriptor_t us;
                    165:        char *s;
                    166:        int i, n;
                    167:        u_int16_t c;
                    168:        usbd_status err;
                    169:        int size;
                    170:
                    171:        if (si == 0)
                    172:                return (0);
                    173:        if (dev->quirks->uq_flags & UQ_NO_STRINGS)
                    174:                return (0);
                    175:        if (dev->langid == USBD_NOLANG) {
                    176:                /* Set up default language */
                    177:                err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us,
                    178:                    &size);
                    179:                if (err || size < 4)
                    180:                        dev->langid = 0; /* Well, just pick English then */
                    181:                else {
                    182:                        /* Pick the first language as the default. */
                    183:                        dev->langid = UGETW(us.bString[0]);
                    184:                }
                    185:        }
                    186:        err = usbd_get_string_desc(dev, si, dev->langid, &us, &size);
                    187:        if (err)
                    188:                return (0);
                    189:        s = buf;
                    190:        n = size / 2 - 1;
                    191:        for (i = 0; i < n; i++) {
                    192:                c = UGETW(us.bString[i]);
                    193:                /* Convert from Unicode, handle buggy strings. */
                    194:                if ((c & 0xff00) == 0)
                    195:                        *s++ = c;
                    196:                else if ((c & 0x00ff) == 0 && swap)
                    197:                        *s++ = c >> 8;
                    198:                else
                    199:                        *s++ = '?';
                    200:        }
                    201:        *s++ = 0;
                    202:        return (buf);
                    203: }
                    204:
                    205: static void
                    206: usbd_trim_spaces(char *p)
                    207: {
                    208:        char *q, *e;
                    209:
                    210:        if (p == NULL)
                    211:                return;
                    212:        q = e = p;
                    213:        while (*q == ' ')       /* skip leading spaces */
                    214:                q++;
                    215:        while ((*p = *q++))     /* copy string */
                    216:                if (*p++ != ' ') /* remember last non-space */
                    217:                        e = p;
                    218:        *e = 0;                 /* kill trailing spaces */
                    219: }
                    220:
                    221: void
                    222: usbd_devinfo_vp(usbd_device_handle dev, char *v, char *p, int usedev)
                    223: {
                    224:        usb_device_descriptor_t *udd = &dev->ddesc;
                    225:        char *vendor = 0, *product = 0;
                    226: #ifdef USBVERBOSE
                    227:        const struct usb_known_vendor *ukv;
                    228:        const struct usb_known_product *ukp;
                    229: #endif
                    230:
                    231:        if (dev == NULL) {
                    232:                v[0] = p[0] = '\0';
                    233:                return;
                    234:        }
                    235:
                    236:        if (usedev) {
                    237:                vendor = usbd_get_string(dev, udd->iManufacturer, v);
                    238:                usbd_trim_spaces(vendor);
                    239:                product = usbd_get_string(dev, udd->iProduct, p);
                    240:                usbd_trim_spaces(product);
                    241:        } else {
                    242:                vendor = NULL;
                    243:                product = NULL;
                    244:        }
                    245: #ifdef USBVERBOSE
                    246:        if (vendor == NULL || product == NULL) {
                    247:                for(ukv = usb_known_vendors;
                    248:                    ukv->vendorname != NULL;
                    249:                    ukv++) {
                    250:                        if (ukv->vendor == UGETW(udd->idVendor)) {
                    251:                                vendor = ukv->vendorname;
                    252:                                break;
                    253:                        }
                    254:                }
                    255:                if (vendor != NULL) {
                    256:                        for(ukp = usb_known_products;
                    257:                            ukp->productname != NULL;
                    258:                            ukp++) {
                    259:                                if (ukp->vendor == UGETW(udd->idVendor) &&
                    260:                                    (ukp->product == UGETW(udd->idProduct))) {
                    261:                                        product = ukp->productname;
                    262:                                        break;
                    263:                                }
                    264:                        }
                    265:                }
                    266:        }
                    267: #endif
                    268:        if (vendor != NULL && *vendor)
                    269:                strlcpy(v, vendor, USB_MAX_STRING_LEN); /* XXX */
                    270:        else
                    271:                snprintf(v, USB_MAX_STRING_LEN, "vendor 0x%04x", /* XXX */
                    272:                    UGETW(udd->idVendor));
                    273:        if (product != NULL && *product)
                    274:                strlcpy(p, product, USB_MAX_STRING_LEN); /* XXX */
                    275:        else
                    276:                snprintf(p, USB_MAX_STRING_LEN, "product 0x%04x", /* XXX */
                    277:                    UGETW(udd->idProduct));
                    278: }
                    279:
                    280: int
                    281: usbd_printBCD(char *cp, size_t len, int bcd)
                    282: {
                    283:        int l;
                    284:
                    285:        l = snprintf(cp, len, "%x.%02x", bcd >> 8, bcd & 0xff);
                    286:        if (l == -1 || len == 0)
                    287:                return (0);
                    288:        if (l >= len)
                    289:                return len - 1;
                    290:        return (l);
                    291: }
                    292:
                    293: void
                    294: usbd_devinfo(usbd_device_handle dev, int showclass, char *base, size_t len)
                    295: {
                    296:        usb_device_descriptor_t *udd = &dev->ddesc;
                    297:        char vendor[USB_MAX_STRING_LEN];
                    298:        char product[USB_MAX_STRING_LEN];
                    299:        char *cp = base;
                    300:        int bcdDevice, bcdUSB;
                    301:
                    302:        usbd_devinfo_vp(dev, vendor, product, 1);
                    303:        snprintf(cp, len, "%s %s", vendor, product);
                    304:        cp += strlen(cp);
                    305:        if (showclass) {
                    306:                snprintf(cp, base + len - cp, ", class %d/%d",
                    307:                    udd->bDeviceClass, udd->bDeviceSubClass);
                    308:                cp += strlen(cp);
                    309:        }
                    310:        bcdUSB = UGETW(udd->bcdUSB);
                    311:        bcdDevice = UGETW(udd->bcdDevice);
                    312:        snprintf(cp, base + len - cp, ", rev ");
                    313:        cp += strlen(cp);
                    314:        usbd_printBCD(cp, base + len - cp, bcdUSB);
                    315:        cp += strlen(cp);
                    316:        snprintf(cp, base + len - cp, "/");
                    317:        cp += strlen(cp);
                    318:        usbd_printBCD(cp, base + len - cp, bcdDevice);
                    319:        cp += strlen(cp);
                    320:        snprintf(cp, base + len - cp, ", addr %d", dev->address);
                    321: }
                    322:
                    323: char *
                    324: usbd_devinfo_alloc(usbd_device_handle dev, int showclass)
                    325: {
                    326:        char *devinfop;
                    327:
                    328:        devinfop = malloc(DEVINFOSIZE, M_TEMP, M_WAITOK);
                    329:        usbd_devinfo(dev, showclass, devinfop, DEVINFOSIZE);
                    330:        return devinfop;
                    331: }
                    332:
                    333: void
                    334: usbd_devinfo_free(char *devinfop)
                    335: {
                    336:        free(devinfop, M_TEMP);
                    337: }
                    338:
                    339: /* Delay for a certain number of ms */
                    340: void
                    341: usb_delay_ms(usbd_bus_handle bus, u_int ms)
                    342: {
                    343:        /* Wait at least two clock ticks so we know the time has passed. */
                    344:        if (bus->use_polling || cold)
                    345:                delay((ms+1) * 1000);
                    346:        else
                    347:                tsleep(&ms, PRIBIO, "usbdly", (ms*hz+999)/1000 + 1);
                    348: }
                    349:
                    350: /* Delay given a device handle. */
                    351: void
                    352: usbd_delay_ms(usbd_device_handle dev, u_int ms)
                    353: {
                    354:        usb_delay_ms(dev->bus, ms);
                    355: }
                    356:
                    357: usbd_status
                    358: usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps)
                    359: {
                    360:        usb_device_request_t req;
                    361:        usbd_status err;
                    362:        int n;
                    363:
                    364:        req.bmRequestType = UT_WRITE_CLASS_OTHER;
                    365:        req.bRequest = UR_SET_FEATURE;
                    366:        USETW(req.wValue, UHF_PORT_RESET);
                    367:        USETW(req.wIndex, port);
                    368:        USETW(req.wLength, 0);
                    369:        err = usbd_do_request(dev, &req, 0);
                    370:        DPRINTFN(1,("usbd_reset_port: port %d reset done, error=%s\n",
                    371:                    port, usbd_errstr(err)));
                    372:        if (err)
                    373:                return (err);
                    374:        n = 10;
                    375:        do {
                    376:                /* Wait for device to recover from reset. */
                    377:                usbd_delay_ms(dev, USB_PORT_RESET_DELAY);
                    378:                err = usbd_get_port_status(dev, port, ps);
                    379:                if (err) {
                    380:                        DPRINTF(("usbd_reset_port: get status failed %d\n",
                    381:                                 err));
                    382:                        return (err);
                    383:                }
                    384:                /* If the device disappeared, just give up. */
                    385:                if (!(UGETW(ps->wPortStatus) & UPS_CURRENT_CONNECT_STATUS))
                    386:                        return (USBD_NORMAL_COMPLETION);
                    387:        } while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0);
                    388:        if (n == 0)
                    389:                return (USBD_TIMEOUT);
                    390:        err = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET);
                    391: #ifdef USB_DEBUG
                    392:        if (err)
                    393:                DPRINTF(("usbd_reset_port: clear port feature failed %d\n",
                    394:                         err));
                    395: #endif
                    396:
                    397:        /* Wait for the device to recover from reset. */
                    398:        usbd_delay_ms(dev, USB_PORT_RESET_RECOVERY);
                    399:        return (err);
                    400: }
                    401:
                    402: usb_interface_descriptor_t *
                    403: usbd_find_idesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx)
                    404: {
                    405:        char *p = (char *)cd;
                    406:        char *end = p + UGETW(cd->wTotalLength);
                    407:        usb_interface_descriptor_t *d;
                    408:        int curidx, lastidx, curaidx = 0;
                    409:
                    410:        for (curidx = lastidx = -1; p < end; ) {
                    411:                d = (usb_interface_descriptor_t *)p;
                    412:                DPRINTFN(4,("usbd_find_idesc: idx=%d(%d) altidx=%d(%d) len=%d "
                    413:                            "type=%d\n",
                    414:                            ifaceidx, curidx, altidx, curaidx,
                    415:                            d->bLength, d->bDescriptorType));
                    416:                if (d->bLength == 0) /* bad descriptor */
                    417:                        break;
                    418:                p += d->bLength;
                    419:                if (p <= end && d->bDescriptorType == UDESC_INTERFACE) {
                    420:                        if (d->bInterfaceNumber != lastidx) {
                    421:                                lastidx = d->bInterfaceNumber;
                    422:                                curidx++;
                    423:                                curaidx = 0;
                    424:                        } else
                    425:                                curaidx++;
                    426:                        if (ifaceidx == curidx && altidx == curaidx)
                    427:                                return (d);
                    428:                }
                    429:        }
                    430:        return (NULL);
                    431: }
                    432:
                    433: usb_endpoint_descriptor_t *
                    434: usbd_find_edesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx,
                    435:                int endptidx)
                    436: {
                    437:        char *p = (char *)cd;
                    438:        char *end = p + UGETW(cd->wTotalLength);
                    439:        usb_interface_descriptor_t *d;
                    440:        usb_endpoint_descriptor_t *e;
                    441:        int curidx;
                    442:
                    443:        d = usbd_find_idesc(cd, ifaceidx, altidx);
                    444:        if (d == NULL)
                    445:                return (NULL);
                    446:        if (endptidx >= d->bNumEndpoints) /* quick exit */
                    447:                return (NULL);
                    448:
                    449:        curidx = -1;
                    450:        for (p = (char *)d + d->bLength; p < end; ) {
                    451:                e = (usb_endpoint_descriptor_t *)p;
                    452:                if (e->bLength == 0) /* bad descriptor */
                    453:                        break;
                    454:                p += e->bLength;
                    455:                if (p <= end && e->bDescriptorType == UDESC_INTERFACE)
                    456:                        return (NULL);
                    457:                if (p <= end && e->bDescriptorType == UDESC_ENDPOINT) {
                    458:                        curidx++;
                    459:                        if (curidx == endptidx)
                    460:                                return (e);
                    461:                }
                    462:        }
                    463:        return (NULL);
                    464: }
                    465:
                    466: usbd_status
                    467: usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx)
                    468: {
                    469:        usbd_interface_handle ifc = &dev->ifaces[ifaceidx];
                    470:        usb_interface_descriptor_t *idesc;
                    471:        char *p, *end;
                    472:        int endpt, nendpt;
                    473:
                    474:        DPRINTFN(4,("usbd_fill_iface_data: ifaceidx=%d altidx=%d\n",
                    475:                    ifaceidx, altidx));
                    476:        idesc = usbd_find_idesc(dev->cdesc, ifaceidx, altidx);
                    477:        if (idesc == NULL)
                    478:                return (USBD_INVAL);
                    479:        ifc->device = dev;
                    480:        ifc->idesc = idesc;
                    481:        ifc->index = ifaceidx;
                    482:        ifc->altindex = altidx;
                    483:        nendpt = ifc->idesc->bNumEndpoints;
                    484:        DPRINTFN(4,("usbd_fill_iface_data: found idesc nendpt=%d\n", nendpt));
                    485:        if (nendpt != 0) {
                    486:                ifc->endpoints = malloc(nendpt * sizeof(struct usbd_endpoint),
                    487:                                        M_USB, M_NOWAIT);
                    488:                if (ifc->endpoints == NULL)
                    489:                        return (USBD_NOMEM);
                    490:        } else
                    491:                ifc->endpoints = NULL;
                    492:        ifc->priv = NULL;
                    493:        p = (char *)ifc->idesc + ifc->idesc->bLength;
                    494:        end = (char *)dev->cdesc + UGETW(dev->cdesc->wTotalLength);
                    495: #define ed ((usb_endpoint_descriptor_t *)p)
                    496:        for (endpt = 0; endpt < nendpt; endpt++) {
                    497:                DPRINTFN(10,("usbd_fill_iface_data: endpt=%d\n", endpt));
                    498:                for (; p < end; p += ed->bLength) {
                    499:                        DPRINTFN(10,("usbd_fill_iface_data: p=%p end=%p "
                    500:                            "len=%d type=%d\n", p, end, ed->bLength,
                    501:                            ed->bDescriptorType));
                    502:                        if (p + ed->bLength <= end && ed->bLength != 0 &&
                    503:                            ed->bDescriptorType == UDESC_ENDPOINT)
                    504:                                goto found;
                    505:                        if (ed->bLength == 0 ||
                    506:                            ed->bDescriptorType == UDESC_INTERFACE)
                    507:                                break;
                    508:                }
                    509:                /* passed end, or bad desc */
                    510:                printf("usbd_fill_iface_data: bad descriptor(s): %s\n",
                    511:                    ed->bLength == 0 ? "0 length" :
                    512:                    ed->bDescriptorType == UDESC_INTERFACE ? "iface desc" :
                    513:                    "out of data");
                    514:                goto bad;
                    515:        found:
                    516:                ifc->endpoints[endpt].edesc = ed;
                    517:                if (dev->speed == USB_SPEED_HIGH) {
                    518:                        u_int mps;
                    519:                        /* Control and bulk endpoints have max packet
                    520:                           limits. */
                    521:                        switch (UE_GET_XFERTYPE(ed->bmAttributes)) {
                    522:                        case UE_CONTROL:
                    523:                                mps = USB_2_MAX_CTRL_PACKET;
                    524:                                goto check;
                    525:                        case UE_BULK:
                    526:                                mps = USB_2_MAX_BULK_PACKET;
                    527:                        check:
                    528:                                if (UGETW(ed->wMaxPacketSize) != mps) {
                    529:                                        USETW(ed->wMaxPacketSize, mps);
                    530: #ifdef DIAGNOSTIC
                    531:                                        printf("usbd_fill_iface_data: bad max "
                    532:                                            "packet size\n");
                    533: #endif
                    534:                                }
                    535:                                break;
                    536:                        default:
                    537:                                break;
                    538:                        }
                    539:                }
                    540:                ifc->endpoints[endpt].refcnt = 0;
                    541:                ifc->endpoints[endpt].savedtoggle = 0;
                    542:                p += ed->bLength;
                    543:        }
                    544: #undef ed
                    545:        LIST_INIT(&ifc->pipes);
                    546:        return (USBD_NORMAL_COMPLETION);
                    547:
                    548:  bad:
                    549:        if (ifc->endpoints != NULL) {
                    550:                free(ifc->endpoints, M_USB);
                    551:                ifc->endpoints = NULL;
                    552:        }
                    553:        return (USBD_INVAL);
                    554: }
                    555:
                    556: void
                    557: usbd_free_iface_data(usbd_device_handle dev, int ifcno)
                    558: {
                    559:        usbd_interface_handle ifc = &dev->ifaces[ifcno];
                    560:        if (ifc->endpoints)
                    561:                free(ifc->endpoints, M_USB);
                    562: }
                    563:
                    564: usbd_status
                    565: usbd_set_config(usbd_device_handle dev, int conf)
                    566: {
                    567:        usb_device_request_t req;
                    568:
                    569:        req.bmRequestType = UT_WRITE_DEVICE;
                    570:        req.bRequest = UR_SET_CONFIG;
                    571:        USETW(req.wValue, conf);
                    572:        USETW(req.wIndex, 0);
                    573:        USETW(req.wLength, 0);
                    574:        return (usbd_do_request(dev, &req, 0));
                    575: }
                    576:
                    577: usbd_status
                    578: usbd_set_config_no(usbd_device_handle dev, int no, int msg)
                    579: {
                    580:        int index;
                    581:        usb_config_descriptor_t cd;
                    582:        usbd_status err;
                    583:
                    584:        if (no == USB_UNCONFIG_NO)
                    585:                return (usbd_set_config_index(dev, USB_UNCONFIG_INDEX, msg));
                    586:
                    587:        DPRINTFN(5,("usbd_set_config_no: %d\n", no));
                    588:        /* Figure out what config index to use. */
                    589:        for (index = 0; index < dev->ddesc.bNumConfigurations; index++) {
                    590:                err = usbd_get_config_desc(dev, index, &cd);
                    591:                if (err)
                    592:                        return (err);
                    593:                if (cd.bConfigurationValue == no)
                    594:                        return (usbd_set_config_index(dev, index, msg));
                    595:        }
                    596:        return (USBD_INVAL);
                    597: }
                    598:
                    599: usbd_status
                    600: usbd_set_config_index(usbd_device_handle dev, int index, int msg)
                    601: {
                    602:        usb_status_t ds;
                    603:        usb_config_descriptor_t cd, *cdp;
                    604:        usbd_status err;
                    605:        int i, ifcidx, nifc, len, selfpowered, power;
                    606:
                    607:        DPRINTFN(5,("usbd_set_config_index: dev=%p index=%d\n", dev, index));
                    608:
                    609:        /* XXX check that all interfaces are idle */
                    610:        if (dev->config != USB_UNCONFIG_NO) {
                    611:                DPRINTF(("usbd_set_config_index: free old config\n"));
                    612:                /* Free all configuration data structures. */
                    613:                nifc = dev->cdesc->bNumInterface;
                    614:                for (ifcidx = 0; ifcidx < nifc; ifcidx++)
                    615:                        usbd_free_iface_data(dev, ifcidx);
                    616:                free(dev->ifaces, M_USB);
                    617:                free(dev->cdesc, M_USB);
                    618:                dev->ifaces = NULL;
                    619:                dev->cdesc = NULL;
                    620:                dev->config = USB_UNCONFIG_NO;
                    621:        }
                    622:
                    623:        if (index == USB_UNCONFIG_INDEX) {
                    624:                /* We are unconfiguring the device, so leave unallocated. */
                    625:                DPRINTF(("usbd_set_config_index: set config 0\n"));
                    626:                err = usbd_set_config(dev, USB_UNCONFIG_NO);
                    627:                if (err)
                    628:                        DPRINTF(("usbd_set_config_index: setting config=0 "
                    629:                                 "failed, error=%s\n", usbd_errstr(err)));
                    630:                return (err);
                    631:        }
                    632:
                    633:        /* Get the short descriptor. */
                    634:        err = usbd_get_config_desc(dev, index, &cd);
                    635:        if (err)
                    636:                return (err);
                    637:        len = UGETW(cd.wTotalLength);
                    638:        cdp = malloc(len, M_USB, M_NOWAIT);
                    639:        if (cdp == NULL)
                    640:                return (USBD_NOMEM);
                    641:        /* Get the full descriptor. */
                    642:        for (i = 0; i < 3; i++) {
                    643:                err = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp);
                    644:                if (!err)
                    645:                        break;
                    646:                usbd_delay_ms(dev, 200);
                    647:        }
                    648:        if (err)
                    649:                goto bad;
                    650:
                    651:        if (cdp->bDescriptorType != UDESC_CONFIG) {
                    652:                DPRINTFN(-1,("usbd_set_config_index: bad desc %d\n",
                    653:                    cdp->bDescriptorType));
                    654:                err = USBD_INVAL;
                    655:                goto bad;
                    656:        }
                    657:
                    658:        /* Figure out if the device is self or bus powered. */
                    659:        selfpowered = 0;
                    660:        if (!(dev->quirks->uq_flags & UQ_BUS_POWERED) &&
                    661:            (cdp->bmAttributes & UC_SELF_POWERED)) {
                    662:                /* May be self powered. */
                    663:                if (cdp->bmAttributes & UC_BUS_POWERED) {
                    664:                        /* Must ask device. */
                    665:                        if (dev->quirks->uq_flags & UQ_POWER_CLAIM) {
                    666:                                /*
                    667:                                 * Hub claims to be self powered, but isn't.
                    668:                                 * It seems that the power status can be
                    669:                                 * determined by the hub characteristics.
                    670:                                 */
                    671:                                usb_hub_descriptor_t hd;
                    672:                                usb_device_request_t req;
                    673:                                req.bmRequestType = UT_READ_CLASS_DEVICE;
                    674:                                req.bRequest = UR_GET_DESCRIPTOR;
                    675:                                USETW(req.wValue, 0);
                    676:                                USETW(req.wIndex, 0);
                    677:                                USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE);
                    678:                                err = usbd_do_request(dev, &req, &hd);
                    679:                                if (!err &&
                    680:                                    (UGETW(hd.wHubCharacteristics) &
                    681:                                     UHD_PWR_INDIVIDUAL))
                    682:                                        selfpowered = 1;
                    683:                                DPRINTF(("usbd_set_config_index: charac=0x%04x"
                    684:                                    ", error=%s\n",
                    685:                                    UGETW(hd.wHubCharacteristics),
                    686:                                    usbd_errstr(err)));
                    687:                        } else {
                    688:                                err = usbd_get_device_status(dev, &ds);
                    689:                                if (!err &&
                    690:                                    (UGETW(ds.wStatus) & UDS_SELF_POWERED))
                    691:                                        selfpowered = 1;
                    692:                                DPRINTF(("usbd_set_config_index: status=0x%04x"
                    693:                                    ", error=%s\n",
                    694:                                    UGETW(ds.wStatus), usbd_errstr(err)));
                    695:                        }
                    696:                } else
                    697:                        selfpowered = 1;
                    698:        }
                    699:        DPRINTF(("usbd_set_config_index: (addr %d) cno=%d attr=0x%02x, "
                    700:                 "selfpowered=%d, power=%d\n",
                    701:                 cdp->bConfigurationValue, dev->address, cdp->bmAttributes,
                    702:                 selfpowered, cdp->bMaxPower * 2));
                    703:
                    704:        /* Check if we have enough power. */
                    705: #ifdef USB_DEBUG
                    706:        if (dev->powersrc == NULL) {
                    707:                DPRINTF(("usbd_set_config_index: No power source?\n"));
                    708:                return (USBD_IOERROR);
                    709:        }
                    710: #endif
                    711:        power = cdp->bMaxPower * 2;
                    712:        if (power > dev->powersrc->power) {
                    713:                DPRINTF(("power exceeded %d %d\n", power,dev->powersrc->power));
                    714:                /* XXX print nicer message. */
                    715:                if (msg)
                    716:                        printf("%s: device addr %d (config %d) exceeds power "
                    717:                            "budget, %d mA > %d mA\n",
                    718:                            dev->bus->bdev.dv_xname, dev->address,
                    719:                            cdp->bConfigurationValue,
                    720:                            power, dev->powersrc->power);
                    721:                err = USBD_NO_POWER;
                    722:                goto bad;
                    723:        }
                    724:        dev->power = power;
                    725:        dev->self_powered = selfpowered;
                    726:
                    727:        /* Set the actual configuration value. */
                    728:        DPRINTF(("usbd_set_config_index: set config %d\n",
                    729:            cdp->bConfigurationValue));
                    730:        err = usbd_set_config(dev, cdp->bConfigurationValue);
                    731:        if (err) {
                    732:                DPRINTF(("usbd_set_config_index: setting config=%d failed, "
                    733:                    "error=%s\n", cdp->bConfigurationValue, usbd_errstr(err)));
                    734:                goto bad;
                    735:        }
                    736:
                    737:        /* Allocate and fill interface data. */
                    738:        nifc = cdp->bNumInterface;
                    739:        dev->ifaces = malloc(nifc * sizeof(struct usbd_interface),
                    740:            M_USB, M_NOWAIT);
                    741:        if (dev->ifaces == NULL) {
                    742:                err = USBD_NOMEM;
                    743:                goto bad;
                    744:        }
                    745:        DPRINTFN(5,("usbd_set_config_index: dev=%p cdesc=%p\n", dev, cdp));
                    746:        dev->cdesc = cdp;
                    747:        dev->config = cdp->bConfigurationValue;
                    748:        for (ifcidx = 0; ifcidx < nifc; ifcidx++) {
                    749:                err = usbd_fill_iface_data(dev, ifcidx, 0);
                    750:                if (err) {
                    751:                        while (--ifcidx >= 0)
                    752:                                usbd_free_iface_data(dev, ifcidx);
                    753:                        goto bad;
                    754:                }
                    755:        }
                    756:
                    757:        return (USBD_NORMAL_COMPLETION);
                    758:
                    759:  bad:
                    760:        free(cdp, M_USB);
                    761:        return (err);
                    762: }
                    763:
                    764: /* XXX add function for alternate settings */
                    765:
                    766: usbd_status
                    767: usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface,
                    768:                struct usbd_endpoint *ep, int ival, usbd_pipe_handle *pipe)
                    769: {
                    770:        usbd_pipe_handle p;
                    771:        usbd_status err;
                    772:
                    773:        DPRINTFN(1,("usbd_setup_pipe: dev=%p iface=%p ep=%p pipe=%p\n",
                    774:                    dev, iface, ep, pipe));
                    775:        p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT);
                    776:        if (p == NULL)
                    777:                return (USBD_NOMEM);
                    778:        p->device = dev;
                    779:        p->iface = iface;
                    780:        p->endpoint = ep;
                    781:        ep->refcnt++;
                    782:        p->refcnt = 1;
                    783:        p->intrxfer = 0;
                    784:        p->running = 0;
                    785:        p->aborting = 0;
                    786:        p->repeat = 0;
                    787:        p->interval = ival;
                    788:        SIMPLEQ_INIT(&p->queue);
                    789:        err = dev->bus->methods->open_pipe(p);
                    790:        if (err) {
                    791:                DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error="
                    792:                         "%s\n",
                    793:                         ep->edesc->bEndpointAddress, usbd_errstr(err)));
                    794:                free(p, M_USB);
                    795:                return (err);
                    796:        }
                    797:        *pipe = p;
                    798:        return (USBD_NORMAL_COMPLETION);
                    799: }
                    800:
                    801: /* Abort the device control pipe. */
                    802: void
                    803: usbd_kill_pipe(usbd_pipe_handle pipe)
                    804: {
                    805:        usbd_abort_pipe(pipe);
                    806:        pipe->methods->close(pipe);
                    807:        pipe->endpoint->refcnt--;
                    808:        free(pipe, M_USB);
                    809: }
                    810:
                    811: int
                    812: usbd_getnewaddr(usbd_bus_handle bus)
                    813: {
                    814:        int addr;
                    815:
                    816:        for (addr = 1; addr < USB_MAX_DEVICES; addr++)
                    817:                if (bus->devices[addr] == 0)
                    818:                        return (addr);
                    819:        return (-1);
                    820: }
                    821:
                    822:
                    823: usbd_status
                    824: usbd_probe_and_attach(struct device *parent, usbd_device_handle dev, int port,
                    825:     int addr)
                    826: {
                    827:        struct usb_attach_arg uaa;
                    828:        usb_device_descriptor_t *dd = &dev->ddesc;
                    829:        int found, i, confi, nifaces, len;
                    830:        usbd_status err;
                    831:        struct device *dv;
                    832:        usbd_interface_handle *ifaces;
                    833:
                    834:        uaa.device = dev;
                    835:        uaa.iface = NULL;
                    836:        uaa.ifaces = NULL;
                    837:        uaa.nifaces = 0;
                    838:        uaa.usegeneric = 0;
                    839:        uaa.port = port;
                    840:        uaa.configno = UHUB_UNK_CONFIGURATION;
                    841:        uaa.ifaceno = UHUB_UNK_INTERFACE;
                    842:        uaa.vendor = UGETW(dd->idVendor);
                    843:        uaa.product = UGETW(dd->idProduct);
                    844:        uaa.release = UGETW(dd->bcdDevice);
                    845:
                    846:        /* First try with device specific drivers. */
                    847:        DPRINTF(("usbd_probe_and_attach: trying device specific drivers\n"));
                    848:        dv = config_found_sm(parent, &uaa, usbd_print, usbd_submatch);
                    849:        if (dv) {
                    850:                dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT);
                    851:                if (dev->subdevs == NULL)
                    852:                        return (USBD_NOMEM);
                    853:                dev->subdevs[0] = dv;
                    854:                dev->subdevs[1] = 0;
                    855:                return (USBD_NORMAL_COMPLETION);
                    856:        }
                    857:
                    858:        DPRINTF(("usbd_probe_and_attach: no device specific driver found\n"));
                    859:
                    860:        DPRINTF(("usbd_probe_and_attach: looping over %d configurations\n",
                    861:                 dd->bNumConfigurations));
                    862:        /* Next try with interface drivers. */
                    863:        for (confi = 0; confi < dd->bNumConfigurations; confi++) {
                    864:                DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n",
                    865:                            confi));
                    866:                err = usbd_set_config_index(dev, confi, 1);
                    867:                if (err) {
                    868: #ifdef USB_DEBUG
                    869:                        DPRINTF(("%s: port %d, set config at addr %d failed, "
                    870:                                 "error=%s\n", parent->dv_xname, port,
                    871:                                 addr, usbd_errstr(err)));
                    872: #else
                    873:                        printf("%s: port %d, set config at addr %d failed\n",
                    874:                            parent->dv_xname, port, addr);
                    875: #endif
                    876:
                    877:                        return (err);
                    878:                }
                    879:                nifaces = dev->cdesc->bNumInterface;
                    880:                uaa.configno = dev->cdesc->bConfigurationValue;
                    881:                ifaces = malloc(nifaces * sizeof(usbd_interface_handle),
                    882:                    M_USB, M_NOWAIT);
                    883:                if (ifaces == NULL)
                    884:                        return (USBD_NOMEM);
                    885:                for (i = 0; i < nifaces; i++)
                    886:                        ifaces[i] = &dev->ifaces[i];
                    887:                uaa.ifaces = ifaces;
                    888:                uaa.nifaces = nifaces;
                    889:                len = (nifaces+1) * sizeof dv;
                    890:                dev->subdevs = malloc(len, M_USB, M_NOWAIT);
                    891:                if (dev->subdevs == NULL) {
                    892:                        free(ifaces, M_USB);
                    893:                        return (USBD_NOMEM);
                    894:                }
                    895:                bzero(dev->subdevs, len);
                    896:
                    897:                found = 0;
                    898:                for (i = 0; i < nifaces; i++) {
                    899:                        if (ifaces[i] == NULL)
                    900:                                continue; /* interface already claimed */
                    901:                        uaa.iface = ifaces[i];
                    902:                        uaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber;
                    903:                        dv = config_found_sm(parent, &uaa, usbd_print,
                    904:                                           usbd_submatch);
                    905:
                    906:                        if (dv != NULL) {
                    907:                                dev->subdevs[found++] = dv;
                    908:                                ifaces[i] = NULL; /* consumed */
                    909:                        }
                    910:                }
                    911:                free(ifaces, M_USB);
                    912:                if (found != 0) {
                    913:                        return (USBD_NORMAL_COMPLETION);
                    914:                }
                    915:                free(dev->subdevs, M_USB);
                    916:                dev->subdevs = 0;
                    917:        }
                    918:        /* No interfaces were attached in any of the configurations. */
                    919:
                    920:        if (dd->bNumConfigurations > 1) /* don't change if only 1 config */
                    921:                usbd_set_config_index(dev, 0, 0);
                    922:
                    923:        DPRINTF(("usbd_probe_and_attach: no interface drivers found\n"));
                    924:
                    925:        /* Finally try the generic driver. */
                    926:        uaa.iface = NULL;
                    927:        uaa.usegeneric = 1;
                    928:        uaa.configno = UHUB_UNK_CONFIGURATION;
                    929:        uaa.ifaceno = UHUB_UNK_INTERFACE;
                    930:        dv = config_found_sm(parent, &uaa, usbd_print, usbd_submatch);
                    931:        if (dv != NULL) {
                    932:                dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT);
                    933:                if (dev->subdevs == 0)
                    934:                        return (USBD_NOMEM);
                    935:                dev->subdevs[0] = dv;
                    936:                dev->subdevs[1] = 0;
                    937:                return (USBD_NORMAL_COMPLETION);
                    938:        }
                    939:
                    940:        /*
                    941:         * The generic attach failed, but leave the device as it is.
                    942:         * We just did not find any drivers, that's all.  The device is
                    943:         * fully operational and not harming anyone.
                    944:         */
                    945:        DPRINTF(("usbd_probe_and_attach: generic attach failed\n"));
                    946:        return (USBD_NORMAL_COMPLETION);
                    947: }
                    948:
                    949:
                    950: /*
                    951:  * Called when a new device has been put in the powered state,
                    952:  * but not yet in the addressed state.
                    953:  * Get initial descriptor, set the address, get full descriptor,
                    954:  * and attach a driver.
                    955:  */
                    956: usbd_status
                    957: usbd_new_device(struct device *parent, usbd_bus_handle bus, int depth,
                    958:                int speed, int port, struct usbd_port *up)
                    959: {
                    960:        usbd_device_handle dev, adev;
                    961:        struct usbd_device *hub;
                    962:        usb_device_descriptor_t *dd;
                    963:        usbd_status err;
                    964:        int addr;
                    965:        int i;
                    966:        int p;
                    967:
                    968:        DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n",
                    969:                 bus, port, depth, speed));
                    970:        addr = usbd_getnewaddr(bus);
                    971:        if (addr < 0) {
                    972:                printf("%s: No free USB addresses, new device ignored.\n",
                    973:                    bus->bdev.dv_xname);
                    974:                return (USBD_NO_ADDR);
                    975:        }
                    976:
                    977:        dev = malloc(sizeof *dev, M_USB, M_NOWAIT);
                    978:        if (dev == NULL)
                    979:                return (USBD_NOMEM);
                    980:        memset(dev, 0, sizeof *dev);
                    981:
                    982:        dev->bus = bus;
                    983:
                    984:        /* Set up default endpoint handle. */
                    985:        dev->def_ep.edesc = &dev->def_ep_desc;
                    986:
                    987:        /* Set up default endpoint descriptor. */
                    988:        dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE;
                    989:        dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT;
                    990:        dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
                    991:        dev->def_ep_desc.bmAttributes = UE_CONTROL;
                    992:        USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET);
                    993:        dev->def_ep_desc.bInterval = 0;
                    994:
                    995:        dev->quirks = &usbd_no_quirk;
                    996:        dev->address = USB_START_ADDR;
                    997:        dev->ddesc.bMaxPacketSize = 0;
                    998:        dev->depth = depth;
                    999:        dev->powersrc = up;
                   1000:        dev->myhub = up->parent;
                   1001:
                   1002:        up->device = dev;
                   1003:
                   1004:        /* Locate port on upstream high speed hub */
                   1005:        for (adev = dev, hub = up->parent;
                   1006:            hub != NULL && hub->speed != USB_SPEED_HIGH;
                   1007:            adev = hub, hub = hub->myhub)
                   1008:                ;
                   1009:        if (hub) {
                   1010:                for (p = 0; p < hub->hub->hubdesc.bNbrPorts; p++) {
                   1011:                        if (hub->hub->ports[p].device == adev) {
                   1012:                                dev->myhsport = &hub->hub->ports[p];
                   1013:                                goto found;
                   1014:                        }
                   1015:                }
                   1016:                panic("usbd_new_device: cannot find HS port");
                   1017:        found:
                   1018:                DPRINTFN(1,("usbd_new_device: high speed port %d\n", p));
                   1019:        } else {
                   1020:                dev->myhsport = NULL;
                   1021:        }
                   1022:        dev->speed = speed;
                   1023:        dev->langid = USBD_NOLANG;
                   1024:        dev->cookie.cookie = ++usb_cookie_no;
                   1025:
                   1026:        /* Establish the default pipe. */
                   1027:        err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
                   1028:            &dev->default_pipe);
                   1029:        if (err) {
                   1030:                usbd_remove_device(dev, up);
                   1031:                return (err);
                   1032:        }
                   1033:
                   1034:        dd = &dev->ddesc;
                   1035:        /* Try a few times in case the device is slow (i.e. outside specs.) */
                   1036:        for (i = 0; i < 5; i++) {
                   1037:                /* Get the first 8 bytes of the device descriptor. */
                   1038:                err = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd);
                   1039:                if (!err)
                   1040:                        break;
                   1041:                /* progressively increase the delay */
                   1042:                usbd_delay_ms(dev, 200 * (i + 1));
                   1043:        }
                   1044:        if (err) {
                   1045:                DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc "
                   1046:                    "failed\n", addr));
                   1047:                usbd_remove_device(dev, up);
                   1048:                return (err);
                   1049:        }
                   1050:
                   1051:        if (speed == USB_SPEED_HIGH) {
                   1052:                /* Max packet size must be 64 (sec 5.5.3). */
                   1053:                if (dd->bMaxPacketSize != USB_2_MAX_CTRL_PACKET) {
                   1054: #ifdef DIAGNOSTIC
                   1055:                        printf("usbd_new_device: addr=%d bad max packet size\n",
                   1056:                            addr);
                   1057: #endif
                   1058:                        dd->bMaxPacketSize = USB_2_MAX_CTRL_PACKET;
                   1059:                }
                   1060:        }
                   1061:
                   1062:        DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, "
                   1063:                 "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n",
                   1064:                 addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass,
                   1065:                 dd->bDeviceProtocol, dd->bMaxPacketSize, dd->bLength,
                   1066:                 dev->speed));
                   1067:
                   1068:        if (dd->bDescriptorType != UDESC_DEVICE) {
                   1069:                /* Illegal device descriptor */
                   1070:                DPRINTFN(-1,("usbd_new_device: illegal descriptor %d\n",
                   1071:                    dd->bDescriptorType));
                   1072:                usbd_remove_device(dev, up);
                   1073:                return (USBD_INVAL);
                   1074:        }
                   1075:
                   1076:        if (dd->bLength < USB_DEVICE_DESCRIPTOR_SIZE) {
                   1077:                DPRINTFN(-1,("usbd_new_device: bad length %d\n", dd->bLength));
                   1078:                usbd_remove_device(dev, up);
                   1079:                return (USBD_INVAL);
                   1080:        }
                   1081:
                   1082:        USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize);
                   1083:
                   1084:        err = usbd_reload_device_desc(dev);
                   1085:        if (err) {
                   1086:                DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc "
                   1087:                    "failed\n", addr));
                   1088:                usbd_remove_device(dev, up);
                   1089:                return (err);
                   1090:        }
                   1091:
                   1092:        /* Set the address */
                   1093:        DPRINTFN(5,("usbd_new_device: setting device address=%d\n", addr));
                   1094:        err = usbd_set_address(dev, addr);
                   1095:        if (err) {
                   1096:                DPRINTFN(-1,("usbd_new_device: set address %d failed\n", addr));
                   1097:                err = USBD_SET_ADDR_FAILED;
                   1098:                usbd_remove_device(dev, up);
                   1099:                return (err);
                   1100:        }
                   1101:        /* Allow device time to set new address */
                   1102:        usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE);
                   1103:
                   1104:        dev->address = addr;    /* New device address now */
                   1105:        bus->devices[addr] = dev;
                   1106:
                   1107:        /* Assume 100mA bus powered for now. Changed when configured. */
                   1108:        dev->power = USB_MIN_POWER;
                   1109:        dev->self_powered = 0;
                   1110:
                   1111:        DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n",
                   1112:                 addr, dev, parent));
                   1113:
                   1114:        usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev);
                   1115:
                   1116:        err = usbd_probe_and_attach(parent, dev, port, addr);
                   1117:        if (err) {
                   1118:                usbd_remove_device(dev, up);
                   1119:                return (err);
                   1120:        }
                   1121:
                   1122:        return (USBD_NORMAL_COMPLETION);
                   1123: }
                   1124:
                   1125: usbd_status
                   1126: usbd_reload_device_desc(usbd_device_handle dev)
                   1127: {
                   1128:        usbd_status err;
                   1129:
                   1130:        /* Get the full device descriptor. */
                   1131:        err = usbd_get_device_desc(dev, &dev->ddesc);
                   1132:        if (err)
                   1133:                return (err);
                   1134:
                   1135:        /* Figure out what's wrong with this device. */
                   1136:        dev->quirks = usbd_find_quirk(&dev->ddesc);
                   1137:
                   1138:        return (USBD_NORMAL_COMPLETION);
                   1139: }
                   1140:
                   1141: void
                   1142: usbd_remove_device(usbd_device_handle dev, struct usbd_port *up)
                   1143: {
                   1144:        DPRINTF(("usbd_remove_device: %p\n", dev));
                   1145:
                   1146:        if (dev->default_pipe != NULL)
                   1147:                usbd_kill_pipe(dev->default_pipe);
                   1148:        up->device = NULL;
                   1149:        dev->bus->devices[dev->address] = NULL;
                   1150:
                   1151:        free(dev, M_USB);
                   1152: }
                   1153:
                   1154: int
                   1155: usbd_print(void *aux, const char *pnp)
                   1156: {
                   1157:        struct usb_attach_arg *uaa = aux;
                   1158:        char devinfo[1024];
                   1159:
                   1160:        DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device));
                   1161:        if (pnp) {
                   1162:                if (!uaa->usegeneric)
                   1163:                        return (QUIET);
                   1164:                usbd_devinfo(uaa->device, 1, devinfo, sizeof devinfo);
                   1165:                printf("%s, %s", devinfo, pnp);
                   1166:        }
                   1167:        if (uaa->port != 0)
                   1168:                printf(" port %d", uaa->port);
                   1169:        if (uaa->configno != UHUB_UNK_CONFIGURATION)
                   1170:                printf(" configuration %d", uaa->configno);
                   1171:        if (uaa->ifaceno != UHUB_UNK_INTERFACE)
                   1172:                printf(" interface %d", uaa->ifaceno);
                   1173: #if 0
                   1174:        /*
                   1175:         * It gets very crowded with these locators on the attach line.
                   1176:         * They are not really needed since they are printed in the clear
                   1177:         * by each driver.
                   1178:         */
                   1179:        if (uaa->vendor != UHUB_UNK_VENDOR)
                   1180:                printf(" vendor 0x%04x", uaa->vendor);
                   1181:        if (uaa->product != UHUB_UNK_PRODUCT)
                   1182:                printf(" product 0x%04x", uaa->product);
                   1183:        if (uaa->release != UHUB_UNK_RELEASE)
                   1184:                printf(" release 0x%04x", uaa->release);
                   1185: #endif
                   1186:        return (UNCONF);
                   1187: }
                   1188:
                   1189: int
                   1190: usbd_submatch(struct device *parent, void *match, void *aux)
                   1191: {
                   1192:        struct cfdata *cf = match;
                   1193:        struct usb_attach_arg *uaa = aux;
                   1194:
                   1195:        DPRINTFN(5,("usbd_submatch port=%d,%d configno=%d,%d "
                   1196:            "ifaceno=%d,%d vendor=%d,%d product=%d,%d release=%d,%d\n",
                   1197:            uaa->port, cf->uhubcf_port,
                   1198:            uaa->configno, cf->uhubcf_configuration,
                   1199:            uaa->ifaceno, cf->uhubcf_interface,
                   1200:            uaa->vendor, cf->uhubcf_vendor,
                   1201:            uaa->product, cf->uhubcf_product,
                   1202:            uaa->release, cf->uhubcf_release));
                   1203:        if (uaa->port != 0 &&   /* root hub has port 0, it should match */
                   1204:            ((uaa->port != 0 &&
                   1205:              cf->uhubcf_port != UHUB_UNK_PORT &&
                   1206:              cf->uhubcf_port != uaa->port) ||
                   1207:             (uaa->configno != UHUB_UNK_CONFIGURATION &&
                   1208:              cf->uhubcf_configuration != UHUB_UNK_CONFIGURATION &&
                   1209:              cf->uhubcf_configuration != uaa->configno) ||
                   1210:             (uaa->ifaceno != UHUB_UNK_INTERFACE &&
                   1211:              cf->uhubcf_interface != UHUB_UNK_INTERFACE &&
                   1212:              cf->uhubcf_interface != uaa->ifaceno) ||
                   1213:             (uaa->vendor != UHUB_UNK_VENDOR &&
                   1214:              cf->uhubcf_vendor != UHUB_UNK_VENDOR &&
                   1215:              cf->uhubcf_vendor != uaa->vendor) ||
                   1216:             (uaa->product != UHUB_UNK_PRODUCT &&
                   1217:              cf->uhubcf_product != UHUB_UNK_PRODUCT &&
                   1218:              cf->uhubcf_product != uaa->product) ||
                   1219:             (uaa->release != UHUB_UNK_RELEASE &&
                   1220:              cf->uhubcf_release != UHUB_UNK_RELEASE &&
                   1221:              cf->uhubcf_release != uaa->release)
                   1222:             )
                   1223:           )
                   1224:                return 0;
                   1225:        if (cf->uhubcf_vendor != UHUB_UNK_VENDOR &&
                   1226:            cf->uhubcf_vendor == uaa->vendor &&
                   1227:            cf->uhubcf_product != UHUB_UNK_PRODUCT &&
                   1228:            cf->uhubcf_product == uaa->product) {
                   1229:                /* We have a vendor&product locator match */
                   1230:                if (cf->uhubcf_release != UHUB_UNK_RELEASE &&
                   1231:                    cf->uhubcf_release == uaa->release)
                   1232:                        uaa->matchlvl = UMATCH_VENDOR_PRODUCT_REV;
                   1233:                else
                   1234:                        uaa->matchlvl = UMATCH_VENDOR_PRODUCT;
                   1235:        } else
                   1236:                uaa->matchlvl = 0;
                   1237:        return ((*cf->cf_attach->ca_match)(parent, cf, aux));
                   1238: }
                   1239:
                   1240: void
                   1241: usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di,
                   1242:     int usedev)
                   1243: {
                   1244:        struct usbd_port *p;
                   1245:        int i, err, s;
                   1246:
                   1247:        di->udi_bus = dev->bus->bdev.dv_unit;
                   1248:        di->udi_addr = dev->address;
                   1249:        di->udi_cookie = dev->cookie;
                   1250:        usbd_devinfo_vp(dev, di->udi_vendor, di->udi_product, usedev);
                   1251:        usbd_printBCD(di->udi_release, sizeof di->udi_release,
                   1252:            UGETW(dev->ddesc.bcdDevice));
                   1253:        di->udi_vendorNo = UGETW(dev->ddesc.idVendor);
                   1254:        di->udi_productNo = UGETW(dev->ddesc.idProduct);
                   1255:        di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice);
                   1256:        di->udi_class = dev->ddesc.bDeviceClass;
                   1257:        di->udi_subclass = dev->ddesc.bDeviceSubClass;
                   1258:        di->udi_protocol = dev->ddesc.bDeviceProtocol;
                   1259:        di->udi_config = dev->config;
                   1260:        di->udi_power = dev->self_powered ? 0 : dev->power;
                   1261:        di->udi_speed = dev->speed;
                   1262:
                   1263:        if (dev->subdevs != NULL) {
                   1264:                for (i = 0; dev->subdevs[i] && i < USB_MAX_DEVNAMES; i++) {
                   1265:                        strncpy(di->udi_devnames[i],
                   1266:                            dev->subdevs[i]->dv_xname, USB_MAX_DEVNAMELEN);
                   1267:                        di->udi_devnames[i][USB_MAX_DEVNAMELEN-1] = '\0';
                   1268:                }
                   1269:        } else
                   1270:                i = 0;
                   1271:
                   1272:        for (/*i is set */; i < USB_MAX_DEVNAMES; i++)
                   1273:                di->udi_devnames[i][0] = 0; /* empty */
                   1274:
                   1275:        if (dev->hub) {
                   1276:                for (i = 0;
                   1277:                    i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) &&
                   1278:                    i < dev->hub->hubdesc.bNbrPorts; i++) {
                   1279:                        p = &dev->hub->ports[i];
                   1280:                        if (p->device)
                   1281:                                err = p->device->address;
                   1282:                        else {
                   1283:                                s = UGETW(p->status.wPortStatus);
                   1284:                                if (s & UPS_PORT_ENABLED)
                   1285:                                        err = USB_PORT_ENABLED;
                   1286:                                else if (s & UPS_SUSPEND)
                   1287:                                        err = USB_PORT_SUSPENDED;
                   1288:                                else if (s & UPS_PORT_POWER)
                   1289:                                        err = USB_PORT_POWERED;
                   1290:                                else
                   1291:                                        err = USB_PORT_DISABLED;
                   1292:                        }
                   1293:                        di->udi_ports[i] = err;
                   1294:                }
                   1295:                di->udi_nports = dev->hub->hubdesc.bNbrPorts;
                   1296:        } else
                   1297:                di->udi_nports = 0;
                   1298: }
                   1299:
                   1300: void
                   1301: usb_free_device(usbd_device_handle dev)
                   1302: {
                   1303:        int ifcidx, nifc;
                   1304:
                   1305:        if (dev->default_pipe != NULL)
                   1306:                usbd_kill_pipe(dev->default_pipe);
                   1307:        if (dev->ifaces != NULL) {
                   1308:                nifc = dev->cdesc->bNumInterface;
                   1309:                for (ifcidx = 0; ifcidx < nifc; ifcidx++)
                   1310:                        usbd_free_iface_data(dev, ifcidx);
                   1311:                free(dev->ifaces, M_USB);
                   1312:        }
                   1313:        if (dev->cdesc != NULL)
                   1314:                free(dev->cdesc, M_USB);
                   1315:        if (dev->subdevs != NULL)
                   1316:                free(dev->subdevs, M_USB);
                   1317:        free(dev, M_USB);
                   1318: }
                   1319:
                   1320: /*
                   1321:  * The general mechanism for detaching drivers works as follows: Each
                   1322:  * driver is responsible for maintaining a reference count on the
                   1323:  * number of outstanding references to its softc (e.g.  from
                   1324:  * processing hanging in a read or write).  The detach method of the
                   1325:  * driver decrements this counter and flags in the softc that the
                   1326:  * driver is dying and then wakes any sleepers.  It then sleeps on the
                   1327:  * softc.  Each place that can sleep must maintain the reference
                   1328:  * count.  When the reference count drops to -1 (0 is the normal value
                   1329:  * of the reference count) the a wakeup on the softc is performed
                   1330:  * signaling to the detach waiter that all references are gone.
                   1331:  */
                   1332:
                   1333: /*
                   1334:  * Called from process context when we discover that a port has
                   1335:  * been disconnected.
                   1336:  */
                   1337: void
                   1338: usb_disconnect_port(struct usbd_port *up, struct device *parent)
                   1339: {
                   1340:        usbd_device_handle dev = up->device;
                   1341:        int i;
                   1342:
                   1343:        DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
                   1344:                    up, dev, up->portno));
                   1345:
                   1346: #ifdef DIAGNOSTIC
                   1347:        if (dev == NULL) {
                   1348:                printf("usb_disconnect_port: no device\n");
                   1349:                return;
                   1350:        }
                   1351: #endif
                   1352:
                   1353:        if (dev->subdevs != NULL) {
                   1354:                DPRINTFN(3,("usb_disconnect_port: disconnect subdevs\n"));
                   1355:                for (i = 0; dev->subdevs[i]; i++) {
                   1356:                        DPRINTF(("%s: at %s", dev->subdevs[i]->dv_xname,
                   1357:                            parent->dv_xname));
                   1358:                        if (up->portno != 0)
                   1359:                                DPRINTF((" port %d", up->portno));
                   1360:                        DPRINTF((" (addr %d) disconnected\n", dev->address));
                   1361:                        config_detach(dev->subdevs[i], DETACH_FORCE);
                   1362:                        dev->subdevs[i] = 0;
                   1363:                }
                   1364:        }
                   1365:
                   1366:        usbd_add_dev_event(USB_EVENT_DEVICE_DETACH, dev);
                   1367:        dev->bus->devices[dev->address] = NULL;
                   1368:        up->device = NULL;
                   1369:        usb_free_device(dev);
                   1370: }

CVSweb