diff options
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.patch | 84 |
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 */ |