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.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 92dde941fdbe..06cec635e703 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1112,16 +1112,13 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
1112 /* 1112 /*
1113 * USB3 protocol ports will automatically transition 1113 * USB3 protocol ports will automatically transition
1114 * to Enabled state when detect an USB3.0 device attach. 1114 * to Enabled state when detect an USB3.0 device attach.
1115 * Do not disable USB3 protocol ports. 1115 * Do not disable USB3 protocol ports, just pretend
1116 * power was lost
1116 */ 1117 */
1117 if (!hub_is_superspeed(hdev)) { 1118 portstatus &= ~USB_PORT_STAT_ENABLE;
1119 if (!hub_is_superspeed(hdev))
1118 usb_clear_port_feature(hdev, port1, 1120 usb_clear_port_feature(hdev, port1,
1119 USB_PORT_FEAT_ENABLE); 1121 USB_PORT_FEAT_ENABLE);
1120 portstatus &= ~USB_PORT_STAT_ENABLE;
1121 } else {
1122 /* Pretend that power was lost for USB3 devs */
1123 portstatus &= ~USB_PORT_STAT_ENABLE;
1124 }
1125 } 1122 }
1126 1123
1127 /* Clear status-change flags; we'll debounce later */ 1124 /* Clear status-change flags; we'll debounce later */
@@ -3958,6 +3955,32 @@ static int hub_set_address(struct usb_device *udev, int devnum)
3958 return retval; 3955 return retval;
3959} 3956}
3960 3957
3958/*
3959 * There are reports of USB 3.0 devices that say they support USB 2.0 Link PM
3960 * when they're plugged into a USB 2.0 port, but they don't work when LPM is
3961 * enabled.
3962 *
3963 * Only enable USB 2.0 Link PM if the port is internal (hardwired), or the
3964 * device says it supports the new USB 2.0 Link PM errata by setting the BESL
3965 * support bit in the BOS descriptor.
3966 */
3967static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev)
3968{
3969 int connect_type;
3970
3971 if (!udev->usb2_hw_lpm_capable)
3972 return;
3973
3974 connect_type = usb_get_hub_port_connect_type(udev->parent,
3975 udev->portnum);
3976
3977 if ((udev->bos->ext_cap->bmAttributes & USB_BESL_SUPPORT) ||
3978 connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
3979 udev->usb2_hw_lpm_allowed = 1;
3980 usb_set_usb2_hardware_lpm(udev, 1);
3981 }
3982}
3983
3961/* Reset device, (re)assign address, get device descriptor. 3984/* Reset device, (re)assign address, get device descriptor.
3962 * Device connection must be stable, no more debouncing needed. 3985 * Device connection must be stable, no more debouncing needed.
3963 * Returns device in USB_STATE_ADDRESS, except on error. 3986 * Returns device in USB_STATE_ADDRESS, except on error.
@@ -4251,6 +4274,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
4251 /* notify HCD that we have a device connected and addressed */ 4274 /* notify HCD that we have a device connected and addressed */
4252 if (hcd->driver->update_device) 4275 if (hcd->driver->update_device)
4253 hcd->driver->update_device(hcd, udev); 4276 hcd->driver->update_device(hcd, udev);
4277 hub_set_initial_usb2_lpm_policy(udev);
4254fail: 4278fail:
4255 if (retval) { 4279 if (retval) {
4256 hub_port_disable(hub, port1, 0); 4280 hub_port_disable(hub, port1, 0);
@@ -5095,6 +5119,12 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
5095 } 5119 }
5096 parent_hub = usb_hub_to_struct_hub(parent_hdev); 5120 parent_hub = usb_hub_to_struct_hub(parent_hdev);
5097 5121
5122 /* Disable USB2 hardware LPM.
5123 * It will be re-enabled by the enumeration process.
5124 */
5125 if (udev->usb2_hw_lpm_enabled == 1)
5126 usb_set_usb2_hardware_lpm(udev, 0);
5127
5098 bos = udev->bos; 5128 bos = udev->bos;
5099 udev->bos = NULL; 5129 udev->bos = NULL;
5100 5130
@@ -5202,6 +5232,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
5202 5232
5203done: 5233done:
5204 /* Now that the alt settings are re-installed, enable LTM and LPM. */ 5234 /* Now that the alt settings are re-installed, enable LTM and LPM. */
5235 usb_set_usb2_hardware_lpm(udev, 1);
5205 usb_unlocked_enable_lpm(udev); 5236 usb_unlocked_enable_lpm(udev);
5206 usb_enable_ltm(udev); 5237 usb_enable_ltm(udev);
5207 usb_release_bos_descriptor(udev); 5238 usb_release_bos_descriptor(udev);