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