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

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

CVSweb <webmaster@jp.NetBSD.org>