]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.8-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 Mar 2013 20:43:28 +0000 (13:43 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 Mar 2013 20:43:28 +0000 (13:43 -0700)
added patches:
usb-ehci-work-around-silicon-bug-in-intel-s-ehci-controllers.patch

queue-3.8/series [new file with mode: 0644]
queue-3.8/usb-ehci-work-around-silicon-bug-in-intel-s-ehci-controllers.patch [new file with mode: 0644]

diff --git a/queue-3.8/series b/queue-3.8/series
new file mode 100644 (file)
index 0000000..533e195
--- /dev/null
@@ -0,0 +1 @@
+usb-ehci-work-around-silicon-bug-in-intel-s-ehci-controllers.patch
diff --git a/queue-3.8/usb-ehci-work-around-silicon-bug-in-intel-s-ehci-controllers.patch b/queue-3.8/usb-ehci-work-around-silicon-bug-in-intel-s-ehci-controllers.patch
new file mode 100644 (file)
index 0000000..d61bc39
--- /dev/null
@@ -0,0 +1,95 @@
+From 6402c796d3b4205d3d7296157956c5100a05d7d6 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 1 Mar 2013 10:50:08 -0500
+Subject: USB: EHCI: work around silicon bug in Intel's EHCI controllers
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 6402c796d3b4205d3d7296157956c5100a05d7d6 upstream.
+
+This patch (as1660) works around a hardware problem present in some
+(if not all) Intel EHCI controllers.  After a QH has been unlinked
+from the async schedule and the corresponding IAA interrupt has
+occurred, the controller is not supposed access the QH and its qTDs.
+There certainly shouldn't be any more DMA writes to those structures.
+Nevertheless, Intel's controllers have been observed to perform a
+final writeback to the QH's overlay region and to the most recent qTD.
+For more information and a test program to determine whether this
+problem is present in a particular controller, see
+
+       http://marc.info/?l=linux-usb&m=135492071812265&w=2
+       http://marc.info/?l=linux-usb&m=136182570800963&w=2
+
+This patch works around the problem by always waiting for two IAA
+cycles when unlinking an async QH.  The extra IAA delay gives the
+controller time to perform its final writeback.
+
+Surprisingly enough, the effects of this silicon bug have gone
+undetected until quite recently.  More through luck than anything
+else, it hasn't caused any apparent problems.  However, it does
+interact badly with the path that follows this one, so it needs to be
+addressed.
+
+This is the first part of a fix for the regression reported at:
+
+       https://bugs.launchpad.net/bugs/1088733
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Tested-by: Stephen Thirlwall <sdt@dr.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/ehci-hcd.c |    6 ++----
+ drivers/usb/host/ehci-q.c   |   18 ++++++++++++++----
+ 2 files changed, 16 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -748,11 +748,9 @@ static irqreturn_t ehci_irq (struct usb_
+               /* guard against (alleged) silicon errata */
+               if (cmd & CMD_IAAD)
+                       ehci_dbg(ehci, "IAA with IAAD still set?\n");
+-              if (ehci->async_iaa) {
++              if (ehci->async_iaa)
+                       COUNT(ehci->stats.iaa);
+-                      end_unlink_async(ehci);
+-              } else
+-                      ehci_dbg(ehci, "IAA with nothing unlinked?\n");
++              end_unlink_async(ehci);
+       }
+       /* remote wakeup [4.3.1] */
+--- a/drivers/usb/host/ehci-q.c
++++ b/drivers/usb/host/ehci-q.c
+@@ -1178,7 +1178,7 @@ static void single_unlink_async(struct e
+       struct ehci_qh          *prev;
+       /* Add to the end of the list of QHs waiting for the next IAAD */
+-      qh->qh_state = QH_STATE_UNLINK;
++      qh->qh_state = QH_STATE_UNLINK_WAIT;
+       if (ehci->async_unlink)
+               ehci->async_unlink_last->unlink_next = qh;
+       else
+@@ -1221,9 +1221,19 @@ static void start_iaa_cycle(struct ehci_
+               /* Do only the first waiting QH (nVidia bug?) */
+               qh = ehci->async_unlink;
+-              ehci->async_iaa = qh;
+-              ehci->async_unlink = qh->unlink_next;
+-              qh->unlink_next = NULL;
++
++              /*
++               * Intel (?) bug: The HC can write back the overlay region
++               * even after the IAA interrupt occurs.  In self-defense,
++               * always go through two IAA cycles for each QH.
++               */
++              if (qh->qh_state == QH_STATE_UNLINK_WAIT) {
++                      qh->qh_state = QH_STATE_UNLINK;
++              } else {
++                      ehci->async_iaa = qh;
++                      ehci->async_unlink = qh->unlink_next;
++                      qh->unlink_next = NULL;
++              }
+               /* Make sure the unlinks are all visible to the hardware */
+               wmb();