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