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