[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.76.2.1

1.76.2.1! minoura     1: /*     $NetBSD: usb_subr.c,v 1.79 2000/06/01 14:37:51 augustss 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: /*
                      5:  * Copyright (c) 1998 The NetBSD Foundation, Inc.
                      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:  * 3. All advertising materials mentioning features or use of this software
                     21:  *    must display the following acknowledgement:
                     22:  *        This product includes software developed by the NetBSD
                     23:  *        Foundation, Inc. and its contributors.
                     24:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     25:  *    contributors may be used to endorse or promote products derived
                     26:  *    from this software without specific prior written permission.
                     27:  *
                     28:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     29:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     30:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     31:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     32:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     33:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     34:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     35:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     36:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     37:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     38:  * POSSIBILITY OF SUCH DAMAGE.
                     39:  */
                     40:
                     41: #include <sys/param.h>
                     42: #include <sys/systm.h>
                     43: #include <sys/kernel.h>
                     44: #include <sys/malloc.h>
1.37      augustss   45: #if defined(__NetBSD__) || defined(__OpenBSD__)
1.1       augustss   46: #include <sys/device.h>
1.56      augustss   47: #include <sys/select.h>
1.18      augustss   48: #elif defined(__FreeBSD__)
                     49: #include <sys/module.h>
                     50: #include <sys/bus.h>
                     51: #endif
1.1       augustss   52: #include <sys/proc.h>
1.46      augustss   53:
                     54: #include <machine/bus.h>
1.1       augustss   55:
                     56: #include <dev/usb/usb.h>
                     57:
                     58: #include <dev/usb/usbdi.h>
                     59: #include <dev/usb/usbdi_util.h>
                     60: #include <dev/usb/usbdivar.h>
                     61: #include <dev/usb/usbdevs.h>
                     62: #include <dev/usb/usb_quirks.h>
                     63:
1.27      augustss   64: #if defined(__FreeBSD__)
                     65: #include <machine/clock.h>
                     66: #define delay(d)         DELAY(d)
                     67: #endif
                     68:
1.1       augustss   69: #ifdef USB_DEBUG
1.35      augustss   70: #define DPRINTF(x)     if (usbdebug) logprintf x
                     71: #define DPRINTFN(n,x)  if (usbdebug>(n)) logprintf x
1.1       augustss   72: extern int usbdebug;
                     73: #else
                     74: #define DPRINTF(x)
                     75: #define DPRINTFN(n,x)
                     76: #endif
                     77:
1.76.2.1! minoura    78: Static usbd_status     usbd_set_config(usbd_device_handle, int);
        !            79: Static char *usbd_get_string(usbd_device_handle, int, char *);
        !            80: Static int usbd_getnewaddr(usbd_bus_handle bus);
1.56      augustss   81: #if defined(__NetBSD__)
1.76.2.1! minoura    82: Static int usbd_print(void *aux, const char *pnp);
        !            83: Static int usbd_submatch(device_ptr_t, struct cfdata *cf, void *);
1.37      augustss   84: #elif defined(__OpenBSD__)
1.76.2.1! minoura    85: Static int usbd_print(void *aux, const char *pnp);
        !            86: Static int usbd_submatch(device_ptr_t, void *, void *);
1.18      augustss   87: #endif
1.76.2.1! minoura    88: Static void usbd_free_iface_data(usbd_device_handle dev, int ifcno);
        !            89: Static void usbd_kill_pipe(usbd_pipe_handle);
        !            90: Static usbd_status usbd_probe_and_attach(device_ptr_t parent,
        !            91:                                 usbd_device_handle dev, int port, int addr);
1.1       augustss   92:
1.69      augustss   93: Static u_int32_t usb_cookie_no = 0;
1.27      augustss   94:
1.1       augustss   95: #ifdef USBVERBOSE
                     96: typedef u_int16_t usb_vendor_id_t;
                     97: typedef u_int16_t usb_product_id_t;
                     98:
                     99: /*
                    100:  * Descriptions of of known vendors and devices ("products").
                    101:  */
                    102: struct usb_knowndev {
                    103:        usb_vendor_id_t         vendor;
                    104:        usb_product_id_t        product;
                    105:        int                     flags;
                    106:        char                    *vendorname, *productname;
                    107: };
                    108: #define        USB_KNOWNDEV_NOPROD     0x01            /* match on vendor only */
                    109:
                    110: #include <dev/usb/usbdevs_data.h>
                    111: #endif /* USBVERBOSE */
                    112:
1.69      augustss  113: Static const char *usbd_error_strs[] = {
1.12      augustss  114:        "NORMAL_COMPLETION",
                    115:        "IN_PROGRESS",
                    116:        "PENDING_REQUESTS",
                    117:        "NOT_STARTED",
                    118:        "INVAL",
                    119:        "NOMEM",
                    120:        "CANCELLED",
                    121:        "BAD_ADDRESS",
                    122:        "IN_USE",
                    123:        "NO_ADDR",
                    124:        "SET_ADDR_FAILED",
                    125:        "NO_POWER",
                    126:        "TOO_DEEP",
                    127:        "IOERROR",
                    128:        "NOT_CONFIGURED",
                    129:        "TIMEOUT",
                    130:        "SHORT_XFER",
                    131:        "STALLED",
1.33      augustss  132:        "INTERRUPTED",
1.12      augustss  133:        "XXX",
                    134: };
1.1       augustss  135:
1.42      thorpej   136: const char *
1.76.2.1! minoura   137: usbd_errstr(usbd_status err)
1.39      augustss  138: {
                    139:        static char buffer[5];
                    140:
1.42      thorpej   141:        if (err < USBD_ERROR_MAX) {
1.39      augustss  142:                return usbd_error_strs[err];
                    143:        } else {
                    144:                snprintf(buffer, sizeof buffer, "%d", err);
                    145:                return buffer;
                    146:        }
                    147: }
                    148:
1.13      augustss  149: usbd_status
1.76.2.1! minoura   150: usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid,
        !           151:                     usb_string_descriptor_t *sdesc)
1.13      augustss  152: {
                    153:        usb_device_request_t req;
1.53      augustss  154:        usbd_status err;
1.13      augustss  155:
                    156:        req.bmRequestType = UT_READ_DEVICE;
                    157:        req.bRequest = UR_GET_DESCRIPTOR;
                    158:        USETW2(req.wValue, UDESC_STRING, sindex);
                    159:        USETW(req.wIndex, langid);
                    160:        USETW(req.wLength, 1);  /* only size byte first */
1.53      augustss  161:        err = usbd_do_request(dev, &req, sdesc);
                    162:        if (err)
                    163:                return (err);
1.13      augustss  164:        USETW(req.wLength, sdesc->bLength);     /* the whole string */
                    165:        return (usbd_do_request(dev, &req, sdesc));
                    166: }
                    167:
1.1       augustss  168: char *
1.76.2.1! minoura   169: usbd_get_string(usbd_device_handle dev, int si, char *buf)
1.1       augustss  170: {
                    171:        int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE;
                    172:        usb_string_descriptor_t us;
                    173:        char *s;
                    174:        int i, n;
                    175:        u_int16_t c;
1.53      augustss  176:        usbd_status err;
1.1       augustss  177:
                    178:        if (si == 0)
1.11      augustss  179:                return (0);
                    180:        if (dev->quirks->uq_flags & UQ_NO_STRINGS)
                    181:                return (0);
1.22      augustss  182:        if (dev->langid == USBD_NOLANG) {
                    183:                /* Set up default language */
1.53      augustss  184:                err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us);
                    185:                if (err || us.bLength < 4) {
1.22      augustss  186:                        dev->langid = 0; /* Well, just pick English then */
                    187:                } else {
                    188:                        /* Pick the first language as the default. */
                    189:                        dev->langid = UGETW(us.bString[0]);
                    190:                }
                    191:        }
1.53      augustss  192:        err = usbd_get_string_desc(dev, si, dev->langid, &us);
                    193:        if (err)
1.13      augustss  194:                return (0);
1.1       augustss  195:        s = buf;
                    196:        n = us.bLength / 2 - 1;
                    197:        for (i = 0; i < n; i++) {
                    198:                c = UGETW(us.bString[i]);
                    199:                /* Convert from Unicode, handle buggy strings. */
                    200:                if ((c & 0xff00) == 0)
                    201:                        *s++ = c;
                    202:                else if ((c & 0x00ff) == 0 && swap)
                    203:                        *s++ = c >> 8;
                    204:                else
                    205:                        *s++ = '?';
                    206:        }
                    207:        *s++ = 0;
1.53      augustss  208:        return (buf);
1.1       augustss  209: }
                    210:
                    211: void
1.76.2.1! minoura   212: usbd_devinfo_vp(usbd_device_handle dev, char *v, char *p)
1.1       augustss  213: {
                    214:        usb_device_descriptor_t *udd = &dev->ddesc;
                    215:        char *vendor = 0, *product = 0;
1.2       is        216: #ifdef USBVERBOSE
1.1       augustss  217:        struct usb_knowndev *kdp;
1.2       is        218: #endif
1.1       augustss  219:
1.53      augustss  220:        if (dev == NULL) {
1.52      augustss  221:                v[0] = p[0] = '\0';
                    222:                return;
                    223:        }
                    224:
1.1       augustss  225:        vendor = usbd_get_string(dev, udd->iManufacturer, v);
                    226:        product = usbd_get_string(dev, udd->iProduct, p);
                    227: #ifdef USBVERBOSE
1.66      jdolecek  228:        if (vendor == NULL || product == NULL) {
1.1       augustss  229:                for(kdp = usb_knowndevs;
                    230:                    kdp->vendorname != NULL;
                    231:                    kdp++) {
                    232:                        if (kdp->vendor == UGETW(udd->idVendor) &&
                    233:                            (kdp->product == UGETW(udd->idProduct) ||
                    234:                             (kdp->flags & USB_KNOWNDEV_NOPROD) != 0))
                    235:                                break;
                    236:                }
1.66      jdolecek  237:                if (kdp->vendorname != NULL) {
                    238:                        if (!vendor)
                    239:                            vendor = kdp->vendorname;
                    240:                        if (!product)
                    241:                            product = (kdp->flags & USB_KNOWNDEV_NOPROD) == 0 ?
1.1       augustss  242:                                kdp->productname : NULL;
                    243:                }
                    244:        }
                    245: #endif
1.53      augustss  246:        if (vendor != NULL)
1.1       augustss  247:                strcpy(v, vendor);
                    248:        else
                    249:                sprintf(v, "vendor 0x%04x", UGETW(udd->idVendor));
1.53      augustss  250:        if (product != NULL)
1.1       augustss  251:                strcpy(p, product);
                    252:        else
                    253:                sprintf(p, "product 0x%04x", UGETW(udd->idProduct));
                    254: }
                    255:
                    256: int
1.76.2.1! minoura   257: usbd_printBCD(char *cp, int bcd)
1.1       augustss  258: {
                    259:        return (sprintf(cp, "%x.%02x", bcd >> 8, bcd & 0xff));
                    260: }
                    261:
                    262: void
1.76.2.1! minoura   263: usbd_devinfo(usbd_device_handle dev, int showclass, char *cp)
1.1       augustss  264: {
                    265:        usb_device_descriptor_t *udd = &dev->ddesc;
                    266:        char vendor[USB_MAX_STRING_LEN];
                    267:        char product[USB_MAX_STRING_LEN];
                    268:        int bcdDevice, bcdUSB;
                    269:
                    270:        usbd_devinfo_vp(dev, vendor, product);
1.11      augustss  271:        cp += sprintf(cp, "%s %s", vendor, product);
1.1       augustss  272:        if (showclass)
1.12      augustss  273:                cp += sprintf(cp, ", class %d/%d",
1.1       augustss  274:                              udd->bDeviceClass, udd->bDeviceSubClass);
                    275:        bcdUSB = UGETW(udd->bcdUSB);
                    276:        bcdDevice = UGETW(udd->bcdDevice);
1.12      augustss  277:        cp += sprintf(cp, ", rev ");
1.1       augustss  278:        cp += usbd_printBCD(cp, bcdUSB);
                    279:        *cp++ = '/';
                    280:        cp += usbd_printBCD(cp, bcdDevice);
1.11      augustss  281:        cp += sprintf(cp, ", addr %d", dev->address);
1.10      augustss  282:        *cp = 0;
1.1       augustss  283: }
                    284:
                    285: /* Delay for a certain number of ms */
                    286: void
1.76.2.1! minoura   287: usb_delay_ms(usbd_bus_handle bus, u_int ms)
1.1       augustss  288: {
                    289:        /* Wait at least two clock ticks so we know the time has passed. */
1.64      augustss  290:        if (bus->use_polling || cold)
1.1       augustss  291:                delay((ms+1) * 1000);
                    292:        else
                    293:                tsleep(&ms, PRIBIO, "usbdly", (ms*hz+999)/1000 + 1);
                    294: }
                    295:
1.23      augustss  296: /* Delay given a device handle. */
                    297: void
1.76.2.1! minoura   298: usbd_delay_ms(usbd_device_handle dev, u_int ms)
1.23      augustss  299: {
                    300:        usb_delay_ms(dev->bus, ms);
                    301: }
                    302:
1.1       augustss  303: usbd_status
1.76.2.1! minoura   304: usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps)
1.1       augustss  305: {
                    306:        usb_device_request_t req;
1.53      augustss  307:        usbd_status err;
1.1       augustss  308:        int n;
                    309:
                    310:        req.bmRequestType = UT_WRITE_CLASS_OTHER;
                    311:        req.bRequest = UR_SET_FEATURE;
                    312:        USETW(req.wValue, UHF_PORT_RESET);
                    313:        USETW(req.wIndex, port);
                    314:        USETW(req.wLength, 0);
1.53      augustss  315:        err = usbd_do_request(dev, &req, 0);
1.39      augustss  316:        DPRINTFN(1,("usbd_reset_port: port %d reset done, error=%s\n",
1.53      augustss  317:                    port, usbd_errstr(err)));
                    318:        if (err)
                    319:                return (err);
1.1       augustss  320:        n = 10;
                    321:        do {
                    322:                /* Wait for device to recover from reset. */
1.23      augustss  323:                usbd_delay_ms(dev, USB_PORT_RESET_DELAY);
1.53      augustss  324:                err = usbd_get_port_status(dev, port, ps);
                    325:                if (err) {
                    326:                        DPRINTF(("usbd_reset_port: get status failed %d\n",
                    327:                                 err));
                    328:                        return (err);
1.1       augustss  329:                }
                    330:        } while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0);
1.73      augustss  331:        if (n == 0)
                    332:                return (USBD_TIMEOUT);
1.53      augustss  333:        err = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET);
1.1       augustss  334: #ifdef USB_DEBUG
1.53      augustss  335:        if (err)
                    336:                DPRINTF(("usbd_reset_port: clear port feature failed %d\n",
                    337:                         err));
1.1       augustss  338: #endif
1.18      augustss  339:
                    340:        /* Wait for the device to recover from reset. */
1.23      augustss  341:        usbd_delay_ms(dev, USB_PORT_RESET_RECOVERY);
1.53      augustss  342:        return (err);
1.1       augustss  343: }
                    344:
1.12      augustss  345: usb_interface_descriptor_t *
1.76.2.1! minoura   346: usbd_find_idesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx)
1.12      augustss  347: {
                    348:        char *p = (char *)cd;
                    349:        char *end = p + UGETW(cd->wTotalLength);
                    350:        usb_interface_descriptor_t *d;
1.19      augustss  351:        int curidx, lastidx, curaidx = 0;
1.12      augustss  352:
1.19      augustss  353:        for (curidx = lastidx = -1; p < end; ) {
1.12      augustss  354:                d = (usb_interface_descriptor_t *)p;
1.18      augustss  355:                DPRINTFN(4,("usbd_find_idesc: idx=%d(%d) altidx=%d(%d) len=%d "
                    356:                            "type=%d\n",
                    357:                            ifaceidx, curidx, altidx, curaidx,
                    358:                            d->bLength, d->bDescriptorType));
1.12      augustss  359:                if (d->bLength == 0) /* bad descriptor */
                    360:                        break;
                    361:                p += d->bLength;
                    362:                if (p <= end && d->bDescriptorType == UDESC_INTERFACE) {
1.19      augustss  363:                        if (d->bInterfaceNumber != lastidx) {
                    364:                                lastidx = d->bInterfaceNumber;
1.12      augustss  365:                                curidx++;
                    366:                                curaidx = 0;
                    367:                        } else
                    368:                                curaidx++;
                    369:                        if (ifaceidx == curidx && altidx == curaidx)
                    370:                                return (d);
                    371:                }
                    372:        }
1.58      augustss  373:        return (NULL);
1.12      augustss  374: }
                    375:
                    376: usb_endpoint_descriptor_t *
1.76.2.1! minoura   377: usbd_find_edesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx,
        !           378:                int endptidx)
1.12      augustss  379: {
                    380:        char *p = (char *)cd;
                    381:        char *end = p + UGETW(cd->wTotalLength);
                    382:        usb_interface_descriptor_t *d;
                    383:        usb_endpoint_descriptor_t *e;
                    384:        int curidx;
                    385:
                    386:        d = usbd_find_idesc(cd, ifaceidx, altidx);
1.53      augustss  387:        if (d == NULL)
1.58      augustss  388:                return (NULL);
1.12      augustss  389:        if (endptidx >= d->bNumEndpoints) /* quick exit */
1.58      augustss  390:                return (NULL);
1.12      augustss  391:
                    392:        curidx = -1;
                    393:        for (p = (char *)d + d->bLength; p < end; ) {
                    394:                e = (usb_endpoint_descriptor_t *)p;
                    395:                if (e->bLength == 0) /* bad descriptor */
                    396:                        break;
                    397:                p += e->bLength;
                    398:                if (p <= end && e->bDescriptorType == UDESC_INTERFACE)
1.58      augustss  399:                        return (NULL);
1.12      augustss  400:                if (p <= end && e->bDescriptorType == UDESC_ENDPOINT) {
                    401:                        curidx++;
                    402:                        if (curidx == endptidx)
                    403:                                return (e);
                    404:                }
1.1       augustss  405:        }
1.58      augustss  406:        return (NULL);
1.1       augustss  407: }
                    408:
                    409: usbd_status
1.76.2.1! minoura   410: usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx)
1.1       augustss  411: {
1.12      augustss  412:        usbd_interface_handle ifc = &dev->ifaces[ifaceidx];
1.76.2.1! minoura   413:        usb_interface_descriptor_t *idesc;
1.1       augustss  414:        char *p, *end;
                    415:        int endpt, nendpt;
                    416:
1.18      augustss  417:        DPRINTFN(4,("usbd_fill_iface_data: ifaceidx=%d altidx=%d\n",
1.14      drochner  418:                    ifaceidx, altidx));
1.76.2.1! minoura   419:        idesc = usbd_find_idesc(dev->cdesc, ifaceidx, altidx);
        !           420:        if (idesc == NULL)
1.19      augustss  421:                return (USBD_INVAL);
1.76.2.1! minoura   422:        ifc->device = dev;
        !           423:        ifc->idesc = idesc;
1.13      augustss  424:        ifc->index = ifaceidx;
                    425:        ifc->altindex = altidx;
1.1       augustss  426:        nendpt = ifc->idesc->bNumEndpoints;
1.59      augustss  427:        DPRINTFN(4,("usbd_fill_iface_data: found idesc nendpt=%d\n", nendpt));
1.1       augustss  428:        if (nendpt != 0) {
                    429:                ifc->endpoints = malloc(nendpt * sizeof(struct usbd_endpoint),
                    430:                                        M_USB, M_NOWAIT);
1.58      augustss  431:                if (ifc->endpoints == NULL)
1.1       augustss  432:                        return (USBD_NOMEM);
                    433:        } else
1.58      augustss  434:                ifc->endpoints = NULL;
                    435:        ifc->priv = NULL;
1.1       augustss  436:        p = (char *)ifc->idesc + ifc->idesc->bLength;
                    437:        end = (char *)dev->cdesc + UGETW(dev->cdesc->wTotalLength);
1.19      augustss  438: #define ed ((usb_endpoint_descriptor_t *)p)
1.1       augustss  439:        for (endpt = 0; endpt < nendpt; endpt++) {
                    440:                DPRINTFN(10,("usbd_fill_iface_data: endpt=%d\n", endpt));
                    441:                for (; p < end; p += ed->bLength) {
                    442:                        ed = (usb_endpoint_descriptor_t *)p;
1.14      drochner  443:                        DPRINTFN(10,("usbd_fill_iface_data: p=%p end=%p "
                    444:                                     "len=%d type=%d\n",
1.1       augustss  445:                                 p, end, ed->bLength, ed->bDescriptorType));
1.24      augustss  446:                        if (p + ed->bLength <= end && ed->bLength != 0 &&
1.1       augustss  447:                            ed->bDescriptorType == UDESC_ENDPOINT)
1.24      augustss  448:                                goto found;
1.59      augustss  449:                        if (ed->bLength == 0 ||
                    450:                            ed->bDescriptorType == UDESC_INTERFACE)
1.1       augustss  451:                                break;
                    452:                }
1.24      augustss  453:                /* passed end, or bad desc */
1.59      augustss  454:                DPRINTF(("usbd_fill_iface_data: bad descriptor(s): %s\n",
                    455:                         ed->bLength == 0 ? "0 length" :
                    456:                         ed->bDescriptorType == UDESC_INTERFACE ? "iface desc":
                    457:                         "out of data"));
1.24      augustss  458:                goto bad;
                    459:        found:
1.1       augustss  460:                ifc->endpoints[endpt].edesc = ed;
                    461:                ifc->endpoints[endpt].refcnt = 0;
1.24      augustss  462:                p += ed->bLength;
1.1       augustss  463:        }
1.19      augustss  464: #undef ed
1.1       augustss  465:        LIST_INIT(&ifc->pipes);
                    466:        return (USBD_NORMAL_COMPLETION);
1.24      augustss  467:
1.1       augustss  468:  bad:
1.76.2.1! minoura   469:        if (ifc->endpoints != NULL) {
1.59      augustss  470:                free(ifc->endpoints, M_USB);
1.76.2.1! minoura   471:                ifc->endpoints = NULL;
        !           472:        }
1.24      augustss  473:        return (USBD_INVAL);
1.1       augustss  474: }
                    475:
                    476: void
1.76.2.1! minoura   477: usbd_free_iface_data(usbd_device_handle dev, int ifcno)
1.1       augustss  478: {
                    479:        usbd_interface_handle ifc = &dev->ifaces[ifcno];
                    480:        if (ifc->endpoints)
                    481:                free(ifc->endpoints, M_USB);
                    482: }
                    483:
1.69      augustss  484: Static usbd_status
1.76.2.1! minoura   485: usbd_set_config(usbd_device_handle dev, int conf)
1.7       augustss  486: {
                    487:        usb_device_request_t req;
                    488:
                    489:        req.bmRequestType = UT_WRITE_DEVICE;
                    490:        req.bRequest = UR_SET_CONFIG;
                    491:        USETW(req.wValue, conf);
                    492:        USETW(req.wIndex, 0);
                    493:        USETW(req.wLength, 0);
                    494:        return (usbd_do_request(dev, &req, 0));
                    495: }
                    496:
1.1       augustss  497: usbd_status
1.76.2.1! minoura   498: usbd_set_config_no(usbd_device_handle dev, int no, int msg)
1.1       augustss  499: {
1.12      augustss  500:        int index;
                    501:        usb_config_descriptor_t cd;
1.53      augustss  502:        usbd_status err;
1.12      augustss  503:
1.75      augustss  504:        if (no == USB_UNCONFIG_NO)
                    505:                return (usbd_set_config_index(dev, USB_UNCONFIG_INDEX, msg));
                    506:
1.12      augustss  507:        DPRINTFN(5,("usbd_set_config_no: %d\n", no));
                    508:        /* Figure out what config index to use. */
                    509:        for (index = 0; index < dev->ddesc.bNumConfigurations; index++) {
1.53      augustss  510:                err = usbd_get_config_desc(dev, index, &cd);
                    511:                if (err)
                    512:                        return (err);
1.12      augustss  513:                if (cd.bConfigurationValue == no)
                    514:                        return (usbd_set_config_index(dev, index, msg));
                    515:        }
                    516:        return (USBD_INVAL);
                    517: }
                    518:
                    519: usbd_status
1.76.2.1! minoura   520: usbd_set_config_index(usbd_device_handle dev, int index, int msg)
1.12      augustss  521: {
1.1       augustss  522:        usb_status_t ds;
                    523:        usb_config_descriptor_t cd, *cdp;
1.53      augustss  524:        usbd_status err;
1.12      augustss  525:        int ifcidx, nifc, len, selfpowered, power;
1.1       augustss  526:
1.12      augustss  527:        DPRINTFN(5,("usbd_set_config_index: dev=%p index=%d\n", dev, index));
1.1       augustss  528:
                    529:        /* XXX check that all interfaces are idle */
1.75      augustss  530:        if (dev->config != USB_UNCONFIG_NO) {
1.12      augustss  531:                DPRINTF(("usbd_set_config_index: free old config\n"));
1.1       augustss  532:                /* Free all configuration data structures. */
                    533:                nifc = dev->cdesc->bNumInterface;
1.12      augustss  534:                for (ifcidx = 0; ifcidx < nifc; ifcidx++)
                    535:                        usbd_free_iface_data(dev, ifcidx);
1.1       augustss  536:                free(dev->ifaces, M_USB);
                    537:                free(dev->cdesc, M_USB);
1.57      augustss  538:                dev->ifaces = NULL;
                    539:                dev->cdesc = NULL;
1.75      augustss  540:                dev->config = USB_UNCONFIG_NO;
                    541:        }
                    542:
                    543:        if (index == USB_UNCONFIG_INDEX) {
                    544:                /* We are unconfiguring the device, so leave unallocated. */
                    545:                DPRINTF(("usbd_set_config_index: set config 0\n"));
                    546:                err = usbd_set_config(dev, USB_UNCONFIG_NO);
                    547:                if (err)
                    548:                        DPRINTF(("usbd_set_config_index: setting config=0 "
                    549:                                 "failed, error=%s\n", usbd_errstr(err)));
                    550:                return (err);
1.1       augustss  551:        }
                    552:
1.74      augustss  553:        /* Get the short descriptor. */
1.53      augustss  554:        err = usbd_get_config_desc(dev, index, &cd);
                    555:        if (err)
                    556:                return (err);
1.1       augustss  557:        len = UGETW(cd.wTotalLength);
                    558:        cdp = malloc(len, M_USB, M_NOWAIT);
1.53      augustss  559:        if (cdp == NULL)
1.1       augustss  560:                return (USBD_NOMEM);
1.74      augustss  561:        /* Get the full descriptor. */
1.53      augustss  562:        err = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp);
                    563:        if (err)
1.1       augustss  564:                goto bad;
1.18      augustss  565:        if (cdp->bDescriptorType != UDESC_CONFIG) {
                    566:                DPRINTFN(-1,("usbd_set_config_index: bad desc %d\n",
                    567:                             cdp->bDescriptorType));
1.53      augustss  568:                err = USBD_INVAL;
1.18      augustss  569:                goto bad;
                    570:        }
1.74      augustss  571:
                    572:        /* Figure out if the device is self or bus powered. */
1.1       augustss  573:        selfpowered = 0;
1.49      augustss  574:        if (!(dev->quirks->uq_flags & UQ_BUS_POWERED) &&
1.74      augustss  575:            (cdp->bmAttributes & UC_SELF_POWERED)) {
1.1       augustss  576:                /* May be self powered. */
                    577:                if (cdp->bmAttributes & UC_BUS_POWERED) {
                    578:                        /* Must ask device. */
1.53      augustss  579:                        err = usbd_get_device_status(dev, &ds);
                    580:                        if (!err && (UGETW(ds.wStatus) & UDS_SELF_POWERED))
1.33      augustss  581:                                selfpowered = 1;
1.14      drochner  582:                        DPRINTF(("usbd_set_config_index: status=0x%04x, "
1.39      augustss  583:                                 "error=%s\n",
1.53      augustss  584:                                 UGETW(ds.wStatus), usbd_errstr(err)));
1.1       augustss  585:                } else
                    586:                        selfpowered = 1;
                    587:        }
1.14      drochner  588:        DPRINTF(("usbd_set_config_index: (addr %d) attr=0x%02x, "
1.33      augustss  589:                 "selfpowered=%d, power=%d\n",
1.1       augustss  590:                 dev->address, cdp->bmAttributes,
1.33      augustss  591:                 selfpowered, cdp->bMaxPower * 2));
1.74      augustss  592:
                    593:        /* Check if we have enough power. */
1.1       augustss  594: #ifdef USB_DEBUG
1.53      augustss  595:        if (dev->powersrc == NULL) {
1.44      augustss  596:                DPRINTF(("usbd_set_config_index: No power source?\n"));
1.13      augustss  597:                return (USBD_IOERROR);
1.1       augustss  598:        }
                    599: #endif
                    600:        power = cdp->bMaxPower * 2;
                    601:        if (power > dev->powersrc->power) {
                    602:                /* XXX print nicer message. */
1.7       augustss  603:                if (msg)
1.18      augustss  604:                        printf("%s: device addr %d (config %d) exceeds power "
                    605:                                 "budget, %d mA > %d mA\n",
                    606:                               USBDEVNAME(dev->bus->bdev), dev->address,
1.7       augustss  607:                               cdp->bConfigurationValue,
                    608:                               power, dev->powersrc->power);
1.53      augustss  609:                err = USBD_NO_POWER;
1.1       augustss  610:                goto bad;
                    611:        }
                    612:        dev->power = power;
                    613:        dev->self_powered = selfpowered;
                    614:
1.74      augustss  615:        /* Set the actual configuration value. */
1.18      augustss  616:        DPRINTF(("usbd_set_config_index: set config %d\n",
                    617:                 cdp->bConfigurationValue));
1.53      augustss  618:        err = usbd_set_config(dev, cdp->bConfigurationValue);
                    619:        if (err) {
1.14      drochner  620:                DPRINTF(("usbd_set_config_index: setting config=%d failed, "
1.39      augustss  621:                         "error=%s\n",
1.53      augustss  622:                         cdp->bConfigurationValue, usbd_errstr(err)));
1.1       augustss  623:                goto bad;
                    624:        }
1.74      augustss  625:
                    626:        /* Allocate and fill interface data. */
1.1       augustss  627:        nifc = cdp->bNumInterface;
                    628:        dev->ifaces = malloc(nifc * sizeof(struct usbd_interface),
                    629:                             M_USB, M_NOWAIT);
1.58      augustss  630:        if (dev->ifaces == NULL) {
1.53      augustss  631:                err = USBD_NOMEM;
1.1       augustss  632:                goto bad;
                    633:        }
1.12      augustss  634:        DPRINTFN(5,("usbd_set_config_index: dev=%p cdesc=%p\n", dev, cdp));
1.1       augustss  635:        dev->cdesc = cdp;
                    636:        dev->config = cdp->bConfigurationValue;
1.12      augustss  637:        for (ifcidx = 0; ifcidx < nifc; ifcidx++) {
1.53      augustss  638:                err = usbd_fill_iface_data(dev, ifcidx, 0);
                    639:                if (err) {
1.12      augustss  640:                        while (--ifcidx >= 0)
                    641:                                usbd_free_iface_data(dev, ifcidx);
1.1       augustss  642:                        goto bad;
                    643:                }
                    644:        }
                    645:
                    646:        return (USBD_NORMAL_COMPLETION);
                    647:
                    648:  bad:
                    649:        free(cdp, M_USB);
1.53      augustss  650:        return (err);
1.1       augustss  651: }
                    652:
                    653: /* XXX add function for alternate settings */
                    654:
                    655: usbd_status
1.76.2.1! minoura   656: usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface,
        !           657:                struct usbd_endpoint *ep, int ival, usbd_pipe_handle *pipe)
1.1       augustss  658: {
                    659:        usbd_pipe_handle p;
1.53      augustss  660:        usbd_status err;
1.1       augustss  661:
                    662:        DPRINTFN(1,("usbd_setup_pipe: dev=%p iface=%p ep=%p pipe=%p\n",
                    663:                    dev, iface, ep, pipe));
                    664:        p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT);
1.53      augustss  665:        if (p == NULL)
1.1       augustss  666:                return (USBD_NOMEM);
                    667:        p->device = dev;
                    668:        p->iface = iface;
                    669:        p->endpoint = ep;
                    670:        ep->refcnt++;
                    671:        p->refcnt = 1;
1.53      augustss  672:        p->intrxfer = 0;
1.1       augustss  673:        p->running = 0;
1.70      augustss  674:        p->aborting = 0;
1.34      augustss  675:        p->repeat = 0;
1.63      augustss  676:        p->interval = ival;
1.1       augustss  677:        SIMPLEQ_INIT(&p->queue);
1.68      augustss  678:        usb_callout_init(p->abort_handle);
1.53      augustss  679:        err = dev->bus->methods->open_pipe(p);
                    680:        if (err) {
1.39      augustss  681:                DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error="
                    682:                         "%s\n",
1.53      augustss  683:                         ep->edesc->bEndpointAddress, usbd_errstr(err)));
1.1       augustss  684:                free(p, M_USB);
1.53      augustss  685:                return (err);
1.1       augustss  686:        }
1.38      augustss  687:        /* Clear any stall and make sure DATA0 toggle will be used next. */
                    688:        if (UE_GET_ADDR(ep->edesc->bEndpointAddress) != USB_CONTROL_ENDPOINT)
                    689:                usbd_clear_endpoint_stall(p);
1.1       augustss  690:        *pipe = p;
                    691:        return (USBD_NORMAL_COMPLETION);
                    692: }
                    693:
                    694: /* Abort the device control pipe. */
                    695: void
1.76.2.1! minoura   696: usbd_kill_pipe(usbd_pipe_handle pipe)
1.1       augustss  697: {
                    698:        pipe->methods->close(pipe);
                    699:        pipe->endpoint->refcnt--;
                    700:        free(pipe, M_USB);
                    701: }
                    702:
                    703: int
1.76.2.1! minoura   704: usbd_getnewaddr(usbd_bus_handle bus)
1.1       augustss  705: {
1.18      augustss  706:        int addr;
1.1       augustss  707:
1.18      augustss  708:        for (addr = 1; addr < USB_MAX_DEVICES; addr++)
                    709:                if (bus->devices[addr] == 0)
                    710:                        return (addr);
1.1       augustss  711:        return (-1);
                    712: }
                    713:
1.18      augustss  714:
                    715: usbd_status
1.76.2.1! minoura   716: usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
        !           717:                      int port, int addr)
1.18      augustss  718: {
                    719:        struct usb_attach_arg uaa;
                    720:        usb_device_descriptor_t *dd = &dev->ddesc;
1.53      augustss  721:        int found, i, confi, nifaces;
                    722:        usbd_status err;
1.43      augustss  723:        device_ptr_t dv;
1.20      augustss  724:        usbd_interface_handle ifaces[256]; /* 256 is the absolute max */
1.18      augustss  725:
                    726: #if defined(__FreeBSD__)
1.28      augustss  727:        /*
                    728:         * XXX uaa is a static var. Not a problem as it _should_ be used only
                    729:         * during probe and attach. Should be changed however.
                    730:         */
1.43      augustss  731:        device_t bdev;
1.52      augustss  732:        bdev = device_add_child(parent, NULL, -1, &uaa);
1.26      augustss  733:        if (!bdev) {
1.18      augustss  734:            printf("%s: Device creation failed\n", USBDEVNAME(dev->bus->bdev));
                    735:            return (USBD_INVAL);
                    736:        }
1.52      augustss  737:        device_quiet(bdev);
1.18      augustss  738: #endif
                    739:
                    740:        uaa.device = dev;
1.72      augustss  741:        uaa.iface = NULL;
                    742:        uaa.ifaces = NULL;
1.20      augustss  743:        uaa.nifaces = 0;
1.18      augustss  744:        uaa.usegeneric = 0;
                    745:        uaa.port = port;
                    746:        uaa.configno = UHUB_UNK_CONFIGURATION;
                    747:        uaa.ifaceno = UHUB_UNK_INTERFACE;
1.32      augustss  748:        uaa.vendor = UGETW(dd->idVendor);
                    749:        uaa.product = UGETW(dd->idProduct);
                    750:        uaa.release = UGETW(dd->bcdDevice);
1.18      augustss  751:
                    752:        /* First try with device specific drivers. */
1.60      augustss  753:        DPRINTF(("usbd_probe_and_attach: trying device specific drivers\n"));
1.34      augustss  754:        dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch);
                    755:        if (dv) {
                    756:                dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT);
1.57      augustss  757:                if (dev->subdevs == NULL)
1.34      augustss  758:                        return (USBD_NOMEM);
                    759:                dev->subdevs[0] = dv;
                    760:                dev->subdevs[1] = 0;
1.18      augustss  761:                return (USBD_NORMAL_COMPLETION);
1.34      augustss  762:        }
1.18      augustss  763:
                    764:        DPRINTF(("usbd_probe_and_attach: no device specific driver found\n"));
                    765:
1.60      augustss  766:        DPRINTF(("usbd_probe_and_attach: looping over %d configurations\n",
                    767:                 dd->bNumConfigurations));
1.18      augustss  768:        /* Next try with interface drivers. */
                    769:        for (confi = 0; confi < dd->bNumConfigurations; confi++) {
                    770:                DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n",
                    771:                            confi));
1.53      augustss  772:                err = usbd_set_config_index(dev, confi, 1);
                    773:                if (err) {
1.18      augustss  774: #ifdef USB_DEBUG
                    775:                        DPRINTF(("%s: port %d, set config at addr %d failed, "
1.43      augustss  776:                                 "error=%s\n", USBDEVPTRNAME(parent), port,
1.53      augustss  777:                                 addr, usbd_errstr(err)));
1.18      augustss  778: #else
                    779:                        printf("%s: port %d, set config at addr %d failed\n",
1.43      augustss  780:                               USBDEVPTRNAME(parent), port, addr);
1.18      augustss  781: #endif
1.27      augustss  782: #if defined(__FreeBSD__)
1.52      augustss  783:                        device_delete_child(parent, bdev);
1.27      augustss  784: #endif
1.52      augustss  785:
1.53      augustss  786:                        return (err);
1.18      augustss  787:                }
1.20      augustss  788:                nifaces = dev->cdesc->bNumInterface;
1.23      augustss  789:                uaa.configno = dev->cdesc->bConfigurationValue;
1.20      augustss  790:                for (i = 0; i < nifaces; i++)
                    791:                        ifaces[i] = &dev->ifaces[i];
                    792:                uaa.ifaces = ifaces;
                    793:                uaa.nifaces = nifaces;
1.34      augustss  794:                dev->subdevs = malloc((nifaces+1) * sizeof dv, M_USB,M_NOWAIT);
1.57      augustss  795:                if (dev->subdevs == NULL) {
1.52      augustss  796: #if defined(__FreeBSD__)
                    797:                        device_delete_child(parent, bdev);
                    798: #endif
1.34      augustss  799:                        return (USBD_NOMEM);
1.52      augustss  800:                }
                    801:
                    802:                found = 0;
                    803:                for (i = 0; i < nifaces; i++) {
1.53      augustss  804:                        if (ifaces[i] == NULL)
1.20      augustss  805:                                continue; /* interface already claimed */
                    806:                        uaa.iface = ifaces[i];
                    807:                        uaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber;
1.34      augustss  808:                        dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print,
                    809:                                           usbd_submatch);
1.53      augustss  810:                        if (dv != NULL) {
1.34      augustss  811:                                dev->subdevs[found++] = dv;
                    812:                                dev->subdevs[found] = 0;
1.20      augustss  813:                                ifaces[i] = 0; /* consumed */
1.52      augustss  814:
                    815: #if defined(__FreeBSD__)
                    816:                                /* create another child for the next iface */
                    817:                                bdev = device_add_child(parent, NULL, -1,&uaa);
                    818:                                if (!bdev) {
                    819:                                        printf("%s: Device creation failed\n",
                    820:                                        USBDEVNAME(dev->bus->bdev));
                    821:                                        return (USBD_NORMAL_COMPLETION);
                    822:                                }
                    823:                                device_quiet(bdev);
                    824: #endif
1.20      augustss  825:                        }
1.18      augustss  826:                }
1.52      augustss  827:                if (found != 0) {
                    828: #if defined(__FreeBSD__)
                    829:                        /* remove the last created child again; it is unused */
                    830:                        device_delete_child(parent, bdev);
                    831: #endif
1.18      augustss  832:                        return (USBD_NORMAL_COMPLETION);
1.52      augustss  833:                }
1.34      augustss  834:                free(dev->subdevs, M_USB);
                    835:                dev->subdevs = 0;
1.18      augustss  836:        }
1.21      augustss  837:        /* No interfaces were attached in any of the configurations. */
1.34      augustss  838:
                    839:        if (dd->bNumConfigurations > 1) /* don't change if only 1 config */
1.18      augustss  840:                usbd_set_config_index(dev, 0, 0);
                    841:
                    842:        DPRINTF(("usbd_probe_and_attach: no interface drivers found\n"));
                    843:
                    844:        /* Finally try the generic driver. */
1.72      augustss  845:        uaa.iface = NULL;
1.18      augustss  846:        uaa.usegeneric = 1;
                    847:        uaa.configno = UHUB_UNK_CONFIGURATION;
                    848:        uaa.ifaceno = UHUB_UNK_INTERFACE;
1.34      augustss  849:        dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch);
1.53      augustss  850:        if (dv != NULL) {
1.34      augustss  851:                dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT);
                    852:                if (dev->subdevs == 0)
                    853:                        return (USBD_NOMEM);
                    854:                dev->subdevs[0] = dv;
                    855:                dev->subdevs[1] = 0;
1.18      augustss  856:                return (USBD_NORMAL_COMPLETION);
1.34      augustss  857:        }
1.18      augustss  858:
                    859:        /*
                    860:         * The generic attach failed, but leave the device as it is.
                    861:         * We just did not find any drivers, that's all.  The device is
                    862:         * fully operational and not harming anyone.
                    863:         */
                    864:        DPRINTF(("usbd_probe_and_attach: generic attach failed\n"));
1.27      augustss  865: #if defined(__FreeBSD__)
1.52      augustss  866:        device_delete_child(parent, bdev);
1.27      augustss  867: #endif
                    868:        return (USBD_NORMAL_COMPLETION);
1.18      augustss  869: }
                    870:
                    871:
1.1       augustss  872: /*
                    873:  * Called when a new device has been put in the powered state,
                    874:  * but not yet in the addressed state.
                    875:  * Get initial descriptor, set the address, get full descriptor,
                    876:  * and attach a driver.
                    877:  */
                    878: usbd_status
1.76.2.1! minoura   879: usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
        !           880:                int lowspeed, int port, struct usbd_port *up)
1.1       augustss  881: {
                    882:        usbd_device_handle dev;
1.18      augustss  883:        usb_device_descriptor_t *dd;
1.53      augustss  884:        usbd_status err;
1.1       augustss  885:        int addr;
1.18      augustss  886:        int i;
1.1       augustss  887:
1.72      augustss  888:        DPRINTF(("usbd_new_device bus=%p port=%d depth=%d lowspeed=%d\n",
                    889:                 bus, port, depth, lowspeed));
1.1       augustss  890:        addr = usbd_getnewaddr(bus);
                    891:        if (addr < 0) {
1.18      augustss  892:                printf("%s: No free USB addresses, new device ignored.\n",
                    893:                       USBDEVNAME(bus->bdev));
1.1       augustss  894:                return (USBD_NO_ADDR);
                    895:        }
                    896:
                    897:        dev = malloc(sizeof *dev, M_USB, M_NOWAIT);
1.53      augustss  898:        if (dev == NULL)
1.1       augustss  899:                return (USBD_NOMEM);
                    900:        memset(dev, 0, sizeof(*dev));
                    901:
                    902:        dev->bus = bus;
                    903:
                    904:        /* Set up default endpoint handle. */
                    905:        dev->def_ep.edesc = &dev->def_ep_desc;
                    906:
                    907:        /* Set up default endpoint descriptor. */
                    908:        dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE;
                    909:        dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT;
                    910:        dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
                    911:        dev->def_ep_desc.bmAttributes = UE_CONTROL;
                    912:        USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET);
                    913:        dev->def_ep_desc.bInterval = 0;
                    914:
                    915:        dev->quirks = &usbd_no_quirk;
                    916:        dev->address = USB_START_ADDR;
1.4       augustss  917:        dev->ddesc.bMaxPacketSize = 0;
1.1       augustss  918:        dev->lowspeed = lowspeed != 0;
                    919:        dev->depth = depth;
                    920:        dev->powersrc = up;
1.22      augustss  921:        dev->langid = USBD_NOLANG;
1.50      augustss  922:        dev->cookie.cookie = ++usb_cookie_no;
1.1       augustss  923:
1.67      soren     924:        /* Establish the default pipe. */
1.63      augustss  925:        err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
                    926:                              &dev->default_pipe);
1.53      augustss  927:        if (err) {
1.18      augustss  928:                usbd_remove_device(dev, up);
1.53      augustss  929:                return (err);
1.18      augustss  930:        }
1.1       augustss  931:
                    932:        up->device = dev;
1.18      augustss  933:        dd = &dev->ddesc;
1.6       augustss  934:        /* Try a few times in case the device is slow (i.e. outside specs.) */
1.56      augustss  935:        for (i = 0; i < 3; i++) {
1.6       augustss  936:                /* Get the first 8 bytes of the device descriptor. */
1.53      augustss  937:                err = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd);
                    938:                if (!err)
1.6       augustss  939:                        break;
1.23      augustss  940:                usbd_delay_ms(dev, 200);
1.6       augustss  941:        }
1.53      augustss  942:        if (err) {
1.14      drochner  943:                DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc "
1.53      augustss  944:                              "failed\n", addr));
1.18      augustss  945:                usbd_remove_device(dev, up);
1.53      augustss  946:                return (err);
1.18      augustss  947:        }
                    948:
1.39      augustss  949:        DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, "
                    950:                 "subclass=%d, protocol=%d, maxpacket=%d, len=%d, ls=%d\n",
                    951:                 addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass,
                    952:                 dd->bDeviceProtocol, dd->bMaxPacketSize, dd->bLength,
                    953:                 dev->lowspeed));
                    954:
1.18      augustss  955:        if (dd->bDescriptorType != UDESC_DEVICE) {
                    956:                /* Illegal device descriptor */
                    957:                DPRINTFN(-1,("usbd_new_device: illegal descriptor %d\n",
                    958:                             dd->bDescriptorType));
                    959:                usbd_remove_device(dev, up);
                    960:                return (USBD_INVAL);
1.1       augustss  961:        }
                    962:
1.39      augustss  963:        if (dd->bLength < USB_DEVICE_DESCRIPTOR_SIZE) {
                    964:                DPRINTFN(-1,("usbd_new_device: bad length %d\n", dd->bLength));
                    965:                usbd_remove_device(dev, up);
                    966:                return (USBD_INVAL);
                    967:        }
1.4       augustss  968:
1.18      augustss  969:        USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize);
1.1       augustss  970:
1.62      augustss  971:        err = usbd_reload_device_desc(dev);
1.53      augustss  972:        if (err) {
1.14      drochner  973:                DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc "
                    974:                              "failed\n", addr));
1.18      augustss  975:                usbd_remove_device(dev, up);
1.53      augustss  976:                return (err);
1.1       augustss  977:        }
                    978:
                    979:        /* Set the address */
1.53      augustss  980:        err = usbd_set_address(dev, addr);
1.61      augustss  981:        DPRINTFN(5,("usbd_new_device: setting device address=%d\n", addr));
1.53      augustss  982:        if (err) {
1.61      augustss  983:                DPRINTFN(-1,("usb_new_device: set address %d failed\n", addr));
1.53      augustss  984:                err = USBD_SET_ADDR_FAILED;
1.18      augustss  985:                usbd_remove_device(dev, up);
1.53      augustss  986:                return (err);
1.1       augustss  987:        }
1.18      augustss  988:        /* Allow device time to set new address */
1.23      augustss  989:        usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE);
1.18      augustss  990:
1.1       augustss  991:        dev->address = addr;    /* New device address now */
                    992:        bus->devices[addr] = dev;
                    993:
                    994:        /* Assume 100mA bus powered for now. Changed when configured. */
                    995:        dev->power = USB_MIN_POWER;
                    996:        dev->self_powered = 0;
                    997:
                    998:        DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n",
                    999:                 addr, dev, parent));
1.65      augustss 1000:
                   1001:        usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev);
1.1       augustss 1002:
1.53      augustss 1003:        err = usbd_probe_and_attach(parent, dev, port, addr);
                   1004:        if (err) {
1.18      augustss 1005:                usbd_remove_device(dev, up);
1.53      augustss 1006:                return (err);
1.18      augustss 1007:        }
1.65      augustss 1008:
1.18      augustss 1009:        return (USBD_NORMAL_COMPLETION);
1.62      augustss 1010: }
                   1011:
                   1012: usbd_status
1.76.2.1! minoura  1013: usbd_reload_device_desc(usbd_device_handle dev)
1.62      augustss 1014: {
                   1015:        usbd_status err;
                   1016:
                   1017:        /* Get the full device descriptor. */
                   1018:        err = usbd_get_device_desc(dev, &dev->ddesc);
                   1019:        if (err)
                   1020:                return (err);
                   1021:
                   1022:        /* Figure out what's wrong with this device. */
                   1023:        dev->quirks = usbd_find_quirk(&dev->ddesc);
                   1024:
                   1025:        return (USBD_NORMAL_COMPLETION);
1.18      augustss 1026: }
1.1       augustss 1027:
1.18      augustss 1028: void
1.76.2.1! minoura  1029: usbd_remove_device(usbd_device_handle dev, struct usbd_port *up)
1.18      augustss 1030: {
                   1031:        DPRINTF(("usbd_remove_device: %p\n", dev));
                   1032:
1.53      augustss 1033:        if (dev->default_pipe != NULL)
1.18      augustss 1034:                usbd_kill_pipe(dev->default_pipe);
                   1035:        up->device = 0;
                   1036:        dev->bus->devices[dev->address] = 0;
1.1       augustss 1037:
                   1038:        free(dev, M_USB);
                   1039: }
                   1040:
1.37      augustss 1041: #if defined(__NetBSD__) || defined(__OpenBSD__)
1.1       augustss 1042: int
1.76.2.1! minoura  1043: usbd_print(void *aux, const char *pnp)
1.1       augustss 1044: {
                   1045:        struct usb_attach_arg *uaa = aux;
                   1046:        char devinfo[1024];
                   1047:
                   1048:        DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device));
                   1049:        if (pnp) {
                   1050:                if (!uaa->usegeneric)
                   1051:                        return (QUIET);
                   1052:                usbd_devinfo(uaa->device, 1, devinfo);
1.11      augustss 1053:                printf("%s, %s", devinfo, pnp);
1.1       augustss 1054:        }
                   1055:        if (uaa->port != 0)
1.11      augustss 1056:                printf(" port %d", uaa->port);
                   1057:        if (uaa->configno != UHUB_UNK_CONFIGURATION)
                   1058:                printf(" configuration %d", uaa->configno);
                   1059:        if (uaa->ifaceno != UHUB_UNK_INTERFACE)
                   1060:                printf(" interface %d", uaa->ifaceno);
1.32      augustss 1061: #if 0
                   1062:        /*
                   1063:         * It gets very crowded with these locators on the attach line.
                   1064:         * They are not really needed since they are printed in the clear
                   1065:         * by each driver.
                   1066:         */
                   1067:        if (uaa->vendor != UHUB_UNK_VENDOR)
                   1068:                printf(" vendor 0x%04x", uaa->vendor);
                   1069:        if (uaa->product != UHUB_UNK_PRODUCT)
                   1070:                printf(" product 0x%04x", uaa->product);
                   1071:        if (uaa->release != UHUB_UNK_RELEASE)
                   1072:                printf(" release 0x%04x", uaa->release);
                   1073: #endif
1.1       augustss 1074:        return (UNCONF);
                   1075: }
                   1076:
1.37      augustss 1077: #if defined(__NetBSD__)
1.1       augustss 1078: int
1.76.2.1! minoura  1079: usbd_submatch(struct device *parent, struct cfdata *cf, void *aux)
1.1       augustss 1080: {
1.37      augustss 1081: #elif defined(__OpenBSD__)
                   1082: int
1.76.2.1! minoura  1083: usbd_submatch(struct device *parent, void *match, void *aux)
1.37      augustss 1084: {
                   1085:        struct cfdata *cf = match;
                   1086: #endif
1.1       augustss 1087:        struct usb_attach_arg *uaa = aux;
                   1088:
1.72      augustss 1089:        DPRINTFN(5,("usbd_submatch port=%d,%d configno=%d,%d "
                   1090:            "ifaceno=%d,%d vendor=%d,%d product=%d,%d release=%d,%d\n",
                   1091:            uaa->port, cf->uhubcf_port,
                   1092:            uaa->configno, cf->uhubcf_configuration,
                   1093:            uaa->ifaceno, cf->uhubcf_interface,
                   1094:            uaa->vendor, cf->uhubcf_vendor,
                   1095:            uaa->product, cf->uhubcf_product,
                   1096:            uaa->release, cf->uhubcf_release));
                   1097:        if (uaa->port != 0 &&   /* root hub has port 0, it should match */
                   1098:            ((uaa->port != 0 &&
                   1099:              cf->uhubcf_port != UHUB_UNK_PORT &&
                   1100:              cf->uhubcf_port != uaa->port) ||
                   1101:             (uaa->configno != UHUB_UNK_CONFIGURATION &&
                   1102:              cf->uhubcf_configuration != UHUB_UNK_CONFIGURATION &&
                   1103:              cf->uhubcf_configuration != uaa->configno) ||
                   1104:             (uaa->ifaceno != UHUB_UNK_INTERFACE &&
                   1105:              cf->uhubcf_interface != UHUB_UNK_INTERFACE &&
                   1106:              cf->uhubcf_interface != uaa->ifaceno) ||
                   1107:             (uaa->vendor != UHUB_UNK_VENDOR &&
                   1108:              cf->uhubcf_vendor != UHUB_UNK_VENDOR &&
                   1109:              cf->uhubcf_vendor != uaa->vendor) ||
                   1110:             (uaa->product != UHUB_UNK_PRODUCT &&
                   1111:              cf->uhubcf_product != UHUB_UNK_PRODUCT &&
                   1112:              cf->uhubcf_product != uaa->product) ||
                   1113:             (uaa->release != UHUB_UNK_RELEASE &&
                   1114:              cf->uhubcf_release != UHUB_UNK_RELEASE &&
                   1115:              cf->uhubcf_release != uaa->release)
                   1116:             )
1.32      augustss 1117:           )
1.1       augustss 1118:                return 0;
                   1119:        return ((*cf->cf_attach->ca_match)(parent, cf, aux));
1.13      augustss 1120: }
1.18      augustss 1121:
                   1122: #endif
1.13      augustss 1123:
                   1124: void
1.76.2.1! minoura  1125: usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di)
1.13      augustss 1126: {
                   1127:        struct usbd_port *p;
1.56      augustss 1128:        int i, err, s;
1.13      augustss 1129:
1.65      augustss 1130:        di->bus = USBDEVUNIT(dev->bus->bdev);
                   1131:        di->addr = dev->address;
                   1132:        di->cookie = dev->cookie;
1.13      augustss 1133:        usbd_devinfo_vp(dev, di->vendor, di->product);
1.32      augustss 1134:        usbd_printBCD(di->release, UGETW(dev->ddesc.bcdDevice));
1.21      augustss 1135:        di->vendorNo = UGETW(dev->ddesc.idVendor);
                   1136:        di->productNo = UGETW(dev->ddesc.idProduct);
1.65      augustss 1137:        di->releaseNo = UGETW(dev->ddesc.bcdDevice);
1.13      augustss 1138:        di->class = dev->ddesc.bDeviceClass;
1.65      augustss 1139:        di->subclass = dev->ddesc.bDeviceSubClass;
                   1140:        di->protocol = dev->ddesc.bDeviceProtocol;
                   1141:        di->config = dev->config;
1.13      augustss 1142:        di->power = dev->self_powered ? 0 : dev->power;
                   1143:        di->lowspeed = dev->lowspeed;
1.65      augustss 1144:
                   1145:        if (dev->subdevs != NULL) {
                   1146:                for (i = 0; dev->subdevs[i] &&
                   1147:                             i < USB_MAX_DEVNAMES; i++) {
                   1148:                        strncpy(di->devnames[i], USBDEVPTRNAME(dev->subdevs[i]),
                   1149:                                USB_MAX_DEVNAMELEN);
                   1150:                        di->devnames[i][USB_MAX_DEVNAMELEN-1] = '\0';
                   1151:                 }
                   1152:         } else {
                   1153:                 i = 0;
                   1154:         }
                   1155:         for (/*i is set */; i < USB_MAX_DEVNAMES; i++)
                   1156:                 di->devnames[i][0] = 0;                 /* empty */
                   1157:
1.13      augustss 1158:        if (dev->hub) {
                   1159:                for (i = 0;
                   1160:                     i < sizeof(di->ports) / sizeof(di->ports[0]) &&
                   1161:                             i < dev->hub->hubdesc.bNbrPorts;
                   1162:                     i++) {
                   1163:                        p = &dev->hub->ports[i];
                   1164:                        if (p->device)
1.56      augustss 1165:                                err = p->device->address;
1.13      augustss 1166:                        else {
                   1167:                                s = UGETW(p->status.wPortStatus);
                   1168:                                if (s & UPS_PORT_ENABLED)
1.56      augustss 1169:                                        err = USB_PORT_ENABLED;
1.13      augustss 1170:                                else if (s & UPS_SUSPEND)
1.56      augustss 1171:                                        err = USB_PORT_SUSPENDED;
1.13      augustss 1172:                                else if (s & UPS_PORT_POWER)
1.56      augustss 1173:                                        err = USB_PORT_POWERED;
1.13      augustss 1174:                                else
1.56      augustss 1175:                                        err = USB_PORT_DISABLED;
1.13      augustss 1176:                        }
1.56      augustss 1177:                        di->ports[i] = err;
1.13      augustss 1178:                }
                   1179:                di->nports = dev->hub->hubdesc.bNbrPorts;
                   1180:        } else
                   1181:                di->nports = 0;
1.34      augustss 1182: }
                   1183:
                   1184: void
1.76.2.1! minoura  1185: usb_free_device(usbd_device_handle dev)
1.34      augustss 1186: {
                   1187:        int ifcidx, nifc;
                   1188:
1.53      augustss 1189:        if (dev->default_pipe != NULL)
1.34      augustss 1190:                usbd_kill_pipe(dev->default_pipe);
1.53      augustss 1191:        if (dev->ifaces != NULL) {
1.34      augustss 1192:                nifc = dev->cdesc->bNumInterface;
                   1193:                for (ifcidx = 0; ifcidx < nifc; ifcidx++)
                   1194:                        usbd_free_iface_data(dev, ifcidx);
                   1195:                free(dev->ifaces, M_USB);
                   1196:        }
1.53      augustss 1197:        if (dev->cdesc != NULL)
1.34      augustss 1198:                free(dev->cdesc, M_USB);
1.53      augustss 1199:        if (dev->subdevs != NULL)
1.34      augustss 1200:                free(dev->subdevs, M_USB);
                   1201:        free(dev, M_USB);
1.1       augustss 1202: }
1.47      augustss 1203:
                   1204: /*
                   1205:  * The general mechanism for detaching drivers works as follows: Each
                   1206:  * driver is responsible for maintaining a reference count on the
                   1207:  * number of outstanding references to its softc (e.g.  from
                   1208:  * processing hanging in a read or write).  The detach method of the
                   1209:  * driver decrements this counter and flags in the softc that the
                   1210:  * driver is dying and then wakes any sleepers.  It then sleeps on the
                   1211:  * softc.  Each place that can sleep must maintain the reference
                   1212:  * count.  When the reference count drops to -1 (0 is the normal value
                   1213:  * of the reference count) the a wakeup on the softc is performed
                   1214:  * signaling to the detach waiter that all references are gone.
                   1215:  */
                   1216:
                   1217: /*
                   1218:  * Called from process context when we discover that a port has
                   1219:  * been disconnected.
                   1220:  */
                   1221: void
1.76.2.1! minoura  1222: usb_disconnect_port(struct usbd_port *up, device_ptr_t parent)
1.47      augustss 1223: {
                   1224:        usbd_device_handle dev = up->device;
1.51      augustss 1225:        char *hubname = USBDEVPTRNAME(parent);
1.47      augustss 1226:        int i;
                   1227:
                   1228:        DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
                   1229:                    up, dev, up->portno));
1.48      augustss 1230:
                   1231: #ifdef DIAGNOSTIC
1.57      augustss 1232:        if (dev == NULL) {
1.48      augustss 1233:                printf("usb_disconnect_port: no device\n");
                   1234:                return;
                   1235:        }
                   1236: #endif
1.47      augustss 1237:
1.55      augustss 1238:        if (dev->subdevs != NULL) {
1.57      augustss 1239:                DPRINTFN(3,("usb_disconnect_port: disconnect subdevs\n"));
1.47      augustss 1240:                for (i = 0; dev->subdevs[i]; i++) {
1.51      augustss 1241:                        printf("%s: at %s", USBDEVPTRNAME(dev->subdevs[i]),
                   1242:                               hubname);
                   1243:                        if (up->portno != 0)
                   1244:                                printf(" port %d", up->portno);
                   1245:                        printf(" (addr %d) disconnected\n", dev->address);
1.56      augustss 1246: #if defined(__NetBSD__) || defined(__OpenBSD__)
1.47      augustss 1247:                        config_detach(dev->subdevs[i], DETACH_FORCE);
1.56      augustss 1248: #elif defined(__FreeBSD__)
                   1249:                         device_delete_child(device_get_parent(dev->subdevs[i]),
                   1250:                                            dev->subdevs[i]);
                   1251: #endif
                   1252:
1.47      augustss 1253:                }
                   1254:        }
                   1255:
1.65      augustss 1256:        usbd_add_dev_event(USB_EVENT_DEVICE_DETACH, dev);
1.57      augustss 1257:        dev->bus->devices[dev->address] = NULL;
                   1258:        up->device = NULL;
1.47      augustss 1259:        usb_free_device(dev);
                   1260: }
                   1261:
1.54      augustss 1262: #ifdef __OpenBSD__
1.76.2.1! minoura  1263: void *usb_realloc(void *p, u_int size, int pool, int flags)
1.54      augustss 1264: {
                   1265:        void *q;
                   1266:
                   1267:        q = malloc(size, pool, flags);
                   1268:        if (q == NULL)
                   1269:                return (NULL);
                   1270:        bcopy(p, q, size);
                   1271:        free(p, pool);
                   1272:        return (q);
                   1273: }
                   1274: #endif

CVSweb <webmaster@jp.NetBSD.org>