]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.5-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 1 Aug 2012 15:48:44 +0000 (08:48 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 1 Aug 2012 15:48:44 +0000 (08:48 -0700)
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

queue-3.5/series
queue-3.5/usb-disable-lpm-while-the-device-is-unconfigured.patch [new file with mode: 0644]
queue-3.5/usb-fix-lpm-disable-count-mismatch-on-driver-unbind.patch [new file with mode: 0644]
queue-3.5/usb-fix-lpm-disable-enable-during-device-reset.patch [new file with mode: 0644]
queue-3.5/usb-remove-unused-lpm-variable.patch [new file with mode: 0644]

index 4f7bd1034ee73bfed312138ff3b42114cf9ba0a9..ec1beae68f70a84ec5066edf570d877efae5f16d 100644 (file)
@@ -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 (file)
index 0000000..31d2f5d
--- /dev/null
@@ -0,0 +1,76 @@
+From 9cf65991dd93ac3d5f97f536171c388918b7c1a9 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Tue, 3 Jul 2012 23:22:38 -0700
+Subject: USB: Disable LPM while the device is unconfigured.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+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 <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..94026d7
--- /dev/null
@@ -0,0 +1,39 @@
+From 249719121bc2b841bdfcab5eb21b10d8b871743b Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Thu, 5 Jul 2012 14:09:30 -0700
+Subject: USB: Fix LPM disable count mismatch on driver unbind.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+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 <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..abd13f2
--- /dev/null
@@ -0,0 +1,119 @@
+From 6d1d051330ee096f575523647fbd8ffe703600b5 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Tue, 3 Jul 2012 22:49:04 -0700
+Subject: USB: Fix LPM disable/enable during device reset.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+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 <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..9c87181
--- /dev/null
@@ -0,0 +1,32 @@
+From c5c4bdf02e518a281b229ae0891b346919e2d291 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Thu, 5 Jul 2012 09:41:22 -0700
+Subject: USB: Remove unused LPM variable.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+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 <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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)