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
--- /dev/null
+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);
--- /dev/null
+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);
--- /dev/null
+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;
+ }
--- /dev/null
+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)
+