aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/hub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r--drivers/usb/core/hub.c124
1 files changed, 57 insertions, 67 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 3b7151687776..73dfa194160b 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -122,12 +122,12 @@ struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev)
122 return usb_get_intfdata(hdev->actconfig->interface[0]); 122 return usb_get_intfdata(hdev->actconfig->interface[0]);
123} 123}
124 124
125static int usb_device_supports_lpm(struct usb_device *udev) 125int usb_device_supports_lpm(struct usb_device *udev)
126{ 126{
127 /* USB 2.1 (and greater) devices indicate LPM support through 127 /* USB 2.1 (and greater) devices indicate LPM support through
128 * their USB 2.0 Extended Capabilities BOS descriptor. 128 * their USB 2.0 Extended Capabilities BOS descriptor.
129 */ 129 */
130 if (udev->speed == USB_SPEED_HIGH) { 130 if (udev->speed == USB_SPEED_HIGH || udev->speed == USB_SPEED_FULL) {
131 if (udev->bos->ext_cap && 131 if (udev->bos->ext_cap &&
132 (USB_LPM_SUPPORT & 132 (USB_LPM_SUPPORT &
133 le32_to_cpu(udev->bos->ext_cap->bmAttributes))) 133 le32_to_cpu(udev->bos->ext_cap->bmAttributes)))
@@ -795,7 +795,8 @@ int usb_hub_clear_tt_buffer(struct urb *urb)
795 * since each TT has "at least two" buffers that can need it (and 795 * since each TT has "at least two" buffers that can need it (and
796 * there can be many TTs per hub). even if they're uncommon. 796 * there can be many TTs per hub). even if they're uncommon.
797 */ 797 */
798 if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) { 798 clear = kmalloc(sizeof *clear, GFP_ATOMIC);
799 if (clear == NULL) {
799 dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n"); 800 dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n");
800 /* FIXME recover somehow ... RESET_TT? */ 801 /* FIXME recover somehow ... RESET_TT? */
801 return -ENOMEM; 802 return -ENOMEM;
@@ -2350,6 +2351,26 @@ static void set_usb_port_removable(struct usb_device *udev)
2350 2351
2351 hub = usb_hub_to_struct_hub(udev->parent); 2352 hub = usb_hub_to_struct_hub(udev->parent);
2352 2353
2354 /*
2355 * If the platform firmware has provided information about a port,
2356 * use that to determine whether it's removable.
2357 */
2358 switch (hub->ports[udev->portnum - 1]->connect_type) {
2359 case USB_PORT_CONNECT_TYPE_HOT_PLUG:
2360 udev->removable = USB_DEVICE_REMOVABLE;
2361 return;
2362 case USB_PORT_CONNECT_TYPE_HARD_WIRED:
2363 case USB_PORT_NOT_USED:
2364 udev->removable = USB_DEVICE_FIXED;
2365 return;
2366 default:
2367 break;
2368 }
2369
2370 /*
2371 * Otherwise, check whether the hub knows whether a port is removable
2372 * or not
2373 */
2353 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); 2374 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);
2354 2375
2355 if (!(wHubCharacteristics & HUB_CHAR_COMPOUND)) 2376 if (!(wHubCharacteristics & HUB_CHAR_COMPOUND))
@@ -2369,21 +2390,6 @@ static void set_usb_port_removable(struct usb_device *udev)
2369 else 2390 else
2370 udev->removable = USB_DEVICE_FIXED; 2391 udev->removable = USB_DEVICE_FIXED;
2371 2392
2372 /*
2373 * Platform firmware may have populated an alternative value for
2374 * removable. If the parent port has a known connect_type use
2375 * that instead.
2376 */
2377 switch (hub->ports[udev->portnum - 1]->connect_type) {
2378 case USB_PORT_CONNECT_TYPE_HOT_PLUG:
2379 udev->removable = USB_DEVICE_REMOVABLE;
2380 break;
2381 case USB_PORT_CONNECT_TYPE_HARD_WIRED:
2382 udev->removable = USB_DEVICE_FIXED;
2383 break;
2384 default: /* use what was set above */
2385 break;
2386 }
2387} 2393}
2388 2394
2389/** 2395/**
@@ -2616,9 +2622,6 @@ static bool use_new_scheme(struct usb_device *udev, int retry)
2616 return USE_NEW_SCHEME(retry); 2622 return USE_NEW_SCHEME(retry);
2617} 2623}
2618 2624
2619static int hub_port_reset(struct usb_hub *hub, int port1,
2620 struct usb_device *udev, unsigned int delay, bool warm);
2621
2622/* Is a USB 3.0 port in the Inactive or Compliance Mode state? 2625/* Is a USB 3.0 port in the Inactive or Compliance Mode state?
2623 * Port worm reset is required to recover 2626 * Port worm reset is required to recover
2624 */ 2627 */
@@ -2706,44 +2709,6 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
2706 return 0; 2709 return 0;
2707} 2710}
2708 2711
2709static void hub_port_finish_reset(struct usb_hub *hub, int port1,
2710 struct usb_device *udev, int *status)
2711{
2712 switch (*status) {
2713 case 0:
2714 /* TRSTRCY = 10 ms; plus some extra */
2715 msleep(10 + 40);
2716 if (udev) {
2717 struct usb_hcd *hcd = bus_to_hcd(udev->bus);
2718
2719 update_devnum(udev, 0);
2720 /* The xHC may think the device is already reset,
2721 * so ignore the status.
2722 */
2723 if (hcd->driver->reset_device)
2724 hcd->driver->reset_device(hcd, udev);
2725 }
2726 /* FALL THROUGH */
2727 case -ENOTCONN:
2728 case -ENODEV:
2729 usb_clear_port_feature(hub->hdev,
2730 port1, USB_PORT_FEAT_C_RESET);
2731 if (hub_is_superspeed(hub->hdev)) {
2732 usb_clear_port_feature(hub->hdev, port1,
2733 USB_PORT_FEAT_C_BH_PORT_RESET);
2734 usb_clear_port_feature(hub->hdev, port1,
2735 USB_PORT_FEAT_C_PORT_LINK_STATE);
2736 usb_clear_port_feature(hub->hdev, port1,
2737 USB_PORT_FEAT_C_CONNECTION);
2738 }
2739 if (udev)
2740 usb_set_device_state(udev, *status
2741 ? USB_STATE_NOTATTACHED
2742 : USB_STATE_DEFAULT);
2743 break;
2744 }
2745}
2746
2747/* Handle port reset and port warm(BH) reset (for USB3 protocol ports) */ 2712/* Handle port reset and port warm(BH) reset (for USB3 protocol ports) */
2748static int hub_port_reset(struct usb_hub *hub, int port1, 2713static int hub_port_reset(struct usb_hub *hub, int port1,
2749 struct usb_device *udev, unsigned int delay, bool warm) 2714 struct usb_device *udev, unsigned int delay, bool warm)
@@ -2767,13 +2732,10 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
2767 * If the caller hasn't explicitly requested a warm reset, 2732 * If the caller hasn't explicitly requested a warm reset,
2768 * double check and see if one is needed. 2733 * double check and see if one is needed.
2769 */ 2734 */
2770 status = hub_port_status(hub, port1, 2735 if (hub_port_status(hub, port1, &portstatus, &portchange) == 0)
2771 &portstatus, &portchange); 2736 if (hub_port_warm_reset_required(hub, port1,
2772 if (status < 0) 2737 portstatus))
2773 goto done; 2738 warm = true;
2774
2775 if (hub_port_warm_reset_required(hub, port1, portstatus))
2776 warm = true;
2777 } 2739 }
2778 clear_bit(port1, hub->warm_reset_bits); 2740 clear_bit(port1, hub->warm_reset_bits);
2779 2741
@@ -2799,11 +2761,19 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
2799 2761
2800 /* Check for disconnect or reset */ 2762 /* Check for disconnect or reset */
2801 if (status == 0 || status == -ENOTCONN || status == -ENODEV) { 2763 if (status == 0 || status == -ENOTCONN || status == -ENODEV) {
2802 hub_port_finish_reset(hub, port1, udev, &status); 2764 usb_clear_port_feature(hub->hdev, port1,
2765 USB_PORT_FEAT_C_RESET);
2803 2766
2804 if (!hub_is_superspeed(hub->hdev)) 2767 if (!hub_is_superspeed(hub->hdev))
2805 goto done; 2768 goto done;
2806 2769
2770 usb_clear_port_feature(hub->hdev, port1,
2771 USB_PORT_FEAT_C_BH_PORT_RESET);
2772 usb_clear_port_feature(hub->hdev, port1,
2773 USB_PORT_FEAT_C_PORT_LINK_STATE);
2774 usb_clear_port_feature(hub->hdev, port1,
2775 USB_PORT_FEAT_C_CONNECTION);
2776
2807 /* 2777 /*
2808 * If a USB 3.0 device migrates from reset to an error 2778 * If a USB 3.0 device migrates from reset to an error
2809 * state, re-issue the warm reset. 2779 * state, re-issue the warm reset.
@@ -2836,6 +2806,26 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
2836 dev_err(&port_dev->dev, "Cannot enable. Maybe the USB cable is bad?\n"); 2806 dev_err(&port_dev->dev, "Cannot enable. Maybe the USB cable is bad?\n");
2837 2807
2838done: 2808done:
2809 if (status == 0) {
2810 /* TRSTRCY = 10 ms; plus some extra */
2811 msleep(10 + 40);
2812 if (udev) {
2813 struct usb_hcd *hcd = bus_to_hcd(udev->bus);
2814
2815 update_devnum(udev, 0);
2816 /* The xHC may think the device is already reset,
2817 * so ignore the status.
2818 */
2819 if (hcd->driver->reset_device)
2820 hcd->driver->reset_device(hcd, udev);
2821
2822 usb_set_device_state(udev, USB_STATE_DEFAULT);
2823 }
2824 } else {
2825 if (udev)
2826 usb_set_device_state(udev, USB_STATE_NOTATTACHED);
2827 }
2828
2839 if (!hub_is_superspeed(hub->hdev)) 2829 if (!hub_is_superspeed(hub->hdev))
2840 up_read(&ehci_cf_port_reset_rwsem); 2830 up_read(&ehci_cf_port_reset_rwsem);
2841 2831