1 /* $NetBSD: uhub.c,v 1.129 2015/03/28 07:58:00 skrll Exp $ */ 2 /* $FreeBSD: src/sys/dev/usb/uhub.c,v 1.18 1999/11/17 22:33:43 n_hibma Exp $ */ 3 4 /* 5 * Copyright (c) 1998, 2004 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 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * USB spec: http://www.usb.org/developers/docs/usbspec.zip 36 */ 37 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: uhub.c,v 1.129 2015/03/28 07:58:00 skrll Exp $"); 40 41 #include <sys/param.h> 42 43 #include <sys/systm.h> 44 #include <sys/device.h> 45 #include <sys/kernel.h> 46 #include <sys/malloc.h> 47 #include <sys/proc.h> 48 #include <sys/sysctl.h> 49 50 #include <sys/bus.h> 51 52 #include <dev/usb/usb.h> 53 #include <dev/usb/usbdi.h> 54 #include <dev/usb/usbdi_util.h> 55 #include <dev/usb/usbdivar.h> 56 #include <dev/usb/usbhist.h> 57 58 #ifdef USB_DEBUG 59 #ifndef UHUB_DEBUG 60 #define uhubdebug 0 61 #else 62 static int uhubdebug = 0; 63 64 SYSCTL_SETUP(sysctl_hw_uhub_setup, "sysctl hw.uhub setup") 65 { 66 int err; 67 const struct sysctlnode *rnode; 68 const struct sysctlnode *cnode; 69 70 err = sysctl_createv(clog, 0, NULL, &rnode, 71 CTLFLAG_PERMANENT, CTLTYPE_NODE, "uhub", 72 SYSCTL_DESCR("uhub global controls"), 73 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 74 75 if (err) 76 goto fail; 77 78 /* control debugging printfs */ 79 err = sysctl_createv(clog, 0, &rnode, &cnode, 80 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 81 "debug", SYSCTL_DESCR("Enable debugging output"), 82 NULL, 0, &uhubdebug, sizeof(uhubdebug), CTL_CREATE, CTL_EOL); 83 if (err) 84 goto fail; 85 86 return; 87 fail: 88 aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); 89 } 90 91 #endif /* UHUB_DEBUG */ 92 #endif /* USB_DEBUG */ 93 94 #define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(uhubdebug,1,FMT,A,B,C,D) 95 #define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(uhubdebug,N,FMT,A,B,C,D) 96 #define UHUBHIST_FUNC() USBHIST_FUNC() 97 #define UHUBHIST_CALLED(name) USBHIST_CALLED(uhubdebug) 98 99 struct uhub_softc { 100 device_t sc_dev; /* base device */ 101 usbd_device_handle sc_hub; /* USB device */ 102 int sc_proto; /* device protocol */ 103 usbd_pipe_handle sc_ipipe; /* interrupt pipe */ 104 105 /* XXX second buffer needed because we can't suspend pipes yet */ 106 u_int8_t *sc_statusbuf; 107 u_int8_t *sc_status; 108 size_t sc_statuslen; 109 int sc_explorepending; 110 int sc_isehciroothub; /* see comment in uhub_intr() */ 111 112 u_char sc_running; 113 }; 114 115 #define UHUB_IS_HIGH_SPEED(sc) ((sc)->sc_proto != UDPROTO_FSHUB) 116 #define UHUB_IS_SINGLE_TT(sc) ((sc)->sc_proto == UDPROTO_HSHUBSTT) 117 118 #define PORTSTAT_ISSET(sc, port) \ 119 ((sc)->sc_status[(port) / 8] & (1 << ((port) % 8))) 120 121 Static usbd_status uhub_explore(usbd_device_handle hub); 122 Static void uhub_intr(usbd_xfer_handle, usbd_private_handle,usbd_status); 123 124 125 /* 126 * We need two attachment points: 127 * hub to usb and hub to hub 128 * Every other driver only connects to hubs 129 */ 130 131 int uhub_match(device_t, cfdata_t, void *); 132 void uhub_attach(device_t, device_t, void *); 133 int uhub_rescan(device_t, const char *, const int *); 134 void uhub_childdet(device_t, device_t); 135 int uhub_detach(device_t, int); 136 extern struct cfdriver uhub_cd; 137 CFATTACH_DECL3_NEW(uhub, sizeof(struct uhub_softc), uhub_match, 138 uhub_attach, uhub_detach, NULL, uhub_rescan, uhub_childdet, 139 DVF_DETACH_SHUTDOWN); 140 CFATTACH_DECL2_NEW(uroothub, sizeof(struct uhub_softc), uhub_match, 141 uhub_attach, uhub_detach, NULL, uhub_rescan, uhub_childdet); 142 143 /* 144 * Setting this to 1 makes sure than an uhub attaches even at higher 145 * priority than ugen when ugen_override is set to 1. This allows to 146 * probe the whole USB bus and attach functions with ugen. 147 */ 148 int uhub_ubermatch = 0; 149 150 int 151 uhub_match(device_t parent, cfdata_t match, void *aux) 152 { 153 struct usb_attach_arg *uaa = aux; 154 int matchvalue; 155 156 UHUBHIST_FUNC(); UHUBHIST_CALLED(); 157 158 if (uhub_ubermatch) 159 matchvalue = UMATCH_HIGHEST+1; 160 else 161 matchvalue = UMATCH_DEVCLASS_DEVSUBCLASS; 162 163 DPRINTFN(5, "uaa=%p", uaa, 0, 0, 0); 164 /* 165 * The subclass for hubs seems to be 0 for some and 1 for others, 166 * so we just ignore the subclass. 167 */ 168 if (uaa->class == UDCLASS_HUB) 169 return (matchvalue); 170 return (UMATCH_NONE); 171 } 172 173 void 174 uhub_attach(device_t parent, device_t self, void *aux) 175 { 176 struct uhub_softc *sc = device_private(self); 177 struct usb_attach_arg *uaa = aux; 178 usbd_device_handle dev = uaa->device; 179 char *devinfop; 180 usbd_status err; 181 struct usbd_hub *hub = NULL; 182 usb_device_request_t req; 183 usb_hub_descriptor_t hubdesc; 184 int p, port, nports, nremov, pwrdly; 185 usbd_interface_handle iface; 186 usb_endpoint_descriptor_t *ed; 187 #if 0 /* notyet */ 188 struct usbd_tt *tts = NULL; 189 #endif 190 191 UHUBHIST_FUNC(); UHUBHIST_CALLED(); 192 193 sc->sc_dev = self; 194 sc->sc_hub = dev; 195 sc->sc_proto = uaa->proto; 196 197 devinfop = usbd_devinfo_alloc(dev, 1); 198 aprint_naive("\n"); 199 aprint_normal(": %s\n", devinfop); 200 usbd_devinfo_free(devinfop); 201 202 if (dev->depth > 0 && UHUB_IS_HIGH_SPEED(sc)) { 203 aprint_normal_dev(self, "%s transaction translator%s\n", 204 UHUB_IS_SINGLE_TT(sc) ? "single" : "multiple", 205 UHUB_IS_SINGLE_TT(sc) ? "" : "s"); 206 } 207 208 err = usbd_set_config_index(dev, 0, 1); 209 if (err) { 210 DPRINTF("configuration failed, sc %p error %d", sc, err, 0, 0); 211 return; 212 } 213 214 if (dev->depth > USB_HUB_MAX_DEPTH) { 215 aprint_error_dev(self, 216 "hub depth (%d) exceeded, hub ignored\n", 217 USB_HUB_MAX_DEPTH); 218 return; 219 } 220 221 /* Get hub descriptor. */ 222 req.bmRequestType = UT_READ_CLASS_DEVICE; 223 req.bRequest = UR_GET_DESCRIPTOR; 224 USETW2(req.wValue, UDESC_HUB, 0); 225 USETW(req.wIndex, 0); 226 USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE); 227 DPRINTF("uhub %d getting hub descriptor", device_unit(self), 0, 0, 0); 228 err = usbd_do_request(dev, &req, &hubdesc); 229 nports = hubdesc.bNbrPorts; 230 if (!err && nports > 7) { 231 USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE + (nports+1) / 8); 232 err = usbd_do_request(dev, &req, &hubdesc); 233 } 234 if (err) { 235 DPRINTF("getting hub descriptor failed, uhub %d error %d", 236 device_unit(self), err, 0, 0); 237 return; 238 } 239 240 for (nremov = 0, port = 1; port <= nports; port++) 241 if (!UHD_NOT_REMOV(&hubdesc, port)) 242 nremov++; 243 aprint_verbose_dev(self, "%d port%s with %d removable, %s powered\n", 244 nports, nports != 1 ? "s" : "", nremov, 245 dev->self_powered ? "self" : "bus"); 246 247 if (nports == 0) { 248 aprint_debug_dev(self, "no ports, hub ignored\n"); 249 goto bad; 250 } 251 252 hub = malloc(sizeof(*hub) + (nports-1) * sizeof(struct usbd_port), 253 M_USBDEV, M_NOWAIT); 254 if (hub == NULL) 255 return; 256 dev->hub = hub; 257 dev->hub->hubsoftc = sc; 258 hub->explore = uhub_explore; 259 hub->hubdesc = hubdesc; 260 261 /* Set up interrupt pipe. */ 262 err = usbd_device2interface_handle(dev, 0, &iface); 263 if (err) { 264 aprint_error_dev(self, "no interface handle\n"); 265 goto bad; 266 } 267 268 if (UHUB_IS_HIGH_SPEED(sc) && !UHUB_IS_SINGLE_TT(sc)) { 269 err = usbd_set_interface(iface, 1); 270 if (err) 271 aprint_error_dev(self, "can't enable multiple TTs\n"); 272 } 273 274 ed = usbd_interface2endpoint_descriptor(iface, 0); 275 if (ed == NULL) { 276 aprint_error_dev(self, "no endpoint descriptor\n"); 277 goto bad; 278 } 279 if ((ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) { 280 aprint_error_dev(self, "bad interrupt endpoint\n"); 281 goto bad; 282 } 283 284 sc->sc_statuslen = (nports + 1 + 7) / 8; 285 sc->sc_statusbuf = malloc(sc->sc_statuslen, M_USBDEV, M_NOWAIT); 286 if (!sc->sc_statusbuf) 287 goto bad; 288 sc->sc_status = malloc(sc->sc_statuslen, M_USBDEV, M_NOWAIT); 289 if (!sc->sc_status) 290 goto bad; 291 if (device_is_a(device_parent(device_parent(sc->sc_dev)), "ehci")) 292 sc->sc_isehciroothub = 1; 293 294 /* force initial scan */ 295 memset(sc->sc_status, 0xff, sc->sc_statuslen); 296 sc->sc_explorepending = 1; 297 298 err = usbd_open_pipe_intr(iface, ed->bEndpointAddress, 299 USBD_SHORT_XFER_OK|USBD_MPSAFE, &sc->sc_ipipe, sc, 300 sc->sc_statusbuf, sc->sc_statuslen, 301 uhub_intr, USBD_DEFAULT_INTERVAL); 302 if (err) { 303 aprint_error_dev(self, "cannot open interrupt pipe\n"); 304 goto bad; 305 } 306 307 /* Wait with power off for a while. */ 308 usbd_delay_ms(dev, USB_POWER_DOWN_TIME); 309 310 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, sc->sc_dev); 311 312 /* 313 * To have the best chance of success we do things in the exact same 314 * order as Windows 98. This should not be necessary, but some 315 * devices do not follow the USB specs to the letter. 316 * 317 * These are the events on the bus when a hub is attached: 318 * Get device and config descriptors (see attach code) 319 * Get hub descriptor (see above) 320 * For all ports 321 * turn on power 322 * wait for power to become stable 323 * (all below happens in explore code) 324 * For all ports 325 * clear C_PORT_CONNECTION 326 * For all ports 327 * get port status 328 * if device connected 329 * wait 100 ms 330 * turn on reset 331 * wait 332 * clear C_PORT_RESET 333 * get port status 334 * proceed with device attachment 335 */ 336 337 #if 0 338 if (UHUB_IS_HIGH_SPEED(sc) && nports > 0) { 339 tts = malloc((UHUB_IS_SINGLE_TT(sc) ? 1 : nports) * 340 sizeof (struct usbd_tt), M_USBDEV, M_NOWAIT); 341 if (!tts) 342 goto bad; 343 } 344 #endif 345 /* Set up data structures */ 346 for (p = 0; p < nports; p++) { 347 struct usbd_port *up = &hub->ports[p]; 348 up->device = NULL; 349 up->parent = dev; 350 up->portno = p+1; 351 if (dev->self_powered) 352 /* Self powered hub, give ports maximum current. */ 353 up->power = USB_MAX_POWER; 354 else 355 up->power = USB_MIN_POWER; 356 up->restartcnt = 0; 357 up->reattach = 0; 358 #if 0 359 if (UHUB_IS_HIGH_SPEED(sc)) { 360 up->tt = &tts[UHUB_IS_SINGLE_TT(sc) ? 0 : p]; 361 up->tt->hub = hub; 362 } else { 363 up->tt = NULL; 364 } 365 #endif 366 } 367 368 /* XXX should check for none, individual, or ganged power? */ 369 370 pwrdly = dev->hub->hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR 371 + USB_EXTRA_POWER_UP_TIME; 372 for (port = 1; port <= nports; port++) { 373 /* Turn the power on. */ 374 err = usbd_set_port_feature(dev, port, UHF_PORT_POWER); 375 if (err) 376 aprint_error_dev(self, "port %d power on failed, %s\n", 377 port, usbd_errstr(err)); 378 DPRINTF("uhub %d turn on port %d power", device_unit(self), 379 port, 0, 0); 380 } 381 382 /* Wait for stable power if we are not a root hub */ 383 if (dev->powersrc->parent != NULL) 384 usbd_delay_ms(dev, pwrdly); 385 386 /* The usual exploration will finish the setup. */ 387 388 sc->sc_running = 1; 389 390 if (!pmf_device_register(self, NULL, NULL)) 391 aprint_error_dev(self, "couldn't establish power handler\n"); 392 393 return; 394 395 bad: 396 if (sc->sc_status) 397 free(sc->sc_status, M_USBDEV); 398 if (sc->sc_statusbuf) 399 free(sc->sc_statusbuf, M_USBDEV); 400 if (hub) 401 free(hub, M_USBDEV); 402 dev->hub = NULL; 403 return; 404 } 405 406 usbd_status 407 uhub_explore(usbd_device_handle dev) 408 { 409 usb_hub_descriptor_t *hd = &dev->hub->hubdesc; 410 struct uhub_softc *sc = dev->hub->hubsoftc; 411 struct usbd_port *up; 412 usbd_status err; 413 int speed; 414 int port; 415 int change, status, reconnect; 416 417 UHUBHIST_FUNC(); UHUBHIST_CALLED(); 418 419 DPRINTFN(10, "uhub %d dev=%p addr=%d speed=%u", 420 device_unit(sc->sc_dev), dev, dev->address, dev->speed); 421 422 if (!sc->sc_running) 423 return (USBD_NOT_STARTED); 424 425 /* Ignore hubs that are too deep. */ 426 if (dev->depth > USB_HUB_MAX_DEPTH) 427 return (USBD_TOO_DEEP); 428 429 if (PORTSTAT_ISSET(sc, 0)) { /* hub status change */ 430 usb_hub_status_t hs; 431 432 err = usbd_get_hub_status(dev, &hs); 433 if (err) { 434 DPRINTF("uhub %d get hub status failed, err %d", 435 device_unit(sc->sc_dev), err, 0, 0); 436 } else { 437 /* just acknowledge */ 438 status = UGETW(hs.wHubStatus); 439 change = UGETW(hs.wHubChange); 440 DPRINTF("uhub %d s/c=%x/%x", device_unit(sc->sc_dev), 441 status, change, 0); 442 443 if (change & UHS_LOCAL_POWER) 444 usbd_clear_hub_feature(dev, 445 UHF_C_HUB_LOCAL_POWER); 446 if (change & UHS_OVER_CURRENT) 447 usbd_clear_hub_feature(dev, 448 UHF_C_HUB_OVER_CURRENT); 449 } 450 } 451 452 for (port = 1; port <= hd->bNbrPorts; port++) { 453 up = &dev->hub->ports[port-1]; 454 455 /* reattach is needed after firmware upload */ 456 reconnect = up->reattach; 457 up->reattach = 0; 458 459 status = change = 0; 460 461 /* don't check if no change summary notification */ 462 if (PORTSTAT_ISSET(sc, port) || reconnect) { 463 err = usbd_get_port_status(dev, port, &up->status); 464 if (err) { 465 DPRINTF("uhub %d get port stat failed, err %d", 466 device_unit(sc->sc_dev), err, 0, 0); 467 continue; 468 } 469 status = UGETW(up->status.wPortStatus); 470 change = UGETW(up->status.wPortChange); 471 472 DPRINTF("uhub %d port %d: s/c=%x/%x", 473 device_unit(sc->sc_dev), port, status, change); 474 } 475 if (!change && !reconnect) { 476 /* No status change, just do recursive explore. */ 477 if (up->device != NULL && up->device->hub != NULL) 478 up->device->hub->explore(up->device); 479 continue; 480 } 481 482 if (change & UPS_C_PORT_ENABLED) { 483 DPRINTF("uhub %d port %d C_PORT_ENABLED", 484 device_unit(sc->sc_dev), port, 0, 0); 485 usbd_clear_port_feature(dev, port, UHF_C_PORT_ENABLE); 486 if (change & UPS_C_CONNECT_STATUS) { 487 /* Ignore the port error if the device 488 vanished. */ 489 } else if (status & UPS_PORT_ENABLED) { 490 aprint_error_dev(sc->sc_dev, 491 "illegal enable change, port %d\n", port); 492 } else { 493 /* Port error condition. */ 494 if (up->restartcnt) /* no message first time */ 495 aprint_error_dev(sc->sc_dev, 496 "port error, restarting port %d\n", 497 port); 498 499 if (up->restartcnt++ < USBD_RESTART_MAX) 500 goto disco; 501 else 502 aprint_error_dev(sc->sc_dev, 503 "port error, giving up port %d\n", 504 port); 505 } 506 } 507 508 /* XXX handle overcurrent and resume events! */ 509 510 if (!reconnect && !(change & UPS_C_CONNECT_STATUS)) { 511 /* No status change, just do recursive explore. */ 512 if (up->device != NULL && up->device->hub != NULL) 513 up->device->hub->explore(up->device); 514 continue; 515 } 516 517 /* We have a connect status change, handle it. */ 518 519 DPRINTF("status change hub=%d port=%d", dev->address, port, 0, 520 0); 521 usbd_clear_port_feature(dev, port, UHF_C_PORT_CONNECTION); 522 /* 523 * If there is already a device on the port the change status 524 * must mean that is has disconnected. Looking at the 525 * current connect status is not enough to figure this out 526 * since a new unit may have been connected before we handle 527 * the disconnect. 528 */ 529 disco: 530 if (up->device != NULL) { 531 /* Disconnected */ 532 DPRINTF("uhub %d device addr=%d disappeared on port %d", 533 device_unit(sc->sc_dev), up->device->address, port, 534 0); 535 usb_disconnect_port(up, sc->sc_dev, DETACH_FORCE); 536 usbd_clear_port_feature(dev, port, 537 UHF_C_PORT_CONNECTION); 538 } 539 if (!(status & UPS_CURRENT_CONNECT_STATUS)) { 540 /* Nothing connected, just ignore it. */ 541 DPRINTFN(3, "uhub %d port=%d !CURRENT_CONNECT_STATUS", 542 device_unit(sc->sc_dev), port, 0, 0); 543 continue; 544 } 545 546 /* Connected */ 547 DPRINTF("unit %d dev->speed=%u dev->depth=%u", 548 device_unit(sc->sc_dev), dev->speed, dev->depth, 0); 549 550 if (!(status & UPS_PORT_POWER)) 551 aprint_normal_dev(sc->sc_dev, 552 "strange, connected port %d has no power\n", port); 553 554 /* Wait for maximum device power up time. */ 555 usbd_delay_ms(dev, USB_PORT_POWERUP_DELAY); 556 557 /* Reset port, which implies enabling it. */ 558 if (usbd_reset_port(dev, port, &up->status)) { 559 aprint_error_dev(sc->sc_dev, 560 "port %d reset failed\n", port); 561 continue; 562 } 563 /* Get port status again, it might have changed during reset */ 564 err = usbd_get_port_status(dev, port, &up->status); 565 if (err) { 566 DPRINTF("uhub %d port=%d get port status failed, " 567 "err %d", device_unit(sc->sc_dev), port, err, 0); 568 continue; 569 } 570 status = UGETW(up->status.wPortStatus); 571 change = UGETW(up->status.wPortChange); 572 if (!(status & UPS_CURRENT_CONNECT_STATUS)) { 573 /* Nothing connected, just ignore it. */ 574 #ifdef DIAGNOSTIC 575 aprint_debug_dev(sc->sc_dev, 576 "port %d, device disappeared after reset\n", port); 577 #endif 578 continue; 579 } 580 if (!(status & UPS_PORT_ENABLED)) { 581 /* Not allowed send/receive packet. */ 582 #ifdef DIAGNOSTIC 583 printf("%s: port %d, device not enabled\n", 584 device_xname(sc->sc_dev), port); 585 #endif 586 continue; 587 } 588 589 /* Figure out device speed */ 590 #if 0 591 if (status & UPS_SUPER_SPEED) 592 speed = USB_SPEED_SUPER; 593 else 594 #endif 595 if (status & UPS_HIGH_SPEED) 596 speed = USB_SPEED_HIGH; 597 else if (status & UPS_LOW_SPEED) 598 speed = USB_SPEED_LOW; 599 else 600 speed = USB_SPEED_FULL; 601 602 DPRINTF("uhub %d speed %u", device_unit(sc->sc_dev), speed, 0, 603 0); 604 605 /* Get device info and set its address. */ 606 err = usbd_new_device(sc->sc_dev, dev->bus, 607 dev->depth + 1, speed, port, up); 608 /* XXX retry a few times? */ 609 if (err) { 610 DPRINTF("usbd_new_device failed, error %d", err, 0, 0, 611 0); 612 /* Avoid addressing problems by disabling. */ 613 /* usbd_reset_port(dev, port, &up->status); */ 614 615 /* 616 * The unit refused to accept a new address, or had 617 * some other serious problem. Since we cannot leave 618 * at 0 we have to disable the port instead. 619 */ 620 aprint_error_dev(sc->sc_dev, 621 "device problem, disabling port %d\n", port); 622 usbd_clear_port_feature(dev, port, UHF_PORT_ENABLE); 623 } else { 624 /* The port set up succeeded, reset error count. */ 625 up->restartcnt = 0; 626 627 if (up->device->hub) 628 up->device->hub->explore(up->device); 629 } 630 } 631 /* enable status change notifications again */ 632 if (!sc->sc_isehciroothub) 633 memset(sc->sc_status, 0, sc->sc_statuslen); 634 sc->sc_explorepending = 0; 635 return (USBD_NORMAL_COMPLETION); 636 } 637 638 /* 639 * Called from process context when the hub is gone. 640 * Detach all devices on active ports. 641 */ 642 int 643 uhub_detach(device_t self, int flags) 644 { 645 struct uhub_softc *sc = device_private(self); 646 struct usbd_hub *hub = sc->sc_hub->hub; 647 struct usbd_port *rup; 648 int nports, port, rc; 649 650 UHUBHIST_FUNC(); UHUBHIST_CALLED(); 651 652 DPRINTF("uhub %d flags=%d", device_unit(self), flags, 0, 0); 653 654 if (hub == NULL) /* Must be partially working */ 655 return (0); 656 657 /* XXXSMP usb */ 658 KERNEL_LOCK(1, curlwp); 659 660 nports = hub->hubdesc.bNbrPorts; 661 for(port = 0; port < nports; port++) { 662 rup = &hub->ports[port]; 663 if (rup->device == NULL) 664 continue; 665 if ((rc = usb_disconnect_port(rup, self, flags)) != 0) { 666 /* XXXSMP usb */ 667 KERNEL_UNLOCK_ONE(curlwp); 668 669 return rc; 670 } 671 } 672 673 pmf_device_deregister(self); 674 usbd_abort_pipe(sc->sc_ipipe); 675 usbd_close_pipe(sc->sc_ipipe); 676 677 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_hub, sc->sc_dev); 678 679 #if 0 680 if (hub->ports[0].tt) 681 free(hub->ports[0].tt, M_USBDEV); 682 #endif 683 free(hub, M_USBDEV); 684 sc->sc_hub->hub = NULL; 685 if (sc->sc_status) 686 free(sc->sc_status, M_USBDEV); 687 if (sc->sc_statusbuf) 688 free(sc->sc_statusbuf, M_USBDEV); 689 690 /* XXXSMP usb */ 691 KERNEL_UNLOCK_ONE(curlwp); 692 693 return (0); 694 } 695 696 int 697 uhub_rescan(device_t self, const char *ifattr, const int *locators) 698 { 699 struct uhub_softc *sc = device_private(self); 700 struct usbd_hub *hub = sc->sc_hub->hub; 701 usbd_device_handle dev; 702 int port; 703 704 for (port = 0; port < hub->hubdesc.bNbrPorts; port++) { 705 dev = hub->ports[port].device; 706 if (dev == NULL) 707 continue; 708 usbd_reattach_device(sc->sc_dev, dev, port, locators); 709 } 710 return 0; 711 } 712 713 /* Called when a device has been detached from it */ 714 void 715 uhub_childdet(device_t self, device_t child) 716 { 717 struct uhub_softc *sc = device_private(self); 718 usbd_device_handle devhub = sc->sc_hub; 719 usbd_device_handle dev; 720 int nports; 721 int port; 722 int i; 723 724 if (!devhub->hub) 725 /* should never happen; children are only created after init */ 726 panic("hub not fully initialised, but child deleted?"); 727 728 nports = devhub->hub->hubdesc.bNbrPorts; 729 for (port = 0; port < nports; port++) { 730 dev = devhub->hub->ports[port].device; 731 if (!dev || dev->subdevlen == 0) 732 continue; 733 for (i = 0; i < dev->subdevlen; i++) { 734 if (dev->subdevs[i] == child) { 735 dev->subdevs[i] = NULL; 736 dev->nifaces_claimed--; 737 } 738 } 739 if (dev->nifaces_claimed == 0) { 740 free(dev->subdevs, M_USB); 741 dev->subdevs = NULL; 742 dev->subdevlen = 0; 743 } 744 } 745 } 746 747 748 /* 749 * Hub interrupt. 750 * This an indication that some port has changed status. 751 * Notify the bus event handler thread that we need 752 * to be explored again. 753 */ 754 void 755 uhub_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) 756 { 757 struct uhub_softc *sc = addr; 758 759 UHUBHIST_FUNC(); UHUBHIST_CALLED(); 760 761 DPRINTFN(5, "uhub %d", device_unit(sc->sc_dev), 0, 0, 0); 762 763 if (status == USBD_STALLED) 764 usbd_clear_endpoint_stall_async(sc->sc_ipipe); 765 else if (status == USBD_NORMAL_COMPLETION && 766 !sc->sc_explorepending) { 767 /* 768 * Make sure the status is not overwritten in between. 769 * XXX we should suspend the pipe instead 770 */ 771 memcpy(sc->sc_status, sc->sc_statusbuf, sc->sc_statuslen); 772 sc->sc_explorepending = 1; 773 usb_needs_explore(sc->sc_hub); 774 } 775 /* 776 * XXX workaround for broken implementation of the interrupt 777 * pipe in EHCI root hub emulation which doesn't resend 778 * status change notifications until handled: force a rescan 779 * of the ports we touched in the last run 780 */ 781 if (status == USBD_NORMAL_COMPLETION && sc->sc_explorepending && 782 sc->sc_isehciroothub) 783 usb_needs_explore(sc->sc_hub); 784 } 785