aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2012-05-02 17:25:52 -0400
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2012-05-18 18:41:59 -0400
commit8306095fd2c1100e8244c09bf560f97aca5a311d (patch)
tree1096f11806046e60f32496f1bac843a6f17b4c26 /drivers/usb/core
parent1ea7e0e8e3d0f50901d335ea4178ab2aa8c88201 (diff)
USB: Disable USB 3.0 LPM in critical sections.
There are several places where the USB core needs to disable USB 3.0 Link PM: - usb_bind_interface - usb_unbind_interface - usb_driver_claim_interface - usb_port_suspend/usb_port_resume - usb_reset_and_verify_device - usb_set_interface - usb_reset_configuration - usb_set_configuration Use the new LPM disable/enable functions to temporarily disable LPM around these critical sections. We need to protect the critical section around binding and unbinding USB interface drivers. USB drivers may want to disable hub-initiated USB 3.0 LPM, which will change the value of the U1/U2 timeouts that the xHCI driver will install. We need to disable LPM completely until the driver is bound to the interface, and the driver has a chance to enable whatever alternate interface setting it needs in its probe routine. Then re-enable USB3 LPM, and recalculate the U1/U2 timeout values. We also need to disable LPM in usb_driver_claim_interface, because drivers like usbfs can bind to an interface through that function. Note, there is no way currently for userspace drivers to disable hub-initiated USB 3.0 LPM. Revisit this later. When a driver is unbound, the U1/U2 timeouts may change because we are unbinding the last driver that needed hub-initiated USB 3.0 LPM to be disabled. USB LPM must be disabled when a USB device is going to be suspended. The USB 3.0 spec does not define a state transition from U1 or U2 into U3, so we need to bring the device into U0 by disabling LPM before we can place it into U3. Therefore, call usb_unlocked_disable_lpm() in usb_port_suspend(), and call usb_unlocked_enable_lpm() in usb_port_resume(). If the port suspend fails, make sure to re-enable LPM by calling usb_unlocked_enable_lpm(), since usb_port_resume() will not be called on a failed port suspend. USB 3.0 devices lose their USB 3.0 LPM settings (including whether USB device-initiated LPM is enabled) across device suspend. Therefore, disable LPM before the device will be reset in usb_reset_and_verify_device(), and re-enable LPM after the reset is complete and the configuration/alt settings are re-installed. The calculated U1/U2 timeout values are heavily dependent on what USB device endpoints are currently enabled. When any of the enabled endpoints on the device might change, due to a new configuration, or new alternate interface setting, we need to first disable USB 3.0 LPM, add or delete endpoints from the xHCI schedule, install the new interfaces and alt settings, and then re-enable LPM. Do this in usb_set_interface, usb_reset_configuration, and usb_set_configuration. Basically, there is a call to disable and then enable LPM in all functions that lock the bandwidth_mutex. One exception is usb_disable_device, because the device is disconnecting or otherwise going away, and we should not care about whether USB 3.0 LPM is enabled. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/driver.c54
-rw-r--r--drivers/usb/core/hub.c27
-rw-r--r--drivers/usb/core/message.c38
3 files changed, 118 insertions, 1 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index f6f81c85c5cf..f536aebc958e 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -288,6 +288,7 @@ static int usb_probe_interface(struct device *dev)
288 struct usb_device *udev = interface_to_usbdev(intf); 288 struct usb_device *udev = interface_to_usbdev(intf);
289 const struct usb_device_id *id; 289 const struct usb_device_id *id;
290 int error = -ENODEV; 290 int error = -ENODEV;
291 int lpm_disable_error;
291 292
292 dev_dbg(dev, "%s\n", __func__); 293 dev_dbg(dev, "%s\n", __func__);
293 294
@@ -324,6 +325,25 @@ static int usb_probe_interface(struct device *dev)
324 if (driver->supports_autosuspend) 325 if (driver->supports_autosuspend)
325 pm_runtime_enable(dev); 326 pm_runtime_enable(dev);
326 327
328 /* If the new driver doesn't allow hub-initiated LPM, and we can't
329 * disable hub-initiated LPM, then fail the probe.
330 *
331 * Otherwise, leaving LPM enabled should be harmless, because the
332 * endpoint intervals should remain the same, and the U1/U2 timeouts
333 * should remain the same.
334 *
335 * If we need to install alt setting 0 before probe, or another alt
336 * setting during probe, that should also be fine. usb_set_interface()
337 * will attempt to disable LPM, and fail if it can't disable it.
338 */
339 lpm_disable_error = usb_unlocked_disable_lpm(udev);
340 if (lpm_disable_error && driver->disable_hub_initiated_lpm) {
341 dev_err(&intf->dev, "%s Failed to disable LPM for driver %s\n.",
342 __func__, driver->name);
343 error = lpm_disable_error;
344 goto err;
345 }
346
327 /* Carry out a deferred switch to altsetting 0 */ 347 /* Carry out a deferred switch to altsetting 0 */
328 if (intf->needs_altsetting0) { 348 if (intf->needs_altsetting0) {
329 error = usb_set_interface(udev, intf->altsetting[0]. 349 error = usb_set_interface(udev, intf->altsetting[0].
@@ -338,6 +358,11 @@ static int usb_probe_interface(struct device *dev)
338 goto err; 358 goto err;
339 359
340 intf->condition = USB_INTERFACE_BOUND; 360 intf->condition = USB_INTERFACE_BOUND;
361
362 /* If the LPM disable succeeded, balance the ref counts. */
363 if (!lpm_disable_error)
364 usb_unlocked_enable_lpm(udev);
365
341 usb_autosuspend_device(udev); 366 usb_autosuspend_device(udev);
342 return error; 367 return error;
343 368
@@ -361,7 +386,7 @@ static int usb_unbind_interface(struct device *dev)
361 struct usb_driver *driver = to_usb_driver(dev->driver); 386 struct usb_driver *driver = to_usb_driver(dev->driver);
362 struct usb_interface *intf = to_usb_interface(dev); 387 struct usb_interface *intf = to_usb_interface(dev);
363 struct usb_device *udev; 388 struct usb_device *udev;
364 int error, r; 389 int error, r, lpm_disable_error;
365 390
366 intf->condition = USB_INTERFACE_UNBINDING; 391 intf->condition = USB_INTERFACE_UNBINDING;
367 392
@@ -369,6 +394,13 @@ static int usb_unbind_interface(struct device *dev)
369 udev = interface_to_usbdev(intf); 394 udev = interface_to_usbdev(intf);
370 error = usb_autoresume_device(udev); 395 error = usb_autoresume_device(udev);
371 396
397 /* Hub-initiated LPM policy may change, so attempt to disable LPM until
398 * the driver is unbound. If LPM isn't disabled, that's fine because it
399 * wouldn't be enabled unless all the bound interfaces supported
400 * hub-initiated LPM.
401 */
402 lpm_disable_error = usb_unlocked_disable_lpm(udev);
403
372 /* Terminate all URBs for this interface unless the driver 404 /* Terminate all URBs for this interface unless the driver
373 * supports "soft" unbinding. 405 * supports "soft" unbinding.
374 */ 406 */
@@ -402,6 +434,10 @@ static int usb_unbind_interface(struct device *dev)
402 intf->condition = USB_INTERFACE_UNBOUND; 434 intf->condition = USB_INTERFACE_UNBOUND;
403 intf->needs_remote_wakeup = 0; 435 intf->needs_remote_wakeup = 0;
404 436
437 /* Attempt to re-enable USB3 LPM, if the disable succeeded. */
438 if (!lpm_disable_error)
439 usb_unlocked_enable_lpm(udev);
440
405 /* Unbound interfaces are always runtime-PM-disabled and -suspended */ 441 /* Unbound interfaces are always runtime-PM-disabled and -suspended */
406 if (driver->supports_autosuspend) 442 if (driver->supports_autosuspend)
407 pm_runtime_disable(dev); 443 pm_runtime_disable(dev);
@@ -442,17 +478,29 @@ int usb_driver_claim_interface(struct usb_driver *driver,
442 struct usb_interface *iface, void *priv) 478 struct usb_interface *iface, void *priv)
443{ 479{
444 struct device *dev = &iface->dev; 480 struct device *dev = &iface->dev;
481 struct usb_device *udev;
445 int retval = 0; 482 int retval = 0;
483 int lpm_disable_error;
446 484
447 if (dev->driver) 485 if (dev->driver)
448 return -EBUSY; 486 return -EBUSY;
449 487
488 udev = interface_to_usbdev(iface);
489
450 dev->driver = &driver->drvwrap.driver; 490 dev->driver = &driver->drvwrap.driver;
451 usb_set_intfdata(iface, priv); 491 usb_set_intfdata(iface, priv);
452 iface->needs_binding = 0; 492 iface->needs_binding = 0;
453 493
454 iface->condition = USB_INTERFACE_BOUND; 494 iface->condition = USB_INTERFACE_BOUND;
455 495
496 /* Disable LPM until this driver is bound. */
497 lpm_disable_error = usb_unlocked_disable_lpm(udev);
498 if (lpm_disable_error && driver->disable_hub_initiated_lpm) {
499 dev_err(&iface->dev, "%s Failed to disable LPM for driver %s\n.",
500 __func__, driver->name);
501 return -ENOMEM;
502 }
503
456 /* Claimed interfaces are initially inactive (suspended) and 504 /* Claimed interfaces are initially inactive (suspended) and
457 * runtime-PM-enabled, but only if the driver has autosuspend 505 * runtime-PM-enabled, but only if the driver has autosuspend
458 * support. Otherwise they are marked active, to prevent the 506 * support. Otherwise they are marked active, to prevent the
@@ -471,6 +519,10 @@ int usb_driver_claim_interface(struct usb_driver *driver,
471 if (device_is_registered(dev)) 519 if (device_is_registered(dev))
472 retval = device_bind_driver(dev); 520 retval = device_bind_driver(dev);
473 521
522 /* Attempt to re-enable USB3 LPM, if the disable was successful. */
523 if (!lpm_disable_error)
524 usb_unlocked_enable_lpm(udev);
525
474 return retval; 526 return retval;
475} 527}
476EXPORT_SYMBOL_GPL(usb_driver_claim_interface); 528EXPORT_SYMBOL_GPL(usb_driver_claim_interface);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index fd1ec481aec1..fcc244e9056f 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2702,6 +2702,12 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
2702 if (udev->usb2_hw_lpm_enabled == 1) 2702 if (udev->usb2_hw_lpm_enabled == 1)
2703 usb_set_usb2_hardware_lpm(udev, 0); 2703 usb_set_usb2_hardware_lpm(udev, 0);
2704 2704
2705 if (usb_unlocked_disable_lpm(udev)) {
2706 dev_err(&udev->dev, "%s Failed to disable LPM before suspend\n.",
2707 __func__);
2708 return -ENOMEM;
2709 }
2710
2705 /* see 7.1.7.6 */ 2711 /* see 7.1.7.6 */
2706 if (hub_is_superspeed(hub->hdev)) 2712 if (hub_is_superspeed(hub->hdev))
2707 status = set_port_feature(hub->hdev, 2713 status = set_port_feature(hub->hdev,
@@ -2725,6 +2731,9 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
2725 if (udev->usb2_hw_lpm_capable == 1) 2731 if (udev->usb2_hw_lpm_capable == 1)
2726 usb_set_usb2_hardware_lpm(udev, 1); 2732 usb_set_usb2_hardware_lpm(udev, 1);
2727 2733
2734 /* Try to enable USB3 LPM again */
2735 usb_unlocked_enable_lpm(udev);
2736
2728 /* System sleep transitions should never fail */ 2737 /* System sleep transitions should never fail */
2729 if (!PMSG_IS_AUTO(msg)) 2738 if (!PMSG_IS_AUTO(msg))
2730 status = 0; 2739 status = 0;
@@ -2922,6 +2931,9 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
2922 /* Try to enable USB2 hardware LPM */ 2931 /* Try to enable USB2 hardware LPM */
2923 if (udev->usb2_hw_lpm_capable == 1) 2932 if (udev->usb2_hw_lpm_capable == 1)
2924 usb_set_usb2_hardware_lpm(udev, 1); 2933 usb_set_usb2_hardware_lpm(udev, 1);
2934
2935 /* Try to enable USB3 LPM */
2936 usb_unlocked_enable_lpm(udev);
2925 } 2937 }
2926 2938
2927 return status; 2939 return status;
@@ -4681,11 +4693,22 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
4681 goto done; 4693 goto done;
4682 4694
4683 mutex_lock(hcd->bandwidth_mutex); 4695 mutex_lock(hcd->bandwidth_mutex);
4696 /* Disable LPM while we reset the device and reinstall the alt settings.
4697 * Device-initiated LPM settings, and system exit latency settings are
4698 * cleared when the device is reset, so we have to set them up again.
4699 */
4700 ret = usb_disable_lpm(udev);
4701 if (ret) {
4702 dev_err(&udev->dev, "%s Failed to disable LPM\n.", __func__);
4703 mutex_unlock(hcd->bandwidth_mutex);
4704 goto done;
4705 }
4684 ret = usb_hcd_alloc_bandwidth(udev, udev->actconfig, NULL, NULL); 4706 ret = usb_hcd_alloc_bandwidth(udev, udev->actconfig, NULL, NULL);
4685 if (ret < 0) { 4707 if (ret < 0) {
4686 dev_warn(&udev->dev, 4708 dev_warn(&udev->dev,
4687 "Busted HC? Not enough HCD resources for " 4709 "Busted HC? Not enough HCD resources for "
4688 "old configuration.\n"); 4710 "old configuration.\n");
4711 usb_enable_lpm(udev);
4689 mutex_unlock(hcd->bandwidth_mutex); 4712 mutex_unlock(hcd->bandwidth_mutex);
4690 goto re_enumerate; 4713 goto re_enumerate;
4691 } 4714 }
@@ -4697,6 +4720,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
4697 dev_err(&udev->dev, 4720 dev_err(&udev->dev,
4698 "can't restore configuration #%d (error=%d)\n", 4721 "can't restore configuration #%d (error=%d)\n",
4699 udev->actconfig->desc.bConfigurationValue, ret); 4722 udev->actconfig->desc.bConfigurationValue, ret);
4723 usb_enable_lpm(udev);
4700 mutex_unlock(hcd->bandwidth_mutex); 4724 mutex_unlock(hcd->bandwidth_mutex);
4701 goto re_enumerate; 4725 goto re_enumerate;
4702 } 4726 }
@@ -4735,10 +4759,13 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
4735 desc->bInterfaceNumber, 4759 desc->bInterfaceNumber,
4736 desc->bAlternateSetting, 4760 desc->bAlternateSetting,
4737 ret); 4761 ret);
4762 usb_unlocked_enable_lpm(udev);
4738 goto re_enumerate; 4763 goto re_enumerate;
4739 } 4764 }
4740 } 4765 }
4741 4766
4767 /* Now that the alt settings are re-installed, enable LPM. */
4768 usb_unlocked_enable_lpm(udev);
4742done: 4769done:
4743 return 0; 4770 return 0;
4744 4771
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index ca717da3be95..b548cf1dbc62 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1308,10 +1308,19 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
1308 * Remove the current alt setting and add the new alt setting. 1308 * Remove the current alt setting and add the new alt setting.
1309 */ 1309 */
1310 mutex_lock(hcd->bandwidth_mutex); 1310 mutex_lock(hcd->bandwidth_mutex);
1311 /* Disable LPM, and re-enable it once the new alt setting is installed,
1312 * so that the xHCI driver can recalculate the U1/U2 timeouts.
1313 */
1314 if (usb_disable_lpm(dev)) {
1315 dev_err(&iface->dev, "%s Failed to disable LPM\n.", __func__);
1316 mutex_unlock(hcd->bandwidth_mutex);
1317 return -ENOMEM;
1318 }
1311 ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt); 1319 ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt);
1312 if (ret < 0) { 1320 if (ret < 0) {
1313 dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n", 1321 dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n",
1314 alternate); 1322 alternate);
1323 usb_enable_lpm(dev);
1315 mutex_unlock(hcd->bandwidth_mutex); 1324 mutex_unlock(hcd->bandwidth_mutex);
1316 return ret; 1325 return ret;
1317 } 1326 }
@@ -1334,6 +1343,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
1334 } else if (ret < 0) { 1343 } else if (ret < 0) {
1335 /* Re-instate the old alt setting */ 1344 /* Re-instate the old alt setting */
1336 usb_hcd_alloc_bandwidth(dev, NULL, alt, iface->cur_altsetting); 1345 usb_hcd_alloc_bandwidth(dev, NULL, alt, iface->cur_altsetting);
1346 usb_enable_lpm(dev);
1337 mutex_unlock(hcd->bandwidth_mutex); 1347 mutex_unlock(hcd->bandwidth_mutex);
1338 return ret; 1348 return ret;
1339 } 1349 }
@@ -1354,6 +1364,9 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
1354 1364
1355 iface->cur_altsetting = alt; 1365 iface->cur_altsetting = alt;
1356 1366
1367 /* Now that the interface is installed, re-enable LPM. */
1368 usb_unlocked_enable_lpm(dev);
1369
1357 /* If the interface only has one altsetting and the device didn't 1370 /* If the interface only has one altsetting and the device didn't
1358 * accept the request, we attempt to carry out the equivalent action 1371 * accept the request, we attempt to carry out the equivalent action
1359 * by manually clearing the HALT feature for each endpoint in the 1372 * by manually clearing the HALT feature for each endpoint in the
@@ -1437,6 +1450,14 @@ int usb_reset_configuration(struct usb_device *dev)
1437 config = dev->actconfig; 1450 config = dev->actconfig;
1438 retval = 0; 1451 retval = 0;
1439 mutex_lock(hcd->bandwidth_mutex); 1452 mutex_lock(hcd->bandwidth_mutex);
1453 /* Disable LPM, and re-enable it once the configuration is reset, so
1454 * that the xHCI driver can recalculate the U1/U2 timeouts.
1455 */
1456 if (usb_disable_lpm(dev)) {
1457 dev_err(&dev->dev, "%s Failed to disable LPM\n.", __func__);
1458 mutex_unlock(hcd->bandwidth_mutex);
1459 return -ENOMEM;
1460 }
1440 /* Make sure we have enough bandwidth for each alternate setting 0 */ 1461 /* Make sure we have enough bandwidth for each alternate setting 0 */
1441 for (i = 0; i < config->desc.bNumInterfaces; i++) { 1462 for (i = 0; i < config->desc.bNumInterfaces; i++) {
1442 struct usb_interface *intf = config->interface[i]; 1463 struct usb_interface *intf = config->interface[i];
@@ -1465,6 +1486,7 @@ reset_old_alts:
1465 usb_hcd_alloc_bandwidth(dev, NULL, 1486 usb_hcd_alloc_bandwidth(dev, NULL,
1466 alt, intf->cur_altsetting); 1487 alt, intf->cur_altsetting);
1467 } 1488 }
1489 usb_enable_lpm(dev);
1468 mutex_unlock(hcd->bandwidth_mutex); 1490 mutex_unlock(hcd->bandwidth_mutex);
1469 return retval; 1491 return retval;
1470 } 1492 }
@@ -1502,6 +1524,8 @@ reset_old_alts:
1502 create_intf_ep_devs(intf); 1524 create_intf_ep_devs(intf);
1503 } 1525 }
1504 } 1526 }
1527 /* Now that the interfaces are installed, re-enable LPM. */
1528 usb_unlocked_enable_lpm(dev);
1505 return 0; 1529 return 0;
1506} 1530}
1507EXPORT_SYMBOL_GPL(usb_reset_configuration); 1531EXPORT_SYMBOL_GPL(usb_reset_configuration);
@@ -1763,8 +1787,18 @@ free_interfaces:
1763 * this call fails, the device state is unchanged. 1787 * this call fails, the device state is unchanged.
1764 */ 1788 */
1765 mutex_lock(hcd->bandwidth_mutex); 1789 mutex_lock(hcd->bandwidth_mutex);
1790 /* Disable LPM, and re-enable it once the new configuration is
1791 * installed, so that the xHCI driver can recalculate the U1/U2
1792 * timeouts.
1793 */
1794 if (usb_disable_lpm(dev)) {
1795 dev_err(&dev->dev, "%s Failed to disable LPM\n.", __func__);
1796 mutex_unlock(hcd->bandwidth_mutex);
1797 return -ENOMEM;
1798 }
1766 ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); 1799 ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
1767 if (ret < 0) { 1800 if (ret < 0) {
1801 usb_enable_lpm(dev);
1768 mutex_unlock(hcd->bandwidth_mutex); 1802 mutex_unlock(hcd->bandwidth_mutex);
1769 usb_autosuspend_device(dev); 1803 usb_autosuspend_device(dev);
1770 goto free_interfaces; 1804 goto free_interfaces;
@@ -1784,6 +1818,7 @@ free_interfaces:
1784 if (!cp) { 1818 if (!cp) {
1785 usb_set_device_state(dev, USB_STATE_ADDRESS); 1819 usb_set_device_state(dev, USB_STATE_ADDRESS);
1786 usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); 1820 usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
1821 usb_enable_lpm(dev);
1787 mutex_unlock(hcd->bandwidth_mutex); 1822 mutex_unlock(hcd->bandwidth_mutex);
1788 usb_autosuspend_device(dev); 1823 usb_autosuspend_device(dev);
1789 goto free_interfaces; 1824 goto free_interfaces;
@@ -1838,6 +1873,9 @@ free_interfaces:
1838 !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS)) 1873 !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
1839 cp->string = usb_cache_string(dev, cp->desc.iConfiguration); 1874 cp->string = usb_cache_string(dev, cp->desc.iConfiguration);
1840 1875
1876 /* Now that the interfaces are installed, re-enable LPM. */
1877 usb_unlocked_enable_lpm(dev);
1878
1841 /* Now that all the interfaces are set up, register them 1879 /* Now that all the interfaces are set up, register them
1842 * to trigger binding of drivers to interfaces. probe() 1880 * to trigger binding of drivers to interfaces. probe()
1843 * routines may install different altsettings and may 1881 * routines may install different altsettings and may