summaryrefslogtreecommitdiffstats
path: root/main/linux-grsec/usb-ehci-revert-remove-ass-pss-polling-timeout.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/linux-grsec/usb-ehci-revert-remove-ass-pss-polling-timeout.patch')
-rw-r--r--main/linux-grsec/usb-ehci-revert-remove-ass-pss-polling-timeout.patch84
1 files changed, 84 insertions, 0 deletions
diff --git a/main/linux-grsec/usb-ehci-revert-remove-ass-pss-polling-timeout.patch b/main/linux-grsec/usb-ehci-revert-remove-ass-pss-polling-timeout.patch
new file mode 100644
index 000000000..12adf16c4
--- /dev/null
+++ b/main/linux-grsec/usb-ehci-revert-remove-ass-pss-polling-timeout.patch
@@ -0,0 +1,84 @@
+From 221f8dfca89276d8aec54c6d07fbe20c281668f0 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 26 Feb 2013 13:43:41 -0500
+Subject: USB: EHCI: revert "remove ASS/PSS polling timeout"
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 221f8dfca89276d8aec54c6d07fbe20c281668f0 upstream.
+
+This patch (as1649) reverts commit
+55bcdce8a8228223ec4d17d8ded8134ed265d2c5 (USB: EHCI: remove ASS/PSS
+polling timeout). That commit was written under the assumption that
+some controllers may take a very long time to turn off their async and
+periodic schedules. It now appears that in fact the schedules do get
+turned off reasonably quickly, but some controllers occasionally leave
+the schedules' status bits turned on and consequently ehci-hcd can't
+tell that the schedules are off.
+
+VIA controllers in particular have this problem. ehci-hcd tells the
+hardware to turn off the async schedule, the schedule does get turned
+off, but the status bit remains on. Since the EHCI spec requires that
+the schedules not be re-enabled until the previous disable has taken
+effect, with an unlimited timeout the async schedule never gets turned
+back on. The resulting symptom is that the system is unable to
+communicate with USB devices.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-and-tested-by: Ronald <ronald645@gmail.com>
+Reported-and-tested-by: Paul Hartman <paul.hartman@gmail.com>
+Reported-and-tested-by: Dieter Nützel <dieter@nuetzel-hh.de>
+Reported-and-tested-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/ehci-timer.c | 29 ++++++++++++++---------------
+ 1 file changed, 14 insertions(+), 15 deletions(-)
+
+--- a/drivers/usb/host/ehci-timer.c
++++ b/drivers/usb/host/ehci-timer.c
+@@ -113,15 +113,14 @@ static void ehci_poll_ASS(struct ehci_hc
+
+ if (want != actual) {
+
+- /* Poll again later */
+- ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true);
+- ++ehci->ASS_poll_count;
+- return;
++ /* Poll again later, but give up after about 20 ms */
++ if (ehci->ASS_poll_count++ < 20) {
++ ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true);
++ return;
++ }
++ ehci_dbg(ehci, "Waited too long for the async schedule status (%x/%x), giving up\n",
++ want, actual);
+ }
+-
+- if (ehci->ASS_poll_count > 20)
+- ehci_dbg(ehci, "ASS poll count reached %d\n",
+- ehci->ASS_poll_count);
+ ehci->ASS_poll_count = 0;
+
+ /* The status is up-to-date; restart or stop the schedule as needed */
+@@ -160,14 +159,14 @@ static void ehci_poll_PSS(struct ehci_hc
+
+ if (want != actual) {
+
+- /* Poll again later */
+- ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true);
+- return;
++ /* Poll again later, but give up after about 20 ms */
++ if (ehci->PSS_poll_count++ < 20) {
++ ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true);
++ return;
++ }
++ ehci_dbg(ehci, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
++ want, actual);
+ }
+-
+- if (ehci->PSS_poll_count > 20)
+- ehci_dbg(ehci, "PSS poll count reached %d\n",
+- ehci->PSS_poll_count);
+ ehci->PSS_poll_count = 0;
+
+ /* The status is up-to-date; restart or stop the schedule as needed */