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

Annotation of src/sys/dev/usb/usb_subr.c, Revision 1.181

1.181   ! martin      1: /*     $NetBSD: usb_subr.c,v 1.180 2011/06/09 19:08:33 matt Exp $      */
1.56      augustss    2: /*     $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $   */
1.1       augustss    3:
                      4: /*
1.121     mycroft     5:  * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
1.1       augustss    6:  * All rights reserved.
                      7:  *
1.9       augustss    8:  * This code is derived from software contributed to The NetBSD Foundation
1.76      augustss    9:  * by Lennart Augustsson (lennart@augustsson.net) at
1.9       augustss   10:  * Carlstedt Research & Technology.
1.1       augustss   11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     22:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     23:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     24:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     25:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     26:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     27:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     28:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     29:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     30:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     31:  * POSSIBILITY OF SUCH DAMAGE.
                     32:  */
1.91      lukem      33:
                     34: #include <sys/cdefs.h>
1.181   ! martin     35: __KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.180 2011/06/09 19:08:33 matt Exp $");
1.104     martin     36:
1.140     pavel      37: #include "opt_compat_netbsd.h"
1.104     martin     38: #include "opt_usbverbose.h"
1.181   ! martin     39: #include "opt_usb.h"
1.1       augustss   40:
                     41: #include <sys/param.h>
                     42: #include <sys/systm.h>
                     43: #include <sys/kernel.h>
                     44: #include <sys/malloc.h>
                     45: #include <sys/device.h>
1.56      augustss   46: #include <sys/select.h>
1.1       augustss   47: #include <sys/proc.h>
1.46      augustss   48:
1.149     ad         49: #include <sys/bus.h>
1.169     pgoyette   50: #include <sys/module.h>
1.1       augustss   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>
1.169     pgoyette   59: #include <dev/usb/usb_verbose.h>
1.1       augustss   60:
1.158     drochner   61: #include "locators.h"
                     62:
1.1       augustss   63: #ifdef USB_DEBUG
1.177     dyoung     64: #define DPRINTF(x)     if (usbdebug) printf x
                     65: #define DPRINTFN(n,x)  if (usbdebug>(n)) printf x
1.1       augustss   66: extern int usbdebug;
                     67: #else
                     68: #define DPRINTF(x)
                     69: #define DPRINTFN(n,x)
                     70: #endif
                     71:
1.178     tsutsui    72: MALLOC_DEFINE(M_USB, "USB", "USB misc. memory");
                     73: MALLOC_DEFINE(M_USBDEV, "USB device", "USB device driver");
                     74: MALLOC_DEFINE(M_USBHC, "USB HC", "USB host controller");
                     75:
1.82      augustss   76: Static usbd_status usbd_set_config(usbd_device_handle, int);
1.124     augustss   77: Static void usbd_devinfo(usbd_device_handle, int, char *, size_t);
1.175     christos   78: Static void usbd_devinfo_vp(usbd_device_handle, char *, size_t, char *, size_t,
                     79:     int, int);
                     80: Static int usbd_getnewaddr(usbd_bus_handle);
1.118     drochner   81: Static int usbd_print(void *, const char *);
1.144     drochner   82: Static int usbd_ifprint(void *, const char *);
1.175     christos   83: Static void usbd_free_iface_data(usbd_device_handle, int);
1.78      augustss   84: Static void usbd_kill_pipe(usbd_pipe_handle);
1.155     drochner   85: usbd_status usbd_attach_roothub(device_t, usbd_device_handle);
1.175     christos   86: Static usbd_status usbd_probe_and_attach(device_t, usbd_device_handle, int,
                     87:     int);
1.1       augustss   88:
1.69      augustss   89: Static u_int32_t usb_cookie_no = 0;
1.27      augustss   90:
1.84      jdolecek   91: Static const char * const usbd_error_strs[] = {
1.12      augustss   92:        "NORMAL_COMPLETION",
                     93:        "IN_PROGRESS",
                     94:        "PENDING_REQUESTS",
                     95:        "NOT_STARTED",
                     96:        "INVAL",
                     97:        "NOMEM",
                     98:        "CANCELLED",
                     99:        "BAD_ADDRESS",
                    100:        "IN_USE",
                    101:        "NO_ADDR",
                    102:        "SET_ADDR_FAILED",
                    103:        "NO_POWER",
                    104:        "TOO_DEEP",
                    105:        "IOERROR",
                    106:        "NOT_CONFIGURED",
                    107:        "TIMEOUT",
                    108:        "SHORT_XFER",
                    109:        "STALLED",
1.33      augustss  110:        "INTERRUPTED",
1.12      augustss  111:        "XXX",
                    112: };
1.1       augustss  113:
1.171     pgoyette  114: void usb_load_verbose(void);
                    115:
1.175     christos  116: void get_usb_vendor_stub(char *, size_t, usb_vendor_id_t);
                    117: void get_usb_product_stub(char *, size_t, usb_vendor_id_t, usb_product_id_t);
1.171     pgoyette  118:
1.175     christos  119: void (*get_usb_vendor)(char *, size_t, usb_vendor_id_t) = get_usb_vendor_stub;
                    120: void (*get_usb_product)(char *, size_t, usb_vendor_id_t, usb_product_id_t) =
1.171     pgoyette  121:        get_usb_product_stub;
                    122:
                    123: int usb_verbose_loaded = 0;
                    124:
                    125: /*
                    126:  * Load the usbverbose module
                    127:  */
                    128: void usb_load_verbose(void)
                    129: {
1.176     pgoyette  130:        if (usb_verbose_loaded == 0)
1.173     pgoyette  131:                module_autoload("usbverbose", MODULE_CLASS_MISC);
1.171     pgoyette  132: }
1.169     pgoyette  133:
1.175     christos  134: void get_usb_vendor_stub(char *v, size_t l, usb_vendor_id_t v_id)
1.169     pgoyette  135: {
1.171     pgoyette  136:        usb_load_verbose();
                    137:        if (usb_verbose_loaded)
1.175     christos  138:                get_usb_vendor(v, l, v_id);
1.169     pgoyette  139: }
                    140:
1.175     christos  141: void get_usb_product_stub(char *p, size_t l, usb_vendor_id_t v_id,
                    142:     usb_product_id_t p_id)
1.169     pgoyette  143: {
1.171     pgoyette  144:        usb_load_verbose();
                    145:        if (usb_verbose_loaded)
1.175     christos  146:                get_usb_product(p, l, v_id, p_id);
1.169     pgoyette  147: }
                    148:
1.42      thorpej   149: const char *
1.78      augustss  150: usbd_errstr(usbd_status err)
1.39      augustss  151: {
                    152:        static char buffer[5];
                    153:
1.42      thorpej   154:        if (err < USBD_ERROR_MAX) {
1.39      augustss  155:                return usbd_error_strs[err];
                    156:        } else {
                    157:                snprintf(buffer, sizeof buffer, "%d", err);
                    158:                return buffer;
                    159:        }
                    160: }
                    161:
1.13      augustss  162: usbd_status
1.78      augustss  163: usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid,
1.114     mycroft   164:                     usb_string_descriptor_t *sdesc, int *sizep)
1.13      augustss  165: {
                    166:        usb_device_request_t req;
1.116     mycroft   167:        usbd_status err;
                    168:        int actlen;
1.13      augustss  169:
                    170:        req.bmRequestType = UT_READ_DEVICE;
                    171:        req.bRequest = UR_GET_DESCRIPTOR;
                    172:        USETW2(req.wValue, UDESC_STRING, sindex);
                    173:        USETW(req.wIndex, langid);
1.146     christos  174:        USETW(req.wLength, 2);  /* only size byte first */
1.116     mycroft   175:        err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
                    176:                &actlen, USBD_DEFAULT_TIMEOUT);
                    177:        if (err)
                    178:                return (err);
                    179:
1.146     christos  180:        if (actlen < 2)
                    181:                return (USBD_SHORT_XFER);
                    182:
                    183:        USETW(req.wLength, sdesc->bLength);     /* the whole string */
                    184:        err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
                    185:                &actlen, USBD_DEFAULT_TIMEOUT);
                    186:        if (err)
                    187:                return (err);
                    188:
1.116     mycroft   189:        if (actlen != sdesc->bLength) {
                    190:                DPRINTFN(-1, ("usbd_get_string_desc: expected %d, got %d\n",
                    191:                    sdesc->bLength, actlen));
                    192:        }
                    193:
                    194:        *sizep = actlen;
                    195:        return (USBD_NORMAL_COMPLETION);
1.13      augustss  196: }
                    197:
1.128     enami     198: static void
                    199: usbd_trim_spaces(char *p)
1.83      augustss  200: {
1.128     enami     201:        char *q, *e;
1.83      augustss  202:
1.128     enami     203:        q = e = p;
                    204:        while (*q == ' ')               /* skip leading spaces */
1.85      augustss  205:                q++;
1.128     enami     206:        while ((*p = *q++))             /* copy string */
                    207:                if (*p++ != ' ')        /* remember last non-space */
                    208:                        e = p;
                    209:        *e = '\0';                      /* kill trailing spaces */
1.83      augustss  210: }
                    211:
1.123     augustss  212: Static void
1.175     christos  213: usbd_devinfo_vp(usbd_device_handle dev, char *v, size_t vl, char *p,
                    214:     size_t pl, int usedev, int useencoded)
1.1       augustss  215: {
                    216:        usb_device_descriptor_t *udd = &dev->ddesc;
1.175     christos  217:        if (dev == NULL)
                    218:                return;
1.1       augustss  219:
1.128     enami     220:        v[0] = p[0] = '\0';
1.52      augustss  221:
1.82      augustss  222:        if (usedev) {
1.139     pavel     223:                if (usbd_get_string0(dev, udd->iManufacturer, v, useencoded) ==
1.128     enami     224:                    USBD_NORMAL_COMPLETION)
                    225:                        usbd_trim_spaces(v);
1.139     pavel     226:                if (usbd_get_string0(dev, udd->iProduct, p, useencoded) ==
1.128     enami     227:                    USBD_NORMAL_COMPLETION)
                    228:                        usbd_trim_spaces(p);
1.82      augustss  229:        }
1.128     enami     230:        if (v[0] == '\0')
1.175     christos  231:                get_usb_vendor(v, vl, UGETW(udd->idVendor));
1.128     enami     232:        if (p[0] == '\0')
1.175     christos  233:                get_usb_product(p, pl, UGETW(udd->idVendor),
                    234:                    UGETW(udd->idProduct));
1.169     pgoyette  235:
1.128     enami     236:        if (v[0] == '\0')
1.175     christos  237:                snprintf(v, vl, "vendor 0x%04x", UGETW(udd->idVendor));
1.128     enami     238:        if (p[0] == '\0')
1.175     christos  239:                snprintf(p, pl, "product 0x%04x", UGETW(udd->idProduct));
1.1       augustss  240: }
                    241:
                    242: int
1.113     itojun    243: usbd_printBCD(char *cp, size_t l, int bcd)
1.1       augustss  244: {
1.175     christos  245:        return snprintf(cp, l, "%x.%02x", bcd >> 8, bcd & 0xff);
1.1       augustss  246: }
                    247:
1.124     augustss  248: Static void
1.113     itojun    249: usbd_devinfo(usbd_device_handle dev, int showclass, char *cp, size_t l)
1.1       augustss  250: {
                    251:        usb_device_descriptor_t *udd = &dev->ddesc;
1.133     christos  252:        char *vendor, *product;
1.1       augustss  253:        int bcdDevice, bcdUSB;
1.113     itojun    254:        char *ep;
                    255:
1.133     christos  256:        vendor = malloc(USB_MAX_ENCODED_STRING_LEN * 2, M_USB, M_NOWAIT);
                    257:        if (vendor == NULL) {
                    258:                *cp = '\0';
                    259:                return;
                    260:        }
                    261:        product = &vendor[USB_MAX_ENCODED_STRING_LEN];
                    262:
1.113     itojun    263:        ep = cp + l;
1.1       augustss  264:
1.175     christos  265:        usbd_devinfo_vp(dev, vendor, USB_MAX_ENCODED_STRING_LEN,
                    266:            product, USB_MAX_ENCODED_STRING_LEN, 1, 1);
1.113     itojun    267:        cp += snprintf(cp, ep - cp, "%s %s", vendor, product);
1.1       augustss  268:        if (showclass)
1.113     itojun    269:                cp += snprintf(cp, ep - cp, ", class %d/%d",
                    270:                    udd->bDeviceClass, udd->bDeviceSubClass);
1.1       augustss  271:        bcdUSB = UGETW(udd->bcdUSB);
                    272:        bcdDevice = UGETW(udd->bcdDevice);
1.113     itojun    273:        cp += snprintf(cp, ep - cp, ", rev ");
                    274:        cp += usbd_printBCD(cp, ep - cp, bcdUSB);
1.1       augustss  275:        *cp++ = '/';
1.113     itojun    276:        cp += usbd_printBCD(cp, ep - cp, bcdDevice);
                    277:        cp += snprintf(cp, ep - cp, ", addr %d", dev->address);
1.10      augustss  278:        *cp = 0;
1.133     christos  279:        free(vendor, M_USB);
1.1       augustss  280: }
                    281:
1.124     augustss  282: char *
                    283: usbd_devinfo_alloc(usbd_device_handle dev, int showclass)
                    284: {
                    285:        char *devinfop;
                    286:
                    287:        devinfop = malloc(DEVINFOSIZE, M_TEMP, M_WAITOK);
                    288:        usbd_devinfo(dev, showclass, devinfop, DEVINFOSIZE);
                    289:        return devinfop;
                    290: }
                    291:
                    292: void
                    293: usbd_devinfo_free(char *devinfop)
                    294: {
                    295:        free(devinfop, M_TEMP);
                    296: }
                    297:
1.1       augustss  298: /* Delay for a certain number of ms */
                    299: void
1.78      augustss  300: usb_delay_ms(usbd_bus_handle bus, u_int ms)
1.1       augustss  301: {
                    302:        /* Wait at least two clock ticks so we know the time has passed. */
1.64      augustss  303:        if (bus->use_polling || cold)
1.1       augustss  304:                delay((ms+1) * 1000);
                    305:        else
                    306:                tsleep(&ms, PRIBIO, "usbdly", (ms*hz+999)/1000 + 1);
                    307: }
                    308:
1.23      augustss  309: /* Delay given a device handle. */
                    310: void
1.78      augustss  311: usbd_delay_ms(usbd_device_handle dev, u_int ms)
1.23      augustss  312: {
                    313:        usb_delay_ms(dev->bus, ms);
                    314: }
                    315:
1.1       augustss  316: usbd_status
1.78      augustss  317: usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps)
1.1       augustss  318: {
                    319:        usb_device_request_t req;
1.53      augustss  320:        usbd_status err;
1.1       augustss  321:        int n;
1.99      augustss  322:
1.1       augustss  323:        req.bmRequestType = UT_WRITE_CLASS_OTHER;
                    324:        req.bRequest = UR_SET_FEATURE;
                    325:        USETW(req.wValue, UHF_PORT_RESET);
                    326:        USETW(req.wIndex, port);
                    327:        USETW(req.wLength, 0);
1.53      augustss  328:        err = usbd_do_request(dev, &req, 0);
1.39      augustss  329:        DPRINTFN(1,("usbd_reset_port: port %d reset done, error=%s\n",
1.53      augustss  330:                    port, usbd_errstr(err)));
                    331:        if (err)
                    332:                return (err);
1.1       augustss  333:        n = 10;
                    334:        do {
                    335:                /* Wait for device to recover from reset. */
1.23      augustss  336:                usbd_delay_ms(dev, USB_PORT_RESET_DELAY);
1.53      augustss  337:                err = usbd_get_port_status(dev, port, ps);
                    338:                if (err) {
                    339:                        DPRINTF(("usbd_reset_port: get status failed %d\n",
                    340:                                 err));
                    341:                        return (err);
1.1       augustss  342:                }
1.92      augustss  343:                /* If the device disappeared, just give up. */
                    344:                if (!(UGETW(ps->wPortStatus) & UPS_CURRENT_CONNECT_STATUS))
                    345:                        return (USBD_NORMAL_COMPLETION);
1.1       augustss  346:        } while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0);
1.73      augustss  347:        if (n == 0)
                    348:                return (USBD_TIMEOUT);
1.53      augustss  349:        err = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET);
1.1       augustss  350: #ifdef USB_DEBUG
1.53      augustss  351:        if (err)
                    352:                DPRINTF(("usbd_reset_port: clear port feature failed %d\n",
                    353:                         err));
1.1       augustss  354: #endif
1.18      augustss  355:
                    356:        /* Wait for the device to recover from reset. */
1.23      augustss  357:        usbd_delay_ms(dev, USB_PORT_RESET_RECOVERY);
1.53      augustss  358:        return (err);
1.1       augustss  359: }
                    360:
1.12      augustss  361: usb_interface_descriptor_t *
1.78      augustss  362: usbd_find_idesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx)
1.12      augustss  363: {
                    364:        char *p = (char *)cd;
                    365:        char *end = p + UGETW(cd->wTotalLength);
                    366:        usb_interface_descriptor_t *d;
1.19      augustss  367:        int curidx, lastidx, curaidx = 0;
1.12      augustss  368:
1.19      augustss  369:        for (curidx = lastidx = -1; p < end; ) {
1.12      augustss  370:                d = (usb_interface_descriptor_t *)p;
1.18      augustss  371:                DPRINTFN(4,("usbd_find_idesc: idx=%d(%d) altidx=%d(%d) len=%d "
1.99      augustss  372:                            "type=%d\n",
1.18      augustss  373:                            ifaceidx, curidx, altidx, curaidx,
                    374:                            d->bLength, d->bDescriptorType));
1.12      augustss  375:                if (d->bLength == 0) /* bad descriptor */
                    376:                        break;
                    377:                p += d->bLength;
                    378:                if (p <= end && d->bDescriptorType == UDESC_INTERFACE) {
1.19      augustss  379:                        if (d->bInterfaceNumber != lastidx) {
                    380:                                lastidx = d->bInterfaceNumber;
1.12      augustss  381:                                curidx++;
                    382:                                curaidx = 0;
                    383:                        } else
                    384:                                curaidx++;
                    385:                        if (ifaceidx == curidx && altidx == curaidx)
                    386:                                return (d);
                    387:                }
                    388:        }
1.58      augustss  389:        return (NULL);
1.12      augustss  390: }
                    391:
                    392: usb_endpoint_descriptor_t *
1.99      augustss  393: usbd_find_edesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx,
1.78      augustss  394:                int endptidx)
1.12      augustss  395: {
                    396:        char *p = (char *)cd;
                    397:        char *end = p + UGETW(cd->wTotalLength);
                    398:        usb_interface_descriptor_t *d;
                    399:        usb_endpoint_descriptor_t *e;
                    400:        int curidx;
                    401:
                    402:        d = usbd_find_idesc(cd, ifaceidx, altidx);
1.53      augustss  403:        if (d == NULL)
1.58      augustss  404:                return (NULL);
1.12      augustss  405:        if (endptidx >= d->bNumEndpoints) /* quick exit */
1.58      augustss  406:                return (NULL);
1.12      augustss  407:
                    408:        curidx = -1;
                    409:        for (p = (char *)d + d->bLength; p < end; ) {
                    410:                e = (usb_endpoint_descriptor_t *)p;
                    411:                if (e->bLength == 0) /* bad descriptor */
                    412:                        break;
                    413:                p += e->bLength;
                    414:                if (p <= end && e->bDescriptorType == UDESC_INTERFACE)
1.58      augustss  415:                        return (NULL);
1.12      augustss  416:                if (p <= end && e->bDescriptorType == UDESC_ENDPOINT) {
                    417:                        curidx++;
                    418:                        if (curidx == endptidx)
                    419:                                return (e);
                    420:                }
1.1       augustss  421:        }
1.58      augustss  422:        return (NULL);
1.1       augustss  423: }
                    424:
                    425: usbd_status
1.78      augustss  426: usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx)
1.1       augustss  427: {
1.12      augustss  428:        usbd_interface_handle ifc = &dev->ifaces[ifaceidx];
1.77      augustss  429:        usb_interface_descriptor_t *idesc;
1.1       augustss  430:        char *p, *end;
                    431:        int endpt, nendpt;
                    432:
1.18      augustss  433:        DPRINTFN(4,("usbd_fill_iface_data: ifaceidx=%d altidx=%d\n",
1.14      drochner  434:                    ifaceidx, altidx));
1.77      augustss  435:        idesc = usbd_find_idesc(dev->cdesc, ifaceidx, altidx);
                    436:        if (idesc == NULL)
                    437:                return (USBD_INVAL);
1.1       augustss  438:        ifc->device = dev;
1.77      augustss  439:        ifc->idesc = idesc;
1.13      augustss  440:        ifc->index = ifaceidx;
                    441:        ifc->altindex = altidx;
1.1       augustss  442:        nendpt = ifc->idesc->bNumEndpoints;
1.59      augustss  443:        DPRINTFN(4,("usbd_fill_iface_data: found idesc nendpt=%d\n", nendpt));
1.1       augustss  444:        if (nendpt != 0) {
                    445:                ifc->endpoints = malloc(nendpt * sizeof(struct usbd_endpoint),
                    446:                                        M_USB, M_NOWAIT);
1.58      augustss  447:                if (ifc->endpoints == NULL)
1.1       augustss  448:                        return (USBD_NOMEM);
                    449:        } else
1.58      augustss  450:                ifc->endpoints = NULL;
                    451:        ifc->priv = NULL;
1.1       augustss  452:        p = (char *)ifc->idesc + ifc->idesc->bLength;
                    453:        end = (char *)dev->cdesc + UGETW(dev->cdesc->wTotalLength);
1.19      augustss  454: #define ed ((usb_endpoint_descriptor_t *)p)
1.1       augustss  455:        for (endpt = 0; endpt < nendpt; endpt++) {
                    456:                DPRINTFN(10,("usbd_fill_iface_data: endpt=%d\n", endpt));
                    457:                for (; p < end; p += ed->bLength) {
1.14      drochner  458:                        DPRINTFN(10,("usbd_fill_iface_data: p=%p end=%p "
                    459:                                     "len=%d type=%d\n",
1.1       augustss  460:                                 p, end, ed->bLength, ed->bDescriptorType));
1.24      augustss  461:                        if (p + ed->bLength <= end && ed->bLength != 0 &&
1.1       augustss  462:                            ed->bDescriptorType == UDESC_ENDPOINT)
1.24      augustss  463:                                goto found;
1.59      augustss  464:                        if (ed->bLength == 0 ||
                    465:                            ed->bDescriptorType == UDESC_INTERFACE)
1.1       augustss  466:                                break;
                    467:                }
1.24      augustss  468:                /* passed end, or bad desc */
1.95      augustss  469:                printf("usbd_fill_iface_data: bad descriptor(s): %s\n",
                    470:                       ed->bLength == 0 ? "0 length" :
                    471:                       ed->bDescriptorType == UDESC_INTERFACE ? "iface desc":
                    472:                       "out of data");
1.24      augustss  473:                goto bad;
                    474:        found:
1.1       augustss  475:                ifc->endpoints[endpt].edesc = ed;
1.95      augustss  476:                if (dev->speed == USB_SPEED_HIGH) {
                    477:                        u_int mps;
                    478:                        /* Control and bulk endpoints have max packet limits. */
                    479:                        switch (UE_GET_XFERTYPE(ed->bmAttributes)) {
                    480:                        case UE_CONTROL:
                    481:                                mps = USB_2_MAX_CTRL_PACKET;
                    482:                                goto check;
                    483:                        case UE_BULK:
                    484:                                mps = USB_2_MAX_BULK_PACKET;
                    485:                        check:
                    486:                                if (UGETW(ed->wMaxPacketSize) != mps) {
                    487:                                        USETW(ed->wMaxPacketSize, mps);
                    488: #ifdef DIAGNOSTIC
                    489:                                        printf("usbd_fill_iface_data: bad max "
                    490:                                               "packet size\n");
                    491: #endif
                    492:                                }
                    493:                                break;
                    494:                        default:
                    495:                                break;
                    496:                        }
                    497:                }
1.1       augustss  498:                ifc->endpoints[endpt].refcnt = 0;
1.179     drochner  499:                ifc->endpoints[endpt].datatoggle = 0;
1.24      augustss  500:                p += ed->bLength;
1.1       augustss  501:        }
1.19      augustss  502: #undef ed
1.1       augustss  503:        LIST_INIT(&ifc->pipes);
                    504:        return (USBD_NORMAL_COMPLETION);
1.24      augustss  505:
1.1       augustss  506:  bad:
1.77      augustss  507:        if (ifc->endpoints != NULL) {
1.59      augustss  508:                free(ifc->endpoints, M_USB);
1.77      augustss  509:                ifc->endpoints = NULL;
                    510:        }
1.24      augustss  511:        return (USBD_INVAL);
1.1       augustss  512: }
                    513:
                    514: void
1.78      augustss  515: usbd_free_iface_data(usbd_device_handle dev, int ifcno)
1.1       augustss  516: {
                    517:        usbd_interface_handle ifc = &dev->ifaces[ifcno];
                    518:        if (ifc->endpoints)
                    519:                free(ifc->endpoints, M_USB);
                    520: }
                    521:
1.69      augustss  522: Static usbd_status
1.78      augustss  523: usbd_set_config(usbd_device_handle dev, int conf)
1.7       augustss  524: {
                    525:        usb_device_request_t req;
                    526:
                    527:        req.bmRequestType = UT_WRITE_DEVICE;
                    528:        req.bRequest = UR_SET_CONFIG;
                    529:        USETW(req.wValue, conf);
                    530:        USETW(req.wIndex, 0);
                    531:        USETW(req.wLength, 0);
                    532:        return (usbd_do_request(dev, &req, 0));
                    533: }
                    534:
1.1       augustss  535: usbd_status
1.78      augustss  536: usbd_set_config_no(usbd_device_handle dev, int no, int msg)
1.1       augustss  537: {
1.12      augustss  538:        int index;
                    539:        usb_config_descriptor_t cd;
1.53      augustss  540:        usbd_status err;
1.12      augustss  541:
1.75      augustss  542:        if (no == USB_UNCONFIG_NO)
                    543:                return (usbd_set_config_index(dev, USB_UNCONFIG_INDEX, msg));
                    544:
1.12      augustss  545:        DPRINTFN(5,("usbd_set_config_no: %d\n", no));
                    546:        /* Figure out what config index to use. */
                    547:        for (index = 0; index < dev->ddesc.bNumConfigurations; index++) {
1.53      augustss  548:                err = usbd_get_config_desc(dev, index, &cd);
                    549:                if (err)
                    550:                        return (err);
1.12      augustss  551:                if (cd.bConfigurationValue == no)
                    552:                        return (usbd_set_config_index(dev, index, msg));
                    553:        }
                    554:        return (USBD_INVAL);
                    555: }
                    556:
                    557: usbd_status
1.78      augustss  558: usbd_set_config_index(usbd_device_handle dev, int index, int msg)
1.12      augustss  559: {
1.1       augustss  560:        usb_config_descriptor_t cd, *cdp;
1.53      augustss  561:        usbd_status err;
1.103     augustss  562:        int i, ifcidx, nifc, len, selfpowered, power;
1.1       augustss  563:
1.12      augustss  564:        DPRINTFN(5,("usbd_set_config_index: dev=%p index=%d\n", dev, index));
1.1       augustss  565:
1.145     drochner  566:        if (index >= dev->ddesc.bNumConfigurations &&
1.161     drochner  567:            index != USB_UNCONFIG_INDEX) {
1.145     drochner  568:                /* panic? */
                    569:                printf("usbd_set_config_index: illegal index\n");
                    570:                return (USBD_INVAL);
                    571:        }
                    572:
1.1       augustss  573:        /* XXX check that all interfaces are idle */
1.75      augustss  574:        if (dev->config != USB_UNCONFIG_NO) {
1.12      augustss  575:                DPRINTF(("usbd_set_config_index: free old config\n"));
1.1       augustss  576:                /* Free all configuration data structures. */
                    577:                nifc = dev->cdesc->bNumInterface;
1.12      augustss  578:                for (ifcidx = 0; ifcidx < nifc; ifcidx++)
                    579:                        usbd_free_iface_data(dev, ifcidx);
1.1       augustss  580:                free(dev->ifaces, M_USB);
                    581:                free(dev->cdesc, M_USB);
1.57      augustss  582:                dev->ifaces = NULL;
                    583:                dev->cdesc = NULL;
1.75      augustss  584:                dev->config = USB_UNCONFIG_NO;
                    585:        }
                    586:
                    587:        if (index == USB_UNCONFIG_INDEX) {
                    588:                /* We are unconfiguring the device, so leave unallocated. */
                    589:                DPRINTF(("usbd_set_config_index: set config 0\n"));
                    590:                err = usbd_set_config(dev, USB_UNCONFIG_NO);
1.136     christos  591:                if (err) {
1.75      augustss  592:                        DPRINTF(("usbd_set_config_index: setting config=0 "
                    593:                                 "failed, error=%s\n", usbd_errstr(err)));
1.136     christos  594:                }
1.75      augustss  595:                return (err);
1.1       augustss  596:        }
                    597:
1.74      augustss  598:        /* Get the short descriptor. */
1.53      augustss  599:        err = usbd_get_config_desc(dev, index, &cd);
1.172     drochner  600:        if (err) {
                    601:                DPRINTF(("usbd_set_config_index: get_config_desc=%d\n", err));
1.53      augustss  602:                return (err);
1.172     drochner  603:        }
1.1       augustss  604:        len = UGETW(cd.wTotalLength);
                    605:        cdp = malloc(len, M_USB, M_NOWAIT);
1.53      augustss  606:        if (cdp == NULL)
1.1       augustss  607:                return (USBD_NOMEM);
1.103     augustss  608:
                    609:        /* Get the full descriptor.  Try a few times for slow devices. */
                    610:        for (i = 0; i < 3; i++) {
                    611:                err = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp);
                    612:                if (!err)
                    613:                        break;
                    614:                usbd_delay_ms(dev, 200);
                    615:        }
1.172     drochner  616:        if (err) {
                    617:                DPRINTF(("usbd_set_config_index: get_desc=%d\n", err));
1.1       augustss  618:                goto bad;
1.172     drochner  619:        }
1.18      augustss  620:        if (cdp->bDescriptorType != UDESC_CONFIG) {
                    621:                DPRINTFN(-1,("usbd_set_config_index: bad desc %d\n",
                    622:                             cdp->bDescriptorType));
1.53      augustss  623:                err = USBD_INVAL;
1.18      augustss  624:                goto bad;
                    625:        }
1.74      augustss  626:
1.142     drochner  627:        /*
                    628:         * Figure out if the device is self or bus powered.
                    629:         */
                    630: #if 0 /* XXX various devices don't report the power state correctly */
1.1       augustss  631:        selfpowered = 0;
1.141     drochner  632:        err = usbd_get_device_status(dev, &ds);
                    633:        if (!err && (UGETW(ds.wStatus) & UDS_SELF_POWERED))
                    634:                selfpowered = 1;
1.142     drochner  635: #endif
                    636:        /*
                    637:         * Use the power state in the configuration we are going
                    638:         * to set. This doesn't necessarily reflect the actual
                    639:         * power state of the device; the driver can control this
                    640:         * by choosing the appropriate configuration.
                    641:         */
                    642:        selfpowered = !!(cdp->bmAttributes & UC_SELF_POWERED);
1.141     drochner  643:
1.81      augustss  644:        DPRINTF(("usbd_set_config_index: (addr %d) cno=%d attr=0x%02x, "
                    645:                 "selfpowered=%d, power=%d\n",
1.99      augustss  646:                 cdp->bConfigurationValue, dev->address, cdp->bmAttributes,
1.33      augustss  647:                 selfpowered, cdp->bMaxPower * 2));
1.74      augustss  648:
                    649:        /* Check if we have enough power. */
1.142     drochner  650: #if 0 /* this is a no-op, see above */
1.141     drochner  651:        if ((cdp->bmAttributes & UC_SELF_POWERED) && !selfpowered) {
                    652:                if (msg)
                    653:                        printf("%s: device addr %d (config %d): "
                    654:                                 "can't set self powered configuration\n",
1.164     dyoung    655:                               device_xname(dev->bus->bdev), dev->address,
1.141     drochner  656:                               cdp->bConfigurationValue);
                    657:                err = USBD_NO_POWER;
                    658:                goto bad;
                    659:        }
1.142     drochner  660: #endif
1.1       augustss  661: #ifdef USB_DEBUG
1.53      augustss  662:        if (dev->powersrc == NULL) {
1.44      augustss  663:                DPRINTF(("usbd_set_config_index: No power source?\n"));
1.141     drochner  664:                err = USBD_IOERROR;
                    665:                goto bad;
1.1       augustss  666:        }
                    667: #endif
                    668:        power = cdp->bMaxPower * 2;
                    669:        if (power > dev->powersrc->power) {
1.81      augustss  670:                DPRINTF(("power exceeded %d %d\n", power,dev->powersrc->power));
1.1       augustss  671:                /* XXX print nicer message. */
1.7       augustss  672:                if (msg)
1.18      augustss  673:                        printf("%s: device addr %d (config %d) exceeds power "
                    674:                                 "budget, %d mA > %d mA\n",
1.151     drochner  675:                               device_xname(dev->bus->usbctl), dev->address,
1.99      augustss  676:                               cdp->bConfigurationValue,
1.7       augustss  677:                               power, dev->powersrc->power);
1.53      augustss  678:                err = USBD_NO_POWER;
1.1       augustss  679:                goto bad;
                    680:        }
                    681:        dev->power = power;
                    682:        dev->self_powered = selfpowered;
                    683:
1.74      augustss  684:        /* Set the actual configuration value. */
1.18      augustss  685:        DPRINTF(("usbd_set_config_index: set config %d\n",
                    686:                 cdp->bConfigurationValue));
1.53      augustss  687:        err = usbd_set_config(dev, cdp->bConfigurationValue);
                    688:        if (err) {
1.14      drochner  689:                DPRINTF(("usbd_set_config_index: setting config=%d failed, "
1.39      augustss  690:                         "error=%s\n",
1.53      augustss  691:                         cdp->bConfigurationValue, usbd_errstr(err)));
1.1       augustss  692:                goto bad;
                    693:        }
1.74      augustss  694:
                    695:        /* Allocate and fill interface data. */
1.1       augustss  696:        nifc = cdp->bNumInterface;
1.99      augustss  697:        dev->ifaces = malloc(nifc * sizeof(struct usbd_interface),
1.1       augustss  698:                             M_USB, M_NOWAIT);
1.58      augustss  699:        if (dev->ifaces == NULL) {
1.53      augustss  700:                err = USBD_NOMEM;
1.1       augustss  701:                goto bad;
                    702:        }
1.12      augustss  703:        DPRINTFN(5,("usbd_set_config_index: dev=%p cdesc=%p\n", dev, cdp));
1.1       augustss  704:        dev->cdesc = cdp;
                    705:        dev->config = cdp->bConfigurationValue;
1.12      augustss  706:        for (ifcidx = 0; ifcidx < nifc; ifcidx++) {
1.53      augustss  707:                err = usbd_fill_iface_data(dev, ifcidx, 0);
                    708:                if (err) {
1.12      augustss  709:                        while (--ifcidx >= 0)
                    710:                                usbd_free_iface_data(dev, ifcidx);
1.1       augustss  711:                        goto bad;
                    712:                }
                    713:        }
                    714:
                    715:        return (USBD_NORMAL_COMPLETION);
                    716:
                    717:  bad:
                    718:        free(cdp, M_USB);
1.53      augustss  719:        return (err);
1.1       augustss  720: }
                    721:
                    722: /* XXX add function for alternate settings */
                    723:
                    724: usbd_status
1.78      augustss  725: usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface,
                    726:                struct usbd_endpoint *ep, int ival, usbd_pipe_handle *pipe)
1.1       augustss  727: {
                    728:        usbd_pipe_handle p;
1.53      augustss  729:        usbd_status err;
1.1       augustss  730:
                    731:        DPRINTFN(1,("usbd_setup_pipe: dev=%p iface=%p ep=%p pipe=%p\n",
                    732:                    dev, iface, ep, pipe));
                    733:        p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT);
1.53      augustss  734:        if (p == NULL)
1.1       augustss  735:                return (USBD_NOMEM);
                    736:        p->device = dev;
                    737:        p->iface = iface;
                    738:        p->endpoint = ep;
                    739:        ep->refcnt++;
                    740:        p->refcnt = 1;
1.53      augustss  741:        p->intrxfer = 0;
1.1       augustss  742:        p->running = 0;
1.70      augustss  743:        p->aborting = 0;
1.34      augustss  744:        p->repeat = 0;
1.63      augustss  745:        p->interval = ival;
1.1       augustss  746:        SIMPLEQ_INIT(&p->queue);
1.53      augustss  747:        err = dev->bus->methods->open_pipe(p);
                    748:        if (err) {
1.39      augustss  749:                DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error="
                    750:                         "%s\n",
1.53      augustss  751:                         ep->edesc->bEndpointAddress, usbd_errstr(err)));
1.1       augustss  752:                free(p, M_USB);
1.53      augustss  753:                return (err);
1.1       augustss  754:        }
                    755:        *pipe = p;
                    756:        return (USBD_NORMAL_COMPLETION);
                    757: }
                    758:
                    759: /* Abort the device control pipe. */
                    760: void
1.78      augustss  761: usbd_kill_pipe(usbd_pipe_handle pipe)
1.1       augustss  762: {
1.89      augustss  763:        usbd_abort_pipe(pipe);
1.1       augustss  764:        pipe->methods->close(pipe);
                    765:        pipe->endpoint->refcnt--;
                    766:        free(pipe, M_USB);
                    767: }
                    768:
                    769: int
1.78      augustss  770: usbd_getnewaddr(usbd_bus_handle bus)
1.1       augustss  771: {
1.18      augustss  772:        int addr;
1.1       augustss  773:
1.18      augustss  774:        for (addr = 1; addr < USB_MAX_DEVICES; addr++)
                    775:                if (bus->devices[addr] == 0)
                    776:                        return (addr);
1.1       augustss  777:        return (-1);
                    778: }
                    779:
1.155     drochner  780: usbd_status
                    781: usbd_attach_roothub(device_t parent, usbd_device_handle dev)
                    782: {
                    783:        struct usb_attach_arg uaa;
                    784:        usb_device_descriptor_t *dd = &dev->ddesc;
                    785:        device_t dv;
                    786:
                    787:        uaa.device = dev;
                    788:        uaa.usegeneric = 0;
                    789:        uaa.port = 0;
                    790:        uaa.vendor = UGETW(dd->idVendor);
                    791:        uaa.product = UGETW(dd->idProduct);
                    792:        uaa.release = UGETW(dd->bcdDevice);
                    793:        uaa.class = dd->bDeviceClass;
                    794:        uaa.subclass = dd->bDeviceSubClass;
                    795:        uaa.proto = dd->bDeviceProtocol;
                    796:
1.156     drochner  797:        dv = config_found_ia(parent, "usbroothubif", &uaa, 0);
1.155     drochner  798:        if (dv) {
                    799:                dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT);
                    800:                if (dev->subdevs == NULL)
                    801:                        return (USBD_NOMEM);
                    802:                dev->subdevs[0] = dv;
                    803:                dev->subdevlen = 1;
                    804:        }
                    805:        return (USBD_NORMAL_COMPLETION);
                    806: }
1.18      augustss  807:
1.160     drochner  808: static usbd_status
                    809: usbd_attachwholedevice(device_t parent, usbd_device_handle dev, int port,
                    810:        int usegeneric)
1.18      augustss  811: {
                    812:        struct usb_attach_arg uaa;
                    813:        usb_device_descriptor_t *dd = &dev->ddesc;
1.160     drochner  814:        device_t dv;
1.158     drochner  815:        int dlocs[USBDEVIFCF_NLOCS];
1.18      augustss  816:
                    817:        uaa.device = dev;
1.160     drochner  818:        uaa.usegeneric = usegeneric;
1.18      augustss  819:        uaa.port = port;
1.32      augustss  820:        uaa.vendor = UGETW(dd->idVendor);
                    821:        uaa.product = UGETW(dd->idProduct);
                    822:        uaa.release = UGETW(dd->bcdDevice);
1.144     drochner  823:        uaa.class = dd->bDeviceClass;
                    824:        uaa.subclass = dd->bDeviceSubClass;
                    825:        uaa.proto = dd->bDeviceProtocol;
1.18      augustss  826:
1.158     drochner  827:        dlocs[USBDEVIFCF_PORT] = uaa.port;
                    828:        dlocs[USBDEVIFCF_VENDOR] = uaa.vendor;
                    829:        dlocs[USBDEVIFCF_PRODUCT] = uaa.product;
                    830:        dlocs[USBDEVIFCF_RELEASE] = uaa.release;
                    831:        /* the rest is historical ballast */
                    832:        dlocs[USBDEVIFCF_CONFIGURATION] = -1;
                    833:        dlocs[USBDEVIFCF_INTERFACE] = -1;
                    834:
                    835:        dv = config_found_sm_loc(parent, "usbdevif", dlocs, &uaa, usbd_print,
1.160     drochner  836:                                 config_stdsubmatch);
1.34      augustss  837:        if (dv) {
1.155     drochner  838:                dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT);
1.57      augustss  839:                if (dev->subdevs == NULL)
1.34      augustss  840:                        return (USBD_NOMEM);
                    841:                dev->subdevs[0] = dv;
1.155     drochner  842:                dev->subdevlen = 1;
1.160     drochner  843:                dev->nifaces_claimed = 1; /* XXX */
1.34      augustss  844:        }
1.160     drochner  845:        return (USBD_NORMAL_COMPLETION);
                    846: }
1.18      augustss  847:
1.160     drochner  848: static usbd_status
1.162     kent      849: usbd_attachinterfaces(device_t parent, usbd_device_handle dev,
                    850:                      int port, const int *locators)
1.160     drochner  851: {
                    852:        struct usbif_attach_arg uiaa;
1.162     kent      853:        int ilocs[USBIFIFCF_NLOCS];
1.160     drochner  854:        usb_device_descriptor_t *dd = &dev->ddesc;
                    855:        int nifaces;
                    856:        usbd_interface_handle *ifaces;
1.162     kent      857:        int i, j, loc;
1.160     drochner  858:        device_t dv;
                    859:
                    860:        nifaces = dev->cdesc->bNumInterface;
                    861:        ifaces = malloc(nifaces * sizeof(*ifaces), M_USB, M_NOWAIT|M_ZERO);
                    862:        if (!ifaces)
                    863:                return (USBD_NOMEM);
                    864:        for (i = 0; i < nifaces; i++)
                    865:                if (!dev->subdevs[i])
                    866:                        ifaces[i] = &dev->ifaces[i];
1.18      augustss  867:
1.144     drochner  868:        uiaa.device = dev;
                    869:        uiaa.port = port;
                    870:        uiaa.vendor = UGETW(dd->idVendor);
                    871:        uiaa.product = UGETW(dd->idProduct);
                    872:        uiaa.release = UGETW(dd->bcdDevice);
1.160     drochner  873:        uiaa.configno = dev->cdesc->bConfigurationValue;
                    874:        uiaa.ifaces = ifaces;
                    875:        uiaa.nifaces = nifaces;
1.158     drochner  876:        ilocs[USBIFIFCF_PORT] = uiaa.port;
                    877:        ilocs[USBIFIFCF_VENDOR] = uiaa.vendor;
                    878:        ilocs[USBIFIFCF_PRODUCT] = uiaa.product;
                    879:        ilocs[USBIFIFCF_RELEASE] = uiaa.release;
1.160     drochner  880:        ilocs[USBIFIFCF_CONFIGURATION] = uiaa.configno;
                    881:
                    882:        for (i = 0; i < nifaces; i++) {
                    883:                if (!ifaces[i])
                    884:                        continue; /* interface already claimed */
                    885:                uiaa.iface = ifaces[i];
                    886:                uiaa.class = ifaces[i]->idesc->bInterfaceClass;
                    887:                uiaa.subclass = ifaces[i]->idesc->bInterfaceSubClass;
                    888:                uiaa.proto = ifaces[i]->idesc->bInterfaceProtocol;
                    889:                uiaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber;
                    890:                ilocs[USBIFIFCF_INTERFACE] = uiaa.ifaceno;
1.162     kent      891:                if (locators != NULL) {
                    892:                        loc = locators[USBIFIFCF_CONFIGURATION];
                    893:                        if (loc != USBIFIFCF_CONFIGURATION_DEFAULT &&
                    894:                            loc != uiaa.configno)
                    895:                                continue;
                    896:                        loc = locators[USBIFIFCF_INTERFACE];
                    897:                        if (loc != USBIFIFCF_INTERFACE && loc != uiaa.ifaceno)
                    898:                                continue;
                    899:                }
1.160     drochner  900:                dv = config_found_sm_loc(parent, "usbifif", ilocs, &uiaa,
                    901:                                         usbd_ifprint, config_stdsubmatch);
                    902:                if (!dv)
                    903:                        continue;
                    904:                ifaces[i] = 0; /* claim */
                    905:                /* account for ifaces claimed by the driver behind our back */
                    906:                for (j = 0; j < nifaces; j++) {
                    907:                        if (!ifaces[j] && !dev->subdevs[j]) {
                    908:                                dev->subdevs[j] = dv;
                    909:                                dev->nifaces_claimed++;
                    910:                        }
                    911:                }
                    912:        }
                    913:
                    914:        free(ifaces, M_USB);
                    915:        return (USBD_NORMAL_COMPLETION);
                    916: }
                    917:
                    918: usbd_status
1.164     dyoung    919: usbd_probe_and_attach(device_t parent, usbd_device_handle dev,
                    920:                       int port, int addr)
1.160     drochner  921: {
                    922:        usb_device_descriptor_t *dd = &dev->ddesc;
                    923:        int confi, nifaces;
                    924:        usbd_status err;
                    925:
                    926:        /* First try with device specific drivers. */
                    927:        DPRINTF(("usbd_probe_and_attach: trying device specific drivers\n"));
                    928:        err = usbd_attachwholedevice(parent, dev, port, 0);
                    929:        if (dev->nifaces_claimed || err)
                    930:                return (err);
                    931:        DPRINTF(("usbd_probe_and_attach: no device specific driver found\n"));
1.158     drochner  932:
1.60      augustss  933:        DPRINTF(("usbd_probe_and_attach: looping over %d configurations\n",
                    934:                 dd->bNumConfigurations));
1.18      augustss  935:        for (confi = 0; confi < dd->bNumConfigurations; confi++) {
                    936:                DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n",
                    937:                            confi));
1.53      augustss  938:                err = usbd_set_config_index(dev, confi, 1);
                    939:                if (err) {
1.18      augustss  940: #ifdef USB_DEBUG
                    941:                        DPRINTF(("%s: port %d, set config at addr %d failed, "
1.164     dyoung    942:                            "error=%s\n", device_xname(parent), port,
                    943:                            addr, usbd_errstr(err)));
1.18      augustss  944: #else
                    945:                        printf("%s: port %d, set config at addr %d failed\n",
1.164     dyoung    946:                            device_xname(parent), port, addr);
1.18      augustss  947: #endif
1.162     kent      948:                        return (err);
1.18      augustss  949:                }
1.20      augustss  950:                nifaces = dev->cdesc->bNumInterface;
1.160     drochner  951:                dev->subdevs = malloc(nifaces * sizeof(device_t), M_USB,
1.155     drochner  952:                                      M_NOWAIT|M_ZERO);
1.160     drochner  953:                if (dev->subdevs == NULL)
1.34      augustss  954:                        return (USBD_NOMEM);
1.155     drochner  955:                dev->subdevlen = nifaces;
1.52      augustss  956:
1.162     kent      957:                err = usbd_attachinterfaces(parent, dev, port, NULL);
1.160     drochner  958:
                    959:                if (!dev->nifaces_claimed) {
                    960:                        free(dev->subdevs, M_USB);
                    961:                        dev->subdevs = 0;
                    962:                        dev->subdevlen = 0;
1.18      augustss  963:                }
1.160     drochner  964:                if (dev->nifaces_claimed || err)
                    965:                        return (err);
1.18      augustss  966:        }
1.21      augustss  967:        /* No interfaces were attached in any of the configurations. */
1.34      augustss  968:
                    969:        if (dd->bNumConfigurations > 1) /* don't change if only 1 config */
1.18      augustss  970:                usbd_set_config_index(dev, 0, 0);
                    971:
                    972:        DPRINTF(("usbd_probe_and_attach: no interface drivers found\n"));
                    973:
                    974:        /* Finally try the generic driver. */
1.160     drochner  975:        err = usbd_attachwholedevice(parent, dev, port, 1);
1.18      augustss  976:
1.99      augustss  977:        /*
1.18      augustss  978:         * The generic attach failed, but leave the device as it is.
                    979:         * We just did not find any drivers, that's all.  The device is
                    980:         * fully operational and not harming anyone.
                    981:         */
                    982:        DPRINTF(("usbd_probe_and_attach: generic attach failed\n"));
1.162     kent      983:        return (USBD_NORMAL_COMPLETION);
1.18      augustss  984: }
                    985:
1.162     kent      986: /**
                    987:  * Called from uhub_rescan().  usbd_new_device() for the target dev must be
                    988:  * called before calling this.
                    989:  */
                    990: usbd_status
1.164     dyoung    991: usbd_reattach_device(device_t parent, usbd_device_handle dev,
                    992:                      int port, const int *locators)
1.162     kent      993: {
                    994:        int i, loc;
                    995:
                    996:        if (locators != NULL) {
                    997:                loc = locators[USBIFIFCF_PORT];
                    998:                if (loc != USBIFIFCF_PORT_DEFAULT && loc != port)
                    999:                        return USBD_NORMAL_COMPLETION;
                   1000:                loc = locators[USBIFIFCF_VENDOR];
                   1001:                if (loc != USBIFIFCF_VENDOR_DEFAULT &&
                   1002:                    loc != UGETW(dev->ddesc.idVendor))
                   1003:                        return USBD_NORMAL_COMPLETION;
                   1004:                loc = locators[USBIFIFCF_PRODUCT];
                   1005:                if (loc != USBIFIFCF_PRODUCT_DEFAULT &&
                   1006:                    loc != UGETW(dev->ddesc.idProduct))
                   1007:                        return USBD_NORMAL_COMPLETION;
                   1008:                loc = locators[USBIFIFCF_RELEASE];
                   1009:                if (loc != USBIFIFCF_RELEASE_DEFAULT &&
                   1010:                    loc != UGETW(dev->ddesc.bcdDevice))
                   1011:                        return USBD_NORMAL_COMPLETION;
                   1012:        }
                   1013:        if (dev->subdevlen == 0) {
                   1014:                /* XXX: check USBIFIFCF_CONFIGURATION and
                   1015:                 * USBIFIFCF_INTERFACE too */
                   1016:                return usbd_probe_and_attach(parent, dev, port, dev->address);
                   1017:        } else if (dev->subdevlen != dev->cdesc->bNumInterface) {
                   1018:                /* device-specific or generic driver is already attached. */
                   1019:                return USBD_NORMAL_COMPLETION;
                   1020:        }
                   1021:        /* Does the device have unconfigured interfaces? */
                   1022:        for (i = 0; i < dev->subdevlen; i++) {
                   1023:                if (dev->subdevs[i] == NULL) {
                   1024:                        break;
                   1025:                }
                   1026:        }
                   1027:        if (i >= dev->subdevlen)
                   1028:                return USBD_NORMAL_COMPLETION;
                   1029:        return usbd_attachinterfaces(parent, dev, port, locators);
                   1030: }
1.18      augustss 1031:
1.1       augustss 1032: /*
1.172     drochner 1033:  * Get the first 8 bytes of the device descriptor.
                   1034:  * Do as Windows does: try to read 64 bytes -- there are devices which
                   1035:  * recognize the initial descriptor fetch (before the control endpoint's
                   1036:  * MaxPacketSize is known by the host) by exactly this length.
                   1037:  */
                   1038: static usbd_status
                   1039: usbd_get_initial_ddesc(usbd_device_handle dev, usb_device_descriptor_t *desc)
                   1040: {
                   1041:        usb_device_request_t req;
                   1042:        char buf[64];
                   1043:        int res, actlen;
                   1044:
                   1045:        req.bmRequestType = UT_READ_DEVICE;
                   1046:        req.bRequest = UR_GET_DESCRIPTOR;
                   1047:        USETW2(req.wValue, UDESC_DEVICE, 0);
                   1048:        USETW(req.wIndex, 0);
                   1049:        USETW(req.wLength, 64);
                   1050:        res = usbd_do_request_flags(dev, &req, buf, USBD_SHORT_XFER_OK,
                   1051:                &actlen, USBD_DEFAULT_TIMEOUT);
                   1052:        if (res)
                   1053:                return res;
                   1054:        if (actlen < 8)
                   1055:                return USBD_SHORT_XFER;
                   1056:        memcpy(desc, buf, 8);
                   1057:        return USBD_NORMAL_COMPLETION;
                   1058: }
                   1059:
                   1060: /*
1.1       augustss 1061:  * Called when a new device has been put in the powered state,
                   1062:  * but not yet in the addressed state.
                   1063:  * Get initial descriptor, set the address, get full descriptor,
                   1064:  * and attach a driver.
                   1065:  */
                   1066: usbd_status
1.164     dyoung   1067: usbd_new_device(device_t parent, usbd_bus_handle bus, int depth,
                   1068:                 int speed, int port, struct usbd_port *up)
1.1       augustss 1069: {
1.120     augustss 1070:        usbd_device_handle dev, adev;
1.94      augustss 1071:        struct usbd_device *hub;
1.18      augustss 1072:        usb_device_descriptor_t *dd;
1.107     augustss 1073:        usb_port_status_t ps;
1.53      augustss 1074:        usbd_status err;
1.1       augustss 1075:        int addr;
1.18      augustss 1076:        int i;
1.120     augustss 1077:        int p;
1.1       augustss 1078:
1.94      augustss 1079:        DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n",
                   1080:                 bus, port, depth, speed));
1.1       augustss 1081:        addr = usbd_getnewaddr(bus);
                   1082:        if (addr < 0) {
1.99      augustss 1083:                printf("%s: No free USB addresses, new device ignored.\n",
1.151     drochner 1084:                       device_xname(bus->usbctl));
1.1       augustss 1085:                return (USBD_NO_ADDR);
                   1086:        }
                   1087:
1.97      tsutsui  1088:        dev = malloc(sizeof *dev, M_USB, M_NOWAIT|M_ZERO);
1.53      augustss 1089:        if (dev == NULL)
1.1       augustss 1090:                return (USBD_NOMEM);
                   1091:
                   1092:        dev->bus = bus;
                   1093:
                   1094:        /* Set up default endpoint handle. */
                   1095:        dev->def_ep.edesc = &dev->def_ep_desc;
                   1096:
                   1097:        /* Set up default endpoint descriptor. */
                   1098:        dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE;
                   1099:        dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT;
                   1100:        dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
                   1101:        dev->def_ep_desc.bmAttributes = UE_CONTROL;
1.172     drochner 1102:        /*
                   1103:         * temporary, will be fixed after first descriptor fetch
                   1104:         * (which uses 64 bytes so it shouldn't be less),
                   1105:         * highspeed devices must support 64 byte packets anyway
                   1106:         */
                   1107:        USETW(dev->def_ep_desc.wMaxPacketSize, 64);
1.1       augustss 1108:        dev->def_ep_desc.bInterval = 0;
                   1109:
1.179     drochner 1110:        /* doesn't matter, just don't let it uninitialized */
                   1111:        dev->def_ep.datatoggle = 0;
                   1112:
1.1       augustss 1113:        dev->quirks = &usbd_no_quirk;
                   1114:        dev->address = USB_START_ADDR;
1.4       augustss 1115:        dev->ddesc.bMaxPacketSize = 0;
1.1       augustss 1116:        dev->depth = depth;
                   1117:        dev->powersrc = up;
1.94      augustss 1118:        dev->myhub = up->parent;
1.120     augustss 1119:
                   1120:        up->device = dev;
                   1121:
                   1122:        /* Locate port on upstream high speed hub */
                   1123:        for (adev = dev, hub = up->parent;
1.94      augustss 1124:             hub != NULL && hub->speed != USB_SPEED_HIGH;
1.120     augustss 1125:             adev = hub, hub = hub->myhub)
1.94      augustss 1126:                ;
1.120     augustss 1127:        if (hub) {
                   1128:                for (p = 0; p < hub->hub->hubdesc.bNbrPorts; p++) {
                   1129:                        if (hub->hub->ports[p].device == adev) {
                   1130:                                dev->myhsport = &hub->hub->ports[p];
                   1131:                                goto found;
                   1132:                        }
                   1133:                }
                   1134:                panic("usbd_new_device: cannot find HS port\n");
                   1135:        found:
                   1136:                DPRINTFN(1,("usbd_new_device: high speed port %d\n", p));
                   1137:        } else {
                   1138:                dev->myhsport = NULL;
                   1139:        }
1.94      augustss 1140:        dev->speed = speed;
1.22      augustss 1141:        dev->langid = USBD_NOLANG;
1.50      augustss 1142:        dev->cookie.cookie = ++usb_cookie_no;
1.1       augustss 1143:
1.67      soren    1144:        /* Establish the default pipe. */
1.63      augustss 1145:        err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
                   1146:                              &dev->default_pipe);
1.53      augustss 1147:        if (err) {
1.18      augustss 1148:                usbd_remove_device(dev, up);
1.53      augustss 1149:                return (err);
1.18      augustss 1150:        }
1.1       augustss 1151:
1.18      augustss 1152:        dd = &dev->ddesc;
1.6       augustss 1153:        /* Try a few times in case the device is slow (i.e. outside specs.) */
1.107     augustss 1154:        for (i = 0; i < 10; i++) {
1.6       augustss 1155:                /* Get the first 8 bytes of the device descriptor. */
1.172     drochner 1156:                err = usbd_get_initial_ddesc(dev, dd);
1.53      augustss 1157:                if (!err)
1.6       augustss 1158:                        break;
1.23      augustss 1159:                usbd_delay_ms(dev, 200);
1.107     augustss 1160:                if ((i & 3) == 3)
                   1161:                        usbd_reset_port(up->parent, port, &ps);
1.6       augustss 1162:        }
1.53      augustss 1163:        if (err) {
1.14      drochner 1164:                DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc "
1.180     matt     1165:                              "failed: %d\n", addr, err));
1.18      augustss 1166:                usbd_remove_device(dev, up);
1.53      augustss 1167:                return (err);
1.95      augustss 1168:        }
                   1169:
1.174     drochner 1170:        /* Windows resets the port here, do likewise */
                   1171:        if (up->parent)
                   1172:                usbd_reset_port(up->parent, port, &ps);
                   1173:
1.95      augustss 1174:        if (speed == USB_SPEED_HIGH) {
                   1175:                /* Max packet size must be 64 (sec 5.5.3). */
                   1176:                if (dd->bMaxPacketSize != USB_2_MAX_CTRL_PACKET) {
                   1177: #ifdef DIAGNOSTIC
1.165     pooka    1178:                        printf("usbd_new_device: addr=%d bad max packet "
                   1179:                            "size=%d. adjusting to %d.\n",
                   1180:                            addr, dd->bMaxPacketSize, USB_2_MAX_CTRL_PACKET);
1.95      augustss 1181: #endif
                   1182:                        dd->bMaxPacketSize = USB_2_MAX_CTRL_PACKET;
                   1183:                }
1.18      augustss 1184:        }
                   1185:
1.39      augustss 1186:        DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, "
1.99      augustss 1187:                 "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n",
1.39      augustss 1188:                 addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass,
1.99      augustss 1189:                 dd->bDeviceProtocol, dd->bMaxPacketSize, dd->bLength,
1.94      augustss 1190:                 dev->speed));
1.39      augustss 1191:
1.18      augustss 1192:        if (dd->bDescriptorType != UDESC_DEVICE) {
                   1193:                /* Illegal device descriptor */
                   1194:                DPRINTFN(-1,("usbd_new_device: illegal descriptor %d\n",
                   1195:                             dd->bDescriptorType));
                   1196:                usbd_remove_device(dev, up);
                   1197:                return (USBD_INVAL);
1.1       augustss 1198:        }
                   1199:
1.39      augustss 1200:        if (dd->bLength < USB_DEVICE_DESCRIPTOR_SIZE) {
                   1201:                DPRINTFN(-1,("usbd_new_device: bad length %d\n", dd->bLength));
                   1202:                usbd_remove_device(dev, up);
                   1203:                return (USBD_INVAL);
                   1204:        }
1.4       augustss 1205:
1.18      augustss 1206:        USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize);
1.1       augustss 1207:
1.159     jmcneill 1208:        /* Set the address */
                   1209:        DPRINTFN(5, ("usbd_new_device: setting device address=%d\n", addr));
                   1210:        err = usbd_set_address(dev, addr);
                   1211:        if (err) {
                   1212:                DPRINTFN(-1, ("usbd_new_device: set address %d failed\n", addr));
                   1213:                err = USBD_SET_ADDR_FAILED;
                   1214:                usbd_remove_device(dev, up);
                   1215:                return err;
                   1216:        }
                   1217:
                   1218:        /* Allow device time to set new address */
                   1219:        usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE);
                   1220:        dev->address = addr;    /* new device address now */
                   1221:        bus->devices[addr] = dev;
                   1222:
1.168     matthias 1223:        err = usbd_reload_device_desc(dev);
                   1224:        if (err) {
                   1225:                DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc "
                   1226:                              "failed\n", addr));
                   1227:                usbd_remove_device(dev, up);
                   1228:                return (err);
                   1229:        }
                   1230:
1.159     jmcneill 1231:        /* Re-establish the default pipe with the new address. */
                   1232:        usbd_kill_pipe(dev->default_pipe);
                   1233:        err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
                   1234:            &dev->default_pipe);
                   1235:        if (err) {
                   1236:                DPRINTFN(-1, ("usbd_new_device: setup default pipe failed\n"));
                   1237:                usbd_remove_device(dev, up);
                   1238:                return err;
                   1239:        }
                   1240:
1.1       augustss 1241:        /* Assume 100mA bus powered for now. Changed when configured. */
                   1242:        dev->power = USB_MIN_POWER;
                   1243:        dev->self_powered = 0;
                   1244:
1.99      augustss 1245:        DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n",
1.1       augustss 1246:                 addr, dev, parent));
1.99      augustss 1247:
1.65      augustss 1248:        usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev);
1.1       augustss 1249:
1.155     drochner 1250:        if (port == 0) { /* root hub */
                   1251:                KASSERT(addr == 1);
                   1252:                usbd_attach_roothub(parent, dev);
                   1253:                return (USBD_NORMAL_COMPLETION);
                   1254:        }
                   1255:
1.53      augustss 1256:        err = usbd_probe_and_attach(parent, dev, port, addr);
                   1257:        if (err) {
1.18      augustss 1258:                usbd_remove_device(dev, up);
1.53      augustss 1259:                return (err);
1.164     dyoung   1260:        }
1.65      augustss 1261:
1.164     dyoung   1262:        return (USBD_NORMAL_COMPLETION);
1.62      augustss 1263: }
                   1264:
                   1265: usbd_status
1.78      augustss 1266: usbd_reload_device_desc(usbd_device_handle dev)
1.62      augustss 1267: {
                   1268:        usbd_status err;
                   1269:
                   1270:        /* Get the full device descriptor. */
                   1271:        err = usbd_get_device_desc(dev, &dev->ddesc);
                   1272:        if (err)
                   1273:                return (err);
                   1274:
                   1275:        /* Figure out what's wrong with this device. */
                   1276:        dev->quirks = usbd_find_quirk(&dev->ddesc);
                   1277:
                   1278:        return (USBD_NORMAL_COMPLETION);
1.18      augustss 1279: }
1.1       augustss 1280:
1.18      augustss 1281: void
1.78      augustss 1282: usbd_remove_device(usbd_device_handle dev, struct usbd_port *up)
1.18      augustss 1283: {
                   1284:        DPRINTF(("usbd_remove_device: %p\n", dev));
1.99      augustss 1285:
1.53      augustss 1286:        if (dev->default_pipe != NULL)
1.18      augustss 1287:                usbd_kill_pipe(dev->default_pipe);
1.120     augustss 1288:        up->device = NULL;
                   1289:        dev->bus->devices[dev->address] = NULL;
1.1       augustss 1290:
                   1291:        free(dev, M_USB);
                   1292: }
                   1293:
                   1294: int
1.78      augustss 1295: usbd_print(void *aux, const char *pnp)
1.1       augustss 1296: {
                   1297:        struct usb_attach_arg *uaa = aux;
                   1298:
                   1299:        DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device));
                   1300:        if (pnp) {
1.134     christos 1301: #define USB_DEVINFO 1024
                   1302:                char *devinfo;
1.1       augustss 1303:                if (!uaa->usegeneric)
                   1304:                        return (QUIET);
1.134     christos 1305:                devinfo = malloc(USB_DEVINFO, M_TEMP, M_WAITOK);
                   1306:                usbd_devinfo(uaa->device, 1, devinfo, USB_DEVINFO);
1.101     thorpej  1307:                aprint_normal("%s, %s", devinfo, pnp);
1.134     christos 1308:                free(devinfo, M_TEMP);
1.1       augustss 1309:        }
1.155     drochner 1310:        aprint_normal(" port %d", uaa->port);
1.144     drochner 1311: #if 0
                   1312:        /*
                   1313:         * It gets very crowded with these locators on the attach line.
                   1314:         * They are not really needed since they are printed in the clear
                   1315:         * by each driver.
                   1316:         */
                   1317:        if (uaa->vendor != UHUB_UNK_VENDOR)
                   1318:                aprint_normal(" vendor 0x%04x", uaa->vendor);
                   1319:        if (uaa->product != UHUB_UNK_PRODUCT)
                   1320:                aprint_normal(" product 0x%04x", uaa->product);
                   1321:        if (uaa->release != UHUB_UNK_RELEASE)
                   1322:                aprint_normal(" release 0x%04x", uaa->release);
                   1323: #endif
                   1324:        return (UNCONF);
                   1325: }
                   1326:
                   1327: int
                   1328: usbd_ifprint(void *aux, const char *pnp)
                   1329: {
                   1330:        struct usbif_attach_arg *uaa = aux;
                   1331:
                   1332:        DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device));
                   1333:        if (pnp)
                   1334:                return (QUIET);
1.155     drochner 1335:        aprint_normal(" port %d", uaa->port);
1.156     drochner 1336:        aprint_normal(" configuration %d", uaa->configno);
                   1337:        aprint_normal(" interface %d", uaa->ifaceno);
1.32      augustss 1338: #if 0
1.99      augustss 1339:        /*
1.32      augustss 1340:         * It gets very crowded with these locators on the attach line.
                   1341:         * They are not really needed since they are printed in the clear
                   1342:         * by each driver.
                   1343:         */
                   1344:        if (uaa->vendor != UHUB_UNK_VENDOR)
1.101     thorpej  1345:                aprint_normal(" vendor 0x%04x", uaa->vendor);
1.32      augustss 1346:        if (uaa->product != UHUB_UNK_PRODUCT)
1.101     thorpej  1347:                aprint_normal(" product 0x%04x", uaa->product);
1.32      augustss 1348:        if (uaa->release != UHUB_UNK_RELEASE)
1.101     thorpej  1349:                aprint_normal(" release 0x%04x", uaa->release);
1.32      augustss 1350: #endif
1.1       augustss 1351:        return (UNCONF);
                   1352: }
                   1353:
1.13      augustss 1354: void
1.82      augustss 1355: usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di,
                   1356:                     int usedev)
1.13      augustss 1357: {
                   1358:        struct usbd_port *p;
1.155     drochner 1359:        int i, j, err, s;
1.13      augustss 1360:
1.151     drochner 1361:        di->udi_bus = device_unit(dev->bus->usbctl);
1.98      christos 1362:        di->udi_addr = dev->address;
                   1363:        di->udi_cookie = dev->cookie;
1.175     christos 1364:        usbd_devinfo_vp(dev, di->udi_vendor, sizeof(di->udi_vendor),
                   1365:            di->udi_product, sizeof(di->udi_product), usedev, 1);
1.113     itojun   1366:        usbd_printBCD(di->udi_release, sizeof(di->udi_release),
                   1367:            UGETW(dev->ddesc.bcdDevice));
1.123     augustss 1368:        di->udi_serial[0] = 0;
                   1369:        if (usedev)
                   1370:                (void)usbd_get_string(dev, dev->ddesc.iSerialNumber,
                   1371:                                      di->udi_serial);
1.98      christos 1372:        di->udi_vendorNo = UGETW(dev->ddesc.idVendor);
                   1373:        di->udi_productNo = UGETW(dev->ddesc.idProduct);
                   1374:        di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice);
                   1375:        di->udi_class = dev->ddesc.bDeviceClass;
                   1376:        di->udi_subclass = dev->ddesc.bDeviceSubClass;
                   1377:        di->udi_protocol = dev->ddesc.bDeviceProtocol;
                   1378:        di->udi_config = dev->config;
                   1379:        di->udi_power = dev->self_powered ? 0 : dev->power;
                   1380:        di->udi_speed = dev->speed;
1.65      augustss 1381:
1.155     drochner 1382:        if (dev->subdevlen > 0) {
                   1383:                for (i = 0, j = 0; i < dev->subdevlen &&
                   1384:                             j < USB_MAX_DEVNAMES; i++) {
                   1385:                        if (!dev->subdevs[i])
                   1386:                                continue;
1.164     dyoung   1387:                        strncpy(di->udi_devnames[j],
                   1388:                            device_xname(dev->subdevs[i]), USB_MAX_DEVNAMELEN);
1.155     drochner 1389:                        di->udi_devnames[j][USB_MAX_DEVNAMELEN-1] = '\0';
                   1390:                        j++;
1.164     dyoung   1391:                }
                   1392:        } else {
                   1393:                j = 0;
                   1394:        }
                   1395:        for (/* j is set */; j < USB_MAX_DEVNAMES; j++)
                   1396:                di->udi_devnames[j][0] = 0;                 /* empty */
1.65      augustss 1397:
1.13      augustss 1398:        if (dev->hub) {
1.99      augustss 1399:                for (i = 0;
1.98      christos 1400:                     i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) &&
1.13      augustss 1401:                             i < dev->hub->hubdesc.bNbrPorts;
                   1402:                     i++) {
                   1403:                        p = &dev->hub->ports[i];
                   1404:                        if (p->device)
1.56      augustss 1405:                                err = p->device->address;
1.13      augustss 1406:                        else {
                   1407:                                s = UGETW(p->status.wPortStatus);
                   1408:                                if (s & UPS_PORT_ENABLED)
1.56      augustss 1409:                                        err = USB_PORT_ENABLED;
1.13      augustss 1410:                                else if (s & UPS_SUSPEND)
1.56      augustss 1411:                                        err = USB_PORT_SUSPENDED;
1.13      augustss 1412:                                else if (s & UPS_PORT_POWER)
1.56      augustss 1413:                                        err = USB_PORT_POWERED;
1.13      augustss 1414:                                else
1.56      augustss 1415:                                        err = USB_PORT_DISABLED;
1.13      augustss 1416:                        }
1.98      christos 1417:                        di->udi_ports[i] = err;
1.13      augustss 1418:                }
1.98      christos 1419:                di->udi_nports = dev->hub->hubdesc.bNbrPorts;
1.13      augustss 1420:        } else
1.98      christos 1421:                di->udi_nports = 0;
1.34      augustss 1422: }
                   1423:
1.139     pavel    1424: #ifdef COMPAT_30
                   1425: void
                   1426: usbd_fill_deviceinfo_old(usbd_device_handle dev, struct usb_device_info_old *di,
                   1427:                          int usedev)
                   1428: {
                   1429:        struct usbd_port *p;
1.155     drochner 1430:        int i, j, err, s;
1.139     pavel    1431:
1.151     drochner 1432:        di->udi_bus = device_unit(dev->bus->usbctl);
1.139     pavel    1433:        di->udi_addr = dev->address;
                   1434:        di->udi_cookie = dev->cookie;
1.175     christos 1435:        usbd_devinfo_vp(dev, di->udi_vendor, sizeof(di->udi_vendor),
                   1436:            di->udi_product, sizeof(di->udi_product), usedev, 0);
1.139     pavel    1437:        usbd_printBCD(di->udi_release, sizeof(di->udi_release),
                   1438:            UGETW(dev->ddesc.bcdDevice));
                   1439:        di->udi_vendorNo = UGETW(dev->ddesc.idVendor);
                   1440:        di->udi_productNo = UGETW(dev->ddesc.idProduct);
                   1441:        di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice);
                   1442:        di->udi_class = dev->ddesc.bDeviceClass;
                   1443:        di->udi_subclass = dev->ddesc.bDeviceSubClass;
                   1444:        di->udi_protocol = dev->ddesc.bDeviceProtocol;
                   1445:        di->udi_config = dev->config;
                   1446:        di->udi_power = dev->self_powered ? 0 : dev->power;
                   1447:        di->udi_speed = dev->speed;
                   1448:
1.155     drochner 1449:        if (dev->subdevlen > 0) {
                   1450:                for (i = 0, j = 0; i < dev->subdevlen &&
                   1451:                             j < USB_MAX_DEVNAMES; i++) {
                   1452:                        if (!dev->subdevs[i])
                   1453:                                continue;
1.164     dyoung   1454:                        strncpy(di->udi_devnames[j],
                   1455:                            device_xname(dev->subdevs[i]), USB_MAX_DEVNAMELEN);
1.155     drochner 1456:                        di->udi_devnames[j][USB_MAX_DEVNAMELEN-1] = '\0';
                   1457:                        j++;
1.139     pavel    1458:                }
                   1459:        } else {
1.155     drochner 1460:                j = 0;
1.139     pavel    1461:        }
1.155     drochner 1462:        for (/* j is set */; j < USB_MAX_DEVNAMES; j++)
                   1463:                di->udi_devnames[j][0] = 0;              /* empty */
1.139     pavel    1464:
                   1465:        if (dev->hub) {
                   1466:                for (i = 0;
                   1467:                     i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) &&
                   1468:                             i < dev->hub->hubdesc.bNbrPorts;
                   1469:                     i++) {
                   1470:                        p = &dev->hub->ports[i];
                   1471:                        if (p->device)
                   1472:                                err = p->device->address;
                   1473:                        else {
                   1474:                                s = UGETW(p->status.wPortStatus);
                   1475:                                if (s & UPS_PORT_ENABLED)
                   1476:                                        err = USB_PORT_ENABLED;
                   1477:                                else if (s & UPS_SUSPEND)
                   1478:                                        err = USB_PORT_SUSPENDED;
                   1479:                                else if (s & UPS_PORT_POWER)
                   1480:                                        err = USB_PORT_POWERED;
                   1481:                                else
                   1482:                                        err = USB_PORT_DISABLED;
                   1483:                        }
                   1484:                        di->udi_ports[i] = err;
                   1485:                }
                   1486:                di->udi_nports = dev->hub->hubdesc.bNbrPorts;
                   1487:        } else
                   1488:                di->udi_nports = 0;
                   1489: }
                   1490: #endif
                   1491:
                   1492:
1.34      augustss 1493: void
1.78      augustss 1494: usb_free_device(usbd_device_handle dev)
1.34      augustss 1495: {
                   1496:        int ifcidx, nifc;
                   1497:
1.53      augustss 1498:        if (dev->default_pipe != NULL)
1.34      augustss 1499:                usbd_kill_pipe(dev->default_pipe);
1.53      augustss 1500:        if (dev->ifaces != NULL) {
1.34      augustss 1501:                nifc = dev->cdesc->bNumInterface;
                   1502:                for (ifcidx = 0; ifcidx < nifc; ifcidx++)
                   1503:                        usbd_free_iface_data(dev, ifcidx);
                   1504:                free(dev->ifaces, M_USB);
                   1505:        }
1.53      augustss 1506:        if (dev->cdesc != NULL)
1.34      augustss 1507:                free(dev->cdesc, M_USB);
1.155     drochner 1508:        if (dev->subdevlen > 0) {
1.34      augustss 1509:                free(dev->subdevs, M_USB);
1.155     drochner 1510:                dev->subdevlen = 0;
                   1511:        }
1.34      augustss 1512:        free(dev, M_USB);
1.1       augustss 1513: }
1.47      augustss 1514:
                   1515: /*
                   1516:  * The general mechanism for detaching drivers works as follows: Each
                   1517:  * driver is responsible for maintaining a reference count on the
                   1518:  * number of outstanding references to its softc (e.g.  from
                   1519:  * processing hanging in a read or write).  The detach method of the
                   1520:  * driver decrements this counter and flags in the softc that the
                   1521:  * driver is dying and then wakes any sleepers.  It then sleeps on the
                   1522:  * softc.  Each place that can sleep must maintain the reference
                   1523:  * count.  When the reference count drops to -1 (0 is the normal value
                   1524:  * of the reference count) the a wakeup on the softc is performed
                   1525:  * signaling to the detach waiter that all references are gone.
                   1526:  */
                   1527:
                   1528: /*
                   1529:  * Called from process context when we discover that a port has
                   1530:  * been disconnected.
                   1531:  */
1.167     dyoung   1532: int
                   1533: usb_disconnect_port(struct usbd_port *up, device_t parent, int flags)
1.47      augustss 1534: {
                   1535:        usbd_device_handle dev = up->device;
1.167     dyoung   1536:        device_t subdev;
                   1537:        char subdevname[16];
1.164     dyoung   1538:        const char *hubname = device_xname(parent);
1.167     dyoung   1539:        int i, rc;
1.47      augustss 1540:
1.99      augustss 1541:        DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
1.47      augustss 1542:                    up, dev, up->portno));
1.48      augustss 1543:
1.167     dyoung   1544:        if (dev == NULL) {
1.48      augustss 1545: #ifdef DIAGNOSTIC
                   1546:                printf("usb_disconnect_port: no device\n");
1.167     dyoung   1547: #endif
                   1548:                return 0;
1.48      augustss 1549:        }
1.47      augustss 1550:
1.155     drochner 1551:        if (dev->subdevlen > 0) {
1.57      augustss 1552:                DPRINTFN(3,("usb_disconnect_port: disconnect subdevs\n"));
1.155     drochner 1553:                for (i = 0; i < dev->subdevlen; i++) {
1.167     dyoung   1554:                        if ((subdev = dev->subdevs[i]) == NULL)
1.155     drochner 1555:                                continue;
1.167     dyoung   1556:                        strlcpy(subdevname, device_xname(subdev),
                   1557:                            sizeof(subdevname));
                   1558:                        if ((rc = config_detach(subdev, flags)) != 0)
                   1559:                                return rc;
                   1560:                        printf("%s: at %s", subdevname, hubname);
1.51      augustss 1561:                        if (up->portno != 0)
                   1562:                                printf(" port %d", up->portno);
                   1563:                        printf(" (addr %d) disconnected\n", dev->address);
1.47      augustss 1564:                }
1.160     drochner 1565:                KASSERT(!dev->nifaces_claimed);
1.47      augustss 1566:        }
                   1567:
1.65      augustss 1568:        usbd_add_dev_event(USB_EVENT_DEVICE_DETACH, dev);
1.57      augustss 1569:        dev->bus->devices[dev->address] = NULL;
                   1570:        up->device = NULL;
1.47      augustss 1571:        usb_free_device(dev);
1.167     dyoung   1572:        return 0;
1.47      augustss 1573: }

CVSweb <webmaster@jp.NetBSD.org>