Sync usage with man page.
[netbsd-mini2440.git] / sys / dev / usb / usb_subr.c
blob69a616be3d7aca3c14791deca5c43ff994996cf6
1 /* $NetBSD: usb_subr.c,v 1.166 2009/11/12 08:41:49 uebayasi Exp $ */
2 /* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */
4 /*
5 * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
6 * All rights reserved.
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart@augustsson.net) at
10 * Carlstedt Research & Technology.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.166 2009/11/12 08:41:49 uebayasi Exp $");
37 #include "opt_compat_netbsd.h"
38 #include "opt_usbverbose.h"
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/malloc.h>
44 #include <sys/device.h>
45 #include <sys/select.h>
46 #include <sys/proc.h>
48 #include <sys/bus.h>
50 #include <dev/usb/usb.h>
52 #include <dev/usb/usbdi.h>
53 #include <dev/usb/usbdi_util.h>
54 #include <dev/usb/usbdivar.h>
55 #include <dev/usb/usbdevs.h>
56 #include <dev/usb/usb_quirks.h>
58 #include "locators.h"
60 #ifdef USB_DEBUG
61 #define DPRINTF(x) if (usbdebug) logprintf x
62 #define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x
63 extern int usbdebug;
64 #else
65 #define DPRINTF(x)
66 #define DPRINTFN(n,x)
67 #endif
69 Static usbd_status usbd_set_config(usbd_device_handle, int);
70 Static void usbd_devinfo(usbd_device_handle, int, char *, size_t);
71 Static void usbd_devinfo_vp(usbd_device_handle dev, char *v, char *p,
72 int usedev, int useencoded);
73 Static int usbd_getnewaddr(usbd_bus_handle bus);
74 Static int usbd_print(void *, const char *);
75 Static int usbd_ifprint(void *, const char *);
76 Static void usbd_free_iface_data(usbd_device_handle dev, int ifcno);
77 Static void usbd_kill_pipe(usbd_pipe_handle);
78 usbd_status usbd_attach_roothub(device_t, usbd_device_handle);
79 Static usbd_status usbd_probe_and_attach(device_t parent,
80 usbd_device_handle dev, int port, int addr);
82 Static u_int32_t usb_cookie_no = 0;
84 #ifdef USBVERBOSE
85 typedef u_int16_t usb_vendor_id_t;
86 typedef u_int16_t usb_product_id_t;
89 * Descriptions of of known vendors and devices ("products").
91 struct usb_vendor {
92 usb_vendor_id_t vendor;
93 const char *vendorname;
95 struct usb_product {
96 usb_vendor_id_t vendor;
97 usb_product_id_t product;
98 const char *productname;
101 #include <dev/usb/usbdevs_data.h>
102 #endif /* USBVERBOSE */
104 Static const char * const usbd_error_strs[] = {
105 "NORMAL_COMPLETION",
106 "IN_PROGRESS",
107 "PENDING_REQUESTS",
108 "NOT_STARTED",
109 "INVAL",
110 "NOMEM",
111 "CANCELLED",
112 "BAD_ADDRESS",
113 "IN_USE",
114 "NO_ADDR",
115 "SET_ADDR_FAILED",
116 "NO_POWER",
117 "TOO_DEEP",
118 "IOERROR",
119 "NOT_CONFIGURED",
120 "TIMEOUT",
121 "SHORT_XFER",
122 "STALLED",
123 "INTERRUPTED",
124 "XXX",
127 const char *
128 usbd_errstr(usbd_status err)
130 static char buffer[5];
132 if (err < USBD_ERROR_MAX) {
133 return usbd_error_strs[err];
134 } else {
135 snprintf(buffer, sizeof buffer, "%d", err);
136 return buffer;
140 usbd_status
141 usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid,
142 usb_string_descriptor_t *sdesc, int *sizep)
144 usb_device_request_t req;
145 usbd_status err;
146 int actlen;
148 req.bmRequestType = UT_READ_DEVICE;
149 req.bRequest = UR_GET_DESCRIPTOR;
150 USETW2(req.wValue, UDESC_STRING, sindex);
151 USETW(req.wIndex, langid);
152 USETW(req.wLength, 2); /* only size byte first */
153 err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
154 &actlen, USBD_DEFAULT_TIMEOUT);
155 if (err)
156 return (err);
158 if (actlen < 2)
159 return (USBD_SHORT_XFER);
161 USETW(req.wLength, sdesc->bLength); /* the whole string */
162 err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
163 &actlen, USBD_DEFAULT_TIMEOUT);
164 if (err)
165 return (err);
167 if (actlen != sdesc->bLength) {
168 DPRINTFN(-1, ("usbd_get_string_desc: expected %d, got %d\n",
169 sdesc->bLength, actlen));
172 *sizep = actlen;
173 return (USBD_NORMAL_COMPLETION);
176 static void
177 usbd_trim_spaces(char *p)
179 char *q, *e;
181 q = e = p;
182 while (*q == ' ') /* skip leading spaces */
183 q++;
184 while ((*p = *q++)) /* copy string */
185 if (*p++ != ' ') /* remember last non-space */
186 e = p;
187 *e = '\0'; /* kill trailing spaces */
190 Static void
191 usbd_devinfo_vp(usbd_device_handle dev, char *v, char *p, int usedev,
192 int useencoded)
194 usb_device_descriptor_t *udd = &dev->ddesc;
195 #ifdef USBVERBOSE
196 int n;
197 #endif
199 v[0] = p[0] = '\0';
200 if (dev == NULL)
201 return;
203 if (usedev) {
204 if (usbd_get_string0(dev, udd->iManufacturer, v, useencoded) ==
205 USBD_NORMAL_COMPLETION)
206 usbd_trim_spaces(v);
207 if (usbd_get_string0(dev, udd->iProduct, p, useencoded) ==
208 USBD_NORMAL_COMPLETION)
209 usbd_trim_spaces(p);
211 /* There is no need for strlcpy & snprintf below. */
212 #ifdef USBVERBOSE
213 if (v[0] == '\0')
214 for (n = 0; n < usb_nvendors; n++)
215 if (usb_vendors[n].vendor == UGETW(udd->idVendor)) {
216 strcpy(v, usb_vendors[n].vendorname);
217 break;
219 if (p[0] == '\0')
220 for (n = 0; n < usb_nproducts; n++)
221 if (usb_products[n].vendor == UGETW(udd->idVendor) &&
222 usb_products[n].product == UGETW(udd->idProduct)) {
223 strcpy(p, usb_products[n].productname);
224 break;
226 #endif
227 if (v[0] == '\0')
228 sprintf(v, "vendor 0x%04x", UGETW(udd->idVendor));
229 if (p[0] == '\0')
230 sprintf(p, "product 0x%04x", UGETW(udd->idProduct));
234 usbd_printBCD(char *cp, size_t l, int bcd)
236 return (snprintf(cp, l, "%x.%02x", bcd >> 8, bcd & 0xff));
239 Static void
240 usbd_devinfo(usbd_device_handle dev, int showclass, char *cp, size_t l)
242 usb_device_descriptor_t *udd = &dev->ddesc;
243 char *vendor, *product;
244 int bcdDevice, bcdUSB;
245 char *ep;
247 vendor = malloc(USB_MAX_ENCODED_STRING_LEN * 2, M_USB, M_NOWAIT);
248 if (vendor == NULL) {
249 *cp = '\0';
250 return;
252 product = &vendor[USB_MAX_ENCODED_STRING_LEN];
254 ep = cp + l;
256 usbd_devinfo_vp(dev, vendor, product, 1, 1);
257 cp += snprintf(cp, ep - cp, "%s %s", vendor, product);
258 if (showclass)
259 cp += snprintf(cp, ep - cp, ", class %d/%d",
260 udd->bDeviceClass, udd->bDeviceSubClass);
261 bcdUSB = UGETW(udd->bcdUSB);
262 bcdDevice = UGETW(udd->bcdDevice);
263 cp += snprintf(cp, ep - cp, ", rev ");
264 cp += usbd_printBCD(cp, ep - cp, bcdUSB);
265 *cp++ = '/';
266 cp += usbd_printBCD(cp, ep - cp, bcdDevice);
267 cp += snprintf(cp, ep - cp, ", addr %d", dev->address);
268 *cp = 0;
269 free(vendor, M_USB);
272 char *
273 usbd_devinfo_alloc(usbd_device_handle dev, int showclass)
275 char *devinfop;
277 devinfop = malloc(DEVINFOSIZE, M_TEMP, M_WAITOK);
278 usbd_devinfo(dev, showclass, devinfop, DEVINFOSIZE);
279 return devinfop;
282 void
283 usbd_devinfo_free(char *devinfop)
285 free(devinfop, M_TEMP);
288 /* Delay for a certain number of ms */
289 void
290 usb_delay_ms(usbd_bus_handle bus, u_int ms)
292 /* Wait at least two clock ticks so we know the time has passed. */
293 if (bus->use_polling || cold)
294 delay((ms+1) * 1000);
295 else
296 tsleep(&ms, PRIBIO, "usbdly", (ms*hz+999)/1000 + 1);
299 /* Delay given a device handle. */
300 void
301 usbd_delay_ms(usbd_device_handle dev, u_int ms)
303 usb_delay_ms(dev->bus, ms);
306 usbd_status
307 usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps)
309 usb_device_request_t req;
310 usbd_status err;
311 int n;
313 req.bmRequestType = UT_WRITE_CLASS_OTHER;
314 req.bRequest = UR_SET_FEATURE;
315 USETW(req.wValue, UHF_PORT_RESET);
316 USETW(req.wIndex, port);
317 USETW(req.wLength, 0);
318 err = usbd_do_request(dev, &req, 0);
319 DPRINTFN(1,("usbd_reset_port: port %d reset done, error=%s\n",
320 port, usbd_errstr(err)));
321 if (err)
322 return (err);
323 n = 10;
324 do {
325 /* Wait for device to recover from reset. */
326 usbd_delay_ms(dev, USB_PORT_RESET_DELAY);
327 err = usbd_get_port_status(dev, port, ps);
328 if (err) {
329 DPRINTF(("usbd_reset_port: get status failed %d\n",
330 err));
331 return (err);
333 /* If the device disappeared, just give up. */
334 if (!(UGETW(ps->wPortStatus) & UPS_CURRENT_CONNECT_STATUS))
335 return (USBD_NORMAL_COMPLETION);
336 } while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0);
337 if (n == 0)
338 return (USBD_TIMEOUT);
339 err = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET);
340 #ifdef USB_DEBUG
341 if (err)
342 DPRINTF(("usbd_reset_port: clear port feature failed %d\n",
343 err));
344 #endif
346 /* Wait for the device to recover from reset. */
347 usbd_delay_ms(dev, USB_PORT_RESET_RECOVERY);
348 return (err);
351 usb_interface_descriptor_t *
352 usbd_find_idesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx)
354 char *p = (char *)cd;
355 char *end = p + UGETW(cd->wTotalLength);
356 usb_interface_descriptor_t *d;
357 int curidx, lastidx, curaidx = 0;
359 for (curidx = lastidx = -1; p < end; ) {
360 d = (usb_interface_descriptor_t *)p;
361 DPRINTFN(4,("usbd_find_idesc: idx=%d(%d) altidx=%d(%d) len=%d "
362 "type=%d\n",
363 ifaceidx, curidx, altidx, curaidx,
364 d->bLength, d->bDescriptorType));
365 if (d->bLength == 0) /* bad descriptor */
366 break;
367 p += d->bLength;
368 if (p <= end && d->bDescriptorType == UDESC_INTERFACE) {
369 if (d->bInterfaceNumber != lastidx) {
370 lastidx = d->bInterfaceNumber;
371 curidx++;
372 curaidx = 0;
373 } else
374 curaidx++;
375 if (ifaceidx == curidx && altidx == curaidx)
376 return (d);
379 return (NULL);
382 usb_endpoint_descriptor_t *
383 usbd_find_edesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx,
384 int endptidx)
386 char *p = (char *)cd;
387 char *end = p + UGETW(cd->wTotalLength);
388 usb_interface_descriptor_t *d;
389 usb_endpoint_descriptor_t *e;
390 int curidx;
392 d = usbd_find_idesc(cd, ifaceidx, altidx);
393 if (d == NULL)
394 return (NULL);
395 if (endptidx >= d->bNumEndpoints) /* quick exit */
396 return (NULL);
398 curidx = -1;
399 for (p = (char *)d + d->bLength; p < end; ) {
400 e = (usb_endpoint_descriptor_t *)p;
401 if (e->bLength == 0) /* bad descriptor */
402 break;
403 p += e->bLength;
404 if (p <= end && e->bDescriptorType == UDESC_INTERFACE)
405 return (NULL);
406 if (p <= end && e->bDescriptorType == UDESC_ENDPOINT) {
407 curidx++;
408 if (curidx == endptidx)
409 return (e);
412 return (NULL);
415 usbd_status
416 usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx)
418 usbd_interface_handle ifc = &dev->ifaces[ifaceidx];
419 usb_interface_descriptor_t *idesc;
420 char *p, *end;
421 int endpt, nendpt;
423 DPRINTFN(4,("usbd_fill_iface_data: ifaceidx=%d altidx=%d\n",
424 ifaceidx, altidx));
425 idesc = usbd_find_idesc(dev->cdesc, ifaceidx, altidx);
426 if (idesc == NULL)
427 return (USBD_INVAL);
428 ifc->device = dev;
429 ifc->idesc = idesc;
430 ifc->index = ifaceidx;
431 ifc->altindex = altidx;
432 nendpt = ifc->idesc->bNumEndpoints;
433 DPRINTFN(4,("usbd_fill_iface_data: found idesc nendpt=%d\n", nendpt));
434 if (nendpt != 0) {
435 ifc->endpoints = malloc(nendpt * sizeof(struct usbd_endpoint),
436 M_USB, M_NOWAIT);
437 if (ifc->endpoints == NULL)
438 return (USBD_NOMEM);
439 } else
440 ifc->endpoints = NULL;
441 ifc->priv = NULL;
442 p = (char *)ifc->idesc + ifc->idesc->bLength;
443 end = (char *)dev->cdesc + UGETW(dev->cdesc->wTotalLength);
444 #define ed ((usb_endpoint_descriptor_t *)p)
445 for (endpt = 0; endpt < nendpt; endpt++) {
446 DPRINTFN(10,("usbd_fill_iface_data: endpt=%d\n", endpt));
447 for (; p < end; p += ed->bLength) {
448 DPRINTFN(10,("usbd_fill_iface_data: p=%p end=%p "
449 "len=%d type=%d\n",
450 p, end, ed->bLength, ed->bDescriptorType));
451 if (p + ed->bLength <= end && ed->bLength != 0 &&
452 ed->bDescriptorType == UDESC_ENDPOINT)
453 goto found;
454 if (ed->bLength == 0 ||
455 ed->bDescriptorType == UDESC_INTERFACE)
456 break;
458 /* passed end, or bad desc */
459 printf("usbd_fill_iface_data: bad descriptor(s): %s\n",
460 ed->bLength == 0 ? "0 length" :
461 ed->bDescriptorType == UDESC_INTERFACE ? "iface desc":
462 "out of data");
463 goto bad;
464 found:
465 ifc->endpoints[endpt].edesc = ed;
466 if (dev->speed == USB_SPEED_HIGH) {
467 u_int mps;
468 /* Control and bulk endpoints have max packet limits. */
469 switch (UE_GET_XFERTYPE(ed->bmAttributes)) {
470 case UE_CONTROL:
471 mps = USB_2_MAX_CTRL_PACKET;
472 goto check;
473 case UE_BULK:
474 mps = USB_2_MAX_BULK_PACKET;
475 check:
476 if (UGETW(ed->wMaxPacketSize) != mps) {
477 USETW(ed->wMaxPacketSize, mps);
478 #ifdef DIAGNOSTIC
479 printf("usbd_fill_iface_data: bad max "
480 "packet size\n");
481 #endif
483 break;
484 default:
485 break;
488 ifc->endpoints[endpt].refcnt = 0;
489 p += ed->bLength;
491 #undef ed
492 LIST_INIT(&ifc->pipes);
493 return (USBD_NORMAL_COMPLETION);
495 bad:
496 if (ifc->endpoints != NULL) {
497 free(ifc->endpoints, M_USB);
498 ifc->endpoints = NULL;
500 return (USBD_INVAL);
503 void
504 usbd_free_iface_data(usbd_device_handle dev, int ifcno)
506 usbd_interface_handle ifc = &dev->ifaces[ifcno];
507 if (ifc->endpoints)
508 free(ifc->endpoints, M_USB);
511 Static usbd_status
512 usbd_set_config(usbd_device_handle dev, int conf)
514 usb_device_request_t req;
516 req.bmRequestType = UT_WRITE_DEVICE;
517 req.bRequest = UR_SET_CONFIG;
518 USETW(req.wValue, conf);
519 USETW(req.wIndex, 0);
520 USETW(req.wLength, 0);
521 return (usbd_do_request(dev, &req, 0));
524 usbd_status
525 usbd_set_config_no(usbd_device_handle dev, int no, int msg)
527 int index;
528 usb_config_descriptor_t cd;
529 usbd_status err;
531 if (no == USB_UNCONFIG_NO)
532 return (usbd_set_config_index(dev, USB_UNCONFIG_INDEX, msg));
534 DPRINTFN(5,("usbd_set_config_no: %d\n", no));
535 /* Figure out what config index to use. */
536 for (index = 0; index < dev->ddesc.bNumConfigurations; index++) {
537 err = usbd_get_config_desc(dev, index, &cd);
538 if (err)
539 return (err);
540 if (cd.bConfigurationValue == no)
541 return (usbd_set_config_index(dev, index, msg));
543 return (USBD_INVAL);
546 usbd_status
547 usbd_set_config_index(usbd_device_handle dev, int index, int msg)
549 usb_config_descriptor_t cd, *cdp;
550 usbd_status err;
551 int i, ifcidx, nifc, len, selfpowered, power;
553 DPRINTFN(5,("usbd_set_config_index: dev=%p index=%d\n", dev, index));
555 if (index >= dev->ddesc.bNumConfigurations &&
556 index != USB_UNCONFIG_INDEX) {
557 /* panic? */
558 printf("usbd_set_config_index: illegal index\n");
559 return (USBD_INVAL);
562 /* XXX check that all interfaces are idle */
563 if (dev->config != USB_UNCONFIG_NO) {
564 DPRINTF(("usbd_set_config_index: free old config\n"));
565 /* Free all configuration data structures. */
566 nifc = dev->cdesc->bNumInterface;
567 for (ifcidx = 0; ifcidx < nifc; ifcidx++)
568 usbd_free_iface_data(dev, ifcidx);
569 free(dev->ifaces, M_USB);
570 free(dev->cdesc, M_USB);
571 dev->ifaces = NULL;
572 dev->cdesc = NULL;
573 dev->config = USB_UNCONFIG_NO;
576 if (index == USB_UNCONFIG_INDEX) {
577 /* We are unconfiguring the device, so leave unallocated. */
578 DPRINTF(("usbd_set_config_index: set config 0\n"));
579 err = usbd_set_config(dev, USB_UNCONFIG_NO);
580 if (err) {
581 DPRINTF(("usbd_set_config_index: setting config=0 "
582 "failed, error=%s\n", usbd_errstr(err)));
584 return (err);
587 /* Get the short descriptor. */
588 err = usbd_get_config_desc(dev, index, &cd);
589 if (err)
590 return (err);
591 len = UGETW(cd.wTotalLength);
592 cdp = malloc(len, M_USB, M_NOWAIT);
593 if (cdp == NULL)
594 return (USBD_NOMEM);
596 /* Get the full descriptor. Try a few times for slow devices. */
597 for (i = 0; i < 3; i++) {
598 err = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp);
599 if (!err)
600 break;
601 usbd_delay_ms(dev, 200);
603 if (err)
604 goto bad;
606 if (cdp->bDescriptorType != UDESC_CONFIG) {
607 DPRINTFN(-1,("usbd_set_config_index: bad desc %d\n",
608 cdp->bDescriptorType));
609 err = USBD_INVAL;
610 goto bad;
614 * Figure out if the device is self or bus powered.
616 #if 0 /* XXX various devices don't report the power state correctly */
617 selfpowered = 0;
618 err = usbd_get_device_status(dev, &ds);
619 if (!err && (UGETW(ds.wStatus) & UDS_SELF_POWERED))
620 selfpowered = 1;
621 #endif
623 * Use the power state in the configuration we are going
624 * to set. This doesn't necessarily reflect the actual
625 * power state of the device; the driver can control this
626 * by choosing the appropriate configuration.
628 selfpowered = !!(cdp->bmAttributes & UC_SELF_POWERED);
630 DPRINTF(("usbd_set_config_index: (addr %d) cno=%d attr=0x%02x, "
631 "selfpowered=%d, power=%d\n",
632 cdp->bConfigurationValue, dev->address, cdp->bmAttributes,
633 selfpowered, cdp->bMaxPower * 2));
635 /* Check if we have enough power. */
636 #if 0 /* this is a no-op, see above */
637 if ((cdp->bmAttributes & UC_SELF_POWERED) && !selfpowered) {
638 if (msg)
639 printf("%s: device addr %d (config %d): "
640 "can't set self powered configuration\n",
641 device_xname(dev->bus->bdev), dev->address,
642 cdp->bConfigurationValue);
643 err = USBD_NO_POWER;
644 goto bad;
646 #endif
647 #ifdef USB_DEBUG
648 if (dev->powersrc == NULL) {
649 DPRINTF(("usbd_set_config_index: No power source?\n"));
650 err = USBD_IOERROR;
651 goto bad;
653 #endif
654 power = cdp->bMaxPower * 2;
655 if (power > dev->powersrc->power) {
656 DPRINTF(("power exceeded %d %d\n", power,dev->powersrc->power));
657 /* XXX print nicer message. */
658 if (msg)
659 printf("%s: device addr %d (config %d) exceeds power "
660 "budget, %d mA > %d mA\n",
661 device_xname(dev->bus->usbctl), dev->address,
662 cdp->bConfigurationValue,
663 power, dev->powersrc->power);
664 err = USBD_NO_POWER;
665 goto bad;
667 dev->power = power;
668 dev->self_powered = selfpowered;
670 /* Set the actual configuration value. */
671 DPRINTF(("usbd_set_config_index: set config %d\n",
672 cdp->bConfigurationValue));
673 err = usbd_set_config(dev, cdp->bConfigurationValue);
674 if (err) {
675 DPRINTF(("usbd_set_config_index: setting config=%d failed, "
676 "error=%s\n",
677 cdp->bConfigurationValue, usbd_errstr(err)));
678 goto bad;
681 /* Allocate and fill interface data. */
682 nifc = cdp->bNumInterface;
683 dev->ifaces = malloc(nifc * sizeof(struct usbd_interface),
684 M_USB, M_NOWAIT);
685 if (dev->ifaces == NULL) {
686 err = USBD_NOMEM;
687 goto bad;
689 DPRINTFN(5,("usbd_set_config_index: dev=%p cdesc=%p\n", dev, cdp));
690 dev->cdesc = cdp;
691 dev->config = cdp->bConfigurationValue;
692 for (ifcidx = 0; ifcidx < nifc; ifcidx++) {
693 err = usbd_fill_iface_data(dev, ifcidx, 0);
694 if (err) {
695 while (--ifcidx >= 0)
696 usbd_free_iface_data(dev, ifcidx);
697 goto bad;
701 return (USBD_NORMAL_COMPLETION);
703 bad:
704 free(cdp, M_USB);
705 return (err);
708 /* XXX add function for alternate settings */
710 usbd_status
711 usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface,
712 struct usbd_endpoint *ep, int ival, usbd_pipe_handle *pipe)
714 usbd_pipe_handle p;
715 usbd_status err;
717 DPRINTFN(1,("usbd_setup_pipe: dev=%p iface=%p ep=%p pipe=%p\n",
718 dev, iface, ep, pipe));
719 p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT);
720 if (p == NULL)
721 return (USBD_NOMEM);
722 p->device = dev;
723 p->iface = iface;
724 p->endpoint = ep;
725 ep->refcnt++;
726 p->refcnt = 1;
727 p->intrxfer = 0;
728 p->running = 0;
729 p->aborting = 0;
730 p->repeat = 0;
731 p->interval = ival;
732 SIMPLEQ_INIT(&p->queue);
733 err = dev->bus->methods->open_pipe(p);
734 if (err) {
735 DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error="
736 "%s\n",
737 ep->edesc->bEndpointAddress, usbd_errstr(err)));
738 free(p, M_USB);
739 return (err);
741 *pipe = p;
742 return (USBD_NORMAL_COMPLETION);
745 /* Abort the device control pipe. */
746 void
747 usbd_kill_pipe(usbd_pipe_handle pipe)
749 usbd_abort_pipe(pipe);
750 pipe->methods->close(pipe);
751 pipe->endpoint->refcnt--;
752 free(pipe, M_USB);
756 usbd_getnewaddr(usbd_bus_handle bus)
758 int addr;
760 for (addr = 1; addr < USB_MAX_DEVICES; addr++)
761 if (bus->devices[addr] == 0)
762 return (addr);
763 return (-1);
766 usbd_status
767 usbd_attach_roothub(device_t parent, usbd_device_handle dev)
769 struct usb_attach_arg uaa;
770 usb_device_descriptor_t *dd = &dev->ddesc;
771 device_t dv;
773 uaa.device = dev;
774 uaa.usegeneric = 0;
775 uaa.port = 0;
776 uaa.vendor = UGETW(dd->idVendor);
777 uaa.product = UGETW(dd->idProduct);
778 uaa.release = UGETW(dd->bcdDevice);
779 uaa.class = dd->bDeviceClass;
780 uaa.subclass = dd->bDeviceSubClass;
781 uaa.proto = dd->bDeviceProtocol;
783 dv = config_found_ia(parent, "usbroothubif", &uaa, 0);
784 if (dv) {
785 dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT);
786 if (dev->subdevs == NULL)
787 return (USBD_NOMEM);
788 dev->subdevs[0] = dv;
789 dev->subdevlen = 1;
791 return (USBD_NORMAL_COMPLETION);
794 static usbd_status
795 usbd_attachwholedevice(device_t parent, usbd_device_handle dev, int port,
796 int usegeneric)
798 struct usb_attach_arg uaa;
799 usb_device_descriptor_t *dd = &dev->ddesc;
800 device_t dv;
801 int dlocs[USBDEVIFCF_NLOCS];
803 uaa.device = dev;
804 uaa.usegeneric = usegeneric;
805 uaa.port = port;
806 uaa.vendor = UGETW(dd->idVendor);
807 uaa.product = UGETW(dd->idProduct);
808 uaa.release = UGETW(dd->bcdDevice);
809 uaa.class = dd->bDeviceClass;
810 uaa.subclass = dd->bDeviceSubClass;
811 uaa.proto = dd->bDeviceProtocol;
813 dlocs[USBDEVIFCF_PORT] = uaa.port;
814 dlocs[USBDEVIFCF_VENDOR] = uaa.vendor;
815 dlocs[USBDEVIFCF_PRODUCT] = uaa.product;
816 dlocs[USBDEVIFCF_RELEASE] = uaa.release;
817 /* the rest is historical ballast */
818 dlocs[USBDEVIFCF_CONFIGURATION] = -1;
819 dlocs[USBDEVIFCF_INTERFACE] = -1;
821 dv = config_found_sm_loc(parent, "usbdevif", dlocs, &uaa, usbd_print,
822 config_stdsubmatch);
823 if (dv) {
824 dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT);
825 if (dev->subdevs == NULL)
826 return (USBD_NOMEM);
827 dev->subdevs[0] = dv;
828 dev->subdevlen = 1;
829 dev->nifaces_claimed = 1; /* XXX */
831 return (USBD_NORMAL_COMPLETION);
834 static usbd_status
835 usbd_attachinterfaces(device_t parent, usbd_device_handle dev,
836 int port, const int *locators)
838 struct usbif_attach_arg uiaa;
839 int ilocs[USBIFIFCF_NLOCS];
840 usb_device_descriptor_t *dd = &dev->ddesc;
841 int nifaces;
842 usbd_interface_handle *ifaces;
843 int i, j, loc;
844 device_t dv;
846 nifaces = dev->cdesc->bNumInterface;
847 ifaces = malloc(nifaces * sizeof(*ifaces), M_USB, M_NOWAIT|M_ZERO);
848 if (!ifaces)
849 return (USBD_NOMEM);
850 for (i = 0; i < nifaces; i++)
851 if (!dev->subdevs[i])
852 ifaces[i] = &dev->ifaces[i];
854 uiaa.device = dev;
855 uiaa.port = port;
856 uiaa.vendor = UGETW(dd->idVendor);
857 uiaa.product = UGETW(dd->idProduct);
858 uiaa.release = UGETW(dd->bcdDevice);
859 uiaa.configno = dev->cdesc->bConfigurationValue;
860 uiaa.ifaces = ifaces;
861 uiaa.nifaces = nifaces;
862 ilocs[USBIFIFCF_PORT] = uiaa.port;
863 ilocs[USBIFIFCF_VENDOR] = uiaa.vendor;
864 ilocs[USBIFIFCF_PRODUCT] = uiaa.product;
865 ilocs[USBIFIFCF_RELEASE] = uiaa.release;
866 ilocs[USBIFIFCF_CONFIGURATION] = uiaa.configno;
868 for (i = 0; i < nifaces; i++) {
869 if (!ifaces[i])
870 continue; /* interface already claimed */
871 uiaa.iface = ifaces[i];
872 uiaa.class = ifaces[i]->idesc->bInterfaceClass;
873 uiaa.subclass = ifaces[i]->idesc->bInterfaceSubClass;
874 uiaa.proto = ifaces[i]->idesc->bInterfaceProtocol;
875 uiaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber;
876 ilocs[USBIFIFCF_INTERFACE] = uiaa.ifaceno;
877 if (locators != NULL) {
878 loc = locators[USBIFIFCF_CONFIGURATION];
879 if (loc != USBIFIFCF_CONFIGURATION_DEFAULT &&
880 loc != uiaa.configno)
881 continue;
882 loc = locators[USBIFIFCF_INTERFACE];
883 if (loc != USBIFIFCF_INTERFACE && loc != uiaa.ifaceno)
884 continue;
886 dv = config_found_sm_loc(parent, "usbifif", ilocs, &uiaa,
887 usbd_ifprint, config_stdsubmatch);
888 if (!dv)
889 continue;
890 ifaces[i] = 0; /* claim */
891 /* account for ifaces claimed by the driver behind our back */
892 for (j = 0; j < nifaces; j++) {
893 if (!ifaces[j] && !dev->subdevs[j]) {
894 dev->subdevs[j] = dv;
895 dev->nifaces_claimed++;
900 free(ifaces, M_USB);
901 return (USBD_NORMAL_COMPLETION);
904 usbd_status
905 usbd_probe_and_attach(device_t parent, usbd_device_handle dev,
906 int port, int addr)
908 usb_device_descriptor_t *dd = &dev->ddesc;
909 int confi, nifaces;
910 usbd_status err;
912 /* First try with device specific drivers. */
913 DPRINTF(("usbd_probe_and_attach: trying device specific drivers\n"));
914 err = usbd_attachwholedevice(parent, dev, port, 0);
915 if (dev->nifaces_claimed || err)
916 return (err);
917 DPRINTF(("usbd_probe_and_attach: no device specific driver found\n"));
919 DPRINTF(("usbd_probe_and_attach: looping over %d configurations\n",
920 dd->bNumConfigurations));
921 for (confi = 0; confi < dd->bNumConfigurations; confi++) {
922 DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n",
923 confi));
924 err = usbd_set_config_index(dev, confi, 1);
925 if (err) {
926 #ifdef USB_DEBUG
927 DPRINTF(("%s: port %d, set config at addr %d failed, "
928 "error=%s\n", device_xname(parent), port,
929 addr, usbd_errstr(err)));
930 #else
931 printf("%s: port %d, set config at addr %d failed\n",
932 device_xname(parent), port, addr);
933 #endif
934 return (err);
936 nifaces = dev->cdesc->bNumInterface;
937 dev->subdevs = malloc(nifaces * sizeof(device_t), M_USB,
938 M_NOWAIT|M_ZERO);
939 if (dev->subdevs == NULL)
940 return (USBD_NOMEM);
941 dev->subdevlen = nifaces;
943 err = usbd_attachinterfaces(parent, dev, port, NULL);
945 if (!dev->nifaces_claimed) {
946 free(dev->subdevs, M_USB);
947 dev->subdevs = 0;
948 dev->subdevlen = 0;
950 if (dev->nifaces_claimed || err)
951 return (err);
953 /* No interfaces were attached in any of the configurations. */
955 if (dd->bNumConfigurations > 1) /* don't change if only 1 config */
956 usbd_set_config_index(dev, 0, 0);
958 DPRINTF(("usbd_probe_and_attach: no interface drivers found\n"));
960 /* Finally try the generic driver. */
961 err = usbd_attachwholedevice(parent, dev, port, 1);
964 * The generic attach failed, but leave the device as it is.
965 * We just did not find any drivers, that's all. The device is
966 * fully operational and not harming anyone.
968 DPRINTF(("usbd_probe_and_attach: generic attach failed\n"));
969 return (USBD_NORMAL_COMPLETION);
973 * Called from uhub_rescan(). usbd_new_device() for the target dev must be
974 * called before calling this.
976 usbd_status
977 usbd_reattach_device(device_t parent, usbd_device_handle dev,
978 int port, const int *locators)
980 int i, loc;
982 if (locators != NULL) {
983 loc = locators[USBIFIFCF_PORT];
984 if (loc != USBIFIFCF_PORT_DEFAULT && loc != port)
985 return USBD_NORMAL_COMPLETION;
986 loc = locators[USBIFIFCF_VENDOR];
987 if (loc != USBIFIFCF_VENDOR_DEFAULT &&
988 loc != UGETW(dev->ddesc.idVendor))
989 return USBD_NORMAL_COMPLETION;
990 loc = locators[USBIFIFCF_PRODUCT];
991 if (loc != USBIFIFCF_PRODUCT_DEFAULT &&
992 loc != UGETW(dev->ddesc.idProduct))
993 return USBD_NORMAL_COMPLETION;
994 loc = locators[USBIFIFCF_RELEASE];
995 if (loc != USBIFIFCF_RELEASE_DEFAULT &&
996 loc != UGETW(dev->ddesc.bcdDevice))
997 return USBD_NORMAL_COMPLETION;
999 if (dev->subdevlen == 0) {
1000 /* XXX: check USBIFIFCF_CONFIGURATION and
1001 * USBIFIFCF_INTERFACE too */
1002 return usbd_probe_and_attach(parent, dev, port, dev->address);
1003 } else if (dev->subdevlen != dev->cdesc->bNumInterface) {
1004 /* device-specific or generic driver is already attached. */
1005 return USBD_NORMAL_COMPLETION;
1007 /* Does the device have unconfigured interfaces? */
1008 for (i = 0; i < dev->subdevlen; i++) {
1009 if (dev->subdevs[i] == NULL) {
1010 break;
1013 if (i >= dev->subdevlen)
1014 return USBD_NORMAL_COMPLETION;
1015 return usbd_attachinterfaces(parent, dev, port, locators);
1019 * Called when a new device has been put in the powered state,
1020 * but not yet in the addressed state.
1021 * Get initial descriptor, set the address, get full descriptor,
1022 * and attach a driver.
1024 usbd_status
1025 usbd_new_device(device_t parent, usbd_bus_handle bus, int depth,
1026 int speed, int port, struct usbd_port *up)
1028 usbd_device_handle dev, adev;
1029 struct usbd_device *hub;
1030 usb_device_descriptor_t *dd;
1031 usb_port_status_t ps;
1032 usbd_status err;
1033 int addr;
1034 int i;
1035 int p;
1037 DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n",
1038 bus, port, depth, speed));
1039 addr = usbd_getnewaddr(bus);
1040 if (addr < 0) {
1041 printf("%s: No free USB addresses, new device ignored.\n",
1042 device_xname(bus->usbctl));
1043 return (USBD_NO_ADDR);
1046 dev = malloc(sizeof *dev, M_USB, M_NOWAIT|M_ZERO);
1047 if (dev == NULL)
1048 return (USBD_NOMEM);
1050 dev->bus = bus;
1052 /* Set up default endpoint handle. */
1053 dev->def_ep.edesc = &dev->def_ep_desc;
1055 /* Set up default endpoint descriptor. */
1056 dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE;
1057 dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT;
1058 dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
1059 dev->def_ep_desc.bmAttributes = UE_CONTROL;
1060 if (speed == USB_SPEED_HIGH)
1061 USETW(dev->def_ep_desc.wMaxPacketSize, 64);
1062 else
1063 USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET);
1064 dev->def_ep_desc.bInterval = 0;
1066 dev->quirks = &usbd_no_quirk;
1067 dev->address = USB_START_ADDR;
1068 dev->ddesc.bMaxPacketSize = 0;
1069 dev->depth = depth;
1070 dev->powersrc = up;
1071 dev->myhub = up->parent;
1073 up->device = dev;
1075 /* Locate port on upstream high speed hub */
1076 for (adev = dev, hub = up->parent;
1077 hub != NULL && hub->speed != USB_SPEED_HIGH;
1078 adev = hub, hub = hub->myhub)
1080 if (hub) {
1081 for (p = 0; p < hub->hub->hubdesc.bNbrPorts; p++) {
1082 if (hub->hub->ports[p].device == adev) {
1083 dev->myhsport = &hub->hub->ports[p];
1084 goto found;
1087 panic("usbd_new_device: cannot find HS port\n");
1088 found:
1089 DPRINTFN(1,("usbd_new_device: high speed port %d\n", p));
1090 } else {
1091 dev->myhsport = NULL;
1093 dev->speed = speed;
1094 dev->langid = USBD_NOLANG;
1095 dev->cookie.cookie = ++usb_cookie_no;
1097 /* Establish the default pipe. */
1098 err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
1099 &dev->default_pipe);
1100 if (err) {
1101 usbd_remove_device(dev, up);
1102 return (err);
1105 dd = &dev->ddesc;
1106 /* Try a few times in case the device is slow (i.e. outside specs.) */
1107 for (i = 0; i < 10; i++) {
1108 /* Get the first 8 bytes of the device descriptor. */
1109 err = usbd_get_desc(dev, UDESC_DEVICE, 0,
1110 (speed == USB_SPEED_HIGH) ? USB_DEVICE_DESCRIPTOR_SIZE
1111 : USB_MAX_IPACKET,
1112 dd);
1114 if (!err)
1115 break;
1116 usbd_delay_ms(dev, 200);
1117 if ((i & 3) == 3)
1118 usbd_reset_port(up->parent, port, &ps);
1120 if (err) {
1121 DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc "
1122 "failed\n", addr));
1123 usbd_remove_device(dev, up);
1124 return (err);
1127 if (speed == USB_SPEED_HIGH) {
1128 /* Max packet size must be 64 (sec 5.5.3). */
1129 if (dd->bMaxPacketSize != USB_2_MAX_CTRL_PACKET) {
1130 #ifdef DIAGNOSTIC
1131 printf("usbd_new_device: addr=%d bad max packet "
1132 "size=%d. adjusting to %d.\n",
1133 addr, dd->bMaxPacketSize, USB_2_MAX_CTRL_PACKET);
1134 #endif
1135 dd->bMaxPacketSize = USB_2_MAX_CTRL_PACKET;
1139 DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, "
1140 "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n",
1141 addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass,
1142 dd->bDeviceProtocol, dd->bMaxPacketSize, dd->bLength,
1143 dev->speed));
1145 if (dd->bDescriptorType != UDESC_DEVICE) {
1146 /* Illegal device descriptor */
1147 DPRINTFN(-1,("usbd_new_device: illegal descriptor %d\n",
1148 dd->bDescriptorType));
1149 usbd_remove_device(dev, up);
1150 return (USBD_INVAL);
1153 if (dd->bLength < USB_DEVICE_DESCRIPTOR_SIZE) {
1154 DPRINTFN(-1,("usbd_new_device: bad length %d\n", dd->bLength));
1155 usbd_remove_device(dev, up);
1156 return (USBD_INVAL);
1159 USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize);
1161 err = usbd_reload_device_desc(dev);
1162 if (err) {
1163 DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc "
1164 "failed\n", addr));
1165 usbd_remove_device(dev, up);
1166 return (err);
1169 /* Set the address */
1170 DPRINTFN(5, ("usbd_new_device: setting device address=%d\n", addr));
1171 err = usbd_set_address(dev, addr);
1172 if (err) {
1173 DPRINTFN(-1, ("usbd_new_device: set address %d failed\n", addr));
1174 err = USBD_SET_ADDR_FAILED;
1175 usbd_remove_device(dev, up);
1176 return err;
1179 /* Allow device time to set new address */
1180 usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE);
1181 dev->address = addr; /* new device address now */
1182 bus->devices[addr] = dev;
1184 /* Re-establish the default pipe with the new address. */
1185 usbd_kill_pipe(dev->default_pipe);
1186 err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
1187 &dev->default_pipe);
1188 if (err) {
1189 DPRINTFN(-1, ("usbd_new_device: setup default pipe failed\n"));
1190 usbd_remove_device(dev, up);
1191 return err;
1194 /* Assume 100mA bus powered for now. Changed when configured. */
1195 dev->power = USB_MIN_POWER;
1196 dev->self_powered = 0;
1198 DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n",
1199 addr, dev, parent));
1201 usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev);
1203 if (port == 0) { /* root hub */
1204 KASSERT(addr == 1);
1205 usbd_attach_roothub(parent, dev);
1206 return (USBD_NORMAL_COMPLETION);
1209 err = usbd_probe_and_attach(parent, dev, port, addr);
1210 if (err) {
1211 usbd_remove_device(dev, up);
1212 return (err);
1215 return (USBD_NORMAL_COMPLETION);
1218 usbd_status
1219 usbd_reload_device_desc(usbd_device_handle dev)
1221 usbd_status err;
1223 /* Get the full device descriptor. */
1224 err = usbd_get_device_desc(dev, &dev->ddesc);
1225 if (err)
1226 return (err);
1228 /* Figure out what's wrong with this device. */
1229 dev->quirks = usbd_find_quirk(&dev->ddesc);
1231 return (USBD_NORMAL_COMPLETION);
1234 void
1235 usbd_remove_device(usbd_device_handle dev, struct usbd_port *up)
1237 DPRINTF(("usbd_remove_device: %p\n", dev));
1239 if (dev->default_pipe != NULL)
1240 usbd_kill_pipe(dev->default_pipe);
1241 up->device = NULL;
1242 dev->bus->devices[dev->address] = NULL;
1244 free(dev, M_USB);
1248 usbd_print(void *aux, const char *pnp)
1250 struct usb_attach_arg *uaa = aux;
1252 DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device));
1253 if (pnp) {
1254 #define USB_DEVINFO 1024
1255 char *devinfo;
1256 if (!uaa->usegeneric)
1257 return (QUIET);
1258 devinfo = malloc(USB_DEVINFO, M_TEMP, M_WAITOK);
1259 usbd_devinfo(uaa->device, 1, devinfo, USB_DEVINFO);
1260 aprint_normal("%s, %s", devinfo, pnp);
1261 free(devinfo, M_TEMP);
1263 aprint_normal(" port %d", uaa->port);
1264 #if 0
1266 * It gets very crowded with these locators on the attach line.
1267 * They are not really needed since they are printed in the clear
1268 * by each driver.
1270 if (uaa->vendor != UHUB_UNK_VENDOR)
1271 aprint_normal(" vendor 0x%04x", uaa->vendor);
1272 if (uaa->product != UHUB_UNK_PRODUCT)
1273 aprint_normal(" product 0x%04x", uaa->product);
1274 if (uaa->release != UHUB_UNK_RELEASE)
1275 aprint_normal(" release 0x%04x", uaa->release);
1276 #endif
1277 return (UNCONF);
1281 usbd_ifprint(void *aux, const char *pnp)
1283 struct usbif_attach_arg *uaa = aux;
1285 DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device));
1286 if (pnp)
1287 return (QUIET);
1288 aprint_normal(" port %d", uaa->port);
1289 aprint_normal(" configuration %d", uaa->configno);
1290 aprint_normal(" interface %d", uaa->ifaceno);
1291 #if 0
1293 * It gets very crowded with these locators on the attach line.
1294 * They are not really needed since they are printed in the clear
1295 * by each driver.
1297 if (uaa->vendor != UHUB_UNK_VENDOR)
1298 aprint_normal(" vendor 0x%04x", uaa->vendor);
1299 if (uaa->product != UHUB_UNK_PRODUCT)
1300 aprint_normal(" product 0x%04x", uaa->product);
1301 if (uaa->release != UHUB_UNK_RELEASE)
1302 aprint_normal(" release 0x%04x", uaa->release);
1303 #endif
1304 return (UNCONF);
1307 void
1308 usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di,
1309 int usedev)
1311 struct usbd_port *p;
1312 int i, j, err, s;
1314 di->udi_bus = device_unit(dev->bus->usbctl);
1315 di->udi_addr = dev->address;
1316 di->udi_cookie = dev->cookie;
1317 usbd_devinfo_vp(dev, di->udi_vendor, di->udi_product, usedev, 1);
1318 usbd_printBCD(di->udi_release, sizeof(di->udi_release),
1319 UGETW(dev->ddesc.bcdDevice));
1320 di->udi_serial[0] = 0;
1321 if (usedev)
1322 (void)usbd_get_string(dev, dev->ddesc.iSerialNumber,
1323 di->udi_serial);
1324 di->udi_vendorNo = UGETW(dev->ddesc.idVendor);
1325 di->udi_productNo = UGETW(dev->ddesc.idProduct);
1326 di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice);
1327 di->udi_class = dev->ddesc.bDeviceClass;
1328 di->udi_subclass = dev->ddesc.bDeviceSubClass;
1329 di->udi_protocol = dev->ddesc.bDeviceProtocol;
1330 di->udi_config = dev->config;
1331 di->udi_power = dev->self_powered ? 0 : dev->power;
1332 di->udi_speed = dev->speed;
1334 if (dev->subdevlen > 0) {
1335 for (i = 0, j = 0; i < dev->subdevlen &&
1336 j < USB_MAX_DEVNAMES; i++) {
1337 if (!dev->subdevs[i])
1338 continue;
1339 strncpy(di->udi_devnames[j],
1340 device_xname(dev->subdevs[i]), USB_MAX_DEVNAMELEN);
1341 di->udi_devnames[j][USB_MAX_DEVNAMELEN-1] = '\0';
1342 j++;
1344 } else {
1345 j = 0;
1347 for (/* j is set */; j < USB_MAX_DEVNAMES; j++)
1348 di->udi_devnames[j][0] = 0; /* empty */
1350 if (dev->hub) {
1351 for (i = 0;
1352 i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) &&
1353 i < dev->hub->hubdesc.bNbrPorts;
1354 i++) {
1355 p = &dev->hub->ports[i];
1356 if (p->device)
1357 err = p->device->address;
1358 else {
1359 s = UGETW(p->status.wPortStatus);
1360 if (s & UPS_PORT_ENABLED)
1361 err = USB_PORT_ENABLED;
1362 else if (s & UPS_SUSPEND)
1363 err = USB_PORT_SUSPENDED;
1364 else if (s & UPS_PORT_POWER)
1365 err = USB_PORT_POWERED;
1366 else
1367 err = USB_PORT_DISABLED;
1369 di->udi_ports[i] = err;
1371 di->udi_nports = dev->hub->hubdesc.bNbrPorts;
1372 } else
1373 di->udi_nports = 0;
1376 #ifdef COMPAT_30
1377 void
1378 usbd_fill_deviceinfo_old(usbd_device_handle dev, struct usb_device_info_old *di,
1379 int usedev)
1381 struct usbd_port *p;
1382 int i, j, err, s;
1384 di->udi_bus = device_unit(dev->bus->usbctl);
1385 di->udi_addr = dev->address;
1386 di->udi_cookie = dev->cookie;
1387 usbd_devinfo_vp(dev, di->udi_vendor, di->udi_product, usedev, 0);
1388 usbd_printBCD(di->udi_release, sizeof(di->udi_release),
1389 UGETW(dev->ddesc.bcdDevice));
1390 di->udi_vendorNo = UGETW(dev->ddesc.idVendor);
1391 di->udi_productNo = UGETW(dev->ddesc.idProduct);
1392 di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice);
1393 di->udi_class = dev->ddesc.bDeviceClass;
1394 di->udi_subclass = dev->ddesc.bDeviceSubClass;
1395 di->udi_protocol = dev->ddesc.bDeviceProtocol;
1396 di->udi_config = dev->config;
1397 di->udi_power = dev->self_powered ? 0 : dev->power;
1398 di->udi_speed = dev->speed;
1400 if (dev->subdevlen > 0) {
1401 for (i = 0, j = 0; i < dev->subdevlen &&
1402 j < USB_MAX_DEVNAMES; i++) {
1403 if (!dev->subdevs[i])
1404 continue;
1405 strncpy(di->udi_devnames[j],
1406 device_xname(dev->subdevs[i]), USB_MAX_DEVNAMELEN);
1407 di->udi_devnames[j][USB_MAX_DEVNAMELEN-1] = '\0';
1408 j++;
1410 } else {
1411 j = 0;
1413 for (/* j is set */; j < USB_MAX_DEVNAMES; j++)
1414 di->udi_devnames[j][0] = 0; /* empty */
1416 if (dev->hub) {
1417 for (i = 0;
1418 i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) &&
1419 i < dev->hub->hubdesc.bNbrPorts;
1420 i++) {
1421 p = &dev->hub->ports[i];
1422 if (p->device)
1423 err = p->device->address;
1424 else {
1425 s = UGETW(p->status.wPortStatus);
1426 if (s & UPS_PORT_ENABLED)
1427 err = USB_PORT_ENABLED;
1428 else if (s & UPS_SUSPEND)
1429 err = USB_PORT_SUSPENDED;
1430 else if (s & UPS_PORT_POWER)
1431 err = USB_PORT_POWERED;
1432 else
1433 err = USB_PORT_DISABLED;
1435 di->udi_ports[i] = err;
1437 di->udi_nports = dev->hub->hubdesc.bNbrPorts;
1438 } else
1439 di->udi_nports = 0;
1441 #endif
1444 void
1445 usb_free_device(usbd_device_handle dev)
1447 int ifcidx, nifc;
1449 if (dev->default_pipe != NULL)
1450 usbd_kill_pipe(dev->default_pipe);
1451 if (dev->ifaces != NULL) {
1452 nifc = dev->cdesc->bNumInterface;
1453 for (ifcidx = 0; ifcidx < nifc; ifcidx++)
1454 usbd_free_iface_data(dev, ifcidx);
1455 free(dev->ifaces, M_USB);
1457 if (dev->cdesc != NULL)
1458 free(dev->cdesc, M_USB);
1459 if (dev->subdevlen > 0) {
1460 free(dev->subdevs, M_USB);
1461 dev->subdevlen = 0;
1463 free(dev, M_USB);
1467 * The general mechanism for detaching drivers works as follows: Each
1468 * driver is responsible for maintaining a reference count on the
1469 * number of outstanding references to its softc (e.g. from
1470 * processing hanging in a read or write). The detach method of the
1471 * driver decrements this counter and flags in the softc that the
1472 * driver is dying and then wakes any sleepers. It then sleeps on the
1473 * softc. Each place that can sleep must maintain the reference
1474 * count. When the reference count drops to -1 (0 is the normal value
1475 * of the reference count) the a wakeup on the softc is performed
1476 * signaling to the detach waiter that all references are gone.
1480 * Called from process context when we discover that a port has
1481 * been disconnected.
1484 usb_disconnect_port(struct usbd_port *up, device_t parent, int flags)
1486 usbd_device_handle dev = up->device;
1487 device_t subdev;
1488 char subdevname[16];
1489 const char *hubname = device_xname(parent);
1490 int i, rc;
1492 DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
1493 up, dev, up->portno));
1495 if (dev == NULL) {
1496 #ifdef DIAGNOSTIC
1497 printf("usb_disconnect_port: no device\n");
1498 #endif
1499 return 0;
1502 if (dev->subdevlen > 0) {
1503 DPRINTFN(3,("usb_disconnect_port: disconnect subdevs\n"));
1504 for (i = 0; i < dev->subdevlen; i++) {
1505 if ((subdev = dev->subdevs[i]) == NULL)
1506 continue;
1507 strlcpy(subdevname, device_xname(subdev),
1508 sizeof(subdevname));
1509 if ((rc = config_detach(subdev, flags)) != 0)
1510 return rc;
1511 printf("%s: at %s", subdevname, hubname);
1512 if (up->portno != 0)
1513 printf(" port %d", up->portno);
1514 printf(" (addr %d) disconnected\n", dev->address);
1516 KASSERT(!dev->nifaces_claimed);
1519 usbd_add_dev_event(USB_EVENT_DEVICE_DETACH, dev);
1520 dev->bus->devices[dev->address] = NULL;
1521 up->device = NULL;
1522 usb_free_device(dev);
1523 return 0;