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