diff options
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r-- | drivers/usb/core/hub.c | 134 |
1 files changed, 106 insertions, 28 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index be86ae3f4088..2af3b4f06054 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -155,6 +155,8 @@ static inline char *portspeed(int portstatus) | |||
155 | return "480 Mb/s"; | 155 | return "480 Mb/s"; |
156 | else if (portstatus & (1 << USB_PORT_FEAT_LOWSPEED)) | 156 | else if (portstatus & (1 << USB_PORT_FEAT_LOWSPEED)) |
157 | return "1.5 Mb/s"; | 157 | return "1.5 Mb/s"; |
158 | else if (portstatus & (1 << USB_PORT_FEAT_SUPERSPEED)) | ||
159 | return "5.0 Gb/s"; | ||
158 | else | 160 | else |
159 | return "12 Mb/s"; | 161 | return "12 Mb/s"; |
160 | } | 162 | } |
@@ -457,13 +459,13 @@ static void hub_tt_kevent (struct work_struct *work) | |||
457 | 459 | ||
458 | spin_lock_irqsave (&hub->tt.lock, flags); | 460 | spin_lock_irqsave (&hub->tt.lock, flags); |
459 | while (--limit && !list_empty (&hub->tt.clear_list)) { | 461 | while (--limit && !list_empty (&hub->tt.clear_list)) { |
460 | struct list_head *temp; | 462 | struct list_head *next; |
461 | struct usb_tt_clear *clear; | 463 | struct usb_tt_clear *clear; |
462 | struct usb_device *hdev = hub->hdev; | 464 | struct usb_device *hdev = hub->hdev; |
463 | int status; | 465 | int status; |
464 | 466 | ||
465 | temp = hub->tt.clear_list.next; | 467 | next = hub->tt.clear_list.next; |
466 | clear = list_entry (temp, struct usb_tt_clear, clear_list); | 468 | clear = list_entry (next, struct usb_tt_clear, clear_list); |
467 | list_del (&clear->clear_list); | 469 | list_del (&clear->clear_list); |
468 | 470 | ||
469 | /* drop lock so HCD can concurrently report other TT errors */ | 471 | /* drop lock so HCD can concurrently report other TT errors */ |
@@ -951,6 +953,9 @@ static int hub_configure(struct usb_hub *hub, | |||
951 | ret); | 953 | ret); |
952 | hub->tt.hub = hdev; | 954 | hub->tt.hub = hdev; |
953 | break; | 955 | break; |
956 | case 3: | ||
957 | /* USB 3.0 hubs don't have a TT */ | ||
958 | break; | ||
954 | default: | 959 | default: |
955 | dev_dbg(hub_dev, "Unrecognized hub protocol %d\n", | 960 | dev_dbg(hub_dev, "Unrecognized hub protocol %d\n", |
956 | hdev->descriptor.bDeviceProtocol); | 961 | hdev->descriptor.bDeviceProtocol); |
@@ -1323,6 +1328,11 @@ EXPORT_SYMBOL_GPL(usb_set_device_state); | |||
1323 | * 0 is reserved by USB for default address; (b) Linux's USB stack | 1328 | * 0 is reserved by USB for default address; (b) Linux's USB stack |
1324 | * uses always #1 for the root hub of the controller. So USB stack's | 1329 | * uses always #1 for the root hub of the controller. So USB stack's |
1325 | * port #1, which is wusb virtual-port #0 has address #2. | 1330 | * port #1, which is wusb virtual-port #0 has address #2. |
1331 | * | ||
1332 | * Devices connected under xHCI are not as simple. The host controller | ||
1333 | * supports virtualization, so the hardware assigns device addresses and | ||
1334 | * the HCD must setup data structures before issuing a set address | ||
1335 | * command to the hardware. | ||
1326 | */ | 1336 | */ |
1327 | static void choose_address(struct usb_device *udev) | 1337 | static void choose_address(struct usb_device *udev) |
1328 | { | 1338 | { |
@@ -1642,6 +1652,9 @@ int usb_new_device(struct usb_device *udev) | |||
1642 | err = usb_configure_device(udev); /* detect & probe dev/intfs */ | 1652 | err = usb_configure_device(udev); /* detect & probe dev/intfs */ |
1643 | if (err < 0) | 1653 | if (err < 0) |
1644 | goto fail; | 1654 | goto fail; |
1655 | dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n", | ||
1656 | udev->devnum, udev->bus->busnum, | ||
1657 | (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); | ||
1645 | /* export the usbdev device-node for libusb */ | 1658 | /* export the usbdev device-node for libusb */ |
1646 | udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, | 1659 | udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, |
1647 | (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); | 1660 | (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); |
@@ -2395,19 +2408,29 @@ EXPORT_SYMBOL_GPL(usb_ep0_reinit); | |||
2395 | static int hub_set_address(struct usb_device *udev, int devnum) | 2408 | static int hub_set_address(struct usb_device *udev, int devnum) |
2396 | { | 2409 | { |
2397 | int retval; | 2410 | int retval; |
2411 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
2398 | 2412 | ||
2399 | if (devnum <= 1) | 2413 | /* |
2414 | * The host controller will choose the device address, | ||
2415 | * instead of the core having chosen it earlier | ||
2416 | */ | ||
2417 | if (!hcd->driver->address_device && devnum <= 1) | ||
2400 | return -EINVAL; | 2418 | return -EINVAL; |
2401 | if (udev->state == USB_STATE_ADDRESS) | 2419 | if (udev->state == USB_STATE_ADDRESS) |
2402 | return 0; | 2420 | return 0; |
2403 | if (udev->state != USB_STATE_DEFAULT) | 2421 | if (udev->state != USB_STATE_DEFAULT) |
2404 | return -EINVAL; | 2422 | return -EINVAL; |
2405 | retval = usb_control_msg(udev, usb_sndaddr0pipe(), | 2423 | if (hcd->driver->address_device) { |
2406 | USB_REQ_SET_ADDRESS, 0, devnum, 0, | 2424 | retval = hcd->driver->address_device(hcd, udev); |
2407 | NULL, 0, USB_CTRL_SET_TIMEOUT); | 2425 | } else { |
2426 | retval = usb_control_msg(udev, usb_sndaddr0pipe(), | ||
2427 | USB_REQ_SET_ADDRESS, 0, devnum, 0, | ||
2428 | NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
2429 | if (retval == 0) | ||
2430 | update_address(udev, devnum); | ||
2431 | } | ||
2408 | if (retval == 0) { | 2432 | if (retval == 0) { |
2409 | /* Device now using proper address. */ | 2433 | /* Device now using proper address. */ |
2410 | update_address(udev, devnum); | ||
2411 | usb_set_device_state(udev, USB_STATE_ADDRESS); | 2434 | usb_set_device_state(udev, USB_STATE_ADDRESS); |
2412 | usb_ep0_reinit(udev); | 2435 | usb_ep0_reinit(udev); |
2413 | } | 2436 | } |
@@ -2430,6 +2453,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2430 | static DEFINE_MUTEX(usb_address0_mutex); | 2453 | static DEFINE_MUTEX(usb_address0_mutex); |
2431 | 2454 | ||
2432 | struct usb_device *hdev = hub->hdev; | 2455 | struct usb_device *hdev = hub->hdev; |
2456 | struct usb_hcd *hcd = bus_to_hcd(hdev->bus); | ||
2433 | int i, j, retval; | 2457 | int i, j, retval; |
2434 | unsigned delay = HUB_SHORT_RESET_TIME; | 2458 | unsigned delay = HUB_SHORT_RESET_TIME; |
2435 | enum usb_device_speed oldspeed = udev->speed; | 2459 | enum usb_device_speed oldspeed = udev->speed; |
@@ -2452,11 +2476,24 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2452 | 2476 | ||
2453 | mutex_lock(&usb_address0_mutex); | 2477 | mutex_lock(&usb_address0_mutex); |
2454 | 2478 | ||
2455 | /* Reset the device; full speed may morph to high speed */ | 2479 | if ((hcd->driver->flags & HCD_USB3) && udev->config) { |
2456 | retval = hub_port_reset(hub, port1, udev, delay); | 2480 | /* FIXME this will need special handling by the xHCI driver. */ |
2457 | if (retval < 0) /* error or disconnect */ | 2481 | dev_dbg(&udev->dev, |
2482 | "xHCI reset of configured device " | ||
2483 | "not supported yet.\n"); | ||
2484 | retval = -EINVAL; | ||
2458 | goto fail; | 2485 | goto fail; |
2459 | /* success, speed is known */ | 2486 | } else if (!udev->config && oldspeed == USB_SPEED_SUPER) { |
2487 | /* Don't reset USB 3.0 devices during an initial setup */ | ||
2488 | usb_set_device_state(udev, USB_STATE_DEFAULT); | ||
2489 | } else { | ||
2490 | /* Reset the device; full speed may morph to high speed */ | ||
2491 | /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ | ||
2492 | retval = hub_port_reset(hub, port1, udev, delay); | ||
2493 | if (retval < 0) /* error or disconnect */ | ||
2494 | goto fail; | ||
2495 | /* success, speed is known */ | ||
2496 | } | ||
2460 | retval = -ENODEV; | 2497 | retval = -ENODEV; |
2461 | 2498 | ||
2462 | if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed) { | 2499 | if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed) { |
@@ -2471,6 +2508,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2471 | * reported as 0xff in the device descriptor). WUSB1.0[4.8.1]. | 2508 | * reported as 0xff in the device descriptor). WUSB1.0[4.8.1]. |
2472 | */ | 2509 | */ |
2473 | switch (udev->speed) { | 2510 | switch (udev->speed) { |
2511 | case USB_SPEED_SUPER: | ||
2474 | case USB_SPEED_VARIABLE: /* fixed at 512 */ | 2512 | case USB_SPEED_VARIABLE: /* fixed at 512 */ |
2475 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512); | 2513 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512); |
2476 | break; | 2514 | break; |
@@ -2496,16 +2534,20 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2496 | case USB_SPEED_LOW: speed = "low"; break; | 2534 | case USB_SPEED_LOW: speed = "low"; break; |
2497 | case USB_SPEED_FULL: speed = "full"; break; | 2535 | case USB_SPEED_FULL: speed = "full"; break; |
2498 | case USB_SPEED_HIGH: speed = "high"; break; | 2536 | case USB_SPEED_HIGH: speed = "high"; break; |
2537 | case USB_SPEED_SUPER: | ||
2538 | speed = "super"; | ||
2539 | break; | ||
2499 | case USB_SPEED_VARIABLE: | 2540 | case USB_SPEED_VARIABLE: |
2500 | speed = "variable"; | 2541 | speed = "variable"; |
2501 | type = "Wireless "; | 2542 | type = "Wireless "; |
2502 | break; | 2543 | break; |
2503 | default: speed = "?"; break; | 2544 | default: speed = "?"; break; |
2504 | } | 2545 | } |
2505 | dev_info (&udev->dev, | 2546 | if (udev->speed != USB_SPEED_SUPER) |
2506 | "%s %s speed %sUSB device using %s and address %d\n", | 2547 | dev_info(&udev->dev, |
2507 | (udev->config) ? "reset" : "new", speed, type, | 2548 | "%s %s speed %sUSB device using %s and address %d\n", |
2508 | udev->bus->controller->driver->name, devnum); | 2549 | (udev->config) ? "reset" : "new", speed, type, |
2550 | udev->bus->controller->driver->name, devnum); | ||
2509 | 2551 | ||
2510 | /* Set up TT records, if needed */ | 2552 | /* Set up TT records, if needed */ |
2511 | if (hdev->tt) { | 2553 | if (hdev->tt) { |
@@ -2530,7 +2572,11 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2530 | * value. | 2572 | * value. |
2531 | */ | 2573 | */ |
2532 | for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) { | 2574 | for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) { |
2533 | if (USE_NEW_SCHEME(retry_counter)) { | 2575 | /* |
2576 | * An xHCI controller cannot send any packets to a device until | ||
2577 | * a set address command successfully completes. | ||
2578 | */ | ||
2579 | if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) { | ||
2534 | struct usb_device_descriptor *buf; | 2580 | struct usb_device_descriptor *buf; |
2535 | int r = 0; | 2581 | int r = 0; |
2536 | 2582 | ||
@@ -2596,7 +2642,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2596 | * unauthorized address in the Connect Ack sequence; | 2642 | * unauthorized address in the Connect Ack sequence; |
2597 | * authorization will assign the final address. | 2643 | * authorization will assign the final address. |
2598 | */ | 2644 | */ |
2599 | if (udev->wusb == 0) { | 2645 | if (udev->wusb == 0) { |
2600 | for (j = 0; j < SET_ADDRESS_TRIES; ++j) { | 2646 | for (j = 0; j < SET_ADDRESS_TRIES; ++j) { |
2601 | retval = hub_set_address(udev, devnum); | 2647 | retval = hub_set_address(udev, devnum); |
2602 | if (retval >= 0) | 2648 | if (retval >= 0) |
@@ -2609,13 +2655,20 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2609 | devnum, retval); | 2655 | devnum, retval); |
2610 | goto fail; | 2656 | goto fail; |
2611 | } | 2657 | } |
2658 | if (udev->speed == USB_SPEED_SUPER) { | ||
2659 | devnum = udev->devnum; | ||
2660 | dev_info(&udev->dev, | ||
2661 | "%s SuperSpeed USB device using %s and address %d\n", | ||
2662 | (udev->config) ? "reset" : "new", | ||
2663 | udev->bus->controller->driver->name, devnum); | ||
2664 | } | ||
2612 | 2665 | ||
2613 | /* cope with hardware quirkiness: | 2666 | /* cope with hardware quirkiness: |
2614 | * - let SET_ADDRESS settle, some device hardware wants it | 2667 | * - let SET_ADDRESS settle, some device hardware wants it |
2615 | * - read ep0 maxpacket even for high and low speed, | 2668 | * - read ep0 maxpacket even for high and low speed, |
2616 | */ | 2669 | */ |
2617 | msleep(10); | 2670 | msleep(10); |
2618 | if (USE_NEW_SCHEME(retry_counter)) | 2671 | if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) |
2619 | break; | 2672 | break; |
2620 | } | 2673 | } |
2621 | 2674 | ||
@@ -2634,8 +2687,11 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2634 | if (retval) | 2687 | if (retval) |
2635 | goto fail; | 2688 | goto fail; |
2636 | 2689 | ||
2637 | i = udev->descriptor.bMaxPacketSize0 == 0xff? /* wusb device? */ | 2690 | if (udev->descriptor.bMaxPacketSize0 == 0xff || |
2638 | 512 : udev->descriptor.bMaxPacketSize0; | 2691 | udev->speed == USB_SPEED_SUPER) |
2692 | i = 512; | ||
2693 | else | ||
2694 | i = udev->descriptor.bMaxPacketSize0; | ||
2639 | if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) { | 2695 | if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) { |
2640 | if (udev->speed != USB_SPEED_FULL || | 2696 | if (udev->speed != USB_SPEED_FULL || |
2641 | !(i == 8 || i == 16 || i == 32 || i == 64)) { | 2697 | !(i == 8 || i == 16 || i == 32 || i == 64)) { |
@@ -2847,19 +2903,41 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2847 | } | 2903 | } |
2848 | 2904 | ||
2849 | usb_set_device_state(udev, USB_STATE_POWERED); | 2905 | usb_set_device_state(udev, USB_STATE_POWERED); |
2850 | udev->speed = USB_SPEED_UNKNOWN; | ||
2851 | udev->bus_mA = hub->mA_per_port; | 2906 | udev->bus_mA = hub->mA_per_port; |
2852 | udev->level = hdev->level + 1; | 2907 | udev->level = hdev->level + 1; |
2853 | udev->wusb = hub_is_wusb(hub); | 2908 | udev->wusb = hub_is_wusb(hub); |
2854 | 2909 | ||
2855 | /* set the address */ | 2910 | /* |
2856 | choose_address(udev); | 2911 | * USB 3.0 devices are reset automatically before the connect |
2857 | if (udev->devnum <= 0) { | 2912 | * port status change appears, and the root hub port status |
2858 | status = -ENOTCONN; /* Don't retry */ | 2913 | * shows the correct speed. We also get port change |
2859 | goto loop; | 2914 | * notifications for USB 3.0 devices from the USB 3.0 portion of |
2915 | * an external USB 3.0 hub, but this isn't handled correctly yet | ||
2916 | * FIXME. | ||
2917 | */ | ||
2918 | |||
2919 | if (!(hcd->driver->flags & HCD_USB3)) | ||
2920 | udev->speed = USB_SPEED_UNKNOWN; | ||
2921 | else if ((hdev->parent == NULL) && | ||
2922 | (portstatus & (1 << USB_PORT_FEAT_SUPERSPEED))) | ||
2923 | udev->speed = USB_SPEED_SUPER; | ||
2924 | else | ||
2925 | udev->speed = USB_SPEED_UNKNOWN; | ||
2926 | |||
2927 | /* | ||
2928 | * xHCI needs to issue an address device command later | ||
2929 | * in the hub_port_init sequence for SS/HS/FS/LS devices. | ||
2930 | */ | ||
2931 | if (!(hcd->driver->flags & HCD_USB3)) { | ||
2932 | /* set the address */ | ||
2933 | choose_address(udev); | ||
2934 | if (udev->devnum <= 0) { | ||
2935 | status = -ENOTCONN; /* Don't retry */ | ||
2936 | goto loop; | ||
2937 | } | ||
2860 | } | 2938 | } |
2861 | 2939 | ||
2862 | /* reset and get descriptor */ | 2940 | /* reset (non-USB 3.0 devices) and get descriptor */ |
2863 | status = hub_port_init(hub, udev, port1, i); | 2941 | status = hub_port_init(hub, udev, port1, i); |
2864 | if (status < 0) | 2942 | if (status < 0) |
2865 | goto loop; | 2943 | goto loop; |