2/*- 3 * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved. 4 * Copyright (c) 1998 Lennart Augustsson. All rights reserved. 5 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29/* 30 * USB spec: http://www.usb.org/developers/docs/usbspec.zip 31 */ 32 33#include <dev/usb2/include/usb2_defs.h> 34#include <dev/usb2/include/usb2_mfunc.h> 35#include <dev/usb2/include/usb2_error.h> 36#include <dev/usb2/include/usb2_standard.h> 37 38#define USB_DEBUG_VAR uhub_debug 39 40#include <dev/usb2/core/usb2_core.h> 41#include <dev/usb2/core/usb2_process.h> 42#include <dev/usb2/core/usb2_device.h> 43#include <dev/usb2/core/usb2_request.h> 44#include <dev/usb2/core/usb2_debug.h> 45#include <dev/usb2/core/usb2_hub.h> 46#include <dev/usb2/core/usb2_util.h> 47#include <dev/usb2/core/usb2_busdma.h> 48#include <dev/usb2/core/usb2_transfer.h> 49#include <dev/usb2/core/usb2_dynamic.h> 50 51#include <dev/usb2/controller/usb2_controller.h> 52#include <dev/usb2/controller/usb2_bus.h> 53 54#define UHUB_INTR_INTERVAL 250 /* ms */ 55 56#if USB_DEBUG 57static int uhub_debug = 0; 58 59SYSCTL_NODE(_hw_usb2, OID_AUTO, uhub, CTLFLAG_RW, 0, "USB HUB"); 60SYSCTL_INT(_hw_usb2_uhub, OID_AUTO, debug, CTLFLAG_RW, &uhub_debug, 0, 61 "Debug level"); 62#endif 63 64struct uhub_current_state { 65 uint16_t port_change; 66 uint16_t port_status; 67}; 68 69struct uhub_softc { 70 struct uhub_current_state sc_st;/* current state */ 71 device_t sc_dev; /* base device */ 72 struct usb2_device *sc_udev; /* USB device */ 73 struct usb2_xfer *sc_xfer[2]; /* interrupt xfer */ 74 uint8_t sc_flags; 75#define UHUB_FLAG_INTR_STALL 0x02 76 char sc_name[32]; 77}; 78 79#define UHUB_PROTO(sc) ((sc)->sc_udev->ddesc.bDeviceProtocol) 80#define UHUB_IS_HIGH_SPEED(sc) (UHUB_PROTO(sc) != UDPROTO_FSHUB) 81#define UHUB_IS_SINGLE_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBSTT) 82 83/* prototypes for type checking: */ 84 85static device_probe_t uhub_probe; 86static device_attach_t uhub_attach; 87static device_detach_t uhub_detach; 88 89static bus_driver_added_t uhub_driver_added; 90static bus_child_location_str_t uhub_child_location_string; 91static bus_child_pnpinfo_str_t uhub_child_pnpinfo_string; 92 93static usb2_callback_t uhub_intr_callback; 94static usb2_callback_t uhub_intr_clear_stall_callback; 95 96static const struct usb2_config uhub_config[2] = { 97 98 [0] = { 99 .type = UE_INTERRUPT, 100 .endpoint = UE_ADDR_ANY, 101 .direction = UE_DIR_ANY, 102 .mh.timeout = 0, 103 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 104 .mh.bufsize = 0, /* use wMaxPacketSize */ 105 .mh.callback = &uhub_intr_callback, 106 .mh.interval = UHUB_INTR_INTERVAL, 107 }, 108 109 [1] = { 110 .type = UE_CONTROL, 111 .endpoint = 0, 112 .direction = UE_DIR_ANY, 113 .mh.timeout = 1000, /* 1 second */ 114 .mh.interval = 50, /* 50ms */ 115 .mh.flags = {}, 116 .mh.bufsize = sizeof(struct usb2_device_request), 117 .mh.callback = &uhub_intr_clear_stall_callback, 118 }, 119}; 120 121/* 122 * driver instance for "hub" connected to "usb" 123 * and "hub" connected to "hub" 124 */ 125static devclass_t uhub_devclass; 126 127static driver_t uhub_driver = 128{ 129 .name = "ushub", 130 .methods = (device_method_t[]){ 131 DEVMETHOD(device_probe, uhub_probe), 132 DEVMETHOD(device_attach, uhub_attach), 133 DEVMETHOD(device_detach, uhub_detach), 134 135 DEVMETHOD(device_suspend, bus_generic_suspend), 136 DEVMETHOD(device_resume, bus_generic_resume), 137 DEVMETHOD(device_shutdown, bus_generic_shutdown), 138 139 DEVMETHOD(bus_child_location_str, uhub_child_location_string), 140 DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_string), 141 DEVMETHOD(bus_driver_added, uhub_driver_added), 142 {0, 0} 143 }, 144 .size = sizeof(struct uhub_softc) 145}; 146 147DRIVER_MODULE(ushub, usbus, uhub_driver, uhub_devclass, 0, 0); 148DRIVER_MODULE(ushub, ushub, uhub_driver, uhub_devclass, NULL, 0); 149 150static void 151uhub_intr_clear_stall_callback(struct usb2_xfer *xfer) 152{ 153 struct uhub_softc *sc = xfer->priv_sc; 154 struct usb2_xfer *xfer_other = sc->sc_xfer[0]; 155 156 if (usb2_clear_stall_callback(xfer, xfer_other)) { 157 DPRINTF("stall cleared\n"); 158 sc->sc_flags &= ~UHUB_FLAG_INTR_STALL; 159 usb2_transfer_start(xfer_other); 160 } 161 return; 162} 163 164static void 165uhub_intr_callback(struct usb2_xfer *xfer) 166{ 167 struct uhub_softc *sc = xfer->priv_sc; 168 169 switch (USB_GET_STATE(xfer)) { 170 case USB_ST_TRANSFERRED: 171 DPRINTFN(2, "\n"); 172 /* 173 * This is an indication that some port 174 * has changed status. Notify the bus 175 * event handler thread that we need 176 * to be explored again: 177 */ 178 usb2_needs_explore(sc->sc_udev->bus, 0); 179 180 case USB_ST_SETUP: 181 if (sc->sc_flags & UHUB_FLAG_INTR_STALL) { 182 usb2_transfer_start(sc->sc_xfer[1]); 183 } else { 184 xfer->frlengths[0] = xfer->max_data_length; 185 usb2_start_hardware(xfer); 186 } 187 return; 188 189 default: /* Error */ 190 if (xfer->error != USB_ERR_CANCELLED) { 191 /* start clear stall */ 192 sc->sc_flags |= UHUB_FLAG_INTR_STALL; 193 usb2_transfer_start(sc->sc_xfer[1]); 194 } 195 return; 196 } 197} 198 199/*------------------------------------------------------------------------* 200 * uhub_explore_sub - subroutine 201 * 202 * Return values: 203 * 0: Success 204 * Else: A control transaction failed 205 *------------------------------------------------------------------------*/ 206static usb2_error_t 207uhub_explore_sub(struct uhub_softc *sc, struct usb2_port *up) 208{ 209 struct usb2_bus *bus; 210 struct usb2_device *child; 211 uint8_t refcount; 212 usb2_error_t err; 213 214 bus = sc->sc_udev->bus; 215 err = 0; 216 217 /* get driver added refcount from USB bus */ 218 refcount = bus->driver_added_refcount; 219 220 /* get device assosiated with the given port */ 221 child = usb2_bus_port_get_device(bus, up); 222 if (child == NULL) { 223 /* nothing to do */ 224 goto done; 225 } 226 /* check if probe and attach should be done */ 227 228 if (child->driver_added_refcount != refcount) { 229 child->driver_added_refcount = refcount; 230 err = usb2_probe_and_attach(child, 231 USB_IFACE_INDEX_ANY); 232 if (err) { 233 goto done; 234 } 235 } 236 /* start control transfer, if device mode */ 237 238 if (child->flags.usb2_mode == USB_MODE_DEVICE) { 239 usb2_default_transfer_setup(child); 240 } 241 /* if a HUB becomes present, do a recursive HUB explore */ 242 243 if (child->hub) { 244 err = (child->hub->explore) (child); 245 } 246done: 247 return (err); 248} 249 250/*------------------------------------------------------------------------* 251 * uhub_read_port_status - factored out code 252 *------------------------------------------------------------------------*/ 253static usb2_error_t 254uhub_read_port_status(struct uhub_softc *sc, uint8_t portno) 255{ 256 struct usb2_port_status ps; 257 usb2_error_t err; 258 259 err = usb2_req_get_port_status( 260 sc->sc_udev, &Giant, &ps, portno); 261 262 /* update status regardless of error */ 263 264 sc->sc_st.port_status = UGETW(ps.wPortStatus); 265 sc->sc_st.port_change = UGETW(ps.wPortChange); 266 267 /* debugging print */ 268 269 DPRINTFN(4, "port %d, wPortStatus=0x%04x, " 270 "wPortChange=0x%04x, err=%s\n", 271 portno, sc->sc_st.port_status, 272 sc->sc_st.port_change, usb2_errstr(err)); 273 return (err); 274} 275 276/*------------------------------------------------------------------------* 277 * uhub_reattach_port 278 * 279 * Returns: 280 * 0: Success 281 * Else: A control transaction failed 282 *------------------------------------------------------------------------*/ 283static usb2_error_t 284uhub_reattach_port(struct uhub_softc *sc, uint8_t portno) 285{ 286 struct usb2_device *child; 287 struct usb2_device *udev; 288 usb2_error_t err; 289 uint8_t timeout; 290 uint8_t speed; 291 uint8_t usb2_mode; 292 293 DPRINTF("reattaching port %d\n", portno); 294 295 err = 0; 296 timeout = 0; 297 udev = sc->sc_udev; 298 child = usb2_bus_port_get_device(udev->bus, 299 udev->hub->ports + portno - 1); 300 301repeat: 302 303 /* first clear the port connection change bit */ 304 305 err = usb2_req_clear_port_feature 306 (udev, &Giant, portno, UHF_C_PORT_CONNECTION); 307 308 if (err) { 309 goto error; 310 } 311 /* detach any existing devices */ 312 313 if (child) { 314 usb2_detach_device(child, USB_IFACE_INDEX_ANY, 1); 315 usb2_free_device(child); 316 child = NULL; 317 } 318 /* get fresh status */ 319 320 err = uhub_read_port_status(sc, portno); 321 if (err) { 322 goto error; 323 } 324 /* check if nothing is connected to the port */ 325 326 if (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS)) { 327 goto error; 328 } 329 /* check if there is no power on the port and print a warning */ 330 331 if (!(sc->sc_st.port_status & UPS_PORT_POWER)) { 332 DPRINTF("WARNING: strange, connected port %d " 333 "has no power\n", portno); 334 } 335 /* check if the device is in Host Mode */ 336 337 if (!(sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)) { 338 339 DPRINTF("Port %d is in Host Mode\n", portno); 340 341 /* USB Host Mode */ 342 343 /* wait for maximum device power up time */ 344 345 usb2_pause_mtx(&Giant, USB_PORT_POWERUP_DELAY); 346 347 /* reset port, which implies enabling it */ 348 349 err = usb2_req_reset_port 350 (udev, &Giant, portno); 351 352 if (err) { 353 DPRINTFN(0, "port %d reset " 354 "failed, error=%s\n", 355 portno, usb2_errstr(err)); 356 goto error; 357 } 358 /* get port status again, it might have changed during reset */ 359 360 err = uhub_read_port_status(sc, portno); 361 if (err) { 362 goto error; 363 } 364 /* check if something changed during port reset */ 365 366 if ((sc->sc_st.port_change & UPS_C_CONNECT_STATUS) || 367 (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS))) { 368 if (timeout) { 369 DPRINTFN(0, "giving up port reset " 370 "- device vanished!\n"); 371 goto error; 372 } 373 timeout = 1; 374 goto repeat; 375 } 376 } else { 377 DPRINTF("Port %d is in Device Mode\n", portno); 378 } 379 380 /* 381 * Figure out the device speed 382 */ 383 speed = 384 (sc->sc_st.port_status & UPS_HIGH_SPEED) ? USB_SPEED_HIGH : 385 (sc->sc_st.port_status & UPS_LOW_SPEED) ? USB_SPEED_LOW : USB_SPEED_FULL; 386 387 /* 388 * Figure out the device mode 389 * 390 * NOTE: This part is currently FreeBSD specific. 391 */ 392 usb2_mode = 393 (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE) ? 394 USB_MODE_DEVICE : USB_MODE_HOST; 395 396 /* need to create a new child */ 397 398 child = usb2_alloc_device(sc->sc_dev, udev->bus, udev, 399 udev->depth + 1, portno - 1, portno, speed, usb2_mode); 400 if (child == NULL) { 401 DPRINTFN(0, "could not allocate new device!\n"); 402 goto error; 403 } 404 return (0); /* success */ 405 406error: 407 if (child) { 408 usb2_detach_device(child, USB_IFACE_INDEX_ANY, 1); 409 usb2_free_device(child); 410 child = NULL; 411 } 412 if (err == 0) { 413 if (sc->sc_st.port_status & UPS_PORT_ENABLED) { 414 err = usb2_req_clear_port_feature 415 (sc->sc_udev, &Giant, 416 portno, UHF_PORT_ENABLE); 417 } 418 } 419 if (err) { 420 DPRINTFN(0, "device problem (%s), " 421 "disabling port %d\n", usb2_errstr(err), portno); 422 } 423 return (err); 424} 425 426/*------------------------------------------------------------------------* 427 * uhub_suspend_resume_port 428 * 429 * Returns: 430 * 0: Success 431 * Else: A control transaction failed 432 *------------------------------------------------------------------------*/ 433static usb2_error_t 434uhub_suspend_resume_port(struct uhub_softc *sc, uint8_t portno) 435{ 436 struct usb2_device *child; 437 struct usb2_device *udev; 438 uint8_t is_suspend; 439 usb2_error_t err; 440 441 DPRINTF("port %d\n", portno); 442 443 udev = sc->sc_udev; 444 child = usb2_bus_port_get_device(udev->bus, 445 udev->hub->ports + portno - 1); 446 447 /* first clear the port suspend change bit */ 448 449 err = usb2_req_clear_port_feature 450 (udev, &Giant, portno, UHF_C_PORT_SUSPEND); 451 452 if (err) { 453 goto done; 454 } 455 /* get fresh status */ 456 457 err = uhub_read_port_status(sc, portno); 458 if (err) { 459 goto done; 460 } 461 /* get current state */ 462 463 if (sc->sc_st.port_status & UPS_SUSPEND) { 464 is_suspend = 1; 465 } else { 466 is_suspend = 0; 467 } 468 /* do the suspend or resume */ 469 470 if (child) { 471 sx_xlock(child->default_sx + 1); 472 err = usb2_suspend_resume(child, is_suspend); 473 sx_unlock(child->default_sx + 1); 474 } 475done: 476 return (err); 477} 478 479/*------------------------------------------------------------------------* 480 * uhub_explore 481 * 482 * Returns: 483 * 0: Success 484 * Else: Failure 485 *------------------------------------------------------------------------*/ 486static usb2_error_t 487uhub_explore(struct usb2_device *udev) 488{ 489 struct usb2_hub *hub; 490 struct uhub_softc *sc; 491 struct usb2_port *up; 492 usb2_error_t err; 493 uint8_t portno; 494 uint8_t x; 495 496 hub = udev->hub; 497 sc = hub->hubsoftc; 498 499 DPRINTFN(11, "udev=%p addr=%d\n", udev, udev->address); 500 501 /* ignore hubs that are too deep */ 502 if (udev->depth > USB_HUB_MAX_DEPTH) { 503 return (USB_ERR_TOO_DEEP); 504 } 505 for (x = 0; x != hub->nports; x++) { 506 up = hub->ports + x; 507 portno = x + 1; 508 509 err = uhub_read_port_status(sc, portno); 510 if (err) { 511 /* most likely the HUB is gone */ 512 break; 513 } 514 if (sc->sc_st.port_change & UPS_C_PORT_ENABLED) { 515 err = usb2_req_clear_port_feature( 516 udev, &Giant, portno, UHF_C_PORT_ENABLE); 517 if (err) { 518 /* most likely the HUB is gone */ 519 break; 520 } 521 if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) { 522 /* 523 * Ignore the port error if the device 524 * has vanished ! 525 */ 526 } else if (sc->sc_st.port_status & UPS_PORT_ENABLED) { 527 DPRINTFN(0, "illegal enable change, " 528 "port %d\n", portno); 529 } else { 530 531 if (up->restartcnt == USB_RESTART_MAX) { 532 /* XXX could try another speed ? */ 533 DPRINTFN(0, "port error, giving up " 534 "port %d\n", portno); 535 } else { 536 sc->sc_st.port_change |= UPS_C_CONNECT_STATUS; 537 up->restartcnt++; 538 } 539 } 540 } 541 if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) { 542 err = uhub_reattach_port(sc, portno); 543 if (err) { 544 /* most likely the HUB is gone */ 545 break; 546 } 547 } 548 if (sc->sc_st.port_change & UPS_C_SUSPEND) { 549 err = uhub_suspend_resume_port(sc, portno); 550 if (err) { 551 /* most likely the HUB is gone */ 552 break; 553 } 554 } 555 err = uhub_explore_sub(sc, up); 556 if (err) { 557 /* no device(s) present */ 558 continue; 559 } 560 /* explore succeeded - reset restart counter */ 561 up->restartcnt = 0; 562 } 563 return (USB_ERR_NORMAL_COMPLETION); 564} 565 566static int 567uhub_probe(device_t dev) 568{ 569 struct usb2_attach_arg *uaa = device_get_ivars(dev); 570 571 if (uaa->usb2_mode != USB_MODE_HOST) { 572 return (ENXIO); 573 } 574 /* 575 * The subclass for USB HUBs is ignored because it is 0 for 576 * some and 1 for others. 577 */ 578 if ((uaa->info.bConfigIndex == 0) && 579 (uaa->info.bDeviceClass == UDCLASS_HUB)) { 580 return (0); 581 } 582 return (ENXIO); 583} 584 585static int 586uhub_attach(device_t dev) 587{ 588 struct uhub_softc *sc = device_get_softc(dev); 589 struct usb2_attach_arg *uaa = device_get_ivars(dev); 590 struct usb2_device *udev = uaa->device; 591 struct usb2_device *parent_hub = udev->parent_hub; 592 struct usb2_hub *hub; 593 struct usb2_hub_descriptor hubdesc; 594 uint16_t pwrdly; 595 uint8_t x; 596 uint8_t nports; 597 uint8_t portno; 598 uint8_t removable; 599 uint8_t iface_index; 600 usb2_error_t err; 601 602 if (sc == NULL) { 603 return (ENOMEM); 604 } 605 sc->sc_udev = udev; 606 sc->sc_dev = dev; 607 608 snprintf(sc->sc_name, sizeof(sc->sc_name), "%s", 609 device_get_nameunit(dev)); 610 611 device_set_usb2_desc(dev); 612 613 DPRINTFN(2, "depth=%d selfpowered=%d, parent=%p, " 614 "parent->selfpowered=%d\n", 615 udev->depth, 616 udev->flags.self_powered, 617 parent_hub, 618 parent_hub ? 619 parent_hub->flags.self_powered : 0); 620 621 if (udev->depth > USB_HUB_MAX_DEPTH) { 622 DPRINTFN(0, "hub depth, %d, exceeded. HUB ignored!\n", 623 USB_HUB_MAX_DEPTH); 624 goto error; 625 } 626 if (!udev->flags.self_powered && parent_hub && 627 (!parent_hub->flags.self_powered)) { 628 DPRINTFN(0, "bus powered HUB connected to " 629 "bus powered HUB. HUB ignored!\n"); 630 goto error; 631 } 632 /* get HUB descriptor */ 633 634 DPRINTFN(2, "getting HUB descriptor\n"); 635 636 /* assuming that there is one port */ 637 err = usb2_req_get_hub_descriptor(udev, &Giant, &hubdesc, 1); 638 639 nports = hubdesc.bNbrPorts; 640 641 if (!err && (nports >= 8)) { 642 /* get complete HUB descriptor */ 643 err = usb2_req_get_hub_descriptor(udev, &Giant, &hubdesc, nports); 644 } 645 if (err) { 646 DPRINTFN(0, "getting hub descriptor failed," 647 "error=%s\n", usb2_errstr(err)); 648 goto error; 649 } 650 if (hubdesc.bNbrPorts != nports) { 651 DPRINTFN(0, "number of ports changed!\n"); 652 goto error; 653 } 654 if (nports == 0) { 655 DPRINTFN(0, "portless HUB!\n"); 656 goto error; 657 } 658 hub = malloc(sizeof(hub[0]) + (sizeof(hub->ports[0]) * nports), 659 M_USBDEV, M_WAITOK | M_ZERO); 660 661 if (hub == NULL) { 662 goto error; 663 } 664 udev->hub = hub; 665 666 /* init FULL-speed ISOCHRONOUS schedule */ 667 usb2_fs_isoc_schedule_init_all(hub->fs_isoc_schedule); 668 669 /* initialize HUB structure */ 670 hub->hubsoftc = sc; 671 hub->explore = &uhub_explore; 672 hub->nports = hubdesc.bNbrPorts; 673 hub->hubudev = udev; 674 675 /* if self powered hub, give ports maximum current */ 676 if (udev->flags.self_powered) { 677 hub->portpower = USB_MAX_POWER; 678 } else { 679 hub->portpower = USB_MIN_POWER; 680 } 681 682 /* set up interrupt pipe */ 683 iface_index = 0; 684 err = usb2_transfer_setup(udev, &iface_index, sc->sc_xfer, 685 uhub_config, 2, sc, &Giant); 686 if (err) { 687 DPRINTFN(0, "cannot setup interrupt transfer, " 688 "errstr=%s!\n", usb2_errstr(err)); 689 goto error; 690 } 691 /* wait with power off for a while */ 692 usb2_pause_mtx(&Giant, USB_POWER_DOWN_TIME); 693 694 /* 695 * To have the best chance of success we do things in the exact same 696 * order as Windoze98. This should not be necessary, but some 697 * devices do not follow the USB specs to the letter. 698 * 699 * These are the events on the bus when a hub is attached: 700 * Get device and config descriptors (see attach code) 701 * Get hub descriptor (see above) 702 * For all ports 703 * turn on power 704 * wait for power to become stable 705 * (all below happens in explore code) 706 * For all ports 707 * clear C_PORT_CONNECTION 708 * For all ports 709 * get port status 710 * if device connected 711 * wait 100 ms 712 * turn on reset 713 * wait 714 * clear C_PORT_RESET 715 * get port status 716 * proceed with device attachment 717 */ 718 719 /* XXX should check for none, individual, or ganged power? */ 720 721 removable = 0; 722 pwrdly = ((hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR) + 723 USB_EXTRA_POWER_UP_TIME); 724 725 for (x = 0; x != nports; x++) { 726 /* set up data structures */ 727 struct usb2_port *up = hub->ports + x; 728 729 up->device_index = 0; 730 up->restartcnt = 0; 731 portno = x + 1; 732 733 /* check if port is removable */ 734 if (!UHD_NOT_REMOV(&hubdesc, portno)) { 735 removable++; 736 } 737 if (!err) { 738 /* turn the power on */ 739 err = usb2_req_set_port_feature 740 (udev, &Giant, portno, UHF_PORT_POWER); 741 } 742 if (err) { 743 DPRINTFN(0, "port %d power on failed, %s\n", 744 portno, usb2_errstr(err)); 745 } 746 DPRINTF("turn on port %d power\n", 747 portno); 748 749 /* wait for stable power */ 750 usb2_pause_mtx(&Giant, pwrdly); 751 } 752 753 device_printf(dev, "%d port%s with %d " 754 "removable, %s powered\n", nports, (nports != 1) ? "s" : "", 755 removable, udev->flags.self_powered ? "self" : "bus"); 756 757 /* start the interrupt endpoint */ 758
| 2/*- 3 * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved. 4 * Copyright (c) 1998 Lennart Augustsson. All rights reserved. 5 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29/* 30 * USB spec: http://www.usb.org/developers/docs/usbspec.zip 31 */ 32 33#include <dev/usb2/include/usb2_defs.h> 34#include <dev/usb2/include/usb2_mfunc.h> 35#include <dev/usb2/include/usb2_error.h> 36#include <dev/usb2/include/usb2_standard.h> 37 38#define USB_DEBUG_VAR uhub_debug 39 40#include <dev/usb2/core/usb2_core.h> 41#include <dev/usb2/core/usb2_process.h> 42#include <dev/usb2/core/usb2_device.h> 43#include <dev/usb2/core/usb2_request.h> 44#include <dev/usb2/core/usb2_debug.h> 45#include <dev/usb2/core/usb2_hub.h> 46#include <dev/usb2/core/usb2_util.h> 47#include <dev/usb2/core/usb2_busdma.h> 48#include <dev/usb2/core/usb2_transfer.h> 49#include <dev/usb2/core/usb2_dynamic.h> 50 51#include <dev/usb2/controller/usb2_controller.h> 52#include <dev/usb2/controller/usb2_bus.h> 53 54#define UHUB_INTR_INTERVAL 250 /* ms */ 55 56#if USB_DEBUG 57static int uhub_debug = 0; 58 59SYSCTL_NODE(_hw_usb2, OID_AUTO, uhub, CTLFLAG_RW, 0, "USB HUB"); 60SYSCTL_INT(_hw_usb2_uhub, OID_AUTO, debug, CTLFLAG_RW, &uhub_debug, 0, 61 "Debug level"); 62#endif 63 64struct uhub_current_state { 65 uint16_t port_change; 66 uint16_t port_status; 67}; 68 69struct uhub_softc { 70 struct uhub_current_state sc_st;/* current state */ 71 device_t sc_dev; /* base device */ 72 struct usb2_device *sc_udev; /* USB device */ 73 struct usb2_xfer *sc_xfer[2]; /* interrupt xfer */ 74 uint8_t sc_flags; 75#define UHUB_FLAG_INTR_STALL 0x02 76 char sc_name[32]; 77}; 78 79#define UHUB_PROTO(sc) ((sc)->sc_udev->ddesc.bDeviceProtocol) 80#define UHUB_IS_HIGH_SPEED(sc) (UHUB_PROTO(sc) != UDPROTO_FSHUB) 81#define UHUB_IS_SINGLE_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBSTT) 82 83/* prototypes for type checking: */ 84 85static device_probe_t uhub_probe; 86static device_attach_t uhub_attach; 87static device_detach_t uhub_detach; 88 89static bus_driver_added_t uhub_driver_added; 90static bus_child_location_str_t uhub_child_location_string; 91static bus_child_pnpinfo_str_t uhub_child_pnpinfo_string; 92 93static usb2_callback_t uhub_intr_callback; 94static usb2_callback_t uhub_intr_clear_stall_callback; 95 96static const struct usb2_config uhub_config[2] = { 97 98 [0] = { 99 .type = UE_INTERRUPT, 100 .endpoint = UE_ADDR_ANY, 101 .direction = UE_DIR_ANY, 102 .mh.timeout = 0, 103 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 104 .mh.bufsize = 0, /* use wMaxPacketSize */ 105 .mh.callback = &uhub_intr_callback, 106 .mh.interval = UHUB_INTR_INTERVAL, 107 }, 108 109 [1] = { 110 .type = UE_CONTROL, 111 .endpoint = 0, 112 .direction = UE_DIR_ANY, 113 .mh.timeout = 1000, /* 1 second */ 114 .mh.interval = 50, /* 50ms */ 115 .mh.flags = {}, 116 .mh.bufsize = sizeof(struct usb2_device_request), 117 .mh.callback = &uhub_intr_clear_stall_callback, 118 }, 119}; 120 121/* 122 * driver instance for "hub" connected to "usb" 123 * and "hub" connected to "hub" 124 */ 125static devclass_t uhub_devclass; 126 127static driver_t uhub_driver = 128{ 129 .name = "ushub", 130 .methods = (device_method_t[]){ 131 DEVMETHOD(device_probe, uhub_probe), 132 DEVMETHOD(device_attach, uhub_attach), 133 DEVMETHOD(device_detach, uhub_detach), 134 135 DEVMETHOD(device_suspend, bus_generic_suspend), 136 DEVMETHOD(device_resume, bus_generic_resume), 137 DEVMETHOD(device_shutdown, bus_generic_shutdown), 138 139 DEVMETHOD(bus_child_location_str, uhub_child_location_string), 140 DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_string), 141 DEVMETHOD(bus_driver_added, uhub_driver_added), 142 {0, 0} 143 }, 144 .size = sizeof(struct uhub_softc) 145}; 146 147DRIVER_MODULE(ushub, usbus, uhub_driver, uhub_devclass, 0, 0); 148DRIVER_MODULE(ushub, ushub, uhub_driver, uhub_devclass, NULL, 0); 149 150static void 151uhub_intr_clear_stall_callback(struct usb2_xfer *xfer) 152{ 153 struct uhub_softc *sc = xfer->priv_sc; 154 struct usb2_xfer *xfer_other = sc->sc_xfer[0]; 155 156 if (usb2_clear_stall_callback(xfer, xfer_other)) { 157 DPRINTF("stall cleared\n"); 158 sc->sc_flags &= ~UHUB_FLAG_INTR_STALL; 159 usb2_transfer_start(xfer_other); 160 } 161 return; 162} 163 164static void 165uhub_intr_callback(struct usb2_xfer *xfer) 166{ 167 struct uhub_softc *sc = xfer->priv_sc; 168 169 switch (USB_GET_STATE(xfer)) { 170 case USB_ST_TRANSFERRED: 171 DPRINTFN(2, "\n"); 172 /* 173 * This is an indication that some port 174 * has changed status. Notify the bus 175 * event handler thread that we need 176 * to be explored again: 177 */ 178 usb2_needs_explore(sc->sc_udev->bus, 0); 179 180 case USB_ST_SETUP: 181 if (sc->sc_flags & UHUB_FLAG_INTR_STALL) { 182 usb2_transfer_start(sc->sc_xfer[1]); 183 } else { 184 xfer->frlengths[0] = xfer->max_data_length; 185 usb2_start_hardware(xfer); 186 } 187 return; 188 189 default: /* Error */ 190 if (xfer->error != USB_ERR_CANCELLED) { 191 /* start clear stall */ 192 sc->sc_flags |= UHUB_FLAG_INTR_STALL; 193 usb2_transfer_start(sc->sc_xfer[1]); 194 } 195 return; 196 } 197} 198 199/*------------------------------------------------------------------------* 200 * uhub_explore_sub - subroutine 201 * 202 * Return values: 203 * 0: Success 204 * Else: A control transaction failed 205 *------------------------------------------------------------------------*/ 206static usb2_error_t 207uhub_explore_sub(struct uhub_softc *sc, struct usb2_port *up) 208{ 209 struct usb2_bus *bus; 210 struct usb2_device *child; 211 uint8_t refcount; 212 usb2_error_t err; 213 214 bus = sc->sc_udev->bus; 215 err = 0; 216 217 /* get driver added refcount from USB bus */ 218 refcount = bus->driver_added_refcount; 219 220 /* get device assosiated with the given port */ 221 child = usb2_bus_port_get_device(bus, up); 222 if (child == NULL) { 223 /* nothing to do */ 224 goto done; 225 } 226 /* check if probe and attach should be done */ 227 228 if (child->driver_added_refcount != refcount) { 229 child->driver_added_refcount = refcount; 230 err = usb2_probe_and_attach(child, 231 USB_IFACE_INDEX_ANY); 232 if (err) { 233 goto done; 234 } 235 } 236 /* start control transfer, if device mode */ 237 238 if (child->flags.usb2_mode == USB_MODE_DEVICE) { 239 usb2_default_transfer_setup(child); 240 } 241 /* if a HUB becomes present, do a recursive HUB explore */ 242 243 if (child->hub) { 244 err = (child->hub->explore) (child); 245 } 246done: 247 return (err); 248} 249 250/*------------------------------------------------------------------------* 251 * uhub_read_port_status - factored out code 252 *------------------------------------------------------------------------*/ 253static usb2_error_t 254uhub_read_port_status(struct uhub_softc *sc, uint8_t portno) 255{ 256 struct usb2_port_status ps; 257 usb2_error_t err; 258 259 err = usb2_req_get_port_status( 260 sc->sc_udev, &Giant, &ps, portno); 261 262 /* update status regardless of error */ 263 264 sc->sc_st.port_status = UGETW(ps.wPortStatus); 265 sc->sc_st.port_change = UGETW(ps.wPortChange); 266 267 /* debugging print */ 268 269 DPRINTFN(4, "port %d, wPortStatus=0x%04x, " 270 "wPortChange=0x%04x, err=%s\n", 271 portno, sc->sc_st.port_status, 272 sc->sc_st.port_change, usb2_errstr(err)); 273 return (err); 274} 275 276/*------------------------------------------------------------------------* 277 * uhub_reattach_port 278 * 279 * Returns: 280 * 0: Success 281 * Else: A control transaction failed 282 *------------------------------------------------------------------------*/ 283static usb2_error_t 284uhub_reattach_port(struct uhub_softc *sc, uint8_t portno) 285{ 286 struct usb2_device *child; 287 struct usb2_device *udev; 288 usb2_error_t err; 289 uint8_t timeout; 290 uint8_t speed; 291 uint8_t usb2_mode; 292 293 DPRINTF("reattaching port %d\n", portno); 294 295 err = 0; 296 timeout = 0; 297 udev = sc->sc_udev; 298 child = usb2_bus_port_get_device(udev->bus, 299 udev->hub->ports + portno - 1); 300 301repeat: 302 303 /* first clear the port connection change bit */ 304 305 err = usb2_req_clear_port_feature 306 (udev, &Giant, portno, UHF_C_PORT_CONNECTION); 307 308 if (err) { 309 goto error; 310 } 311 /* detach any existing devices */ 312 313 if (child) { 314 usb2_detach_device(child, USB_IFACE_INDEX_ANY, 1); 315 usb2_free_device(child); 316 child = NULL; 317 } 318 /* get fresh status */ 319 320 err = uhub_read_port_status(sc, portno); 321 if (err) { 322 goto error; 323 } 324 /* check if nothing is connected to the port */ 325 326 if (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS)) { 327 goto error; 328 } 329 /* check if there is no power on the port and print a warning */ 330 331 if (!(sc->sc_st.port_status & UPS_PORT_POWER)) { 332 DPRINTF("WARNING: strange, connected port %d " 333 "has no power\n", portno); 334 } 335 /* check if the device is in Host Mode */ 336 337 if (!(sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)) { 338 339 DPRINTF("Port %d is in Host Mode\n", portno); 340 341 /* USB Host Mode */ 342 343 /* wait for maximum device power up time */ 344 345 usb2_pause_mtx(&Giant, USB_PORT_POWERUP_DELAY); 346 347 /* reset port, which implies enabling it */ 348 349 err = usb2_req_reset_port 350 (udev, &Giant, portno); 351 352 if (err) { 353 DPRINTFN(0, "port %d reset " 354 "failed, error=%s\n", 355 portno, usb2_errstr(err)); 356 goto error; 357 } 358 /* get port status again, it might have changed during reset */ 359 360 err = uhub_read_port_status(sc, portno); 361 if (err) { 362 goto error; 363 } 364 /* check if something changed during port reset */ 365 366 if ((sc->sc_st.port_change & UPS_C_CONNECT_STATUS) || 367 (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS))) { 368 if (timeout) { 369 DPRINTFN(0, "giving up port reset " 370 "- device vanished!\n"); 371 goto error; 372 } 373 timeout = 1; 374 goto repeat; 375 } 376 } else { 377 DPRINTF("Port %d is in Device Mode\n", portno); 378 } 379 380 /* 381 * Figure out the device speed 382 */ 383 speed = 384 (sc->sc_st.port_status & UPS_HIGH_SPEED) ? USB_SPEED_HIGH : 385 (sc->sc_st.port_status & UPS_LOW_SPEED) ? USB_SPEED_LOW : USB_SPEED_FULL; 386 387 /* 388 * Figure out the device mode 389 * 390 * NOTE: This part is currently FreeBSD specific. 391 */ 392 usb2_mode = 393 (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE) ? 394 USB_MODE_DEVICE : USB_MODE_HOST; 395 396 /* need to create a new child */ 397 398 child = usb2_alloc_device(sc->sc_dev, udev->bus, udev, 399 udev->depth + 1, portno - 1, portno, speed, usb2_mode); 400 if (child == NULL) { 401 DPRINTFN(0, "could not allocate new device!\n"); 402 goto error; 403 } 404 return (0); /* success */ 405 406error: 407 if (child) { 408 usb2_detach_device(child, USB_IFACE_INDEX_ANY, 1); 409 usb2_free_device(child); 410 child = NULL; 411 } 412 if (err == 0) { 413 if (sc->sc_st.port_status & UPS_PORT_ENABLED) { 414 err = usb2_req_clear_port_feature 415 (sc->sc_udev, &Giant, 416 portno, UHF_PORT_ENABLE); 417 } 418 } 419 if (err) { 420 DPRINTFN(0, "device problem (%s), " 421 "disabling port %d\n", usb2_errstr(err), portno); 422 } 423 return (err); 424} 425 426/*------------------------------------------------------------------------* 427 * uhub_suspend_resume_port 428 * 429 * Returns: 430 * 0: Success 431 * Else: A control transaction failed 432 *------------------------------------------------------------------------*/ 433static usb2_error_t 434uhub_suspend_resume_port(struct uhub_softc *sc, uint8_t portno) 435{ 436 struct usb2_device *child; 437 struct usb2_device *udev; 438 uint8_t is_suspend; 439 usb2_error_t err; 440 441 DPRINTF("port %d\n", portno); 442 443 udev = sc->sc_udev; 444 child = usb2_bus_port_get_device(udev->bus, 445 udev->hub->ports + portno - 1); 446 447 /* first clear the port suspend change bit */ 448 449 err = usb2_req_clear_port_feature 450 (udev, &Giant, portno, UHF_C_PORT_SUSPEND); 451 452 if (err) { 453 goto done; 454 } 455 /* get fresh status */ 456 457 err = uhub_read_port_status(sc, portno); 458 if (err) { 459 goto done; 460 } 461 /* get current state */ 462 463 if (sc->sc_st.port_status & UPS_SUSPEND) { 464 is_suspend = 1; 465 } else { 466 is_suspend = 0; 467 } 468 /* do the suspend or resume */ 469 470 if (child) { 471 sx_xlock(child->default_sx + 1); 472 err = usb2_suspend_resume(child, is_suspend); 473 sx_unlock(child->default_sx + 1); 474 } 475done: 476 return (err); 477} 478 479/*------------------------------------------------------------------------* 480 * uhub_explore 481 * 482 * Returns: 483 * 0: Success 484 * Else: Failure 485 *------------------------------------------------------------------------*/ 486static usb2_error_t 487uhub_explore(struct usb2_device *udev) 488{ 489 struct usb2_hub *hub; 490 struct uhub_softc *sc; 491 struct usb2_port *up; 492 usb2_error_t err; 493 uint8_t portno; 494 uint8_t x; 495 496 hub = udev->hub; 497 sc = hub->hubsoftc; 498 499 DPRINTFN(11, "udev=%p addr=%d\n", udev, udev->address); 500 501 /* ignore hubs that are too deep */ 502 if (udev->depth > USB_HUB_MAX_DEPTH) { 503 return (USB_ERR_TOO_DEEP); 504 } 505 for (x = 0; x != hub->nports; x++) { 506 up = hub->ports + x; 507 portno = x + 1; 508 509 err = uhub_read_port_status(sc, portno); 510 if (err) { 511 /* most likely the HUB is gone */ 512 break; 513 } 514 if (sc->sc_st.port_change & UPS_C_PORT_ENABLED) { 515 err = usb2_req_clear_port_feature( 516 udev, &Giant, portno, UHF_C_PORT_ENABLE); 517 if (err) { 518 /* most likely the HUB is gone */ 519 break; 520 } 521 if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) { 522 /* 523 * Ignore the port error if the device 524 * has vanished ! 525 */ 526 } else if (sc->sc_st.port_status & UPS_PORT_ENABLED) { 527 DPRINTFN(0, "illegal enable change, " 528 "port %d\n", portno); 529 } else { 530 531 if (up->restartcnt == USB_RESTART_MAX) { 532 /* XXX could try another speed ? */ 533 DPRINTFN(0, "port error, giving up " 534 "port %d\n", portno); 535 } else { 536 sc->sc_st.port_change |= UPS_C_CONNECT_STATUS; 537 up->restartcnt++; 538 } 539 } 540 } 541 if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) { 542 err = uhub_reattach_port(sc, portno); 543 if (err) { 544 /* most likely the HUB is gone */ 545 break; 546 } 547 } 548 if (sc->sc_st.port_change & UPS_C_SUSPEND) { 549 err = uhub_suspend_resume_port(sc, portno); 550 if (err) { 551 /* most likely the HUB is gone */ 552 break; 553 } 554 } 555 err = uhub_explore_sub(sc, up); 556 if (err) { 557 /* no device(s) present */ 558 continue; 559 } 560 /* explore succeeded - reset restart counter */ 561 up->restartcnt = 0; 562 } 563 return (USB_ERR_NORMAL_COMPLETION); 564} 565 566static int 567uhub_probe(device_t dev) 568{ 569 struct usb2_attach_arg *uaa = device_get_ivars(dev); 570 571 if (uaa->usb2_mode != USB_MODE_HOST) { 572 return (ENXIO); 573 } 574 /* 575 * The subclass for USB HUBs is ignored because it is 0 for 576 * some and 1 for others. 577 */ 578 if ((uaa->info.bConfigIndex == 0) && 579 (uaa->info.bDeviceClass == UDCLASS_HUB)) { 580 return (0); 581 } 582 return (ENXIO); 583} 584 585static int 586uhub_attach(device_t dev) 587{ 588 struct uhub_softc *sc = device_get_softc(dev); 589 struct usb2_attach_arg *uaa = device_get_ivars(dev); 590 struct usb2_device *udev = uaa->device; 591 struct usb2_device *parent_hub = udev->parent_hub; 592 struct usb2_hub *hub; 593 struct usb2_hub_descriptor hubdesc; 594 uint16_t pwrdly; 595 uint8_t x; 596 uint8_t nports; 597 uint8_t portno; 598 uint8_t removable; 599 uint8_t iface_index; 600 usb2_error_t err; 601 602 if (sc == NULL) { 603 return (ENOMEM); 604 } 605 sc->sc_udev = udev; 606 sc->sc_dev = dev; 607 608 snprintf(sc->sc_name, sizeof(sc->sc_name), "%s", 609 device_get_nameunit(dev)); 610 611 device_set_usb2_desc(dev); 612 613 DPRINTFN(2, "depth=%d selfpowered=%d, parent=%p, " 614 "parent->selfpowered=%d\n", 615 udev->depth, 616 udev->flags.self_powered, 617 parent_hub, 618 parent_hub ? 619 parent_hub->flags.self_powered : 0); 620 621 if (udev->depth > USB_HUB_MAX_DEPTH) { 622 DPRINTFN(0, "hub depth, %d, exceeded. HUB ignored!\n", 623 USB_HUB_MAX_DEPTH); 624 goto error; 625 } 626 if (!udev->flags.self_powered && parent_hub && 627 (!parent_hub->flags.self_powered)) { 628 DPRINTFN(0, "bus powered HUB connected to " 629 "bus powered HUB. HUB ignored!\n"); 630 goto error; 631 } 632 /* get HUB descriptor */ 633 634 DPRINTFN(2, "getting HUB descriptor\n"); 635 636 /* assuming that there is one port */ 637 err = usb2_req_get_hub_descriptor(udev, &Giant, &hubdesc, 1); 638 639 nports = hubdesc.bNbrPorts; 640 641 if (!err && (nports >= 8)) { 642 /* get complete HUB descriptor */ 643 err = usb2_req_get_hub_descriptor(udev, &Giant, &hubdesc, nports); 644 } 645 if (err) { 646 DPRINTFN(0, "getting hub descriptor failed," 647 "error=%s\n", usb2_errstr(err)); 648 goto error; 649 } 650 if (hubdesc.bNbrPorts != nports) { 651 DPRINTFN(0, "number of ports changed!\n"); 652 goto error; 653 } 654 if (nports == 0) { 655 DPRINTFN(0, "portless HUB!\n"); 656 goto error; 657 } 658 hub = malloc(sizeof(hub[0]) + (sizeof(hub->ports[0]) * nports), 659 M_USBDEV, M_WAITOK | M_ZERO); 660 661 if (hub == NULL) { 662 goto error; 663 } 664 udev->hub = hub; 665 666 /* init FULL-speed ISOCHRONOUS schedule */ 667 usb2_fs_isoc_schedule_init_all(hub->fs_isoc_schedule); 668 669 /* initialize HUB structure */ 670 hub->hubsoftc = sc; 671 hub->explore = &uhub_explore; 672 hub->nports = hubdesc.bNbrPorts; 673 hub->hubudev = udev; 674 675 /* if self powered hub, give ports maximum current */ 676 if (udev->flags.self_powered) { 677 hub->portpower = USB_MAX_POWER; 678 } else { 679 hub->portpower = USB_MIN_POWER; 680 } 681 682 /* set up interrupt pipe */ 683 iface_index = 0; 684 err = usb2_transfer_setup(udev, &iface_index, sc->sc_xfer, 685 uhub_config, 2, sc, &Giant); 686 if (err) { 687 DPRINTFN(0, "cannot setup interrupt transfer, " 688 "errstr=%s!\n", usb2_errstr(err)); 689 goto error; 690 } 691 /* wait with power off for a while */ 692 usb2_pause_mtx(&Giant, USB_POWER_DOWN_TIME); 693 694 /* 695 * To have the best chance of success we do things in the exact same 696 * order as Windoze98. This should not be necessary, but some 697 * devices do not follow the USB specs to the letter. 698 * 699 * These are the events on the bus when a hub is attached: 700 * Get device and config descriptors (see attach code) 701 * Get hub descriptor (see above) 702 * For all ports 703 * turn on power 704 * wait for power to become stable 705 * (all below happens in explore code) 706 * For all ports 707 * clear C_PORT_CONNECTION 708 * For all ports 709 * get port status 710 * if device connected 711 * wait 100 ms 712 * turn on reset 713 * wait 714 * clear C_PORT_RESET 715 * get port status 716 * proceed with device attachment 717 */ 718 719 /* XXX should check for none, individual, or ganged power? */ 720 721 removable = 0; 722 pwrdly = ((hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR) + 723 USB_EXTRA_POWER_UP_TIME); 724 725 for (x = 0; x != nports; x++) { 726 /* set up data structures */ 727 struct usb2_port *up = hub->ports + x; 728 729 up->device_index = 0; 730 up->restartcnt = 0; 731 portno = x + 1; 732 733 /* check if port is removable */ 734 if (!UHD_NOT_REMOV(&hubdesc, portno)) { 735 removable++; 736 } 737 if (!err) { 738 /* turn the power on */ 739 err = usb2_req_set_port_feature 740 (udev, &Giant, portno, UHF_PORT_POWER); 741 } 742 if (err) { 743 DPRINTFN(0, "port %d power on failed, %s\n", 744 portno, usb2_errstr(err)); 745 } 746 DPRINTF("turn on port %d power\n", 747 portno); 748 749 /* wait for stable power */ 750 usb2_pause_mtx(&Giant, pwrdly); 751 } 752 753 device_printf(dev, "%d port%s with %d " 754 "removable, %s powered\n", nports, (nports != 1) ? "s" : "", 755 removable, udev->flags.self_powered ? "self" : "bus"); 756 757 /* start the interrupt endpoint */ 758
|
762 763 return (0); 764 765error: 766 usb2_transfer_unsetup(sc->sc_xfer, 2); 767 768 if (udev->hub) { 769 free(udev->hub, M_USBDEV); 770 udev->hub = NULL; 771 } 772 return (ENXIO); 773} 774 775/* 776 * Called from process context when the hub is gone. 777 * Detach all devices on active ports. 778 */ 779static int 780uhub_detach(device_t dev) 781{ 782 struct uhub_softc *sc = device_get_softc(dev); 783 struct usb2_hub *hub = sc->sc_udev->hub; 784 struct usb2_device *child; 785 uint8_t x; 786 787 /* detach all children first */ 788 bus_generic_detach(dev); 789 790 if (hub == NULL) { /* must be partially working */ 791 return (0); 792 } 793 for (x = 0; x != hub->nports; x++) { 794 795 child = usb2_bus_port_get_device(sc->sc_udev->bus, hub->ports + x); 796 797 if (child == NULL) { 798 continue; 799 } 800 /* 801 * Subdevices are not freed, because the caller of 802 * uhub_detach() will do that. 803 */ 804 usb2_detach_device(child, USB_IFACE_INDEX_ANY, 0); 805 usb2_free_device(child); 806 child = NULL; 807 } 808 809 usb2_transfer_unsetup(sc->sc_xfer, 2); 810 811 free(hub, M_USBDEV); 812 sc->sc_udev->hub = NULL; 813 return (0); 814} 815 816static void 817uhub_driver_added(device_t dev, driver_t *driver) 818{ 819 usb2_needs_explore_all(); 820 return; 821} 822 823struct hub_result { 824 struct usb2_device *udev; 825 uint8_t portno; 826 uint8_t iface_index; 827}; 828 829static void 830uhub_find_iface_index(struct usb2_hub *hub, device_t child, 831 struct hub_result *res) 832{ 833 struct usb2_interface *iface; 834 struct usb2_device *udev; 835 uint8_t nports; 836 uint8_t x; 837 uint8_t i; 838 839 nports = hub->nports; 840 for (x = 0; x != nports; x++) { 841 udev = usb2_bus_port_get_device(hub->hubudev->bus, 842 hub->ports + x); 843 if (!udev) { 844 continue; 845 } 846 for (i = 0; i != USB_IFACE_MAX; i++) { 847 iface = usb2_get_iface(udev, i); 848 if (iface && 849 (iface->subdev == child)) { 850 res->iface_index = i; 851 res->udev = udev; 852 res->portno = x + 1; 853 return; 854 } 855 } 856 } 857 res->iface_index = 0; 858 res->udev = NULL; 859 res->portno = 0; 860 return; 861} 862 863static int 864uhub_child_location_string(device_t parent, device_t child, 865 char *buf, size_t buflen) 866{ 867 struct uhub_softc *sc = device_get_softc(parent); 868 struct usb2_hub *hub = sc->sc_udev->hub; 869 struct hub_result res; 870 871 mtx_lock(&Giant); 872 uhub_find_iface_index(hub, child, &res); 873 if (!res.udev) { 874 DPRINTF("device not on hub\n"); 875 if (buflen) { 876 buf[0] = '\0'; 877 } 878 goto done; 879 } 880 snprintf(buf, buflen, "port=%u interface=%u", 881 res.portno, res.iface_index); 882done: 883 mtx_unlock(&Giant); 884 885 return (0); 886} 887 888static int 889uhub_child_pnpinfo_string(device_t parent, device_t child, 890 char *buf, size_t buflen) 891{ 892 struct uhub_softc *sc = device_get_softc(parent); 893 struct usb2_hub *hub = sc->sc_udev->hub; 894 struct usb2_interface *iface; 895 struct hub_result res; 896 897 mtx_lock(&Giant); 898 uhub_find_iface_index(hub, child, &res); 899 if (!res.udev) { 900 DPRINTF("device not on hub\n"); 901 if (buflen) { 902 buf[0] = '\0'; 903 } 904 goto done; 905 } 906 iface = usb2_get_iface(res.udev, res.iface_index); 907 if (iface && iface->idesc) { 908 snprintf(buf, buflen, "vendor=0x%04x product=0x%04x " 909 "devclass=0x%02x devsubclass=0x%02x " 910 "sernum=\"%s\" " 911 "intclass=0x%02x intsubclass=0x%02x", 912 UGETW(res.udev->ddesc.idVendor), 913 UGETW(res.udev->ddesc.idProduct), 914 res.udev->ddesc.bDeviceClass, 915 res.udev->ddesc.bDeviceSubClass, 916 res.udev->serial, 917 iface->idesc->bInterfaceClass, 918 iface->idesc->bInterfaceSubClass); 919 } else { 920 if (buflen) { 921 buf[0] = '\0'; 922 } 923 goto done; 924 } 925done: 926 mtx_unlock(&Giant); 927 928 return (0); 929} 930 931/* 932 * The USB Transaction Translator: 933 * =============================== 934 * 935 * When doing LOW- and FULL-speed USB transfers accross a HIGH-speed 936 * USB HUB, bandwidth must be allocated for ISOCHRONOUS and INTERRUPT 937 * USB transfers. To utilize bandwidth dynamically the "scatter and 938 * gather" principle must be applied. This means that bandwidth must 939 * be divided into equal parts of bandwidth. With regard to USB all 940 * data is transferred in smaller packets with length 941 * "wMaxPacketSize". The problem however is that "wMaxPacketSize" is 942 * not a constant! 943 * 944 * The bandwidth scheduler which I have implemented will simply pack 945 * the USB transfers back to back until there is no more space in the 946 * schedule. Out of the 8 microframes which the USB 2.0 standard 947 * provides, only 6 are available for non-HIGH-speed devices. I have 948 * reserved the first 4 microframes for ISOCHRONOUS transfers. The 949 * last 2 microframes I have reserved for INTERRUPT transfers. Without 950 * this division, it is very difficult to allocate and free bandwidth 951 * dynamically. 952 * 953 * NOTE about the Transaction Translator in USB HUBs: 954 * 955 * USB HUBs have a very simple Transaction Translator, that will 956 * simply pipeline all the SPLIT transactions. That means that the 957 * transactions will be executed in the order they are queued! 958 * 959 */ 960 961/*------------------------------------------------------------------------* 962 * usb2_intr_find_best_slot 963 * 964 * Return value: 965 * The best Transaction Translation slot for an interrupt endpoint. 966 *------------------------------------------------------------------------*/ 967static uint8_t 968usb2_intr_find_best_slot(uint32_t *ptr, uint8_t start, uint8_t end) 969{ 970 uint32_t max = 0xffffffff; 971 uint8_t x; 972 uint8_t y; 973 974 y = 0; 975 976 /* find the last slot with lesser used bandwidth */ 977 978 for (x = start; x < end; x++) { 979 if (max >= ptr[x]) { 980 max = ptr[x]; 981 y = x; 982 } 983 } 984 return (y); 985} 986 987/*------------------------------------------------------------------------* 988 * usb2_intr_schedule_adjust 989 * 990 * This function will update the bandwith usage for the microframe 991 * having index "slot" by "len" bytes. "len" can be negative. If the 992 * "slot" argument is greater or equal to "USB_HS_MICRO_FRAMES_MAX" 993 * the "slot" argument will be replaced by the slot having least used 994 * bandwidth. 995 * 996 * Returns: 997 * The slot on which the bandwidth update was done. 998 *------------------------------------------------------------------------*/ 999uint8_t 1000usb2_intr_schedule_adjust(struct usb2_device *udev, int16_t len, uint8_t slot) 1001{ 1002 struct usb2_bus *bus = udev->bus; 1003 struct usb2_hub *hub; 1004
| 762 763 return (0); 764 765error: 766 usb2_transfer_unsetup(sc->sc_xfer, 2); 767 768 if (udev->hub) { 769 free(udev->hub, M_USBDEV); 770 udev->hub = NULL; 771 } 772 return (ENXIO); 773} 774 775/* 776 * Called from process context when the hub is gone. 777 * Detach all devices on active ports. 778 */ 779static int 780uhub_detach(device_t dev) 781{ 782 struct uhub_softc *sc = device_get_softc(dev); 783 struct usb2_hub *hub = sc->sc_udev->hub; 784 struct usb2_device *child; 785 uint8_t x; 786 787 /* detach all children first */ 788 bus_generic_detach(dev); 789 790 if (hub == NULL) { /* must be partially working */ 791 return (0); 792 } 793 for (x = 0; x != hub->nports; x++) { 794 795 child = usb2_bus_port_get_device(sc->sc_udev->bus, hub->ports + x); 796 797 if (child == NULL) { 798 continue; 799 } 800 /* 801 * Subdevices are not freed, because the caller of 802 * uhub_detach() will do that. 803 */ 804 usb2_detach_device(child, USB_IFACE_INDEX_ANY, 0); 805 usb2_free_device(child); 806 child = NULL; 807 } 808 809 usb2_transfer_unsetup(sc->sc_xfer, 2); 810 811 free(hub, M_USBDEV); 812 sc->sc_udev->hub = NULL; 813 return (0); 814} 815 816static void 817uhub_driver_added(device_t dev, driver_t *driver) 818{ 819 usb2_needs_explore_all(); 820 return; 821} 822 823struct hub_result { 824 struct usb2_device *udev; 825 uint8_t portno; 826 uint8_t iface_index; 827}; 828 829static void 830uhub_find_iface_index(struct usb2_hub *hub, device_t child, 831 struct hub_result *res) 832{ 833 struct usb2_interface *iface; 834 struct usb2_device *udev; 835 uint8_t nports; 836 uint8_t x; 837 uint8_t i; 838 839 nports = hub->nports; 840 for (x = 0; x != nports; x++) { 841 udev = usb2_bus_port_get_device(hub->hubudev->bus, 842 hub->ports + x); 843 if (!udev) { 844 continue; 845 } 846 for (i = 0; i != USB_IFACE_MAX; i++) { 847 iface = usb2_get_iface(udev, i); 848 if (iface && 849 (iface->subdev == child)) { 850 res->iface_index = i; 851 res->udev = udev; 852 res->portno = x + 1; 853 return; 854 } 855 } 856 } 857 res->iface_index = 0; 858 res->udev = NULL; 859 res->portno = 0; 860 return; 861} 862 863static int 864uhub_child_location_string(device_t parent, device_t child, 865 char *buf, size_t buflen) 866{ 867 struct uhub_softc *sc = device_get_softc(parent); 868 struct usb2_hub *hub = sc->sc_udev->hub; 869 struct hub_result res; 870 871 mtx_lock(&Giant); 872 uhub_find_iface_index(hub, child, &res); 873 if (!res.udev) { 874 DPRINTF("device not on hub\n"); 875 if (buflen) { 876 buf[0] = '\0'; 877 } 878 goto done; 879 } 880 snprintf(buf, buflen, "port=%u interface=%u", 881 res.portno, res.iface_index); 882done: 883 mtx_unlock(&Giant); 884 885 return (0); 886} 887 888static int 889uhub_child_pnpinfo_string(device_t parent, device_t child, 890 char *buf, size_t buflen) 891{ 892 struct uhub_softc *sc = device_get_softc(parent); 893 struct usb2_hub *hub = sc->sc_udev->hub; 894 struct usb2_interface *iface; 895 struct hub_result res; 896 897 mtx_lock(&Giant); 898 uhub_find_iface_index(hub, child, &res); 899 if (!res.udev) { 900 DPRINTF("device not on hub\n"); 901 if (buflen) { 902 buf[0] = '\0'; 903 } 904 goto done; 905 } 906 iface = usb2_get_iface(res.udev, res.iface_index); 907 if (iface && iface->idesc) { 908 snprintf(buf, buflen, "vendor=0x%04x product=0x%04x " 909 "devclass=0x%02x devsubclass=0x%02x " 910 "sernum=\"%s\" " 911 "intclass=0x%02x intsubclass=0x%02x", 912 UGETW(res.udev->ddesc.idVendor), 913 UGETW(res.udev->ddesc.idProduct), 914 res.udev->ddesc.bDeviceClass, 915 res.udev->ddesc.bDeviceSubClass, 916 res.udev->serial, 917 iface->idesc->bInterfaceClass, 918 iface->idesc->bInterfaceSubClass); 919 } else { 920 if (buflen) { 921 buf[0] = '\0'; 922 } 923 goto done; 924 } 925done: 926 mtx_unlock(&Giant); 927 928 return (0); 929} 930 931/* 932 * The USB Transaction Translator: 933 * =============================== 934 * 935 * When doing LOW- and FULL-speed USB transfers accross a HIGH-speed 936 * USB HUB, bandwidth must be allocated for ISOCHRONOUS and INTERRUPT 937 * USB transfers. To utilize bandwidth dynamically the "scatter and 938 * gather" principle must be applied. This means that bandwidth must 939 * be divided into equal parts of bandwidth. With regard to USB all 940 * data is transferred in smaller packets with length 941 * "wMaxPacketSize". The problem however is that "wMaxPacketSize" is 942 * not a constant! 943 * 944 * The bandwidth scheduler which I have implemented will simply pack 945 * the USB transfers back to back until there is no more space in the 946 * schedule. Out of the 8 microframes which the USB 2.0 standard 947 * provides, only 6 are available for non-HIGH-speed devices. I have 948 * reserved the first 4 microframes for ISOCHRONOUS transfers. The 949 * last 2 microframes I have reserved for INTERRUPT transfers. Without 950 * this division, it is very difficult to allocate and free bandwidth 951 * dynamically. 952 * 953 * NOTE about the Transaction Translator in USB HUBs: 954 * 955 * USB HUBs have a very simple Transaction Translator, that will 956 * simply pipeline all the SPLIT transactions. That means that the 957 * transactions will be executed in the order they are queued! 958 * 959 */ 960 961/*------------------------------------------------------------------------* 962 * usb2_intr_find_best_slot 963 * 964 * Return value: 965 * The best Transaction Translation slot for an interrupt endpoint. 966 *------------------------------------------------------------------------*/ 967static uint8_t 968usb2_intr_find_best_slot(uint32_t *ptr, uint8_t start, uint8_t end) 969{ 970 uint32_t max = 0xffffffff; 971 uint8_t x; 972 uint8_t y; 973 974 y = 0; 975 976 /* find the last slot with lesser used bandwidth */ 977 978 for (x = start; x < end; x++) { 979 if (max >= ptr[x]) { 980 max = ptr[x]; 981 y = x; 982 } 983 } 984 return (y); 985} 986 987/*------------------------------------------------------------------------* 988 * usb2_intr_schedule_adjust 989 * 990 * This function will update the bandwith usage for the microframe 991 * having index "slot" by "len" bytes. "len" can be negative. If the 992 * "slot" argument is greater or equal to "USB_HS_MICRO_FRAMES_MAX" 993 * the "slot" argument will be replaced by the slot having least used 994 * bandwidth. 995 * 996 * Returns: 997 * The slot on which the bandwidth update was done. 998 *------------------------------------------------------------------------*/ 999uint8_t 1000usb2_intr_schedule_adjust(struct usb2_device *udev, int16_t len, uint8_t slot) 1001{ 1002 struct usb2_bus *bus = udev->bus; 1003 struct usb2_hub *hub; 1004
|