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