Merge from vendor branch LUKEMFTP:
[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.10 2004/03/19 00:35:57 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__) || defined(__DragonFly__)
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__) || defined(__DragonFly__)
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_INTWAIT);
472         } else {
473                 ifc->endpoints = NULL;
474         }
475         ifc->priv = NULL;
476         p = (char *)ifc->idesc + ifc->idesc->bLength;
477         end = (char *)dev->cdesc + UGETW(dev->cdesc->wTotalLength);
478 #define ed ((usb_endpoint_descriptor_t *)p)
479         for (endpt = 0; endpt < nendpt; endpt++) {
480                 DPRINTFN(10,("usbd_fill_iface_data: endpt=%d\n", endpt));
481                 for (; p < end; p += ed->bLength) {
482                         DPRINTFN(10,("usbd_fill_iface_data: p=%p end=%p "
483                                      "len=%d type=%d\n",
484                                  p, end, ed->bLength, ed->bDescriptorType));
485                         if (p + ed->bLength <= end && ed->bLength != 0 &&
486                             ed->bDescriptorType == UDESC_ENDPOINT)
487                                 goto found;
488                         if (ed->bLength == 0 ||
489                             ed->bDescriptorType == UDESC_INTERFACE)
490                                 break;
491                 }
492                 /* passed end, or bad desc */
493                 printf("usbd_fill_iface_data: bad descriptor(s): %s\n",
494                        ed->bLength == 0 ? "0 length" :
495                        ed->bDescriptorType == UDESC_INTERFACE ? "iface desc":
496                        "out of data");
497                 goto bad;
498         found:
499                 ifc->endpoints[endpt].edesc = ed;
500                 if (dev->speed == USB_SPEED_HIGH) {
501                         u_int mps;
502                         /* Control and bulk endpoints have max packet limits. */
503                         switch (UE_GET_XFERTYPE(ed->bmAttributes)) {
504                         case UE_CONTROL:
505                                 mps = USB_2_MAX_CTRL_PACKET;
506                                 goto check;
507                         case UE_BULK:
508                                 mps = USB_2_MAX_BULK_PACKET;
509                         check:
510                                 if (UGETW(ed->wMaxPacketSize) != mps) {
511                                         USETW(ed->wMaxPacketSize, mps);
512 #ifdef DIAGNOSTIC
513                                         printf("usbd_fill_iface_data: bad max "
514                                                "packet size\n");
515 #endif
516                                 }
517                                 break;
518                         default:
519                                 break;
520                         }
521                 }
522                 ifc->endpoints[endpt].refcnt = 0;
523                 p += ed->bLength;
524         }
525 #undef ed
526         LIST_INIT(&ifc->pipes);
527         return (USBD_NORMAL_COMPLETION);
528
529  bad:
530         if (ifc->endpoints != NULL) {
531                 free(ifc->endpoints, M_USB);
532                 ifc->endpoints = NULL;
533         }
534         return (USBD_INVAL);
535 }
536
537 void
538 usbd_free_iface_data(usbd_device_handle dev, int ifcno)
539 {
540         usbd_interface_handle ifc = &dev->ifaces[ifcno];
541         if (ifc->endpoints)
542                 free(ifc->endpoints, M_USB);
543 }
544
545 Static usbd_status
546 usbd_set_config(usbd_device_handle dev, int conf)
547 {
548         usb_device_request_t req;
549
550         req.bmRequestType = UT_WRITE_DEVICE;
551         req.bRequest = UR_SET_CONFIG;
552         USETW(req.wValue, conf);
553         USETW(req.wIndex, 0);
554         USETW(req.wLength, 0);
555         return (usbd_do_request(dev, &req, 0));
556 }
557
558 usbd_status
559 usbd_set_config_no(usbd_device_handle dev, int no, int msg)
560 {
561         int index;
562         usb_config_descriptor_t cd;
563         usbd_status err;
564
565         if (no == USB_UNCONFIG_NO)
566                 return (usbd_set_config_index(dev, USB_UNCONFIG_INDEX, msg));
567
568         DPRINTFN(5,("usbd_set_config_no: %d\n", no));
569         /* Figure out what config index to use. */
570         for (index = 0; index < dev->ddesc.bNumConfigurations; index++) {
571                 err = usbd_get_config_desc(dev, index, &cd);
572                 if (err)
573                         return (err);
574                 if (cd.bConfigurationValue == no)
575                         return (usbd_set_config_index(dev, index, msg));
576         }
577         return (USBD_INVAL);
578 }
579
580 usbd_status
581 usbd_set_config_index(usbd_device_handle dev, int index, int msg)
582 {
583         usb_status_t ds;
584         usb_config_descriptor_t cd, *cdp;
585         usbd_status err;
586         int ifcidx, nifc, len, selfpowered, power;
587
588         DPRINTFN(5,("usbd_set_config_index: dev=%p index=%d\n", dev, index));
589
590         /* XXX check that all interfaces are idle */
591         if (dev->config != USB_UNCONFIG_NO) {
592                 DPRINTF(("usbd_set_config_index: free old config\n"));
593                 /* Free all configuration data structures. */
594                 nifc = dev->cdesc->bNumInterface;
595                 for (ifcidx = 0; ifcidx < nifc; ifcidx++)
596                         usbd_free_iface_data(dev, ifcidx);
597                 free(dev->ifaces, M_USB);
598                 free(dev->cdesc, M_USB);
599                 dev->ifaces = NULL;
600                 dev->cdesc = NULL;
601                 dev->config = USB_UNCONFIG_NO;
602         }
603
604         if (index == USB_UNCONFIG_INDEX) {
605                 /* We are unconfiguring the device, so leave unallocated. */
606                 DPRINTF(("usbd_set_config_index: set config 0\n"));
607                 err = usbd_set_config(dev, USB_UNCONFIG_NO);
608                 if (err)
609                         DPRINTF(("usbd_set_config_index: setting config=0 "
610                                  "failed, error=%s\n", usbd_errstr(err)));
611                 return (err);
612         }
613
614         /* Get the short descriptor. */
615         err = usbd_get_config_desc(dev, index, &cd);
616         if (err)
617                 return (err);
618         len = UGETW(cd.wTotalLength);
619         cdp = malloc(len, M_USB, M_INTWAIT);
620         /* Get the full descriptor. */
621         err = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp);
622         if (err)
623                 goto bad;
624         if (cdp->bDescriptorType != UDESC_CONFIG) {
625                 DPRINTFN(-1,("usbd_set_config_index: bad desc %d\n",
626                              cdp->bDescriptorType));
627                 err = USBD_INVAL;
628                 goto bad;
629         }
630
631         /* Figure out if the device is self or bus powered. */
632         selfpowered = 0;
633         if (!(dev->quirks->uq_flags & UQ_BUS_POWERED) &&
634             (cdp->bmAttributes & UC_SELF_POWERED)) {
635                 /* May be self powered. */
636                 if (cdp->bmAttributes & UC_BUS_POWERED) {
637                         /* Must ask device. */
638                         if (dev->quirks->uq_flags & UQ_POWER_CLAIM) {
639                                 /*
640                                  * Hub claims to be self powered, but isn't.
641                                  * It seems that the power status can be
642                                  * determined by the hub characteristics.
643                                  */
644                                 usb_hub_descriptor_t hd;
645                                 usb_device_request_t req;
646                                 req.bmRequestType = UT_READ_CLASS_DEVICE;
647                                 req.bRequest = UR_GET_DESCRIPTOR;
648                                 USETW(req.wValue, 0);
649                                 USETW(req.wIndex, 0);
650                                 USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE);
651                                 err = usbd_do_request(dev, &req, &hd);
652                                 if (!err &&
653                                     (UGETW(hd.wHubCharacteristics) &
654                                      UHD_PWR_INDIVIDUAL))
655                                         selfpowered = 1;
656                                 DPRINTF(("usbd_set_config_index: charac=0x%04x"
657                                     ", error=%s\n",
658                                     UGETW(hd.wHubCharacteristics),
659                                     usbd_errstr(err)));
660                         } else {
661                                 err = usbd_get_device_status(dev, &ds);
662                                 if (!err &&
663                                     (UGETW(ds.wStatus) & UDS_SELF_POWERED))
664                                         selfpowered = 1;
665                                 DPRINTF(("usbd_set_config_index: status=0x%04x"
666                                     ", error=%s\n",
667                                     UGETW(ds.wStatus), usbd_errstr(err)));
668                         }
669                 } else
670                         selfpowered = 1;
671         }
672         DPRINTF(("usbd_set_config_index: (addr %d) cno=%d attr=0x%02x, "
673                  "selfpowered=%d, power=%d\n",
674                  cdp->bConfigurationValue, dev->address, cdp->bmAttributes,
675                  selfpowered, cdp->bMaxPower * 2));
676
677         /* Check if we have enough power. */
678 #ifdef USB_DEBUG
679         if (dev->powersrc == NULL) {
680                 DPRINTF(("usbd_set_config_index: No power source?\n"));
681                 return (USBD_IOERROR);
682         }
683 #endif
684         power = cdp->bMaxPower * 2;
685         if (power > dev->powersrc->power) {
686                 DPRINTF(("power exceeded %d %d\n", power,dev->powersrc->power));
687                 /* XXX print nicer message. */
688                 if (msg)
689                         printf("%s: device addr %d (config %d) exceeds power "
690                                  "budget, %d mA > %d mA\n",
691                                USBDEVNAME(dev->bus->bdev), dev->address,
692                                cdp->bConfigurationValue,
693                                power, dev->powersrc->power);
694                 err = USBD_NO_POWER;
695                 goto bad;
696         }
697         dev->power = power;
698         dev->self_powered = selfpowered;
699
700         /* Set the actual configuration value. */
701         DPRINTF(("usbd_set_config_index: set config %d\n",
702                  cdp->bConfigurationValue));
703         err = usbd_set_config(dev, cdp->bConfigurationValue);
704         if (err) {
705                 DPRINTF(("usbd_set_config_index: setting config=%d failed, "
706                          "error=%s\n",
707                          cdp->bConfigurationValue, usbd_errstr(err)));
708                 goto bad;
709         }
710
711         /* Allocate and fill interface data. */
712         nifc = cdp->bNumInterface;
713         dev->ifaces = malloc(nifc * sizeof(struct usbd_interface),
714                              M_USB, M_INTWAIT);
715         DPRINTFN(5,("usbd_set_config_index: dev=%p cdesc=%p\n", dev, cdp));
716         dev->cdesc = cdp;
717         dev->config = cdp->bConfigurationValue;
718         for (ifcidx = 0; ifcidx < nifc; ifcidx++) {
719                 err = usbd_fill_iface_data(dev, ifcidx, 0);
720                 if (err) {
721                         while (--ifcidx >= 0)
722                                 usbd_free_iface_data(dev, ifcidx);
723                         goto bad;
724                 }
725         }
726
727         return (USBD_NORMAL_COMPLETION);
728
729  bad:
730         free(cdp, M_USB);
731         return (err);
732 }
733
734 /* XXX add function for alternate settings */
735
736 usbd_status
737 usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface,
738                 struct usbd_endpoint *ep, int ival, usbd_pipe_handle *pipe)
739 {
740         usbd_pipe_handle p;
741         usbd_status err;
742
743         DPRINTFN(1,("usbd_setup_pipe: dev=%p iface=%p ep=%p pipe=%p\n",
744                     dev, iface, ep, pipe));
745         p = malloc(dev->bus->pipe_size, M_USB, M_INTWAIT);
746         p->device = dev;
747         p->iface = iface;
748         p->endpoint = ep;
749         ep->refcnt++;
750         p->refcnt = 1;
751         p->intrxfer = 0;
752         p->running = 0;
753         p->aborting = 0;
754         p->repeat = 0;
755         p->interval = ival;
756         SIMPLEQ_INIT(&p->queue);
757         err = dev->bus->methods->open_pipe(p);
758         if (err) {
759                 DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error="
760                          "%s\n",
761                          ep->edesc->bEndpointAddress, usbd_errstr(err)));
762                 free(p, M_USB);
763                 return (err);
764         }
765         /* Clear any stall and make sure DATA0 toggle will be used next. */
766         if (UE_GET_ADDR(ep->edesc->bEndpointAddress) != USB_CONTROL_ENDPOINT)
767                 usbd_clear_endpoint_stall(p);
768         *pipe = p;
769         return (USBD_NORMAL_COMPLETION);
770 }
771
772 /* Abort the device control pipe. */
773 void
774 usbd_kill_pipe(usbd_pipe_handle pipe)
775 {
776         usbd_abort_pipe(pipe);
777         pipe->methods->close(pipe);
778         pipe->endpoint->refcnt--;
779         free(pipe, M_USB);
780 }
781
782 int
783 usbd_getnewaddr(usbd_bus_handle bus)
784 {
785         int addr;
786
787         for (addr = 1; addr < USB_MAX_DEVICES; addr++)
788                 if (bus->devices[addr] == 0)
789                         return (addr);
790         return (-1);
791 }
792
793
794 usbd_status
795 usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
796                       int port, int addr)
797 {
798         struct usb_attach_arg uaa;
799         usb_device_descriptor_t *dd = &dev->ddesc;
800         int found, i, confi, nifaces;
801         usbd_status err;
802         device_ptr_t dv;
803         usbd_interface_handle ifaces[256]; /* 256 is the absolute max */
804
805 #if defined(__FreeBSD__) || defined(__DragonFly__)
806         /*
807          * XXX uaa is a static var. Not a problem as it _should_ be used only
808          * during probe and attach. Should be changed however.
809          */
810         device_t bdev;
811         bdev = device_add_child(parent, NULL, -1);
812         if (!bdev) {
813             printf("%s: Device creation failed\n", USBDEVNAME(dev->bus->bdev));
814             return (USBD_INVAL);
815         }
816         device_set_ivars(bdev, &uaa);
817         device_quiet(bdev);
818 #endif
819
820         uaa.device = dev;
821         uaa.iface = NULL;
822         uaa.ifaces = NULL;
823         uaa.nifaces = 0;
824         uaa.usegeneric = 0;
825         uaa.port = port;
826         uaa.configno = UHUB_UNK_CONFIGURATION;
827         uaa.ifaceno = UHUB_UNK_INTERFACE;
828         uaa.vendor = UGETW(dd->idVendor);
829         uaa.product = UGETW(dd->idProduct);
830         uaa.release = UGETW(dd->bcdDevice);
831
832         /* First try with device specific drivers. */
833         DPRINTF(("usbd_probe_and_attach: trying device specific drivers\n"));
834         dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch);
835         if (dv) {
836                 dev->subdevs = malloc(2 * sizeof dv, M_USB, M_INTWAIT);
837                 dev->subdevs[0] = dv;
838                 dev->subdevs[1] = 0;
839                 return (USBD_NORMAL_COMPLETION);
840         }
841
842         DPRINTF(("usbd_probe_and_attach: no device specific driver found\n"));
843
844         DPRINTF(("usbd_probe_and_attach: looping over %d configurations\n",
845                  dd->bNumConfigurations));
846         /* Next try with interface drivers. */
847         for (confi = 0; confi < dd->bNumConfigurations; confi++) {
848                 DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n",
849                             confi));
850                 err = usbd_set_config_index(dev, confi, 1);
851                 if (err) {
852 #ifdef USB_DEBUG
853                         DPRINTF(("%s: port %d, set config at addr %d failed, "
854                                  "error=%s\n", USBDEVPTRNAME(parent), port,
855                                  addr, usbd_errstr(err)));
856 #else
857                         printf("%s: port %d, set config at addr %d failed\n",
858                                USBDEVPTRNAME(parent), port, addr);
859 #endif
860 #if defined(__FreeBSD__) || defined(__DragonFly__)
861                         device_delete_child(parent, bdev);
862 #endif
863
864                         return (err);
865                 }
866                 nifaces = dev->cdesc->bNumInterface;
867                 uaa.configno = dev->cdesc->bConfigurationValue;
868                 for (i = 0; i < nifaces; i++)
869                         ifaces[i] = &dev->ifaces[i];
870                 uaa.ifaces = ifaces;
871                 uaa.nifaces = nifaces;
872                 dev->subdevs = malloc((nifaces+1) * sizeof dv, M_USB, M_INTWAIT);
873
874                 found = 0;
875                 for (i = 0; i < nifaces; i++) {
876                         if (ifaces[i] == NULL)
877                                 continue; /* interface already claimed */
878                         uaa.iface = ifaces[i];
879                         uaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber;
880                         dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print,
881                                            usbd_submatch);
882                         if (dv != NULL) {
883                                 dev->subdevs[found++] = dv;
884                                 dev->subdevs[found] = 0;
885                                 ifaces[i] = 0; /* consumed */
886
887 #if defined(__FreeBSD__) || defined(__DragonFly__)
888                                 /* create another child for the next iface */
889                                 bdev = device_add_child(parent, NULL, -1);
890                                 if (!bdev) {
891                                         printf("%s: Device creation failed\n",
892                                         USBDEVNAME(dev->bus->bdev));
893                                         return (USBD_NORMAL_COMPLETION);
894                                 }
895                                 device_set_ivars(bdev, &uaa);
896                                 device_quiet(bdev);
897 #endif
898                         }
899                 }
900                 if (found != 0) {
901 #if defined(__FreeBSD__) || defined(__DragonFly__)
902                         /* remove the last created child again; it is unused */
903                         device_delete_child(parent, bdev);
904 #endif
905                         return (USBD_NORMAL_COMPLETION);
906                 }
907                 free(dev->subdevs, M_USB);
908                 dev->subdevs = 0;
909         }
910         /* No interfaces were attached in any of the configurations. */
911
912         if (dd->bNumConfigurations > 1) /* don't change if only 1 config */
913                 usbd_set_config_index(dev, 0, 0);
914
915         DPRINTF(("usbd_probe_and_attach: no interface drivers found\n"));
916
917         /* Finally try the generic driver. */
918         uaa.iface = NULL;
919         uaa.usegeneric = 1;
920         uaa.configno = UHUB_UNK_CONFIGURATION;
921         uaa.ifaceno = UHUB_UNK_INTERFACE;
922         dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch);
923         if (dv != NULL) {
924                 dev->subdevs = malloc(2 * sizeof dv, M_USB, M_INTWAIT);
925                 dev->subdevs[0] = dv;
926                 dev->subdevs[1] = 0;
927                 return (USBD_NORMAL_COMPLETION);
928         }
929
930         /*
931          * The generic attach failed, but leave the device as it is.
932          * We just did not find any drivers, that's all.  The device is
933          * fully operational and not harming anyone.
934          */
935         DPRINTF(("usbd_probe_and_attach: generic attach failed\n"));
936 #if defined(__FreeBSD__) || defined(__DragonFly__)
937         device_delete_child(parent, bdev);
938 #endif
939         return (USBD_NORMAL_COMPLETION);
940 }
941
942
943 /*
944  * Called when a new device has been put in the powered state,
945  * but not yet in the addressed state.
946  * Get initial descriptor, set the address, get full descriptor,
947  * and attach a driver.
948  */
949 usbd_status
950 usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
951                 int speed, int port, struct usbd_port *up)
952 {
953         usbd_device_handle dev;
954         struct usbd_device *hub;
955         usb_device_descriptor_t *dd;
956         usb_port_status_t ps;
957         usbd_status err;
958         int addr;
959         int i;
960
961         DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n",
962                  bus, port, depth, speed));
963         addr = usbd_getnewaddr(bus);
964         if (addr < 0) {
965                 printf("%s: No free USB addresses, new device ignored.\n",
966                        USBDEVNAME(bus->bdev));
967                 return (USBD_NO_ADDR);
968         }
969
970         dev = malloc(sizeof *dev, M_USB, M_INTWAIT | M_ZERO);
971         dev->bus = bus;
972
973         /* Set up default endpoint handle. */
974         dev->def_ep.edesc = &dev->def_ep_desc;
975
976         /* Set up default endpoint descriptor. */
977         dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE;
978         dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT;
979         dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
980         dev->def_ep_desc.bmAttributes = UE_CONTROL;
981         USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET);
982         dev->def_ep_desc.bInterval = 0;
983
984         dev->quirks = &usbd_no_quirk;
985         dev->address = USB_START_ADDR;
986         dev->ddesc.bMaxPacketSize = 0;
987         dev->depth = depth;
988         dev->powersrc = up;
989         dev->myhub = up->parent;
990         for (hub = up->parent;
991              hub != NULL && hub->speed != USB_SPEED_HIGH;
992              hub = hub->myhub)
993                 ;
994         dev->myhighhub = hub;
995         dev->speed = speed;
996         dev->langid = USBD_NOLANG;
997         dev->cookie.cookie = ++usb_cookie_no;
998
999         /* Establish the default pipe. */
1000         err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
1001                               &dev->default_pipe);
1002         if (err) {
1003                 usbd_remove_device(dev, up);
1004                 return (err);
1005         }
1006
1007         up->device = dev;
1008
1009         /* Set the address.  Do this early; some devices need that. */
1010         err = usbd_set_address(dev, addr);
1011         DPRINTFN(5,("usbd_new_device: setting device address=%d\n", addr));
1012         if (err) {
1013                 DPRINTFN(-1,("usb_new_device: set address %d failed\n", addr));
1014                 err = USBD_SET_ADDR_FAILED;
1015                 usbd_remove_device(dev, up);
1016                 return (err);
1017         }
1018         /* Allow device time to set new address */
1019         usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE);
1020         dev->address = addr;    /* New device address now */
1021         bus->devices[addr] = dev;
1022
1023         dd = &dev->ddesc;
1024         /* Try a few times in case the device is slow (i.e. outside specs.) */
1025         for (i = 0; i < 15; i++) {
1026                 /* Get the first 8 bytes of the device descriptor. */
1027                 err = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd);
1028                 if (!err)
1029                         break;
1030                 usbd_delay_ms(dev, 200);
1031                 if ((i & 3) == 3)
1032                         usbd_reset_port(up->parent, port, &ps);
1033         }
1034         if (err) {
1035                 DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc "
1036                               "failed\n", addr));
1037                 usbd_remove_device(dev, up);
1038                 return (err);
1039         }
1040
1041         if (speed == USB_SPEED_HIGH) {
1042                 /* Max packet size must be 64 (sec 5.5.3). */
1043                 if (dd->bMaxPacketSize != USB_2_MAX_CTRL_PACKET) {
1044 #ifdef DIAGNOSTIC
1045                         printf("usbd_new_device: addr=%d bad max packet size\n",
1046                                addr);
1047 #endif
1048                         dd->bMaxPacketSize = USB_2_MAX_CTRL_PACKET;
1049                 }
1050         }
1051
1052         DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, "
1053                  "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n",
1054                  addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass,
1055                  dd->bDeviceProtocol, dd->bMaxPacketSize, dd->bLength,
1056                  dev->speed));
1057
1058         if (dd->bDescriptorType != UDESC_DEVICE) {
1059                 /* Illegal device descriptor */
1060                 DPRINTFN(-1,("usbd_new_device: illegal descriptor %d\n",
1061                              dd->bDescriptorType));
1062                 usbd_remove_device(dev, up);
1063                 return (USBD_INVAL);
1064         }
1065
1066         if (dd->bLength < USB_DEVICE_DESCRIPTOR_SIZE) {
1067                 DPRINTFN(-1,("usbd_new_device: bad length %d\n", dd->bLength));
1068                 usbd_remove_device(dev, up);
1069                 return (USBD_INVAL);
1070         }
1071
1072         USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize);
1073
1074         err = usbd_reload_device_desc(dev);
1075         if (err) {
1076                 DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc "
1077                               "failed\n", addr));
1078                 usbd_remove_device(dev, up);
1079                 return (err);
1080         }
1081
1082         /* Assume 100mA bus powered for now. Changed when configured. */
1083         dev->power = USB_MIN_POWER;
1084         dev->self_powered = 0;
1085
1086         DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n",
1087                  addr, dev, parent));
1088
1089         err = usbd_probe_and_attach(parent, dev, port, addr);
1090         if (err) {
1091                 usbd_remove_device(dev, up);
1092                 return (err);
1093         }
1094
1095         usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev);
1096
1097         return (USBD_NORMAL_COMPLETION);
1098 }
1099
1100 usbd_status
1101 usbd_reload_device_desc(usbd_device_handle dev)
1102 {
1103         usbd_status err = 0;
1104         int i;
1105
1106         /* Get the full device descriptor. */
1107         for (i = 0; i < 3; ++i) {
1108                 err = usbd_get_device_desc(dev, &dev->ddesc);
1109                 if (!err)
1110                         break;
1111                 usbd_delay_ms(dev, 200);
1112         }
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);
1120 }
1121
1122 void
1123 usbd_remove_device(usbd_device_handle dev, struct usbd_port *up)
1124 {
1125         DPRINTF(("usbd_remove_device: %p\n", dev));
1126
1127         if (dev->default_pipe != NULL)
1128                 usbd_kill_pipe(dev->default_pipe);
1129         up->device = 0;
1130         dev->bus->devices[dev->address] = 0;
1131
1132         free(dev, M_USB);
1133 }
1134
1135 #if defined(__NetBSD__) || defined(__OpenBSD__)
1136 int
1137 usbd_print(void *aux, const char *pnp)
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);
1147                 printf("%s, %s", devinfo, pnp);
1148         }
1149         if (uaa->port != 0)
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);
1155 #if 0
1156         /*
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
1168         return (UNCONF);
1169 }
1170
1171 #if defined(__NetBSD__)
1172 int
1173 usbd_submatch(struct device *parent, struct cfdata *cf, void *aux)
1174 {
1175 #elif defined(__OpenBSD__)
1176 int
1177 usbd_submatch(struct device *parent, void *match, void *aux)
1178 {
1179         struct cfdata *cf = match;
1180 #endif
1181         struct usb_attach_arg *uaa = aux;
1182
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              )
1211            )
1212                 return 0;
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;
1225         return ((*cf->cf_attach->ca_match)(parent, cf, aux));
1226 }
1227
1228 #endif
1229
1230 void
1231 usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di,
1232                      int usedev)
1233 {
1234         struct usbd_port *p;
1235         int i, err, s;
1236
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;
1251
1252         if (dev->subdevs != NULL) {
1253                 for (i = 0; dev->subdevs[i] &&
1254                              i < USB_MAX_DEVNAMES; i++) {
1255                         strncpy(di->udi_devnames[i], USBDEVPTRNAME(dev->subdevs[i]),
1256                                 USB_MAX_DEVNAMELEN);
1257                         di->udi_devnames[i][USB_MAX_DEVNAMELEN-1] = '\0';
1258                 }
1259         } else {
1260                 i = 0;
1261         }
1262         for (/*i is set */; i < USB_MAX_DEVNAMES; i++)
1263                 di->udi_devnames[i][0] = 0;                 /* empty */
1264
1265         if (dev->hub) {
1266                 for (i = 0;
1267                      i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) &&
1268                              i < dev->hub->hubdesc.bNbrPorts;
1269                      i++) {
1270                         p = &dev->hub->ports[i];
1271                         if (p->device)
1272                                 err = p->device->address;
1273                         else {
1274                                 s = UGETW(p->status.wPortStatus);
1275                                 if (s & UPS_PORT_ENABLED)
1276                                         err = USB_PORT_ENABLED;
1277                                 else if (s & UPS_SUSPEND)
1278                                         err = USB_PORT_SUSPENDED;
1279                                 else if (s & UPS_PORT_POWER)
1280                                         err = USB_PORT_POWERED;
1281                                 else
1282                                         err = USB_PORT_DISABLED;
1283                         }
1284                         di->udi_ports[i] = err;
1285                 }
1286                 di->udi_nports = dev->hub->hubdesc.bNbrPorts;
1287         } else
1288                 di->udi_nports = 0;
1289 }
1290
1291 void
1292 usb_free_device(usbd_device_handle dev)
1293 {
1294         int ifcidx, nifc;
1295
1296         if (dev->default_pipe != NULL)
1297                 usbd_kill_pipe(dev->default_pipe);
1298         if (dev->ifaces != NULL) {
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         }
1304         if (dev->cdesc != NULL)
1305                 free(dev->cdesc, M_USB);
1306         if (dev->subdevs != NULL)
1307                 free(dev->subdevs, M_USB);
1308         free(dev, M_USB);
1309 }
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
1329 usb_disconnect_port(struct usbd_port *up, device_ptr_t parent)
1330 {
1331         usbd_device_handle dev = up->device;
1332         const char *hubname = USBDEVPTRNAME(parent);
1333         int i;
1334
1335         DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
1336                     up, dev, up->portno));
1337
1338 #ifdef DIAGNOSTIC
1339         if (dev == NULL) {
1340                 printf("usb_disconnect_port: no device\n");
1341                 return;
1342         }
1343 #endif
1344
1345         if (dev->subdevs != NULL) {
1346                 DPRINTFN(3,("usb_disconnect_port: disconnect subdevs\n"));
1347                 for (i = 0; dev->subdevs[i]; i++) {
1348                         printf("%s: at %s", USBDEVPTRNAME(dev->subdevs[i]),
1349                                hubname);
1350                         if (up->portno != 0)
1351                                 printf(" port %d", up->portno);
1352                         printf(" (addr %d) disconnected\n", dev->address);
1353                         config_detach(dev->subdevs[i], DETACH_FORCE);
1354                         dev->subdevs[i] = NULL;
1355                 }
1356         }
1357
1358         usbd_add_dev_event(USB_EVENT_DEVICE_DETACH, dev);
1359         dev->bus->devices[dev->address] = NULL;
1360         up->device = NULL;
1361         usb_free_device(dev);
1362 }
1363
1364 #ifdef __OpenBSD__
1365 void *usb_realloc(void *p, u_int size, int pool, int flags)
1366 {
1367         void *q;
1368
1369         q = malloc(size, pool, flags);
1370         if (q == NULL)
1371                 return (NULL);
1372         bcopy(p, q, size);
1373         free(p, pool);
1374         return (q);
1375 }
1376 #endif