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