usb_subr.c revision 1.11 1 /* $NetBSD: usb_subr.c,v 1.11 1998/12/02 22:57:08 augustss Exp $ */
2
3 /*
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (augustss (at) carlstedt.se) at
9 * Carlstedt Research & Technology.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
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/proc.h>
46 #include <sys/select.h>
47
48 #include <dev/usb/usb.h>
49
50 #include <dev/usb/usbdi.h>
51 #include <dev/usb/usbdi_util.h>
52 #include <dev/usb/usbdivar.h>
53 #include <dev/usb/usbdevs.h>
54 #include <dev/usb/usb_quirks.h>
55
56 #include "opt_usbverbose.h"
57
58 #ifdef USB_DEBUG
59 #define DPRINTF(x) if (usbdebug) printf x
60 #define DPRINTFN(n,x) if (usbdebug>(n)) printf x
61 extern int usbdebug;
62 #else
63 #define DPRINTF(x)
64 #define DPRINTFN(n,x)
65 #endif
66
67 static usbd_status usbd_set_config __P((usbd_device_handle, int));
68 char *usbd_get_string __P((usbd_device_handle, int, char *));
69 usbd_status usbd_get_desc __P((usbd_device_handle dev, int type,
70 int index, int len, void *desc));
71 int usbd_getnewaddr __P((usbd_bus_handle bus));
72 int usbd_print __P((void *aux, const char *pnp));
73 int usbd_submatch __P((struct device *, struct cfdata *cf, void *));
74 usb_interface_descriptor_t *usbd_find_idesc __P((usb_config_descriptor_t *cd,
75 int ino, int ano));
76 usbd_status usbd_fill_iface_data __P((usbd_device_handle dev, int i, int a));
77 void usbd_free_iface_data __P((usbd_device_handle dev, int ifcno));
78 void usbd_kill_pipe __P((usbd_pipe_handle));
79
80 #ifdef USBVERBOSE
81 typedef u_int16_t usb_vendor_id_t;
82 typedef u_int16_t usb_product_id_t;
83
84 /*
85 * Descriptions of of known vendors and devices ("products").
86 */
87 struct usb_knowndev {
88 usb_vendor_id_t vendor;
89 usb_product_id_t product;
90 int flags;
91 char *vendorname, *productname;
92 };
93 #define USB_KNOWNDEV_NOPROD 0x01 /* match on vendor only */
94
95 #include <dev/usb/usbdevs_data.h>
96 #endif /* USBVERBOSE */
97
98
99 char *
100 usbd_get_string(dev, si, buf)
101 usbd_device_handle dev;
102 int si;
103 char *buf;
104 {
105 int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE;
106 usb_device_request_t req;
107 usb_string_descriptor_t us;
108 char *s;
109 int i, n;
110 u_int16_t c;
111 usbd_status r;
112
113 if (si == 0)
114 return (0);
115 if (dev->quirks->uq_flags & UQ_NO_STRINGS)
116 return (0);
117 req.bmRequestType = UT_READ_DEVICE;
118 req.bRequest = UR_GET_DESCRIPTOR;
119 USETW2(req.wValue, UDESC_STRING, si);
120 USETW(req.wIndex, 0);
121 USETW(req.wLength, 1); /* only size byte first */
122 r = usbd_do_request(dev, &req, &us);
123 if (r != USBD_NORMAL_COMPLETION)
124 return 0;
125 USETW(req.wLength, us.bLength); /* the whole string */
126 r = usbd_do_request(dev, &req, &us);
127 if (r != USBD_NORMAL_COMPLETION)
128 return 0;
129 s = buf;
130 n = us.bLength / 2 - 1;
131 for (i = 0; i < n; i++) {
132 c = UGETW(us.bString[i]);
133 /* Convert from Unicode, handle buggy strings. */
134 if ((c & 0xff00) == 0)
135 *s++ = c;
136 else if ((c & 0x00ff) == 0 && swap)
137 *s++ = c >> 8;
138 else
139 *s++ = '?';
140 }
141 *s++ = 0;
142 return buf;
143 }
144
145 void
146 usbd_devinfo_vp(dev, v, p)
147 usbd_device_handle dev;
148 char *v, *p;
149 {
150 usb_device_descriptor_t *udd = &dev->ddesc;
151 char *vendor = 0, *product = 0;
152 #ifdef USBVERBOSE
153 struct usb_knowndev *kdp;
154 #endif
155
156 vendor = usbd_get_string(dev, udd->iManufacturer, v);
157 product = usbd_get_string(dev, udd->iProduct, p);
158 #ifdef USBVERBOSE
159 if (!vendor) {
160 for(kdp = usb_knowndevs;
161 kdp->vendorname != NULL;
162 kdp++) {
163 if (kdp->vendor == UGETW(udd->idVendor) &&
164 (kdp->product == UGETW(udd->idProduct) ||
165 (kdp->flags & USB_KNOWNDEV_NOPROD) != 0))
166 break;
167 }
168 if (kdp->vendorname == NULL)
169 vendor = product = NULL;
170 else {
171 vendor = kdp->vendorname;
172 product = (kdp->flags & USB_KNOWNDEV_NOPROD) == 0 ?
173 kdp->productname : NULL;
174 }
175 }
176 #endif
177 if (vendor)
178 strcpy(v, vendor);
179 else
180 sprintf(v, "vendor 0x%04x", UGETW(udd->idVendor));
181 if (product)
182 strcpy(p, product);
183 else
184 sprintf(p, "product 0x%04x", UGETW(udd->idProduct));
185 }
186
187 int
188 usbd_printBCD(cp, bcd)
189 char *cp;
190 int bcd;
191 {
192 return (sprintf(cp, "%x.%02x", bcd >> 8, bcd & 0xff));
193 }
194
195 void
196 usbd_devinfo(dev, showclass, cp)
197 usbd_device_handle dev;
198 int showclass;
199 char *cp;
200 {
201 usb_device_descriptor_t *udd = &dev->ddesc;
202 char vendor[USB_MAX_STRING_LEN];
203 char product[USB_MAX_STRING_LEN];
204 int bcdDevice, bcdUSB;
205
206 usbd_devinfo_vp(dev, vendor, product);
207 cp += sprintf(cp, "%s %s", vendor, product);
208 if (showclass)
209 cp += sprintf(cp, " (class %d/%d)",
210 udd->bDeviceClass, udd->bDeviceSubClass);
211 bcdUSB = UGETW(udd->bcdUSB);
212 bcdDevice = UGETW(udd->bcdDevice);
213 cp += sprintf(cp, " (rev ");
214 cp += usbd_printBCD(cp, bcdUSB);
215 *cp++ = '/';
216 cp += usbd_printBCD(cp, bcdDevice);
217 *cp++ = ')';
218 cp += sprintf(cp, ", addr %d", dev->address);
219 *cp = 0;
220 }
221
222 /* Delay for a certain number of ms */
223 void
224 usbd_delay_ms(bus, ms)
225 usbd_bus_handle bus;
226 int ms;
227 {
228 /* Wait at least two clock ticks so we know the time has passed. */
229 if (bus->use_polling)
230 delay((ms+1) * 1000);
231 else
232 tsleep(&ms, PRIBIO, "usbdly", (ms*hz+999)/1000 + 1);
233 }
234
235 usbd_status
236 usbd_reset_port(dev, port, ps)
237 usbd_device_handle dev;
238 int port;
239 usb_port_status_t *ps;
240 {
241 usb_device_request_t req;
242 usbd_status r;
243 int n;
244
245 req.bmRequestType = UT_WRITE_CLASS_OTHER;
246 req.bRequest = UR_SET_FEATURE;
247 USETW(req.wValue, UHF_PORT_RESET);
248 USETW(req.wIndex, port);
249 USETW(req.wLength, 0);
250 r = usbd_do_request(dev, &req, 0);
251 DPRINTFN(1,("usbd_reset_port: port %d reset done, error=%d\n",
252 port, r));
253 if (r != USBD_NORMAL_COMPLETION)
254 return (r);
255 n = 10;
256 do {
257 /* Wait for device to recover from reset. */
258 usbd_delay_ms(dev->bus, USB_PORT_RESET_DELAY);
259 r = usbd_get_port_status(dev, port, ps);
260 if (r != USBD_NORMAL_COMPLETION) {
261 DPRINTF(("usbd_reset_port: get status failed %d\n",r));
262 return (r);
263 }
264 } while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0);
265 if (n == 0) {
266 printf("usbd_reset_port: timeout\n");
267 return (USBD_IOERROR);
268 }
269 r = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET);
270 #ifdef USB_DEBUG
271 if (r != USBD_NORMAL_COMPLETION)
272 DPRINTF(("usbd_reset_port: clear port feature failed %d\n",r));
273 #endif
274 return (r);
275 }
276
277 usb_interface_descriptor_t *
278 usbd_find_idesc(cd, ino, ano)
279 usb_config_descriptor_t *cd;
280 int ino;
281 int ano;
282 {
283 char *p = (char *)cd;
284 char *end = p + UGETW(cd->wTotalLength);
285 usb_interface_descriptor_t *d;
286
287 for (; p < end; p += d->bLength) {
288 d = (usb_interface_descriptor_t *)p;
289 if (p + d->bLength <= end &&
290 d->bDescriptorType == UDESC_INTERFACE &&
291 d->bInterfaceNumber == ino && d->bAlternateSetting == ano)
292 return (d);
293 }
294 return (0);
295 }
296
297 usbd_status
298 usbd_fill_iface_data(dev, ino, ano)
299 usbd_device_handle dev;
300 int ino;
301 int ano;
302 {
303 usbd_interface_handle ifc = &dev->ifaces[ino];
304 usb_endpoint_descriptor_t *ed;
305 char *p, *end;
306 int endpt, nendpt;
307 usbd_status r;
308
309 DPRINTFN(5,("usbd_fill_iface_data: ino=%d ano=%d\n", ino, ano));
310 ifc->device = dev;
311 ifc->state = USBD_INTERFACE_ACTIVE;
312 ifc->idesc = usbd_find_idesc(dev->cdesc, ino, ano);
313 if (ifc->idesc == 0)
314 return (USBD_INVAL);
315 nendpt = ifc->idesc->bNumEndpoints;
316 DPRINTFN(10,("usbd_fill_iface_data: found idesc n=%d\n", nendpt));
317 if (nendpt != 0) {
318 ifc->endpoints = malloc(nendpt * sizeof(struct usbd_endpoint),
319 M_USB, M_NOWAIT);
320 if (ifc->endpoints == 0)
321 return (USBD_NOMEM);
322 } else
323 ifc->endpoints = 0;
324 ifc->priv = 0;
325 p = (char *)ifc->idesc + ifc->idesc->bLength;
326 end = (char *)dev->cdesc + UGETW(dev->cdesc->wTotalLength);
327 for (endpt = 0; endpt < nendpt; endpt++) {
328 DPRINTFN(10,("usbd_fill_iface_data: endpt=%d\n", endpt));
329 for (; p < end; p += ed->bLength) {
330 ed = (usb_endpoint_descriptor_t *)p;
331 DPRINTFN(10,("usbd_fill_iface_data: p=%p end=%p len=%d type=%d\n",
332 p, end, ed->bLength, ed->bDescriptorType));
333 if (p + ed->bLength <= end &&
334 ed->bDescriptorType == UDESC_ENDPOINT)
335 goto found;
336 if (ed->bDescriptorType == UDESC_INTERFACE)
337 break;
338 }
339 r = USBD_INVAL;
340 goto bad;
341 found:
342 ifc->endpoints[endpt].edesc = ed;
343 ifc->endpoints[endpt].state = USBD_ENDPOINT_ACTIVE;
344 ifc->endpoints[endpt].refcnt = 0;
345 ifc->endpoints[endpt].toggle = 0;
346 }
347 LIST_INIT(&ifc->pipes);
348 return (USBD_NORMAL_COMPLETION);
349 bad:
350 free(ifc->endpoints, M_USB);
351 return (r);
352 }
353
354 void
355 usbd_free_iface_data(dev, ifcno)
356 usbd_device_handle dev;
357 int ifcno;
358 {
359 usbd_interface_handle ifc = &dev->ifaces[ifcno];
360 if (ifc->endpoints)
361 free(ifc->endpoints, M_USB);
362 }
363
364 static usbd_status
365 usbd_set_config(dev, conf)
366 usbd_device_handle dev;
367 int conf;
368 {
369 usb_device_request_t req;
370
371 req.bmRequestType = UT_WRITE_DEVICE;
372 req.bRequest = UR_SET_CONFIG;
373 USETW(req.wValue, conf);
374 USETW(req.wIndex, 0);
375 USETW(req.wLength, 0);
376 return (usbd_do_request(dev, &req, 0));
377 }
378
379 usbd_status
380 usbd_set_config_no(dev, no, msg)
381 usbd_device_handle dev;
382 int no;
383 int msg;
384 {
385 usb_status_t ds;
386 usb_hub_status_t hs;
387 usb_config_descriptor_t cd, *cdp;
388 usbd_status r;
389 int ifcno, nifc, len, selfpowered, power;
390
391 DPRINTFN(5, ("usbd_set_config_no: dev=%p no=%d\n", dev, no));
392
393 /* XXX check that all interfaces are idle */
394 if (dev->config != 0) {
395 DPRINTF(("usbd_set_config_no: free old config\n"));
396 /* Free all configuration data structures. */
397 nifc = dev->cdesc->bNumInterface;
398 for (ifcno = 0; ifcno < nifc; ifcno++)
399 usbd_free_iface_data(dev, ifcno);
400 free(dev->ifaces, M_USB);
401 free(dev->cdesc, M_USB);
402 dev->ifaces = 0;
403 dev->cdesc = 0;
404 dev->config = 0;
405 dev->state = USBD_DEVICE_ADDRESSED;
406 }
407
408 /* Figure out what config number to use. */
409 r = usbd_get_config_desc(dev, no, &cd);
410 if (r != USBD_NORMAL_COMPLETION)
411 return (r);
412 len = UGETW(cd.wTotalLength);
413 cdp = malloc(len, M_USB, M_NOWAIT);
414 if (cdp == 0)
415 return (USBD_NOMEM);
416 r = usbd_get_desc(dev, UDESC_CONFIG, no, len, cdp);
417 if (r != USBD_NORMAL_COMPLETION)
418 goto bad;
419 selfpowered = 0;
420 if (cdp->bmAttributes & UC_SELF_POWERED) {
421 /* May be self powered. */
422 if (cdp->bmAttributes & UC_BUS_POWERED) {
423 /* Must ask device. */
424 if (dev->quirks->uq_flags & UQ_HUB_POWER) {
425 /* Buggy hub, use hub descriptor. */
426 r = usbd_get_hub_status(dev, &hs);
427 if (r == USBD_NORMAL_COMPLETION &&
428 !(UGETW(hs.wHubStatus) & UHS_LOCAL_POWER))
429 selfpowered = 1;
430 } else {
431 r = usbd_get_device_status(dev, &ds);
432 if (r == USBD_NORMAL_COMPLETION &&
433 (UGETW(ds.wStatus) & UDS_SELF_POWERED))
434 selfpowered = 1;
435 }
436 DPRINTF(("usbd_set_config_no: status=0x%04x, error=%d\n",
437 UGETW(ds.wStatus), r));
438 } else
439 selfpowered = 1;
440 }
441 DPRINTF(("usbd_set_config_no: (addr %d) attr=0x%02x, selfpowered=%d, power=%d, powerquirk=%x\n",
442 dev->address, cdp->bmAttributes,
443 selfpowered, cdp->bMaxPower * 2,
444 dev->quirks->uq_flags & UQ_HUB_POWER));
445 #ifdef USB_DEBUG
446 if (!dev->powersrc) {
447 printf("usbd_set_config_no: No power source?\n");
448 return (EIO);
449 }
450 #endif
451 power = cdp->bMaxPower * 2;
452 if (power > dev->powersrc->power) {
453 /* XXX print nicer message. */
454 if (msg)
455 printf("%s: device addr %d (config %d) exceeds power budget, %d mA > %d mA\n",
456 dev->bus->bdev.dv_xname, dev->address,
457 cdp->bConfigurationValue,
458 power, dev->powersrc->power);
459 r = USBD_NO_POWER;
460 goto bad;
461 }
462 dev->power = power;
463 dev->self_powered = selfpowered;
464
465 r = usbd_set_config(dev, cdp->bConfigurationValue);
466 if (r != USBD_NORMAL_COMPLETION) {
467 DPRINTF(("usbd_set_config_no: setting config=%d failed, error=%d\n",
468 cdp->bConfigurationValue, r));
469 goto bad;
470 }
471 DPRINTF(("usbd_set_config_no: setting new config %d\n",
472 cdp->bConfigurationValue));
473 nifc = cdp->bNumInterface;
474 dev->ifaces = malloc(nifc * sizeof(struct usbd_interface),
475 M_USB, M_NOWAIT);
476 if (dev->ifaces == 0) {
477 r = USBD_NOMEM;
478 goto bad;
479 }
480 DPRINTFN(5,("usbd_set_config_no: dev=%p cdesc=%p\n", dev, cdp));
481 dev->cdesc = cdp;
482 dev->config = cdp->bConfigurationValue;
483 dev->state = USBD_DEVICE_CONFIGURED;
484 for (ifcno = 0; ifcno < nifc; ifcno++) {
485 r = usbd_fill_iface_data(dev, ifcno, 0);
486 if (r != USBD_NORMAL_COMPLETION) {
487 while (--ifcno >= 0)
488 usbd_free_iface_data(dev, ifcno);
489 goto bad;
490 }
491 }
492
493 return (USBD_NORMAL_COMPLETION);
494
495 bad:
496 free(cdp, M_USB);
497 return (r);
498 }
499
500 /* XXX add function for alternate settings */
501
502 usbd_status
503 usbd_setup_pipe(dev, iface, ep, pipe)
504 usbd_device_handle dev;
505 usbd_interface_handle iface;
506 struct usbd_endpoint *ep;
507 usbd_pipe_handle *pipe;
508 {
509 usbd_pipe_handle p;
510 usbd_status r;
511
512 DPRINTFN(1,("usbd_setup_pipe: dev=%p iface=%p ep=%p pipe=%p\n",
513 dev, iface, ep, pipe));
514 p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT);
515 if (p == 0)
516 return (USBD_NOMEM);
517 p->device = dev;
518 p->iface = iface;
519 p->state = USBD_PIPE_ACTIVE;
520 p->endpoint = ep;
521 ep->refcnt++;
522 p->refcnt = 1;
523 p->intrreqh = 0;
524 p->running = 0;
525 SIMPLEQ_INIT(&p->queue);
526 r = dev->bus->open_pipe(p);
527 if (r != USBD_NORMAL_COMPLETION) {
528 DPRINTF(("usbd_setup_pipe: endpoint=%d failed, error=%d\n",
529 ep->edesc->bEndpointAddress, r));
530 free(p, M_USB);
531 return (r);
532 }
533 *pipe = p;
534 return (USBD_NORMAL_COMPLETION);
535 }
536
537 /* Abort the device control pipe. */
538 void
539 usbd_kill_pipe(pipe)
540 usbd_pipe_handle pipe;
541 {
542 pipe->methods->close(pipe);
543 pipe->endpoint->refcnt--;
544 free(pipe, M_USB);
545 }
546
547 int
548 usbd_getnewaddr(bus)
549 usbd_bus_handle bus;
550 {
551 int i;
552
553 for (i = 1; i < USB_MAX_DEVICES; i++)
554 if (bus->devices[i] == 0)
555 return (i);
556 return (-1);
557 }
558
559 /*
560 * Called when a new device has been put in the powered state,
561 * but not yet in the addressed state.
562 * Get initial descriptor, set the address, get full descriptor,
563 * and attach a driver.
564 */
565 usbd_status
566 usbd_new_device(parent, bus, depth, lowspeed, port, up)
567 struct device *parent;
568 usbd_bus_handle bus;
569 int depth;
570 int lowspeed;
571 int port;
572 struct usbd_port *up;
573 {
574 usbd_device_handle dev;
575 usb_device_descriptor_t *d;
576 usbd_status r;
577 struct usb_attach_arg uaa;
578 int addr;
579 int found, i, confi;
580
581 DPRINTF(("usbd_new_device bus=%p depth=%d lowspeed=%d\n",
582 bus, depth, lowspeed));
583 addr = usbd_getnewaddr(bus);
584 if (addr < 0) {
585 printf("%s: No free USB addresses, new device ignored.\n",
586 bus->bdev.dv_xname);
587 return (USBD_NO_ADDR);
588 }
589
590 dev = malloc(sizeof *dev, M_USB, M_NOWAIT);
591 if (dev == 0)
592 return (USBD_NOMEM);
593 memset(dev, 0, sizeof(*dev));
594
595 dev->bus = bus;
596
597 /* Set up default endpoint handle. */
598 dev->def_ep.edesc = &dev->def_ep_desc;
599 dev->def_ep.state = USBD_ENDPOINT_ACTIVE;
600 dev->def_ep.refcnt = 0;
601 dev->def_ep.toggle = 0; /* XXX */
602
603 /* Set up default endpoint descriptor. */
604 dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE;
605 dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT;
606 dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
607 dev->def_ep_desc.bmAttributes = UE_CONTROL;
608 USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET);
609 dev->def_ep_desc.bInterval = 0;
610
611 dev->state = USBD_DEVICE_DEFAULT;
612 dev->quirks = &usbd_no_quirk;
613 dev->address = USB_START_ADDR;
614 dev->ddesc.bMaxPacketSize = 0;
615 dev->lowspeed = lowspeed != 0;
616 dev->depth = depth;
617 dev->powersrc = up;
618
619 /* Establish the the default pipe. */
620 r = usbd_setup_pipe(dev, 0, &dev->def_ep, &dev->default_pipe);
621 if (r != USBD_NORMAL_COMPLETION)
622 goto bad1;
623
624 up->device = dev;
625 d = &dev->ddesc;
626 /* Try a few times in case the device is slow (i.e. outside specs.) */
627 for (i = 0; i < 5; i++) {
628 /* Get the first 8 bytes of the device descriptor. */
629 r = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, d);
630 if (r == USBD_NORMAL_COMPLETION)
631 break;
632 usbd_delay_ms(dev->bus, 200);
633 }
634 if (r != USBD_NORMAL_COMPLETION) {
635 DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc failed\n",
636 addr));
637 goto bad;
638 }
639
640 DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, subclass=%d, protocol=%d, maxpacket=%d, ls=%d\n",
641 addr, UGETW(d->bcdUSB), d->bDeviceClass, d->bDeviceSubClass,
642 d->bDeviceProtocol, d->bMaxPacketSize, dev->lowspeed));
643
644 USETW(dev->def_ep_desc.wMaxPacketSize, d->bMaxPacketSize);
645
646 /* Get the full device descriptor. */
647 r = usbd_get_device_desc(dev, d);
648 if (r != USBD_NORMAL_COMPLETION) {
649 DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc failed\n", addr));
650 goto bad;
651 }
652
653 /* Figure out what's wrong with this device. */
654 dev->quirks = usbd_find_quirk(d);
655
656 /* Set the address */
657 r = usbd_set_address(dev, addr);
658 if (r != USBD_NORMAL_COMPLETION) {
659 DPRINTFN(-1,("usb_new_device: set address %d failed\n",addr));
660 r = USBD_SET_ADDR_FAILED;
661 goto bad;
662 }
663 dev->address = addr; /* New device address now */
664 dev->state = USBD_DEVICE_ADDRESSED;
665 bus->devices[addr] = dev;
666
667 /* Assume 100mA bus powered for now. Changed when configured. */
668 dev->power = USB_MIN_POWER;
669 dev->self_powered = 0;
670
671 DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n",
672 addr, dev, parent));
673
674 uaa.device = dev;
675 uaa.iface = 0;
676 uaa.usegeneric = 0;
677 uaa.port = port;
678 uaa.configno = UHUB_UNK_CONFIGURATION;
679 uaa.ifaceno = UHUB_UNK_INTERFACE;
680 /* First try with device specific drivers. */
681 if (config_found_sm(parent, &uaa, usbd_print, usbd_submatch) != 0)
682 return (USBD_NORMAL_COMPLETION);
683
684 DPRINTF(("usbd_new_device: no device driver found\n"));
685
686 /* Next try with interface drivers. */
687 for (confi = 0; confi < d->bNumConfigurations; confi++) {
688 r = usbd_set_config_no(dev, confi, 1);
689 if (r != USBD_NORMAL_COMPLETION) {
690 printf("%s: set config at addr %d failed, error=%d\n",
691 parent->dv_xname, addr, r);
692 goto bad;
693 }
694 uaa.configno = confi;
695 for (found = i = 0; i < dev->cdesc->bNumInterface; i++) {
696 uaa.iface = &dev->ifaces[i];
697 uaa.ifaceno = dev->ifaces[i].idesc->bInterfaceNumber;
698 if (config_found_sm(parent, &uaa, usbd_print,
699 usbd_submatch))
700 found++;
701 }
702 if (found != 0)
703 return (USBD_NORMAL_COMPLETION);
704 }
705 /* No interfaces were attached in any of the configurations. */
706 if (d->bNumConfigurations > 0)
707 usbd_set_config_no(dev, 0, 0);
708
709 DPRINTF(("usbd_new_device: no interface drivers found\n"));
710
711 /* Finally try the generic driver. */
712 uaa.iface = 0;
713 uaa.usegeneric = 1;
714 uaa.configno = 0;
715 uaa.ifaceno = UHUB_UNK_INTERFACE;
716 if (config_found_sm(parent, &uaa, usbd_print, usbd_submatch) != 0)
717 return (USBD_NORMAL_COMPLETION);
718
719 DPRINTF(("usbd_new_device: generic attach failed\n"));
720
721 return (USBD_NORMAL_COMPLETION);
722
723 bad:
724 usbd_kill_pipe(dev->default_pipe);
725 bad1:
726 up->device = 0;
727 bus->devices[addr] = 0;
728 free(dev, M_USB);
729 return (r);
730 }
731
732 int
733 usbd_print(aux, pnp)
734 void *aux;
735 const char *pnp;
736 {
737 struct usb_attach_arg *uaa = aux;
738 char devinfo[1024];
739
740 DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device));
741 if (pnp) {
742 if (!uaa->usegeneric)
743 return (QUIET);
744 usbd_devinfo(uaa->device, 1, devinfo);
745 printf("%s, %s", devinfo, pnp);
746 }
747 if (uaa->port != 0)
748 printf(" port %d", uaa->port);
749 if (uaa->configno != UHUB_UNK_CONFIGURATION)
750 printf(" configuration %d", uaa->configno);
751 if (uaa->ifaceno != UHUB_UNK_INTERFACE)
752 printf(" interface %d", uaa->ifaceno);
753 return (UNCONF);
754 }
755
756 int
757 usbd_submatch(parent, cf, aux)
758 struct device *parent;
759 struct cfdata *cf;
760 void *aux;
761 {
762 struct usb_attach_arg *uaa = aux;
763
764 if ((uaa->port != 0 &&
765 cf->uhubcf_port != UHUB_UNK_PORT &&
766 cf->uhubcf_port != uaa->port) ||
767 (uaa->configno != UHUB_UNK_CONFIGURATION &&
768 cf->uhubcf_configuration != UHUB_UNK_CONFIGURATION &&
769 cf->uhubcf_configuration != uaa->configno) ||
770 (uaa->ifaceno != UHUB_UNK_INTERFACE &&
771 cf->uhubcf_interface != UHUB_UNK_INTERFACE &&
772 cf->uhubcf_interface != uaa->ifaceno))
773 return 0;
774 return ((*cf->cf_attach->ca_match)(parent, cf, aux));
775 }
776