]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 7 Jul 2016 00:45:39 +0000 (17:45 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 7 Jul 2016 00:45:39 +0000 (17:45 -0700)
added patches:
usb-dwc3-exynos-fix-deferred-probing-storm.patch
usb-gadget-fix-spinlock-dead-lock-in-gadgetfs.patch
usb-host-ehci-tegra-grab-the-correct-utmi-pads-reset.patch
usb-mos7720-delete-parport.patch
usb-musb-ensure-rx-reinit-occurs-for-shared_fifo-endpoints.patch
usb-musb-host-correct-cppi-dma-channel-for-isoch-transfer.patch
usb-musb-only-restore-devctl-when-session-was-set-in-backup.patch
usb-musb-stop-bulk-endpoint-while-queue-is-rotated.patch
usb-quirks-add-no-lpm-quirk-for-acer-c120-led-projector.patch
usb-quirks-fix-sorting.patch
usb-uas-fix-slave-queue_depth-not-being-set.patch
usb-xhci-add-broken-streams-quirk-for-frescologic-device-id-1009.patch
usb-xhci-plat-properly-handle-probe-deferral-for-devm_clk_get.patch
xhci-cleanup-only-when-releasing-primary-hcd.patch
xhci-fix-handling-timeouted-commands-on-hosts-in-weird-states.patch

16 files changed:
queue-4.6/series
queue-4.6/usb-dwc3-exynos-fix-deferred-probing-storm.patch [new file with mode: 0644]
queue-4.6/usb-gadget-fix-spinlock-dead-lock-in-gadgetfs.patch [new file with mode: 0644]
queue-4.6/usb-host-ehci-tegra-grab-the-correct-utmi-pads-reset.patch [new file with mode: 0644]
queue-4.6/usb-mos7720-delete-parport.patch [new file with mode: 0644]
queue-4.6/usb-musb-ensure-rx-reinit-occurs-for-shared_fifo-endpoints.patch [new file with mode: 0644]
queue-4.6/usb-musb-host-correct-cppi-dma-channel-for-isoch-transfer.patch [new file with mode: 0644]
queue-4.6/usb-musb-only-restore-devctl-when-session-was-set-in-backup.patch [new file with mode: 0644]
queue-4.6/usb-musb-stop-bulk-endpoint-while-queue-is-rotated.patch [new file with mode: 0644]
queue-4.6/usb-quirks-add-no-lpm-quirk-for-acer-c120-led-projector.patch [new file with mode: 0644]
queue-4.6/usb-quirks-fix-sorting.patch [new file with mode: 0644]
queue-4.6/usb-uas-fix-slave-queue_depth-not-being-set.patch [new file with mode: 0644]
queue-4.6/usb-xhci-add-broken-streams-quirk-for-frescologic-device-id-1009.patch [new file with mode: 0644]
queue-4.6/usb-xhci-plat-properly-handle-probe-deferral-for-devm_clk_get.patch [new file with mode: 0644]
queue-4.6/xhci-cleanup-only-when-releasing-primary-hcd.patch [new file with mode: 0644]
queue-4.6/xhci-fix-handling-timeouted-commands-on-hosts-in-weird-states.patch [new file with mode: 0644]

index 28680d0e72323e6acdc4711d6ca2897bfe127ea8..d506348c8e5e6db028ca0bda402bea201043fd57 100644 (file)
@@ -14,3 +14,18 @@ ax.25-close-socket-connection-on-session-completion.patch
 crypto-vmx-increase-priority-of-aes-cbc-cipher.patch
 crypto-ux500-memmove-the-right-size.patch
 crypto-user-re-add-size-check-for-crypto_msg_getalg.patch
+usb-uas-fix-slave-queue_depth-not-being-set.patch
+usb-quirks-fix-sorting.patch
+usb-quirks-add-no-lpm-quirk-for-acer-c120-led-projector.patch
+usb-musb-only-restore-devctl-when-session-was-set-in-backup.patch
+usb-musb-stop-bulk-endpoint-while-queue-is-rotated.patch
+usb-musb-ensure-rx-reinit-occurs-for-shared_fifo-endpoints.patch
+usb-musb-host-correct-cppi-dma-channel-for-isoch-transfer.patch
+xhci-cleanup-only-when-releasing-primary-hcd.patch
+usb-xhci-plat-properly-handle-probe-deferral-for-devm_clk_get.patch
+usb-xhci-add-broken-streams-quirk-for-frescologic-device-id-1009.patch
+xhci-fix-handling-timeouted-commands-on-hosts-in-weird-states.patch
+usb-mos7720-delete-parport.patch
+usb-gadget-fix-spinlock-dead-lock-in-gadgetfs.patch
+usb-host-ehci-tegra-grab-the-correct-utmi-pads-reset.patch
+usb-dwc3-exynos-fix-deferred-probing-storm.patch
diff --git a/queue-4.6/usb-dwc3-exynos-fix-deferred-probing-storm.patch b/queue-4.6/usb-dwc3-exynos-fix-deferred-probing-storm.patch
new file mode 100644 (file)
index 0000000..e27f960
--- /dev/null
@@ -0,0 +1,82 @@
+From 4879efb34f7d49235fac334d76d9c6a77a021413 Mon Sep 17 00:00:00 2001
+From: "Steinar H. Gunderson" <sesse@google.com>
+Date: Tue, 24 May 2016 20:13:15 +0200
+Subject: usb: dwc3: exynos: Fix deferred probing storm.
+
+From: Steinar H. Gunderson <sesse@google.com>
+
+commit 4879efb34f7d49235fac334d76d9c6a77a021413 upstream.
+
+dwc3-exynos has two problems during init if the regulators are slow
+to come up (for instance if the I2C bus driver is not on the initramfs)
+and return probe deferral. First, every time this happens, the driver
+leaks the USB phys created; they need to be deallocated on error.
+
+Second, since the phy devices are created before the regulators fail,
+this means that there's a new device to re-trigger deferred probing,
+which causes it to essentially go into a busy loop of re-probing the
+device until the regulators come up.
+
+Move the phy creation to after the regulators have succeeded, and also
+fix cleanup on failure. On my ODROID XU4 system (with Debian's initramfs
+which doesn't contain the I2C driver), this reduces the number of probe
+attempts (for each of the two controllers) from more than 2000 to eight.
+
+Signed-off-by: Steinar H. Gunderson <sesse@google.com>
+Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Reviewed-by: Vivek Gautam <gautam.vivek@samsung.com>
+Fixes: d720f057fda4 ("usb: dwc3: exynos: add nop transceiver support")
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/dwc3-exynos.c |   19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/dwc3/dwc3-exynos.c
++++ b/drivers/usb/dwc3/dwc3-exynos.c
+@@ -128,12 +128,6 @@ static int dwc3_exynos_probe(struct plat
+       platform_set_drvdata(pdev, exynos);
+-      ret = dwc3_exynos_register_phys(exynos);
+-      if (ret) {
+-              dev_err(dev, "couldn't register PHYs\n");
+-              return ret;
+-      }
+-
+       exynos->dev     = dev;
+       exynos->clk = devm_clk_get(dev, "usbdrd30");
+@@ -183,20 +177,29 @@ static int dwc3_exynos_probe(struct plat
+               goto err3;
+       }
++      ret = dwc3_exynos_register_phys(exynos);
++      if (ret) {
++              dev_err(dev, "couldn't register PHYs\n");
++              goto err4;
++      }
++
+       if (node) {
+               ret = of_platform_populate(node, NULL, NULL, dev);
+               if (ret) {
+                       dev_err(dev, "failed to add dwc3 core\n");
+-                      goto err4;
++                      goto err5;
+               }
+       } else {
+               dev_err(dev, "no device node, failed to add dwc3 core\n");
+               ret = -ENODEV;
+-              goto err4;
++              goto err5;
+       }
+       return 0;
++err5:
++      platform_device_unregister(exynos->usb2_phy);
++      platform_device_unregister(exynos->usb3_phy);
+ err4:
+       regulator_disable(exynos->vdd10);
+ err3:
diff --git a/queue-4.6/usb-gadget-fix-spinlock-dead-lock-in-gadgetfs.patch b/queue-4.6/usb-gadget-fix-spinlock-dead-lock-in-gadgetfs.patch
new file mode 100644 (file)
index 0000000..3d03d30
--- /dev/null
@@ -0,0 +1,108 @@
+From d246dcb2331c5783743720e6510892eb1d2801d9 Mon Sep 17 00:00:00 2001
+From: Bin Liu <b-liu@ti.com>
+Date: Thu, 26 May 2016 11:43:45 -0500
+Subject: usb: gadget: fix spinlock dead lock in gadgetfs
+
+From: Bin Liu <b-liu@ti.com>
+
+commit d246dcb2331c5783743720e6510892eb1d2801d9 upstream.
+
+[   40.467381] =============================================
+[   40.473013] [ INFO: possible recursive locking detected ]
+[   40.478651] 4.6.0-08691-g7f3db9a #37 Not tainted
+[   40.483466] ---------------------------------------------
+[   40.489098] usb/733 is trying to acquire lock:
+[   40.493734]  (&(&dev->lock)->rlock){-.....}, at: [<bf129288>] ep0_complete+0x18/0xdc [gadgetfs]
+[   40.502882]
+[   40.502882] but task is already holding lock:
+[   40.508967]  (&(&dev->lock)->rlock){-.....}, at: [<bf12a420>] ep0_read+0x20/0x5e0 [gadgetfs]
+[   40.517811]
+[   40.517811] other info that might help us debug this:
+[   40.524623]  Possible unsafe locking scenario:
+[   40.524623]
+[   40.530798]        CPU0
+[   40.533346]        ----
+[   40.535894]   lock(&(&dev->lock)->rlock);
+[   40.540088]   lock(&(&dev->lock)->rlock);
+[   40.544284]
+[   40.544284]  *** DEADLOCK ***
+[   40.544284]
+[   40.550461]  May be due to missing lock nesting notation
+[   40.550461]
+[   40.557544] 2 locks held by usb/733:
+[   40.561271]  #0:  (&f->f_pos_lock){+.+.+.}, at: [<c02a6114>] __fdget_pos+0x40/0x48
+[   40.569219]  #1:  (&(&dev->lock)->rlock){-.....}, at: [<bf12a420>] ep0_read+0x20/0x5e0 [gadgetfs]
+[   40.578523]
+[   40.578523] stack backtrace:
+[   40.583075] CPU: 0 PID: 733 Comm: usb Not tainted 4.6.0-08691-g7f3db9a #37
+[   40.590246] Hardware name: Generic AM33XX (Flattened Device Tree)
+[   40.596625] [<c010ffbc>] (unwind_backtrace) from [<c010c1bc>] (show_stack+0x10/0x14)
+[   40.604718] [<c010c1bc>] (show_stack) from [<c04207fc>] (dump_stack+0xb0/0xe4)
+[   40.612267] [<c04207fc>] (dump_stack) from [<c01886ec>] (__lock_acquire+0xf68/0x1994)
+[   40.620440] [<c01886ec>] (__lock_acquire) from [<c0189528>] (lock_acquire+0xd8/0x238)
+[   40.628621] [<c0189528>] (lock_acquire) from [<c06ad6b4>] (_raw_spin_lock_irqsave+0x38/0x4c)
+[   40.637440] [<c06ad6b4>] (_raw_spin_lock_irqsave) from [<bf129288>] (ep0_complete+0x18/0xdc [gadgetfs])
+[   40.647339] [<bf129288>] (ep0_complete [gadgetfs]) from [<bf10a728>] (musb_g_giveback+0x118/0x1b0 [musb_hdrc])
+[   40.657842] [<bf10a728>] (musb_g_giveback [musb_hdrc]) from [<bf108768>] (musb_g_ep0_queue+0x16c/0x188 [musb_hdrc])
+[   40.668772] [<bf108768>] (musb_g_ep0_queue [musb_hdrc]) from [<bf12a944>] (ep0_read+0x544/0x5e0 [gadgetfs])
+[   40.678963] [<bf12a944>] (ep0_read [gadgetfs]) from [<c0284470>] (__vfs_read+0x20/0x110)
+[   40.687414] [<c0284470>] (__vfs_read) from [<c0285324>] (vfs_read+0x88/0x114)
+[   40.694864] [<c0285324>] (vfs_read) from [<c0286150>] (SyS_read+0x44/0x9c)
+[   40.702051] [<c0286150>] (SyS_read) from [<c0107820>] (ret_fast_syscall+0x0/0x1c)
+
+This is caused by the spinlock bug in ep0_read().
+Fix the two other deadlock sources in gadgetfs_setup() too.
+
+Signed-off-by: Bin Liu <b-liu@ti.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/legacy/inode.c |   17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/gadget/legacy/inode.c
++++ b/drivers/usb/gadget/legacy/inode.c
+@@ -938,8 +938,11 @@ ep0_read (struct file *fd, char __user *
+                       struct usb_ep           *ep = dev->gadget->ep0;
+                       struct usb_request      *req = dev->req;
+-                      if ((retval = setup_req (ep, req, 0)) == 0)
+-                              retval = usb_ep_queue (ep, req, GFP_ATOMIC);
++                      if ((retval = setup_req (ep, req, 0)) == 0) {
++                              spin_unlock_irq (&dev->lock);
++                              retval = usb_ep_queue (ep, req, GFP_KERNEL);
++                              spin_lock_irq (&dev->lock);
++                      }
+                       dev->state = STATE_DEV_CONNECTED;
+                       /* assume that was SET_CONFIGURATION */
+@@ -1457,8 +1460,11 @@ delegate:
+                                                       w_length);
+                               if (value < 0)
+                                       break;
++
++                              spin_unlock (&dev->lock);
+                               value = usb_ep_queue (gadget->ep0, dev->req,
+-                                                      GFP_ATOMIC);
++                                                      GFP_KERNEL);
++                              spin_lock (&dev->lock);
+                               if (value < 0) {
+                                       clean_req (gadget->ep0, dev->req);
+                                       break;
+@@ -1481,11 +1487,14 @@ delegate:
+       if (value >= 0 && dev->state != STATE_DEV_SETUP) {
+               req->length = value;
+               req->zero = value < w_length;
+-              value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
++
++              spin_unlock (&dev->lock);
++              value = usb_ep_queue (gadget->ep0, req, GFP_KERNEL);
+               if (value < 0) {
+                       DBG (dev, "ep_queue --> %d\n", value);
+                       req->status = 0;
+               }
++              return value;
+       }
+       /* device stalls when value < 0 */
diff --git a/queue-4.6/usb-host-ehci-tegra-grab-the-correct-utmi-pads-reset.patch b/queue-4.6/usb-host-ehci-tegra-grab-the-correct-utmi-pads-reset.patch
new file mode 100644 (file)
index 0000000..181e3da
--- /dev/null
@@ -0,0 +1,48 @@
+From f8a15a9650694feaa0dabf197b0c94d37cd3fb42 Mon Sep 17 00:00:00 2001
+From: Thierry Reding <treding@nvidia.com>
+Date: Thu, 26 May 2016 17:23:29 +0200
+Subject: usb: host: ehci-tegra: Grab the correct UTMI pads reset
+
+From: Thierry Reding <treding@nvidia.com>
+
+commit f8a15a9650694feaa0dabf197b0c94d37cd3fb42 upstream.
+
+There are three EHCI controllers on Tegra SoCs, each with its own reset
+line. However, the first controller contains a set of UTMI configuration
+registers that are shared with its siblings. These registers will only
+be reset as part of the first controller's reset. For proper operation
+it must be ensured that the UTMI configuration registers are reset
+before any of the EHCI controllers are enabled, irrespective of the
+probe order.
+
+Commit a47cc24cd1e5 ("USB: EHCI: tegra: Fix probe order issue leading to
+broken USB") introduced code that ensures the first controller is always
+reset before setting up any of the controllers, and is never again reset
+afterwards.
+
+This code, however, grabs the wrong reset. Each EHCI controller has two
+reset controls attached: 1) the USB controller reset and 2) the UTMI
+pads reset (really the first controller's reset). In order to reset the
+UTMI pads registers the code must grab the second reset, but instead it
+grabbing the first.
+
+Fixes: a47cc24cd1e5 ("USB: EHCI: tegra: Fix probe order issue leading to broken USB")
+Acked-by: Jon Hunter <jonathanh@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/ehci-tegra.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/ehci-tegra.c
++++ b/drivers/usb/host/ehci-tegra.c
+@@ -89,7 +89,7 @@ static int tegra_reset_usb_controller(st
+       if (!usb1_reset_attempted) {
+               struct reset_control *usb1_reset;
+-              usb1_reset = of_reset_control_get(phy_np, "usb");
++              usb1_reset = of_reset_control_get(phy_np, "utmi-pads");
+               if (IS_ERR(usb1_reset)) {
+                       dev_warn(&pdev->dev,
+                                "can't get utmi-pads reset from the PHY\n");
diff --git a/queue-4.6/usb-mos7720-delete-parport.patch b/queue-4.6/usb-mos7720-delete-parport.patch
new file mode 100644 (file)
index 0000000..920dc6b
--- /dev/null
@@ -0,0 +1,45 @@
+From dcb21ad4385731b7fc3ef39d255685f2f63c8c5d Mon Sep 17 00:00:00 2001
+From: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Date: Mon, 30 May 2016 19:16:33 +0530
+Subject: USB: mos7720: delete parport
+
+From: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+
+commit dcb21ad4385731b7fc3ef39d255685f2f63c8c5d upstream.
+
+parport subsystem has introduced parport_del_port() to delete a port
+when it is going away. Without parport_del_port() the registered port
+will not be unregistered.
+To reproduce and verify the error:
+Command to be used is : ls /sys/bus/parport/devices
+1) without the device attached there is no output as there is no
+registered parport.
+2) Attach the device, and the command will show "parport0".
+3) Remove the device and the command still shows "parport0".
+4) Attach the device again and we get "parport1".
+
+With the patch applied:
+1) without the device attached there is no output as there is no
+registered parport.
+2) Attach the device, and the command will show "parport0".
+3) Remove the device and there is no output as "parport0" is now
+removed.
+4) Attach device again to get "parport0" again.
+
+Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/mos7720.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/serial/mos7720.c
++++ b/drivers/usb/serial/mos7720.c
+@@ -2007,6 +2007,7 @@ static void mos7720_release(struct usb_s
+                                   urblist_entry)
+                       usb_unlink_urb(urbtrack->urb);
+               spin_unlock_irqrestore(&mos_parport->listlock, flags);
++              parport_del_port(mos_parport->pp);
+               kref_put(&mos_parport->ref_count, destroy_mos_parport);
+       }
diff --git a/queue-4.6/usb-musb-ensure-rx-reinit-occurs-for-shared_fifo-endpoints.patch b/queue-4.6/usb-musb-ensure-rx-reinit-occurs-for-shared_fifo-endpoints.patch
new file mode 100644 (file)
index 0000000..9cf03d6
--- /dev/null
@@ -0,0 +1,46 @@
+From f3eec0cf784e0d6c47822ca6b66df3d5812af7e6 Mon Sep 17 00:00:00 2001
+From: Andrew Goodbody <andrew.goodbody@cambrionix.com>
+Date: Tue, 31 May 2016 10:05:26 -0500
+Subject: usb: musb: Ensure rx reinit occurs for shared_fifo endpoints
+
+From: Andrew Goodbody <andrew.goodbody@cambrionix.com>
+
+commit f3eec0cf784e0d6c47822ca6b66df3d5812af7e6 upstream.
+
+shared_fifo endpoints would only get a previous tx state cleared
+out, the rx state was only cleared for non shared_fifo endpoints
+Change this so that the rx state is cleared for all endpoints.
+This addresses an issue that resulted in rx packets being dropped
+silently.
+
+Signed-off-by: Andrew Goodbody <andrew.goodbody@cambrionix.com>
+Signed-off-by: Bin Liu <b-liu@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/musb/musb_host.c |   13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/musb/musb_host.c
++++ b/drivers/usb/musb/musb_host.c
+@@ -594,14 +594,13 @@ musb_rx_reinit(struct musb *musb, struct
+               musb_writew(ep->regs, MUSB_TXCSR, 0);
+       /* scrub all previous state, clearing toggle */
+-      } else {
+-              csr = musb_readw(ep->regs, MUSB_RXCSR);
+-              if (csr & MUSB_RXCSR_RXPKTRDY)
+-                      WARNING("rx%d, packet/%d ready?\n", ep->epnum,
+-                              musb_readw(ep->regs, MUSB_RXCOUNT));
+-
+-              musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG);
+       }
++      csr = musb_readw(ep->regs, MUSB_RXCSR);
++      if (csr & MUSB_RXCSR_RXPKTRDY)
++              WARNING("rx%d, packet/%d ready?\n", ep->epnum,
++                      musb_readw(ep->regs, MUSB_RXCOUNT));
++
++      musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG);
+       /* target addr and (for multipoint) hub addr/port */
+       if (musb->is_multipoint) {
diff --git a/queue-4.6/usb-musb-host-correct-cppi-dma-channel-for-isoch-transfer.patch b/queue-4.6/usb-musb-host-correct-cppi-dma-channel-for-isoch-transfer.patch
new file mode 100644 (file)
index 0000000..0008c15
--- /dev/null
@@ -0,0 +1,36 @@
+From 04471eb8c3158c0ad9df4b24da845a63b2e8f23a Mon Sep 17 00:00:00 2001
+From: Bin Liu <b-liu@ti.com>
+Date: Tue, 31 May 2016 10:05:25 -0500
+Subject: usb: musb: host: correct cppi dma channel for isoch transfer
+
+From: Bin Liu <b-liu@ti.com>
+
+commit 04471eb8c3158c0ad9df4b24da845a63b2e8f23a upstream.
+
+Incorrect cppi dma channel is referenced in musb_rx_dma_iso_cppi41(),
+which causes kernel NULL pointer reference oops later when calling
+cppi41_dma_channel_program().
+
+Fixes: 069a3fd (usb: musb: Remove ifdefs for musb_host_rx in musb_host.c
+part1)
+
+Reported-by: Matwey V. Kornilov <matwey@sai.msu.ru>
+Acked-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Bin Liu <b-liu@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/musb/musb_host.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/musb/musb_host.c
++++ b/drivers/usb/musb/musb_host.c
+@@ -1556,7 +1556,7 @@ static int musb_rx_dma_iso_cppi41(struct
+                                 struct urb *urb,
+                                 size_t len)
+ {
+-      struct dma_channel *channel = hw_ep->tx_channel;
++      struct dma_channel *channel = hw_ep->rx_channel;
+       void __iomem *epio = hw_ep->regs;
+       dma_addr_t *buf;
+       u32 length, res;
diff --git a/queue-4.6/usb-musb-only-restore-devctl-when-session-was-set-in-backup.patch b/queue-4.6/usb-musb-only-restore-devctl-when-session-was-set-in-backup.patch
new file mode 100644 (file)
index 0000000..7398156
--- /dev/null
@@ -0,0 +1,35 @@
+From 84ac5d1140f716a616522f952734e850448d2556 Mon Sep 17 00:00:00 2001
+From: Bin Liu <b-liu@ti.com>
+Date: Tue, 31 May 2016 10:05:24 -0500
+Subject: usb: musb: only restore devctl when session was set in backup
+
+From: Bin Liu <b-liu@ti.com>
+
+commit 84ac5d1140f716a616522f952734e850448d2556 upstream.
+
+If the session bit was not set in the backup of devctl register,
+restoring devctl would clear the session bit. Therefor, only restore
+devctl register when the session bit was set in the backup.
+
+This solves the device enumeration failure in otg mode exposed by commit
+56f487c (PM / Runtime: Update last_busy in rpm_resume).
+
+Signed-off-by: Bin Liu <b-liu@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/musb/musb_core.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -2429,7 +2429,8 @@ static void musb_restore_context(struct
+       musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe);
+       musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe);
+       musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe);
+-      musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl);
++      if (musb->context.devctl & MUSB_DEVCTL_SESSION)
++              musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl);
+       for (i = 0; i < musb->config->num_eps; ++i) {
+               struct musb_hw_ep       *hw_ep;
diff --git a/queue-4.6/usb-musb-stop-bulk-endpoint-while-queue-is-rotated.patch b/queue-4.6/usb-musb-stop-bulk-endpoint-while-queue-is-rotated.patch
new file mode 100644 (file)
index 0000000..59deeb1
--- /dev/null
@@ -0,0 +1,45 @@
+From 7b2c17f829545df27a910e8d82e133c21c9a8c9c Mon Sep 17 00:00:00 2001
+From: Andrew Goodbody <andrew.goodbody@cambrionix.com>
+Date: Tue, 31 May 2016 10:05:27 -0500
+Subject: usb: musb: Stop bulk endpoint while queue is rotated
+
+From: Andrew Goodbody <andrew.goodbody@cambrionix.com>
+
+commit 7b2c17f829545df27a910e8d82e133c21c9a8c9c upstream.
+
+Ensure that the endpoint is stopped by clearing REQPKT before
+clearing DATAERR_NAKTIMEOUT before rotating the queue on the
+dedicated bulk endpoint.
+This addresses an issue where a race could result in the endpoint
+receiving data before it was reprogrammed resulting in a warning
+about such data from musb_rx_reinit before it was thrown away.
+The data thrown away was a valid packet that had been correctly
+ACKed which meant the host and device got out of sync.
+
+Signed-off-by: Andrew Goodbody <andrew.goodbody@cambrionix.com>
+Signed-off-by: Bin Liu <b-liu@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/musb/musb_host.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/musb/musb_host.c
++++ b/drivers/usb/musb/musb_host.c
+@@ -995,9 +995,15 @@ static void musb_bulk_nak_timeout(struct
+       if (is_in) {
+               dma = is_dma_capable() ? ep->rx_channel : NULL;
+-              /* clear nak timeout bit */
++              /*
++               * Need to stop the transaction by clearing REQPKT first
++               * then the NAK Timeout bit ref MUSBMHDRC USB 2.0 HIGH-SPEED
++               * DUAL-ROLE CONTROLLER Programmer's Guide, section 9.2.2
++               */
+               rx_csr = musb_readw(epio, MUSB_RXCSR);
+               rx_csr |= MUSB_RXCSR_H_WZC_BITS;
++              rx_csr &= ~MUSB_RXCSR_H_REQPKT;
++              musb_writew(epio, MUSB_RXCSR, rx_csr);
+               rx_csr &= ~MUSB_RXCSR_DATAERROR;
+               musb_writew(epio, MUSB_RXCSR, rx_csr);
diff --git a/queue-4.6/usb-quirks-add-no-lpm-quirk-for-acer-c120-led-projector.patch b/queue-4.6/usb-quirks-add-no-lpm-quirk-for-acer-c120-led-projector.patch
new file mode 100644 (file)
index 0000000..aec11ed
--- /dev/null
@@ -0,0 +1,34 @@
+From 32cb0b37098f4beeff5ad9e325f11b42a6ede56c Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Thu, 19 May 2016 17:12:20 +0200
+Subject: usb: quirks: Add no-lpm quirk for Acer C120 LED Projector
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 32cb0b37098f4beeff5ad9e325f11b42a6ede56c upstream.
+
+The Acer C120 LED Projector is a USB-3 connected pico projector which
+takes both its power and video data from USB-3.
+
+In combination with some hubs this device does not play well with
+lpm, so disable lpm for it.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/quirks.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -199,6 +199,9 @@ static const struct usb_device_id usb_qu
+       { USB_DEVICE(0x1a0a, 0x0200), .driver_info =
+                       USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
++      /* Acer C120 LED Projector */
++      { USB_DEVICE(0x1de1, 0xc102), .driver_info = USB_QUIRK_NO_LPM },
++
+       /* Blackmagic Design Intensity Shuttle */
+       { USB_DEVICE(0x1edb, 0xbd3b), .driver_info = USB_QUIRK_NO_LPM },
diff --git a/queue-4.6/usb-quirks-fix-sorting.patch b/queue-4.6/usb-quirks-fix-sorting.patch
new file mode 100644 (file)
index 0000000..eb15448
--- /dev/null
@@ -0,0 +1,68 @@
+From 81099f97bd31e25ff2719a435b1860fc3876122f Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Thu, 19 May 2016 17:12:19 +0200
+Subject: usb: quirks: Fix sorting
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 81099f97bd31e25ff2719a435b1860fc3876122f upstream.
+
+Properly sort all the entries by vendor id.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/quirks.c |   20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -44,6 +44,9 @@ static const struct usb_device_id usb_qu
+       /* Creative SB Audigy 2 NX */
+       { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
++      /* USB3503 */
++      { USB_DEVICE(0x0424, 0x3503), .driver_info = USB_QUIRK_RESET_RESUME },
++
+       /* Microsoft Wireless Laser Mouse 6000 Receiver */
+       { USB_DEVICE(0x045e, 0x00e1), .driver_info = USB_QUIRK_RESET_RESUME },
+@@ -173,6 +176,10 @@ static const struct usb_device_id usb_qu
+       /* MAYA44USB sound device */
+       { USB_DEVICE(0x0a92, 0x0091), .driver_info = USB_QUIRK_RESET_RESUME },
++      /* ASUS Base Station(T100) */
++      { USB_DEVICE(0x0b05, 0x17e0), .driver_info =
++                      USB_QUIRK_IGNORE_REMOTE_WAKEUP },
++
+       /* Action Semiconductor flash disk */
+       { USB_DEVICE(0x10d6, 0x2200), .driver_info =
+                       USB_QUIRK_STRING_FETCH_255 },
+@@ -188,16 +195,6 @@ static const struct usb_device_id usb_qu
+       { USB_DEVICE(0x1908, 0x1315), .driver_info =
+                       USB_QUIRK_HONOR_BNUMINTERFACES },
+-      /* INTEL VALUE SSD */
+-      { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
+-
+-      /* USB3503 */
+-      { USB_DEVICE(0x0424, 0x3503), .driver_info = USB_QUIRK_RESET_RESUME },
+-
+-      /* ASUS Base Station(T100) */
+-      { USB_DEVICE(0x0b05, 0x17e0), .driver_info =
+-                      USB_QUIRK_IGNORE_REMOTE_WAKEUP },
+-
+       /* Protocol and OTG Electrical Test Device */
+       { USB_DEVICE(0x1a0a, 0x0200), .driver_info =
+                       USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
+@@ -208,6 +205,9 @@ static const struct usb_device_id usb_qu
+       /* Blackmagic Design UltraStudio SDI */
+       { USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM },
++      /* INTEL VALUE SSD */
++      { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
++
+       { }  /* terminating entry must be last */
+ };
diff --git a/queue-4.6/usb-uas-fix-slave-queue_depth-not-being-set.patch b/queue-4.6/usb-uas-fix-slave-queue_depth-not-being-set.patch
new file mode 100644 (file)
index 0000000..eb69366
--- /dev/null
@@ -0,0 +1,38 @@
+From 593224ea77b1ca842f45cf76f4deeef44dfbacd1 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Tue, 31 May 2016 09:18:03 +0200
+Subject: USB: uas: Fix slave queue_depth not being set
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 593224ea77b1ca842f45cf76f4deeef44dfbacd1 upstream.
+
+Commit 198de51dbc34 ("USB: uas: Limit qdepth at the scsi-host level")
+removed the scsi_change_queue_depth() call from uas_slave_configure()
+assuming that the slave would inherit the host's queue_depth, which
+that commit sets to the same value.
+
+This is incorrect, without the scsi_change_queue_depth() call the slave's
+queue_depth defaults to 1, introducing a performance regression.
+
+This commit restores the call, fixing the performance regression.
+
+Fixes: 198de51dbc34 ("USB: uas: Limit qdepth at the scsi-host level")
+Reported-by: Tom Yan <tom.ty89@gmail.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/storage/uas.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/storage/uas.c
++++ b/drivers/usb/storage/uas.c
+@@ -835,6 +835,7 @@ static int uas_slave_configure(struct sc
+       if (devinfo->flags & US_FL_BROKEN_FUA)
+               sdev->broken_fua = 1;
++      scsi_change_queue_depth(sdev, devinfo->qdepth - 2);
+       return 0;
+ }
diff --git a/queue-4.6/usb-xhci-add-broken-streams-quirk-for-frescologic-device-id-1009.patch b/queue-4.6/usb-xhci-add-broken-streams-quirk-for-frescologic-device-id-1009.patch
new file mode 100644 (file)
index 0000000..c44d988
--- /dev/null
@@ -0,0 +1,44 @@
+From d95815ba6a0f287213118c136e64d8c56daeaeab Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Wed, 1 Jun 2016 21:01:29 +0200
+Subject: USB: xhci: Add broken streams quirk for Frescologic device id 1009
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit d95815ba6a0f287213118c136e64d8c56daeaeab upstream.
+
+I got one of these cards for testing uas with, it seems that with streams
+it dma-s all over the place, corrupting memory. On my first tests it
+managed to dma over the BIOS of the motherboard somehow and completely
+bricked it.
+
+Tests on another motherboard show that it does work with streams disabled.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-pci.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -37,6 +37,7 @@
+ /* Device for a quirk */
+ #define PCI_VENDOR_ID_FRESCO_LOGIC    0x1b73
+ #define PCI_DEVICE_ID_FRESCO_LOGIC_PDK        0x1000
++#define PCI_DEVICE_ID_FRESCO_LOGIC_FL1009     0x1009
+ #define PCI_DEVICE_ID_FRESCO_LOGIC_FL1400     0x1400
+ #define PCI_VENDOR_ID_ETRON           0x1b6f
+@@ -114,6 +115,10 @@ static void xhci_pci_quirks(struct devic
+               xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+       }
++      if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
++                      pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1009)
++              xhci->quirks |= XHCI_BROKEN_STREAMS;
++
+       if (pdev->vendor == PCI_VENDOR_ID_NEC)
+               xhci->quirks |= XHCI_NEC_HOST;
diff --git a/queue-4.6/usb-xhci-plat-properly-handle-probe-deferral-for-devm_clk_get.patch b/queue-4.6/usb-xhci-plat-properly-handle-probe-deferral-for-devm_clk_get.patch
new file mode 100644 (file)
index 0000000..2300ee4
--- /dev/null
@@ -0,0 +1,49 @@
+From de95c40d5beaa47f6dc8fe9ac4159b4672b51523 Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Date: Wed, 1 Jun 2016 18:09:09 +0300
+Subject: usb: xhci-plat: properly handle probe deferral for devm_clk_get()
+
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+
+commit de95c40d5beaa47f6dc8fe9ac4159b4672b51523 upstream.
+
+On some platforms, the clocks might be registered by a platform
+driver. When this is the case, the clock platform driver may very well
+be probed after xhci-plat, in which case the first probe() invocation
+of xhci-plat will receive -EPROBE_DEFER as the return value of
+devm_clk_get().
+
+The current code handles that as a normal error, and simply assumes
+that this means that the system doesn't have a clock for the XHCI
+controller, and continues probing without calling
+clk_prepare_enable(). Unfortunately, this doesn't work on systems
+where the XHCI controller does have a clock, but that clock is
+provided by another platform driver. In order to fix this situation,
+we handle the -EPROBE_DEFER error condition specially, and abort the
+XHCI controller probe(). It will be retried later automatically, the
+clock will be available, devm_clk_get() will succeed, and the probe()
+will continue with the clock prepared and enabled as expected.
+
+In practice, such issue is seen on the ARM64 Marvell 7K/8K platform,
+where the clocks are registered by a platform driver.
+
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-plat.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/host/xhci-plat.c
++++ b/drivers/usb/host/xhci-plat.c
+@@ -194,6 +194,9 @@ static int xhci_plat_probe(struct platfo
+               ret = clk_prepare_enable(clk);
+               if (ret)
+                       goto put_hcd;
++      } else if (PTR_ERR(clk) == -EPROBE_DEFER) {
++              ret = -EPROBE_DEFER;
++              goto put_hcd;
+       }
+       xhci = hcd_to_xhci(hcd);
diff --git a/queue-4.6/xhci-cleanup-only-when-releasing-primary-hcd.patch b/queue-4.6/xhci-cleanup-only-when-releasing-primary-hcd.patch
new file mode 100644 (file)
index 0000000..b54351f
--- /dev/null
@@ -0,0 +1,130 @@
+From 27a41a83ec54d0edfcaf079310244e7f013a7701 Mon Sep 17 00:00:00 2001
+From: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com>
+Date: Wed, 1 Jun 2016 18:09:07 +0300
+Subject: xhci: Cleanup only when releasing primary hcd
+
+From: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com>
+
+commit 27a41a83ec54d0edfcaf079310244e7f013a7701 upstream.
+
+Under stress occasions some TI devices might not return early when
+reading the status register during the quirk invocation of xhci_irq made
+by usb_hcd_pci_remove.  This means that instead of returning, we end up
+handling this interruption in the middle of a shutdown.  Since
+xhci->event_ring has already been freed in xhci_mem_cleanup, we end up
+accessing freed memory, causing the Oops below.
+
+commit 8c24d6d7b09d ("usb: xhci: stop everything on the first call to
+xhci_stop") is the one that changed the instant in which we clean up the
+event queue when stopping a device.  Before, we didn't call
+xhci_mem_cleanup at the first time xhci_stop is executed (for the shared
+HCD), instead, we only did it after the invocation for the primary HCD,
+much later at the removal path.  The code flow for this oops looks like
+this:
+
+xhci_pci_remove()
+       usb_remove_hcd(xhci->shared)
+               xhci_stop(xhci->shared)
+                       xhci_halt()
+                       xhci_mem_cleanup(xhci);  // Free the event_queue
+       usb_hcd_pci_remove(primary)
+               xhci_irq()  // Access the event_queue if STS_EINT is set. Crash.
+               xhci_stop()
+                       xhci_halt()
+                       // return early
+
+The fix modifies xhci_stop to only cleanup the xhci data when releasing
+the primary HCD.  This way, we still have the event_queue configured
+when invoking xhci_irq.  We still halt the device on the first call to
+xhci_stop, though.
+
+I could reproduce this issue several times on the mainline kernel by
+doing a bind-unbind stress test with a specific storage gadget attached.
+I also ran the same test over-night with my patch applied and didn't
+observe the issue anymore.
+
+[  113.334124] Unable to handle kernel paging request for data at address 0x00000028
+[  113.335514] Faulting instruction address: 0xd00000000d4f767c
+[  113.336839] Oops: Kernel access of bad area, sig: 11 [#1]
+[  113.338214] SMP NR_CPUS=1024 NUMA PowerNV
+
+[c000000efe47ba90] c000000000720850 usb_hcd_irq+0x50/0x80
+[c000000efe47bac0] c00000000073d328 usb_hcd_pci_remove+0x68/0x1f0
+[c000000efe47bb00] d00000000daf0128 xhci_pci_remove+0x78/0xb0
+[xhci_pci]
+[c000000efe47bb30] c00000000055cf70 pci_device_remove+0x70/0x110
+[c000000efe47bb70] c00000000061c6bc __device_release_driver+0xbc/0x190
+[c000000efe47bba0] c00000000061c7d0 device_release_driver+0x40/0x70
+[c000000efe47bbd0] c000000000619510 unbind_store+0x120/0x150
+[c000000efe47bc20] c0000000006183c4 drv_attr_store+0x64/0xa0
+[c000000efe47bc60] c00000000039f1d0 sysfs_kf_write+0x80/0xb0
+[c000000efe47bca0] c00000000039e14c kernfs_fop_write+0x18c/0x1f0
+[c000000efe47bcf0] c0000000002e962c __vfs_write+0x6c/0x190
+[c000000efe47bd90] c0000000002eab40 vfs_write+0xc0/0x200
+[c000000efe47bde0] c0000000002ec85c SyS_write+0x6c/0x110
+[c000000efe47be30] c000000000009260 system_call+0x38/0x108
+
+Signed-off-by: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com>
+Cc: Roger Quadros <rogerq@ti.com>
+Cc: joel@jms.id.au
+Reviewed-by: Roger Quadros <rogerq@ti.com>
+Tested-by: Joel Stanley <joel@jms.id.au>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |    3 ++-
+ drivers/usb/host/xhci.c      |   29 ++++++++++++++++-------------
+ 2 files changed, 18 insertions(+), 14 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -2728,7 +2728,8 @@ hw_died:
+               writel(irq_pending, &xhci->ir_set->irq_pending);
+       }
+-      if (xhci->xhc_state & XHCI_STATE_DYING) {
++      if (xhci->xhc_state & XHCI_STATE_DYING ||
++          xhci->xhc_state & XHCI_STATE_HALTED) {
+               xhci_dbg(xhci, "xHCI dying, ignoring interrupt. "
+                               "Shouldn't IRQs be disabled?\n");
+               /* Clear the event handler busy flag (RW1C);
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -685,20 +685,23 @@ void xhci_stop(struct usb_hcd *hcd)
+       u32 temp;
+       struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+-      if (xhci->xhc_state & XHCI_STATE_HALTED)
+-              return;
+-
+       mutex_lock(&xhci->mutex);
+-      spin_lock_irq(&xhci->lock);
+-      xhci->xhc_state |= XHCI_STATE_HALTED;
+-      xhci->cmd_ring_state = CMD_RING_STATE_STOPPED;
+-
+-      /* Make sure the xHC is halted for a USB3 roothub
+-       * (xhci_stop() could be called as part of failed init).
+-       */
+-      xhci_halt(xhci);
+-      xhci_reset(xhci);
+-      spin_unlock_irq(&xhci->lock);
++
++      if (!(xhci->xhc_state & XHCI_STATE_HALTED)) {
++              spin_lock_irq(&xhci->lock);
++
++              xhci->xhc_state |= XHCI_STATE_HALTED;
++              xhci->cmd_ring_state = CMD_RING_STATE_STOPPED;
++              xhci_halt(xhci);
++              xhci_reset(xhci);
++
++              spin_unlock_irq(&xhci->lock);
++      }
++
++      if (!usb_hcd_is_primary_hcd(hcd)) {
++              mutex_unlock(&xhci->mutex);
++              return;
++      }
+       xhci_cleanup_msix(xhci);
diff --git a/queue-4.6/xhci-fix-handling-timeouted-commands-on-hosts-in-weird-states.patch b/queue-4.6/xhci-fix-handling-timeouted-commands-on-hosts-in-weird-states.patch
new file mode 100644 (file)
index 0000000..96eedfa
--- /dev/null
@@ -0,0 +1,110 @@
+From 3425aa03f484d45dc21e0e791c2f6c74ea656421 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Wed, 1 Jun 2016 18:09:08 +0300
+Subject: xhci: Fix handling timeouted commands on hosts in weird states.
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 3425aa03f484d45dc21e0e791c2f6c74ea656421 upstream.
+
+If commands timeout we mark them for abortion, then stop the command
+ring, and turn the commands to no-ops and finally restart the command
+ring.
+
+If the host is working properly the no-op commands will finish and
+pending completions are called.
+If we notice the host is failing, driver clears the command ring and
+completes, deletes and frees all pending commands.
+
+There are two separate cases reported where host is believed to work
+properly but is not. In the first case we successfully stop the ring
+but no abort or stop command ring event is ever sent and host locks up.
+
+The second case is if a host is removed, command times out and driver
+believes the ring is stopped, and assumes it will be restarted, but
+actually ends up timing out on the same command forever.
+If one of the pending commands has the xhci->mutex held it will block
+xhci_stop() in the remove codepath which otherwise would cleanup pending
+commands.
+
+Add a check that clears all pending commands in case host is removed,
+or we are stuck timing out on the same command. Also restart the
+command timeout timer when stopping the command ring to ensure we
+recive an ring stop/abort event.
+
+Tested-by: Joe Lawrence <joe.lawrence@stratus.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |   27 ++++++++++++++++++++++-----
+ 1 file changed, 22 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -290,6 +290,14 @@ static int xhci_abort_cmd_ring(struct xh
+       temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
+       xhci->cmd_ring_state = CMD_RING_STATE_ABORTED;
++
++      /*
++       * Writing the CMD_RING_ABORT bit should cause a cmd completion event,
++       * however on some host hw the CMD_RING_RUNNING bit is correctly cleared
++       * but the completion event in never sent. Use the cmd timeout timer to
++       * handle those cases. Use twice the time to cover the bit polling retry
++       */
++      mod_timer(&xhci->cmd_timer, jiffies + (2 * XHCI_CMD_DEFAULT_TIMEOUT));
+       xhci_write_64(xhci, temp_64 | CMD_RING_ABORT,
+                       &xhci->op_regs->cmd_ring);
+@@ -314,6 +322,7 @@ static int xhci_abort_cmd_ring(struct xh
+               xhci_err(xhci, "Stopped the command ring failed, "
+                               "maybe the host is dead\n");
++              del_timer(&xhci->cmd_timer);
+               xhci->xhc_state |= XHCI_STATE_DYING;
+               xhci_quiesce(xhci);
+               xhci_halt(xhci);
+@@ -1253,22 +1262,21 @@ void xhci_handle_command_timeout(unsigne
+       int ret;
+       unsigned long flags;
+       u64 hw_ring_state;
+-      struct xhci_command *cur_cmd = NULL;
++      bool second_timeout = false;
+       xhci = (struct xhci_hcd *) data;
+       /* mark this command to be cancelled */
+       spin_lock_irqsave(&xhci->lock, flags);
+       if (xhci->current_cmd) {
+-              cur_cmd = xhci->current_cmd;
+-              cur_cmd->status = COMP_CMD_ABORT;
++              if (xhci->current_cmd->status == COMP_CMD_ABORT)
++                      second_timeout = true;
++              xhci->current_cmd->status = COMP_CMD_ABORT;
+       }
+-
+       /* Make sure command ring is running before aborting it */
+       hw_ring_state = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
+       if ((xhci->cmd_ring_state & CMD_RING_STATE_RUNNING) &&
+           (hw_ring_state & CMD_RING_RUNNING))  {
+-
+               spin_unlock_irqrestore(&xhci->lock, flags);
+               xhci_dbg(xhci, "Command timeout\n");
+               ret = xhci_abort_cmd_ring(xhci);
+@@ -1280,6 +1288,15 @@ void xhci_handle_command_timeout(unsigne
+               }
+               return;
+       }
++
++      /* command ring failed to restart, or host removed. Bail out */
++      if (second_timeout || xhci->xhc_state & XHCI_STATE_REMOVING) {
++              spin_unlock_irqrestore(&xhci->lock, flags);
++              xhci_dbg(xhci, "command timed out twice, ring start fail?\n");
++              xhci_cleanup_command_queue(xhci);
++              return;
++      }
++
+       /* command timeout on stopped ring, ring can't be aborted */
+       xhci_dbg(xhci, "Command timeout on stopped ring\n");
+       xhci_handle_stopped_cmd_ring(xhci, xhci->current_cmd);