This source file includes following definitions.
- usbd_errstr
- usbd_get_string_desc
- usbd_get_string
- usbd_trim_spaces
- usbd_devinfo_vp
- usbd_printBCD
- usbd_devinfo
- usbd_devinfo_alloc
- usbd_devinfo_free
- usb_delay_ms
- usbd_delay_ms
- usbd_reset_port
- usbd_find_idesc
- usbd_find_edesc
- usbd_fill_iface_data
- usbd_free_iface_data
- usbd_set_config
- usbd_set_config_no
- usbd_set_config_index
- usbd_setup_pipe
- usbd_kill_pipe
- usbd_getnewaddr
- usbd_probe_and_attach
- usbd_new_device
- usbd_reload_device_desc
- usbd_remove_device
- usbd_print
- usbd_submatch
- usbd_fill_deviceinfo
- usb_free_device
- usb_disconnect_port
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/malloc.h>
46 #include <sys/device.h>
47 #include <sys/selinfo.h>
48 #include <sys/proc.h>
49
50 #include <machine/bus.h>
51
52 #include <dev/usb/usb.h>
53
54 #include <dev/usb/usbdi.h>
55 #include <dev/usb/usbdi_util.h>
56 #include <dev/usb/usbdivar.h>
57 #include <dev/usb/usbdevs.h>
58 #include <dev/usb/usb_quirks.h>
59
60 #ifdef USB_DEBUG
61 #define DPRINTF(x) do { if (usbdebug) printf x; } while (0)
62 #define DPRINTFN(n,x) do { if (usbdebug>(n)) printf x; } while (0)
63 extern int usbdebug;
64 #else
65 #define DPRINTF(x)
66 #define DPRINTFN(n,x)
67 #endif
68
69 usbd_status usbd_set_config(usbd_device_handle, int);
70 void usbd_devinfo(usbd_device_handle, int, char *, size_t);
71 void usbd_devinfo_vp(usbd_device_handle, char *, char *,
72 int);
73 char *usbd_get_string(usbd_device_handle, int, char *);
74 int usbd_getnewaddr(usbd_bus_handle);
75 int usbd_print(void *, const char *);
76 int usbd_submatch(struct device *, void *, void *);
77 void usbd_free_iface_data(usbd_device_handle, int);
78 void usbd_kill_pipe(usbd_pipe_handle);
79 usbd_status usbd_probe_and_attach(struct device *,
80 usbd_device_handle, int, int);
81
82 u_int32_t usb_cookie_no = 0;
83
84 #ifdef USBVERBOSE
85 #include <dev/usb/usbdevs_data.h>
86 #endif
87
88 const char * const usbd_error_strs[] = {
89 "NORMAL_COMPLETION",
90 "IN_PROGRESS",
91 "PENDING_REQUESTS",
92 "NOT_STARTED",
93 "INVAL",
94 "NOMEM",
95 "CANCELLED",
96 "BAD_ADDRESS",
97 "IN_USE",
98 "NO_ADDR",
99 "SET_ADDR_FAILED",
100 "NO_POWER",
101 "TOO_DEEP",
102 "IOERROR",
103 "NOT_CONFIGURED",
104 "TIMEOUT",
105 "SHORT_XFER",
106 "STALLED",
107 "INTERRUPTED",
108 "XXX",
109 };
110
111 const char *
112 usbd_errstr(usbd_status err)
113 {
114 static char buffer[5];
115
116 if (err < USBD_ERROR_MAX)
117 return (usbd_error_strs[err]);
118 else {
119 snprintf(buffer, sizeof(buffer), "%d", err);
120 return (buffer);
121 }
122 }
123
124 usbd_status
125 usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid,
126 usb_string_descriptor_t *sdesc, int *sizep)
127 {
128 usb_device_request_t req;
129 usbd_status err;
130 int actlen;
131
132 req.bmRequestType = UT_READ_DEVICE;
133 req.bRequest = UR_GET_DESCRIPTOR;
134 USETW2(req.wValue, UDESC_STRING, sindex);
135 USETW(req.wIndex, langid);
136 USETW(req.wLength, 1);
137 err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
138 &actlen, USBD_DEFAULT_TIMEOUT);
139 if (err)
140 return (err);
141
142 if (actlen < 1)
143 return (USBD_SHORT_XFER);
144
145 USETW(req.wLength, sdesc->bLength);
146 err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
147 &actlen, USBD_DEFAULT_TIMEOUT);
148 if (err)
149 return (err);
150
151 if (actlen != sdesc->bLength) {
152 DPRINTFN(-1, ("usbd_get_string_desc: expected %d, got %d\n",
153 sdesc->bLength, actlen));
154 }
155
156 *sizep = actlen;
157 return (USBD_NORMAL_COMPLETION);
158 }
159
160 char *
161 usbd_get_string(usbd_device_handle dev, int si, char *buf)
162 {
163 int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE;
164 usb_string_descriptor_t us;
165 char *s;
166 int i, n;
167 u_int16_t c;
168 usbd_status err;
169 int size;
170
171 if (si == 0)
172 return (0);
173 if (dev->quirks->uq_flags & UQ_NO_STRINGS)
174 return (0);
175 if (dev->langid == USBD_NOLANG) {
176
177 err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us,
178 &size);
179 if (err || size < 4)
180 dev->langid = 0;
181 else {
182
183 dev->langid = UGETW(us.bString[0]);
184 }
185 }
186 err = usbd_get_string_desc(dev, si, dev->langid, &us, &size);
187 if (err)
188 return (0);
189 s = buf;
190 n = size / 2 - 1;
191 for (i = 0; i < n; i++) {
192 c = UGETW(us.bString[i]);
193
194 if ((c & 0xff00) == 0)
195 *s++ = c;
196 else if ((c & 0x00ff) == 0 && swap)
197 *s++ = c >> 8;
198 else
199 *s++ = '?';
200 }
201 *s++ = 0;
202 return (buf);
203 }
204
205 static void
206 usbd_trim_spaces(char *p)
207 {
208 char *q, *e;
209
210 if (p == NULL)
211 return;
212 q = e = p;
213 while (*q == ' ')
214 q++;
215 while ((*p = *q++))
216 if (*p++ != ' ')
217 e = p;
218 *e = 0;
219 }
220
221 void
222 usbd_devinfo_vp(usbd_device_handle dev, char *v, char *p, int usedev)
223 {
224 usb_device_descriptor_t *udd = &dev->ddesc;
225 char *vendor = 0, *product = 0;
226 #ifdef USBVERBOSE
227 const struct usb_known_vendor *ukv;
228 const struct usb_known_product *ukp;
229 #endif
230
231 if (dev == NULL) {
232 v[0] = p[0] = '\0';
233 return;
234 }
235
236 if (usedev) {
237 vendor = usbd_get_string(dev, udd->iManufacturer, v);
238 usbd_trim_spaces(vendor);
239 product = usbd_get_string(dev, udd->iProduct, p);
240 usbd_trim_spaces(product);
241 } else {
242 vendor = NULL;
243 product = NULL;
244 }
245 #ifdef USBVERBOSE
246 if (vendor == NULL || product == NULL) {
247 for(ukv = usb_known_vendors;
248 ukv->vendorname != NULL;
249 ukv++) {
250 if (ukv->vendor == UGETW(udd->idVendor)) {
251 vendor = ukv->vendorname;
252 break;
253 }
254 }
255 if (vendor != NULL) {
256 for(ukp = usb_known_products;
257 ukp->productname != NULL;
258 ukp++) {
259 if (ukp->vendor == UGETW(udd->idVendor) &&
260 (ukp->product == UGETW(udd->idProduct))) {
261 product = ukp->productname;
262 break;
263 }
264 }
265 }
266 }
267 #endif
268 if (vendor != NULL && *vendor)
269 strlcpy(v, vendor, USB_MAX_STRING_LEN);
270 else
271 snprintf(v, USB_MAX_STRING_LEN, "vendor 0x%04x",
272 UGETW(udd->idVendor));
273 if (product != NULL && *product)
274 strlcpy(p, product, USB_MAX_STRING_LEN);
275 else
276 snprintf(p, USB_MAX_STRING_LEN, "product 0x%04x",
277 UGETW(udd->idProduct));
278 }
279
280 int
281 usbd_printBCD(char *cp, size_t len, int bcd)
282 {
283 int l;
284
285 l = snprintf(cp, len, "%x.%02x", bcd >> 8, bcd & 0xff);
286 if (l == -1 || len == 0)
287 return (0);
288 if (l >= len)
289 return len - 1;
290 return (l);
291 }
292
293 void
294 usbd_devinfo(usbd_device_handle dev, int showclass, char *base, size_t len)
295 {
296 usb_device_descriptor_t *udd = &dev->ddesc;
297 char vendor[USB_MAX_STRING_LEN];
298 char product[USB_MAX_STRING_LEN];
299 char *cp = base;
300 int bcdDevice, bcdUSB;
301
302 usbd_devinfo_vp(dev, vendor, product, 1);
303 snprintf(cp, len, "%s %s", vendor, product);
304 cp += strlen(cp);
305 if (showclass) {
306 snprintf(cp, base + len - cp, ", class %d/%d",
307 udd->bDeviceClass, udd->bDeviceSubClass);
308 cp += strlen(cp);
309 }
310 bcdUSB = UGETW(udd->bcdUSB);
311 bcdDevice = UGETW(udd->bcdDevice);
312 snprintf(cp, base + len - cp, ", rev ");
313 cp += strlen(cp);
314 usbd_printBCD(cp, base + len - cp, bcdUSB);
315 cp += strlen(cp);
316 snprintf(cp, base + len - cp, "/");
317 cp += strlen(cp);
318 usbd_printBCD(cp, base + len - cp, bcdDevice);
319 cp += strlen(cp);
320 snprintf(cp, base + len - cp, ", addr %d", dev->address);
321 }
322
323 char *
324 usbd_devinfo_alloc(usbd_device_handle dev, int showclass)
325 {
326 char *devinfop;
327
328 devinfop = malloc(DEVINFOSIZE, M_TEMP, M_WAITOK);
329 usbd_devinfo(dev, showclass, devinfop, DEVINFOSIZE);
330 return devinfop;
331 }
332
333 void
334 usbd_devinfo_free(char *devinfop)
335 {
336 free(devinfop, M_TEMP);
337 }
338
339
340 void
341 usb_delay_ms(usbd_bus_handle bus, u_int ms)
342 {
343
344 if (bus->use_polling || cold)
345 delay((ms+1) * 1000);
346 else
347 tsleep(&ms, PRIBIO, "usbdly", (ms*hz+999)/1000 + 1);
348 }
349
350
351 void
352 usbd_delay_ms(usbd_device_handle dev, u_int ms)
353 {
354 usb_delay_ms(dev->bus, ms);
355 }
356
357 usbd_status
358 usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps)
359 {
360 usb_device_request_t req;
361 usbd_status err;
362 int n;
363
364 req.bmRequestType = UT_WRITE_CLASS_OTHER;
365 req.bRequest = UR_SET_FEATURE;
366 USETW(req.wValue, UHF_PORT_RESET);
367 USETW(req.wIndex, port);
368 USETW(req.wLength, 0);
369 err = usbd_do_request(dev, &req, 0);
370 DPRINTFN(1,("usbd_reset_port: port %d reset done, error=%s\n",
371 port, usbd_errstr(err)));
372 if (err)
373 return (err);
374 n = 10;
375 do {
376
377 usbd_delay_ms(dev, USB_PORT_RESET_DELAY);
378 err = usbd_get_port_status(dev, port, ps);
379 if (err) {
380 DPRINTF(("usbd_reset_port: get status failed %d\n",
381 err));
382 return (err);
383 }
384
385 if (!(UGETW(ps->wPortStatus) & UPS_CURRENT_CONNECT_STATUS))
386 return (USBD_NORMAL_COMPLETION);
387 } while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0);
388 if (n == 0)
389 return (USBD_TIMEOUT);
390 err = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET);
391 #ifdef USB_DEBUG
392 if (err)
393 DPRINTF(("usbd_reset_port: clear port feature failed %d\n",
394 err));
395 #endif
396
397
398 usbd_delay_ms(dev, USB_PORT_RESET_RECOVERY);
399 return (err);
400 }
401
402 usb_interface_descriptor_t *
403 usbd_find_idesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx)
404 {
405 char *p = (char *)cd;
406 char *end = p + UGETW(cd->wTotalLength);
407 usb_interface_descriptor_t *d;
408 int curidx, lastidx, curaidx = 0;
409
410 for (curidx = lastidx = -1; p < end; ) {
411 d = (usb_interface_descriptor_t *)p;
412 DPRINTFN(4,("usbd_find_idesc: idx=%d(%d) altidx=%d(%d) len=%d "
413 "type=%d\n",
414 ifaceidx, curidx, altidx, curaidx,
415 d->bLength, d->bDescriptorType));
416 if (d->bLength == 0)
417 break;
418 p += d->bLength;
419 if (p <= end && d->bDescriptorType == UDESC_INTERFACE) {
420 if (d->bInterfaceNumber != lastidx) {
421 lastidx = d->bInterfaceNumber;
422 curidx++;
423 curaidx = 0;
424 } else
425 curaidx++;
426 if (ifaceidx == curidx && altidx == curaidx)
427 return (d);
428 }
429 }
430 return (NULL);
431 }
432
433 usb_endpoint_descriptor_t *
434 usbd_find_edesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx,
435 int endptidx)
436 {
437 char *p = (char *)cd;
438 char *end = p + UGETW(cd->wTotalLength);
439 usb_interface_descriptor_t *d;
440 usb_endpoint_descriptor_t *e;
441 int curidx;
442
443 d = usbd_find_idesc(cd, ifaceidx, altidx);
444 if (d == NULL)
445 return (NULL);
446 if (endptidx >= d->bNumEndpoints)
447 return (NULL);
448
449 curidx = -1;
450 for (p = (char *)d + d->bLength; p < end; ) {
451 e = (usb_endpoint_descriptor_t *)p;
452 if (e->bLength == 0)
453 break;
454 p += e->bLength;
455 if (p <= end && e->bDescriptorType == UDESC_INTERFACE)
456 return (NULL);
457 if (p <= end && e->bDescriptorType == UDESC_ENDPOINT) {
458 curidx++;
459 if (curidx == endptidx)
460 return (e);
461 }
462 }
463 return (NULL);
464 }
465
466 usbd_status
467 usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx)
468 {
469 usbd_interface_handle ifc = &dev->ifaces[ifaceidx];
470 usb_interface_descriptor_t *idesc;
471 char *p, *end;
472 int endpt, nendpt;
473
474 DPRINTFN(4,("usbd_fill_iface_data: ifaceidx=%d altidx=%d\n",
475 ifaceidx, altidx));
476 idesc = usbd_find_idesc(dev->cdesc, ifaceidx, altidx);
477 if (idesc == NULL)
478 return (USBD_INVAL);
479 ifc->device = dev;
480 ifc->idesc = idesc;
481 ifc->index = ifaceidx;
482 ifc->altindex = altidx;
483 nendpt = ifc->idesc->bNumEndpoints;
484 DPRINTFN(4,("usbd_fill_iface_data: found idesc nendpt=%d\n", nendpt));
485 if (nendpt != 0) {
486 ifc->endpoints = malloc(nendpt * sizeof(struct usbd_endpoint),
487 M_USB, M_NOWAIT);
488 if (ifc->endpoints == NULL)
489 return (USBD_NOMEM);
490 } else
491 ifc->endpoints = NULL;
492 ifc->priv = NULL;
493 p = (char *)ifc->idesc + ifc->idesc->bLength;
494 end = (char *)dev->cdesc + UGETW(dev->cdesc->wTotalLength);
495 #define ed ((usb_endpoint_descriptor_t *)p)
496 for (endpt = 0; endpt < nendpt; endpt++) {
497 DPRINTFN(10,("usbd_fill_iface_data: endpt=%d\n", endpt));
498 for (; p < end; p += ed->bLength) {
499 DPRINTFN(10,("usbd_fill_iface_data: p=%p end=%p "
500 "len=%d type=%d\n", p, end, ed->bLength,
501 ed->bDescriptorType));
502 if (p + ed->bLength <= end && ed->bLength != 0 &&
503 ed->bDescriptorType == UDESC_ENDPOINT)
504 goto found;
505 if (ed->bLength == 0 ||
506 ed->bDescriptorType == UDESC_INTERFACE)
507 break;
508 }
509
510 printf("usbd_fill_iface_data: bad descriptor(s): %s\n",
511 ed->bLength == 0 ? "0 length" :
512 ed->bDescriptorType == UDESC_INTERFACE ? "iface desc" :
513 "out of data");
514 goto bad;
515 found:
516 ifc->endpoints[endpt].edesc = ed;
517 if (dev->speed == USB_SPEED_HIGH) {
518 u_int mps;
519
520
521 switch (UE_GET_XFERTYPE(ed->bmAttributes)) {
522 case UE_CONTROL:
523 mps = USB_2_MAX_CTRL_PACKET;
524 goto check;
525 case UE_BULK:
526 mps = USB_2_MAX_BULK_PACKET;
527 check:
528 if (UGETW(ed->wMaxPacketSize) != mps) {
529 USETW(ed->wMaxPacketSize, mps);
530 #ifdef DIAGNOSTIC
531 printf("usbd_fill_iface_data: bad max "
532 "packet size\n");
533 #endif
534 }
535 break;
536 default:
537 break;
538 }
539 }
540 ifc->endpoints[endpt].refcnt = 0;
541 ifc->endpoints[endpt].savedtoggle = 0;
542 p += ed->bLength;
543 }
544 #undef ed
545 LIST_INIT(&ifc->pipes);
546 return (USBD_NORMAL_COMPLETION);
547
548 bad:
549 if (ifc->endpoints != NULL) {
550 free(ifc->endpoints, M_USB);
551 ifc->endpoints = NULL;
552 }
553 return (USBD_INVAL);
554 }
555
556 void
557 usbd_free_iface_data(usbd_device_handle dev, int ifcno)
558 {
559 usbd_interface_handle ifc = &dev->ifaces[ifcno];
560 if (ifc->endpoints)
561 free(ifc->endpoints, M_USB);
562 }
563
564 usbd_status
565 usbd_set_config(usbd_device_handle dev, int conf)
566 {
567 usb_device_request_t req;
568
569 req.bmRequestType = UT_WRITE_DEVICE;
570 req.bRequest = UR_SET_CONFIG;
571 USETW(req.wValue, conf);
572 USETW(req.wIndex, 0);
573 USETW(req.wLength, 0);
574 return (usbd_do_request(dev, &req, 0));
575 }
576
577 usbd_status
578 usbd_set_config_no(usbd_device_handle dev, int no, int msg)
579 {
580 int index;
581 usb_config_descriptor_t cd;
582 usbd_status err;
583
584 if (no == USB_UNCONFIG_NO)
585 return (usbd_set_config_index(dev, USB_UNCONFIG_INDEX, msg));
586
587 DPRINTFN(5,("usbd_set_config_no: %d\n", no));
588
589 for (index = 0; index < dev->ddesc.bNumConfigurations; index++) {
590 err = usbd_get_config_desc(dev, index, &cd);
591 if (err)
592 return (err);
593 if (cd.bConfigurationValue == no)
594 return (usbd_set_config_index(dev, index, msg));
595 }
596 return (USBD_INVAL);
597 }
598
599 usbd_status
600 usbd_set_config_index(usbd_device_handle dev, int index, int msg)
601 {
602 usb_status_t ds;
603 usb_config_descriptor_t cd, *cdp;
604 usbd_status err;
605 int i, ifcidx, nifc, len, selfpowered, power;
606
607 DPRINTFN(5,("usbd_set_config_index: dev=%p index=%d\n", dev, index));
608
609
610 if (dev->config != USB_UNCONFIG_NO) {
611 DPRINTF(("usbd_set_config_index: free old config\n"));
612
613 nifc = dev->cdesc->bNumInterface;
614 for (ifcidx = 0; ifcidx < nifc; ifcidx++)
615 usbd_free_iface_data(dev, ifcidx);
616 free(dev->ifaces, M_USB);
617 free(dev->cdesc, M_USB);
618 dev->ifaces = NULL;
619 dev->cdesc = NULL;
620 dev->config = USB_UNCONFIG_NO;
621 }
622
623 if (index == USB_UNCONFIG_INDEX) {
624
625 DPRINTF(("usbd_set_config_index: set config 0\n"));
626 err = usbd_set_config(dev, USB_UNCONFIG_NO);
627 if (err)
628 DPRINTF(("usbd_set_config_index: setting config=0 "
629 "failed, error=%s\n", usbd_errstr(err)));
630 return (err);
631 }
632
633
634 err = usbd_get_config_desc(dev, index, &cd);
635 if (err)
636 return (err);
637 len = UGETW(cd.wTotalLength);
638 cdp = malloc(len, M_USB, M_NOWAIT);
639 if (cdp == NULL)
640 return (USBD_NOMEM);
641
642 for (i = 0; i < 3; i++) {
643 err = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp);
644 if (!err)
645 break;
646 usbd_delay_ms(dev, 200);
647 }
648 if (err)
649 goto bad;
650
651 if (cdp->bDescriptorType != UDESC_CONFIG) {
652 DPRINTFN(-1,("usbd_set_config_index: bad desc %d\n",
653 cdp->bDescriptorType));
654 err = USBD_INVAL;
655 goto bad;
656 }
657
658
659 selfpowered = 0;
660 if (!(dev->quirks->uq_flags & UQ_BUS_POWERED) &&
661 (cdp->bmAttributes & UC_SELF_POWERED)) {
662
663 if (cdp->bmAttributes & UC_BUS_POWERED) {
664
665 if (dev->quirks->uq_flags & UQ_POWER_CLAIM) {
666
667
668
669
670
671 usb_hub_descriptor_t hd;
672 usb_device_request_t req;
673 req.bmRequestType = UT_READ_CLASS_DEVICE;
674 req.bRequest = UR_GET_DESCRIPTOR;
675 USETW(req.wValue, 0);
676 USETW(req.wIndex, 0);
677 USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE);
678 err = usbd_do_request(dev, &req, &hd);
679 if (!err &&
680 (UGETW(hd.wHubCharacteristics) &
681 UHD_PWR_INDIVIDUAL))
682 selfpowered = 1;
683 DPRINTF(("usbd_set_config_index: charac=0x%04x"
684 ", error=%s\n",
685 UGETW(hd.wHubCharacteristics),
686 usbd_errstr(err)));
687 } else {
688 err = usbd_get_device_status(dev, &ds);
689 if (!err &&
690 (UGETW(ds.wStatus) & UDS_SELF_POWERED))
691 selfpowered = 1;
692 DPRINTF(("usbd_set_config_index: status=0x%04x"
693 ", error=%s\n",
694 UGETW(ds.wStatus), usbd_errstr(err)));
695 }
696 } else
697 selfpowered = 1;
698 }
699 DPRINTF(("usbd_set_config_index: (addr %d) cno=%d attr=0x%02x, "
700 "selfpowered=%d, power=%d\n",
701 cdp->bConfigurationValue, dev->address, cdp->bmAttributes,
702 selfpowered, cdp->bMaxPower * 2));
703
704
705 #ifdef USB_DEBUG
706 if (dev->powersrc == NULL) {
707 DPRINTF(("usbd_set_config_index: No power source?\n"));
708 return (USBD_IOERROR);
709 }
710 #endif
711 power = cdp->bMaxPower * 2;
712 if (power > dev->powersrc->power) {
713 DPRINTF(("power exceeded %d %d\n", power,dev->powersrc->power));
714
715 if (msg)
716 printf("%s: device addr %d (config %d) exceeds power "
717 "budget, %d mA > %d mA\n",
718 dev->bus->bdev.dv_xname, dev->address,
719 cdp->bConfigurationValue,
720 power, dev->powersrc->power);
721 err = USBD_NO_POWER;
722 goto bad;
723 }
724 dev->power = power;
725 dev->self_powered = selfpowered;
726
727
728 DPRINTF(("usbd_set_config_index: set config %d\n",
729 cdp->bConfigurationValue));
730 err = usbd_set_config(dev, cdp->bConfigurationValue);
731 if (err) {
732 DPRINTF(("usbd_set_config_index: setting config=%d failed, "
733 "error=%s\n", cdp->bConfigurationValue, usbd_errstr(err)));
734 goto bad;
735 }
736
737
738 nifc = cdp->bNumInterface;
739 dev->ifaces = malloc(nifc * sizeof(struct usbd_interface),
740 M_USB, M_NOWAIT);
741 if (dev->ifaces == NULL) {
742 err = USBD_NOMEM;
743 goto bad;
744 }
745 DPRINTFN(5,("usbd_set_config_index: dev=%p cdesc=%p\n", dev, cdp));
746 dev->cdesc = cdp;
747 dev->config = cdp->bConfigurationValue;
748 for (ifcidx = 0; ifcidx < nifc; ifcidx++) {
749 err = usbd_fill_iface_data(dev, ifcidx, 0);
750 if (err) {
751 while (--ifcidx >= 0)
752 usbd_free_iface_data(dev, ifcidx);
753 goto bad;
754 }
755 }
756
757 return (USBD_NORMAL_COMPLETION);
758
759 bad:
760 free(cdp, M_USB);
761 return (err);
762 }
763
764
765
766 usbd_status
767 usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface,
768 struct usbd_endpoint *ep, int ival, usbd_pipe_handle *pipe)
769 {
770 usbd_pipe_handle p;
771 usbd_status err;
772
773 DPRINTFN(1,("usbd_setup_pipe: dev=%p iface=%p ep=%p pipe=%p\n",
774 dev, iface, ep, pipe));
775 p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT);
776 if (p == NULL)
777 return (USBD_NOMEM);
778 p->device = dev;
779 p->iface = iface;
780 p->endpoint = ep;
781 ep->refcnt++;
782 p->refcnt = 1;
783 p->intrxfer = 0;
784 p->running = 0;
785 p->aborting = 0;
786 p->repeat = 0;
787 p->interval = ival;
788 SIMPLEQ_INIT(&p->queue);
789 err = dev->bus->methods->open_pipe(p);
790 if (err) {
791 DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error="
792 "%s\n",
793 ep->edesc->bEndpointAddress, usbd_errstr(err)));
794 free(p, M_USB);
795 return (err);
796 }
797 *pipe = p;
798 return (USBD_NORMAL_COMPLETION);
799 }
800
801
802 void
803 usbd_kill_pipe(usbd_pipe_handle pipe)
804 {
805 usbd_abort_pipe(pipe);
806 pipe->methods->close(pipe);
807 pipe->endpoint->refcnt--;
808 free(pipe, M_USB);
809 }
810
811 int
812 usbd_getnewaddr(usbd_bus_handle bus)
813 {
814 int addr;
815
816 for (addr = 1; addr < USB_MAX_DEVICES; addr++)
817 if (bus->devices[addr] == 0)
818 return (addr);
819 return (-1);
820 }
821
822
823 usbd_status
824 usbd_probe_and_attach(struct device *parent, usbd_device_handle dev, int port,
825 int addr)
826 {
827 struct usb_attach_arg uaa;
828 usb_device_descriptor_t *dd = &dev->ddesc;
829 int found, i, confi, nifaces, len;
830 usbd_status err;
831 struct device *dv;
832 usbd_interface_handle *ifaces;
833
834 uaa.device = dev;
835 uaa.iface = NULL;
836 uaa.ifaces = NULL;
837 uaa.nifaces = 0;
838 uaa.usegeneric = 0;
839 uaa.port = port;
840 uaa.configno = UHUB_UNK_CONFIGURATION;
841 uaa.ifaceno = UHUB_UNK_INTERFACE;
842 uaa.vendor = UGETW(dd->idVendor);
843 uaa.product = UGETW(dd->idProduct);
844 uaa.release = UGETW(dd->bcdDevice);
845
846
847 DPRINTF(("usbd_probe_and_attach: trying device specific drivers\n"));
848 dv = config_found_sm(parent, &uaa, usbd_print, usbd_submatch);
849 if (dv) {
850 dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT);
851 if (dev->subdevs == NULL)
852 return (USBD_NOMEM);
853 dev->subdevs[0] = dv;
854 dev->subdevs[1] = 0;
855 return (USBD_NORMAL_COMPLETION);
856 }
857
858 DPRINTF(("usbd_probe_and_attach: no device specific driver found\n"));
859
860 DPRINTF(("usbd_probe_and_attach: looping over %d configurations\n",
861 dd->bNumConfigurations));
862
863 for (confi = 0; confi < dd->bNumConfigurations; confi++) {
864 DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n",
865 confi));
866 err = usbd_set_config_index(dev, confi, 1);
867 if (err) {
868 #ifdef USB_DEBUG
869 DPRINTF(("%s: port %d, set config at addr %d failed, "
870 "error=%s\n", parent->dv_xname, port,
871 addr, usbd_errstr(err)));
872 #else
873 printf("%s: port %d, set config at addr %d failed\n",
874 parent->dv_xname, port, addr);
875 #endif
876
877 return (err);
878 }
879 nifaces = dev->cdesc->bNumInterface;
880 uaa.configno = dev->cdesc->bConfigurationValue;
881 ifaces = malloc(nifaces * sizeof(usbd_interface_handle),
882 M_USB, M_NOWAIT);
883 if (ifaces == NULL)
884 return (USBD_NOMEM);
885 for (i = 0; i < nifaces; i++)
886 ifaces[i] = &dev->ifaces[i];
887 uaa.ifaces = ifaces;
888 uaa.nifaces = nifaces;
889 len = (nifaces+1) * sizeof dv;
890 dev->subdevs = malloc(len, M_USB, M_NOWAIT);
891 if (dev->subdevs == NULL) {
892 free(ifaces, M_USB);
893 return (USBD_NOMEM);
894 }
895 bzero(dev->subdevs, len);
896
897 found = 0;
898 for (i = 0; i < nifaces; i++) {
899 if (ifaces[i] == NULL)
900 continue;
901 uaa.iface = ifaces[i];
902 uaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber;
903 dv = config_found_sm(parent, &uaa, usbd_print,
904 usbd_submatch);
905
906 if (dv != NULL) {
907 dev->subdevs[found++] = dv;
908 ifaces[i] = NULL;
909 }
910 }
911 free(ifaces, M_USB);
912 if (found != 0) {
913 return (USBD_NORMAL_COMPLETION);
914 }
915 free(dev->subdevs, M_USB);
916 dev->subdevs = 0;
917 }
918
919
920 if (dd->bNumConfigurations > 1)
921 usbd_set_config_index(dev, 0, 0);
922
923 DPRINTF(("usbd_probe_and_attach: no interface drivers found\n"));
924
925
926 uaa.iface = NULL;
927 uaa.usegeneric = 1;
928 uaa.configno = UHUB_UNK_CONFIGURATION;
929 uaa.ifaceno = UHUB_UNK_INTERFACE;
930 dv = config_found_sm(parent, &uaa, usbd_print, usbd_submatch);
931 if (dv != NULL) {
932 dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT);
933 if (dev->subdevs == 0)
934 return (USBD_NOMEM);
935 dev->subdevs[0] = dv;
936 dev->subdevs[1] = 0;
937 return (USBD_NORMAL_COMPLETION);
938 }
939
940
941
942
943
944
945 DPRINTF(("usbd_probe_and_attach: generic attach failed\n"));
946 return (USBD_NORMAL_COMPLETION);
947 }
948
949
950
951
952
953
954
955
956 usbd_status
957 usbd_new_device(struct device *parent, usbd_bus_handle bus, int depth,
958 int speed, int port, struct usbd_port *up)
959 {
960 usbd_device_handle dev, adev;
961 struct usbd_device *hub;
962 usb_device_descriptor_t *dd;
963 usbd_status err;
964 int addr;
965 int i;
966 int p;
967
968 DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n",
969 bus, port, depth, speed));
970 addr = usbd_getnewaddr(bus);
971 if (addr < 0) {
972 printf("%s: No free USB addresses, new device ignored.\n",
973 bus->bdev.dv_xname);
974 return (USBD_NO_ADDR);
975 }
976
977 dev = malloc(sizeof *dev, M_USB, M_NOWAIT);
978 if (dev == NULL)
979 return (USBD_NOMEM);
980 memset(dev, 0, sizeof *dev);
981
982 dev->bus = bus;
983
984
985 dev->def_ep.edesc = &dev->def_ep_desc;
986
987
988 dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE;
989 dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT;
990 dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
991 dev->def_ep_desc.bmAttributes = UE_CONTROL;
992 USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET);
993 dev->def_ep_desc.bInterval = 0;
994
995 dev->quirks = &usbd_no_quirk;
996 dev->address = USB_START_ADDR;
997 dev->ddesc.bMaxPacketSize = 0;
998 dev->depth = depth;
999 dev->powersrc = up;
1000 dev->myhub = up->parent;
1001
1002 up->device = dev;
1003
1004
1005 for (adev = dev, hub = up->parent;
1006 hub != NULL && hub->speed != USB_SPEED_HIGH;
1007 adev = hub, hub = hub->myhub)
1008 ;
1009 if (hub) {
1010 for (p = 0; p < hub->hub->hubdesc.bNbrPorts; p++) {
1011 if (hub->hub->ports[p].device == adev) {
1012 dev->myhsport = &hub->hub->ports[p];
1013 goto found;
1014 }
1015 }
1016 panic("usbd_new_device: cannot find HS port");
1017 found:
1018 DPRINTFN(1,("usbd_new_device: high speed port %d\n", p));
1019 } else {
1020 dev->myhsport = NULL;
1021 }
1022 dev->speed = speed;
1023 dev->langid = USBD_NOLANG;
1024 dev->cookie.cookie = ++usb_cookie_no;
1025
1026
1027 err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
1028 &dev->default_pipe);
1029 if (err) {
1030 usbd_remove_device(dev, up);
1031 return (err);
1032 }
1033
1034 dd = &dev->ddesc;
1035
1036 for (i = 0; i < 5; i++) {
1037
1038 err = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd);
1039 if (!err)
1040 break;
1041
1042 usbd_delay_ms(dev, 200 * (i + 1));
1043 }
1044 if (err) {
1045 DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc "
1046 "failed\n", addr));
1047 usbd_remove_device(dev, up);
1048 return (err);
1049 }
1050
1051 if (speed == USB_SPEED_HIGH) {
1052
1053 if (dd->bMaxPacketSize != USB_2_MAX_CTRL_PACKET) {
1054 #ifdef DIAGNOSTIC
1055 printf("usbd_new_device: addr=%d bad max packet size\n",
1056 addr);
1057 #endif
1058 dd->bMaxPacketSize = USB_2_MAX_CTRL_PACKET;
1059 }
1060 }
1061
1062 DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, "
1063 "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n",
1064 addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass,
1065 dd->bDeviceProtocol, dd->bMaxPacketSize, dd->bLength,
1066 dev->speed));
1067
1068 if (dd->bDescriptorType != UDESC_DEVICE) {
1069
1070 DPRINTFN(-1,("usbd_new_device: illegal descriptor %d\n",
1071 dd->bDescriptorType));
1072 usbd_remove_device(dev, up);
1073 return (USBD_INVAL);
1074 }
1075
1076 if (dd->bLength < USB_DEVICE_DESCRIPTOR_SIZE) {
1077 DPRINTFN(-1,("usbd_new_device: bad length %d\n", dd->bLength));
1078 usbd_remove_device(dev, up);
1079 return (USBD_INVAL);
1080 }
1081
1082 USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize);
1083
1084 err = usbd_reload_device_desc(dev);
1085 if (err) {
1086 DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc "
1087 "failed\n", addr));
1088 usbd_remove_device(dev, up);
1089 return (err);
1090 }
1091
1092
1093 DPRINTFN(5,("usbd_new_device: setting device address=%d\n", addr));
1094 err = usbd_set_address(dev, addr);
1095 if (err) {
1096 DPRINTFN(-1,("usbd_new_device: set address %d failed\n", addr));
1097 err = USBD_SET_ADDR_FAILED;
1098 usbd_remove_device(dev, up);
1099 return (err);
1100 }
1101
1102 usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE);
1103
1104 dev->address = addr;
1105 bus->devices[addr] = dev;
1106
1107
1108 dev->power = USB_MIN_POWER;
1109 dev->self_powered = 0;
1110
1111 DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n",
1112 addr, dev, parent));
1113
1114 usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev);
1115
1116 err = usbd_probe_and_attach(parent, dev, port, addr);
1117 if (err) {
1118 usbd_remove_device(dev, up);
1119 return (err);
1120 }
1121
1122 return (USBD_NORMAL_COMPLETION);
1123 }
1124
1125 usbd_status
1126 usbd_reload_device_desc(usbd_device_handle dev)
1127 {
1128 usbd_status err;
1129
1130
1131 err = usbd_get_device_desc(dev, &dev->ddesc);
1132 if (err)
1133 return (err);
1134
1135
1136 dev->quirks = usbd_find_quirk(&dev->ddesc);
1137
1138 return (USBD_NORMAL_COMPLETION);
1139 }
1140
1141 void
1142 usbd_remove_device(usbd_device_handle dev, struct usbd_port *up)
1143 {
1144 DPRINTF(("usbd_remove_device: %p\n", dev));
1145
1146 if (dev->default_pipe != NULL)
1147 usbd_kill_pipe(dev->default_pipe);
1148 up->device = NULL;
1149 dev->bus->devices[dev->address] = NULL;
1150
1151 free(dev, M_USB);
1152 }
1153
1154 int
1155 usbd_print(void *aux, const char *pnp)
1156 {
1157 struct usb_attach_arg *uaa = aux;
1158 char devinfo[1024];
1159
1160 DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device));
1161 if (pnp) {
1162 if (!uaa->usegeneric)
1163 return (QUIET);
1164 usbd_devinfo(uaa->device, 1, devinfo, sizeof devinfo);
1165 printf("%s, %s", devinfo, pnp);
1166 }
1167 if (uaa->port != 0)
1168 printf(" port %d", uaa->port);
1169 if (uaa->configno != UHUB_UNK_CONFIGURATION)
1170 printf(" configuration %d", uaa->configno);
1171 if (uaa->ifaceno != UHUB_UNK_INTERFACE)
1172 printf(" interface %d", uaa->ifaceno);
1173 #if 0
1174
1175
1176
1177
1178
1179 if (uaa->vendor != UHUB_UNK_VENDOR)
1180 printf(" vendor 0x%04x", uaa->vendor);
1181 if (uaa->product != UHUB_UNK_PRODUCT)
1182 printf(" product 0x%04x", uaa->product);
1183 if (uaa->release != UHUB_UNK_RELEASE)
1184 printf(" release 0x%04x", uaa->release);
1185 #endif
1186 return (UNCONF);
1187 }
1188
1189 int
1190 usbd_submatch(struct device *parent, void *match, void *aux)
1191 {
1192 struct cfdata *cf = match;
1193 struct usb_attach_arg *uaa = aux;
1194
1195 DPRINTFN(5,("usbd_submatch port=%d,%d configno=%d,%d "
1196 "ifaceno=%d,%d vendor=%d,%d product=%d,%d release=%d,%d\n",
1197 uaa->port, cf->uhubcf_port,
1198 uaa->configno, cf->uhubcf_configuration,
1199 uaa->ifaceno, cf->uhubcf_interface,
1200 uaa->vendor, cf->uhubcf_vendor,
1201 uaa->product, cf->uhubcf_product,
1202 uaa->release, cf->uhubcf_release));
1203 if (uaa->port != 0 &&
1204 ((uaa->port != 0 &&
1205 cf->uhubcf_port != UHUB_UNK_PORT &&
1206 cf->uhubcf_port != uaa->port) ||
1207 (uaa->configno != UHUB_UNK_CONFIGURATION &&
1208 cf->uhubcf_configuration != UHUB_UNK_CONFIGURATION &&
1209 cf->uhubcf_configuration != uaa->configno) ||
1210 (uaa->ifaceno != UHUB_UNK_INTERFACE &&
1211 cf->uhubcf_interface != UHUB_UNK_INTERFACE &&
1212 cf->uhubcf_interface != uaa->ifaceno) ||
1213 (uaa->vendor != UHUB_UNK_VENDOR &&
1214 cf->uhubcf_vendor != UHUB_UNK_VENDOR &&
1215 cf->uhubcf_vendor != uaa->vendor) ||
1216 (uaa->product != UHUB_UNK_PRODUCT &&
1217 cf->uhubcf_product != UHUB_UNK_PRODUCT &&
1218 cf->uhubcf_product != uaa->product) ||
1219 (uaa->release != UHUB_UNK_RELEASE &&
1220 cf->uhubcf_release != UHUB_UNK_RELEASE &&
1221 cf->uhubcf_release != uaa->release)
1222 )
1223 )
1224 return 0;
1225 if (cf->uhubcf_vendor != UHUB_UNK_VENDOR &&
1226 cf->uhubcf_vendor == uaa->vendor &&
1227 cf->uhubcf_product != UHUB_UNK_PRODUCT &&
1228 cf->uhubcf_product == uaa->product) {
1229
1230 if (cf->uhubcf_release != UHUB_UNK_RELEASE &&
1231 cf->uhubcf_release == uaa->release)
1232 uaa->matchlvl = UMATCH_VENDOR_PRODUCT_REV;
1233 else
1234 uaa->matchlvl = UMATCH_VENDOR_PRODUCT;
1235 } else
1236 uaa->matchlvl = 0;
1237 return ((*cf->cf_attach->ca_match)(parent, cf, aux));
1238 }
1239
1240 void
1241 usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di,
1242 int usedev)
1243 {
1244 struct usbd_port *p;
1245 int i, err, s;
1246
1247 di->udi_bus = dev->bus->bdev.dv_unit;
1248 di->udi_addr = dev->address;
1249 di->udi_cookie = dev->cookie;
1250 usbd_devinfo_vp(dev, di->udi_vendor, di->udi_product, usedev);
1251 usbd_printBCD(di->udi_release, sizeof di->udi_release,
1252 UGETW(dev->ddesc.bcdDevice));
1253 di->udi_vendorNo = UGETW(dev->ddesc.idVendor);
1254 di->udi_productNo = UGETW(dev->ddesc.idProduct);
1255 di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice);
1256 di->udi_class = dev->ddesc.bDeviceClass;
1257 di->udi_subclass = dev->ddesc.bDeviceSubClass;
1258 di->udi_protocol = dev->ddesc.bDeviceProtocol;
1259 di->udi_config = dev->config;
1260 di->udi_power = dev->self_powered ? 0 : dev->power;
1261 di->udi_speed = dev->speed;
1262
1263 if (dev->subdevs != NULL) {
1264 for (i = 0; dev->subdevs[i] && i < USB_MAX_DEVNAMES; i++) {
1265 strncpy(di->udi_devnames[i],
1266 dev->subdevs[i]->dv_xname, USB_MAX_DEVNAMELEN);
1267 di->udi_devnames[i][USB_MAX_DEVNAMELEN-1] = '\0';
1268 }
1269 } else
1270 i = 0;
1271
1272 for (; i < USB_MAX_DEVNAMES; i++)
1273 di->udi_devnames[i][0] = 0;
1274
1275 if (dev->hub) {
1276 for (i = 0;
1277 i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) &&
1278 i < dev->hub->hubdesc.bNbrPorts; i++) {
1279 p = &dev->hub->ports[i];
1280 if (p->device)
1281 err = p->device->address;
1282 else {
1283 s = UGETW(p->status.wPortStatus);
1284 if (s & UPS_PORT_ENABLED)
1285 err = USB_PORT_ENABLED;
1286 else if (s & UPS_SUSPEND)
1287 err = USB_PORT_SUSPENDED;
1288 else if (s & UPS_PORT_POWER)
1289 err = USB_PORT_POWERED;
1290 else
1291 err = USB_PORT_DISABLED;
1292 }
1293 di->udi_ports[i] = err;
1294 }
1295 di->udi_nports = dev->hub->hubdesc.bNbrPorts;
1296 } else
1297 di->udi_nports = 0;
1298 }
1299
1300 void
1301 usb_free_device(usbd_device_handle dev)
1302 {
1303 int ifcidx, nifc;
1304
1305 if (dev->default_pipe != NULL)
1306 usbd_kill_pipe(dev->default_pipe);
1307 if (dev->ifaces != NULL) {
1308 nifc = dev->cdesc->bNumInterface;
1309 for (ifcidx = 0; ifcidx < nifc; ifcidx++)
1310 usbd_free_iface_data(dev, ifcidx);
1311 free(dev->ifaces, M_USB);
1312 }
1313 if (dev->cdesc != NULL)
1314 free(dev->cdesc, M_USB);
1315 if (dev->subdevs != NULL)
1316 free(dev->subdevs, M_USB);
1317 free(dev, M_USB);
1318 }
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337 void
1338 usb_disconnect_port(struct usbd_port *up, struct device *parent)
1339 {
1340 usbd_device_handle dev = up->device;
1341 int i;
1342
1343 DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
1344 up, dev, up->portno));
1345
1346 #ifdef DIAGNOSTIC
1347 if (dev == NULL) {
1348 printf("usb_disconnect_port: no device\n");
1349 return;
1350 }
1351 #endif
1352
1353 if (dev->subdevs != NULL) {
1354 DPRINTFN(3,("usb_disconnect_port: disconnect subdevs\n"));
1355 for (i = 0; dev->subdevs[i]; i++) {
1356 DPRINTF(("%s: at %s", dev->subdevs[i]->dv_xname,
1357 parent->dv_xname));
1358 if (up->portno != 0)
1359 DPRINTF((" port %d", up->portno));
1360 DPRINTF((" (addr %d) disconnected\n", dev->address));
1361 config_detach(dev->subdevs[i], DETACH_FORCE);
1362 dev->subdevs[i] = 0;
1363 }
1364 }
1365
1366 usbd_add_dev_event(USB_EVENT_DEVICE_DETACH, dev);
1367 dev->bus->devices[dev->address] = NULL;
1368 up->device = NULL;
1369 usb_free_device(dev);
1370 }