From: Greg Kroah-Hartman Date: Wed, 1 Aug 2012 15:48:44 +0000 (-0700) Subject: 3.5-stable patches X-Git-Tag: v3.0.39~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2d47a2983d64348d02cb01f659a0303b7f022ddb;p=thirdparty%2Fkernel%2Fstable-queue.git 3.5-stable patches added patches: usb-disable-lpm-while-the-device-is-unconfigured.patch usb-fix-lpm-disable-count-mismatch-on-driver-unbind.patch usb-fix-lpm-disable-enable-during-device-reset.patch usb-remove-unused-lpm-variable.patch --- diff --git a/queue-3.5/series b/queue-3.5/series index 4f7bd1034ee..ec1beae68f7 100644 --- a/queue-3.5/series +++ b/queue-3.5/series @@ -29,3 +29,7 @@ usbdevfs-correct-amount-of-data-copied-to-user-in-processcompl_compat.patch usb-gadget-fix-g_ether-interface-link-status.patch usb-option-add-zte-mf821d.patch revert-usb-uas-make-sure-data-urb-is-gone-if-we-receive-status-before-that.patch +usb-disable-lpm-while-the-device-is-unconfigured.patch +usb-fix-lpm-disable-enable-during-device-reset.patch +usb-remove-unused-lpm-variable.patch +usb-fix-lpm-disable-count-mismatch-on-driver-unbind.patch diff --git a/queue-3.5/usb-disable-lpm-while-the-device-is-unconfigured.patch b/queue-3.5/usb-disable-lpm-while-the-device-is-unconfigured.patch new file mode 100644 index 00000000000..31d2f5dbd54 --- /dev/null +++ b/queue-3.5/usb-disable-lpm-while-the-device-is-unconfigured.patch @@ -0,0 +1,76 @@ +From 9cf65991dd93ac3d5f97f536171c388918b7c1a9 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Tue, 3 Jul 2012 23:22:38 -0700 +Subject: USB: Disable LPM while the device is unconfigured. + +From: Sarah Sharp + +commit 9cf65991dd93ac3d5f97f536171c388918b7c1a9 upstream. + +The USB 3.0 Set/Clear Feature U1/U2 Enable cannot be sent to a device in +the Default or Addressed state. It can only be sent to a configured +device. Change the USB core to initialize the LPM disable count to 1 +(disabled), which reflects this limitation. + +Change usb_set_configuration() to ensure that if the device is +unconfigured on entry, usb_lpm_disable() is not called. This avoids +sending the Clear Feature U1/U2 when the device is in the Addressed +state. When usb_set_configuration() exits with a successfully installed +configuration, usb_lpm_enable() will be called. + +Once the new configuration is installed, make sure +usb_set_configuration() only calls usb_enable_lpm() if the device moved +to the Configured state. If we have unconfigured the device by sending +it a Set Configuration for config 0, don't enable LPM. + +This commit should be backported to kernels as old as 3.5, that contain +the commit 8306095fd2c1100e8244c09bf560f97aca5a311d "USB: Disable USB +3.0 LPM in critical sections." + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/message.c | 7 ++++--- + drivers/usb/core/usb.c | 1 + + 2 files changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -1791,14 +1791,15 @@ free_interfaces: + * installed, so that the xHCI driver can recalculate the U1/U2 + * timeouts. + */ +- if (usb_disable_lpm(dev)) { ++ if (dev->actconfig && usb_disable_lpm(dev)) { + dev_err(&dev->dev, "%s Failed to disable LPM\n.", __func__); + mutex_unlock(hcd->bandwidth_mutex); + return -ENOMEM; + } + ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); + if (ret < 0) { +- usb_enable_lpm(dev); ++ if (dev->actconfig) ++ usb_enable_lpm(dev); + mutex_unlock(hcd->bandwidth_mutex); + usb_autosuspend_device(dev); + goto free_interfaces; +@@ -1818,7 +1819,7 @@ free_interfaces: + if (!cp) { + usb_set_device_state(dev, USB_STATE_ADDRESS); + usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); +- usb_enable_lpm(dev); ++ /* Leave LPM disabled while the device is unconfigured. */ + mutex_unlock(hcd->bandwidth_mutex); + usb_autosuspend_device(dev); + goto free_interfaces; +--- a/drivers/usb/core/usb.c ++++ b/drivers/usb/core/usb.c +@@ -396,6 +396,7 @@ struct usb_device *usb_alloc_dev(struct + dev->dev.dma_mask = bus->controller->dma_mask; + set_dev_node(&dev->dev, dev_to_node(bus->controller)); + dev->state = USB_STATE_ATTACHED; ++ dev->lpm_disable_count = 1; + atomic_set(&dev->urbnum, 0); + + INIT_LIST_HEAD(&dev->ep0.urb_list); diff --git a/queue-3.5/usb-fix-lpm-disable-count-mismatch-on-driver-unbind.patch b/queue-3.5/usb-fix-lpm-disable-count-mismatch-on-driver-unbind.patch new file mode 100644 index 00000000000..94026d740e0 --- /dev/null +++ b/queue-3.5/usb-fix-lpm-disable-count-mismatch-on-driver-unbind.patch @@ -0,0 +1,39 @@ +From 249719121bc2b841bdfcab5eb21b10d8b871743b Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Thu, 5 Jul 2012 14:09:30 -0700 +Subject: USB: Fix LPM disable count mismatch on driver unbind. + +From: Sarah Sharp + +commit 249719121bc2b841bdfcab5eb21b10d8b871743b upstream. + +When a user runs `echo 0 > bConfigurationValue` for a USB 3.0 device, +usb_disable_device() is called. This function disables all drivers, +deallocates interfaces, and sets the device configuration value to 0 +(unconfigured). + +With the new scheme to ensure that unconfigured devices have LPM +disabled, usb_disable_device() must call usb_unlocked_disable_lpm() once +it unconfigures the device. + +This commit should be backported to kernels as old as 3.5, that contain +the commit 8306095fd2c1100e8244c09bf560f97aca5a311d "USB: Disable USB +3.0 LPM in critical sections." + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/message.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -1174,6 +1174,7 @@ void usb_disable_device(struct usb_devic + put_device(&dev->actconfig->interface[i]->dev); + dev->actconfig->interface[i] = NULL; + } ++ usb_unlocked_disable_lpm(dev); + dev->actconfig = NULL; + if (dev->state == USB_STATE_CONFIGURED) + usb_set_device_state(dev, USB_STATE_ADDRESS); diff --git a/queue-3.5/usb-fix-lpm-disable-enable-during-device-reset.patch b/queue-3.5/usb-fix-lpm-disable-enable-during-device-reset.patch new file mode 100644 index 00000000000..abd13f2e14e --- /dev/null +++ b/queue-3.5/usb-fix-lpm-disable-enable-during-device-reset.patch @@ -0,0 +1,119 @@ +From 6d1d051330ee096f575523647fbd8ffe703600b5 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Tue, 3 Jul 2012 22:49:04 -0700 +Subject: USB: Fix LPM disable/enable during device reset. + +From: Sarah Sharp + +commit 6d1d051330ee096f575523647fbd8ffe703600b5 upstream. + +The USB 3.0 specification says that sending a Set Feature or Clear +Feature for U1/U2 Enable is not a valid request when the device is in +the Default or Addressed state. It is only valid when the device is in +the Configured state. + +The original LPM patch attempted to disable LPM after the device had +been reset by hub_port_init(), before it had the configuration +reinstalled. The TI hub I tested with did not fail the Clear Feature +U1/U2 Enable request that khubd sent while it was in the addressed +state, which is why I didn't catch it. + +Move the LPM disable before the device reset, so that we can send the +Clear Feature U1/U2 Enable successfully, and balance the LPM disable +count. + +Also delete any calls to usb_enable_lpm() on error paths that lead to +re-enumeration. The calls will fail because the device isn't +configured, and it's not useful to balance the LPM disable count because +the usb_device is about to be destroyed before re-enumeration. + +Fix the early exit path ("done" label) to call usb_enable_lpm() to +balance the LPM disable count. + +Note that calling usb_reset_and_verify_device() with an unconfigured +device may fail on the first call to usb_disable_lpm(). That's because +the LPM disable count is initialized to 0 (LPM enabled), and +usb_disable_lpm() will attempt to send a Clear Feature U1/U2 request to +a device in the Addressed state. The next patch will fix that. + +This commit should be backported to kernels as old as 3.5, that contain +the commit 8306095fd2c1100e8244c09bf560f97aca5a311d "USB: Disable USB +3.0 LPM in critical sections." + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 26 ++++++++++++-------------- + 1 file changed, 12 insertions(+), 14 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -4672,6 +4672,16 @@ static int usb_reset_and_verify_device(s + } + parent_hub = hdev_to_hub(parent_hdev); + ++ /* Disable LPM while we reset the device and reinstall the alt settings. ++ * Device-initiated LPM settings, and system exit latency settings are ++ * cleared when the device is reset, so we have to set them up again. ++ */ ++ ret = usb_unlocked_disable_lpm(udev); ++ if (ret) { ++ dev_err(&udev->dev, "%s Failed to disable LPM\n.", __func__); ++ goto re_enumerate; ++ } ++ + set_bit(port1, parent_hub->busy_bits); + for (i = 0; i < SET_CONFIG_TRIES; ++i) { + +@@ -4699,22 +4709,11 @@ static int usb_reset_and_verify_device(s + goto done; + + mutex_lock(hcd->bandwidth_mutex); +- /* Disable LPM while we reset the device and reinstall the alt settings. +- * Device-initiated LPM settings, and system exit latency settings are +- * cleared when the device is reset, so we have to set them up again. +- */ +- ret = usb_disable_lpm(udev); +- if (ret) { +- dev_err(&udev->dev, "%s Failed to disable LPM\n.", __func__); +- mutex_unlock(hcd->bandwidth_mutex); +- goto done; +- } + ret = usb_hcd_alloc_bandwidth(udev, udev->actconfig, NULL, NULL); + if (ret < 0) { + dev_warn(&udev->dev, + "Busted HC? Not enough HCD resources for " + "old configuration.\n"); +- usb_enable_lpm(udev); + mutex_unlock(hcd->bandwidth_mutex); + goto re_enumerate; + } +@@ -4726,7 +4725,6 @@ static int usb_reset_and_verify_device(s + dev_err(&udev->dev, + "can't restore configuration #%d (error=%d)\n", + udev->actconfig->desc.bConfigurationValue, ret); +- usb_enable_lpm(udev); + mutex_unlock(hcd->bandwidth_mutex); + goto re_enumerate; + } +@@ -4765,17 +4763,17 @@ static int usb_reset_and_verify_device(s + desc->bInterfaceNumber, + desc->bAlternateSetting, + ret); +- usb_unlocked_enable_lpm(udev); + goto re_enumerate; + } + } + ++done: + /* Now that the alt settings are re-installed, enable LPM. */ + usb_unlocked_enable_lpm(udev); +-done: + return 0; + + re_enumerate: ++ /* LPM state doesn't matter when we're about to destroy the device. */ + hub_port_logical_disconnect(parent_hub, port1); + return -ENODEV; + } diff --git a/queue-3.5/usb-remove-unused-lpm-variable.patch b/queue-3.5/usb-remove-unused-lpm-variable.patch new file mode 100644 index 00000000000..9c87181541a --- /dev/null +++ b/queue-3.5/usb-remove-unused-lpm-variable.patch @@ -0,0 +1,32 @@ +From c5c4bdf02e518a281b229ae0891b346919e2d291 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Thu, 5 Jul 2012 09:41:22 -0700 +Subject: USB: Remove unused LPM variable. + +From: Sarah Sharp + +commit c5c4bdf02e518a281b229ae0891b346919e2d291 upstream. + +hub_initiated_lpm_disable_count is not used by any code, so remove it. + +This commit should be backported to kernels as old as 3.5, that contain +the commit 8306095fd2c1100e8244c09bf560f97aca5a311d "USB: Disable USB +3.0 LPM in critical sections." + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/usb.h | 1 - + 1 file changed, 1 deletion(-) + +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -556,7 +556,6 @@ struct usb_device { + struct usb3_lpm_parameters u1_params; + struct usb3_lpm_parameters u2_params; + unsigned lpm_disable_count; +- unsigned hub_initiated_lpm_disable_count; + }; + #define to_usb_device(d) container_of(d, struct usb_device, dev) +