Commit 55bcdce8 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

USB: EHCI: remove ASS/PSS polling timeout

This patch (as1647) attempts to work around a problem that seems to
affect some nVidia EHCI controllers.  They sometimes take a very long
time to turn off their async or periodic schedules.  I don't know if
this is a result of other problems, but in any case it seems wise not
to depend on schedule enables or disables taking effect in any
specific length of time.

The patch removes the existing 20-ms timeout for enabling and
disabling the schedules.  The driver will now continue to poll the
schedule state at 1-ms intervals until the controller finally decides
to obey the most recent command issued by the driver.  Just in case
this hides a problem, a debugging message will be logged if the
controller takes longer than 20 polls.

I don't know if this will actually fix anything, but it can't hurt.
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Tested-by: default avatarPiergiorgio Sartor <piergiorgio.sartor@nexgo.de>
CC: <stable@vger.kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a28dde61
...@@ -113,14 +113,15 @@ static void ehci_poll_ASS(struct ehci_hcd *ehci) ...@@ -113,14 +113,15 @@ static void ehci_poll_ASS(struct ehci_hcd *ehci)
if (want != actual) { if (want != actual) {
/* Poll again later, but give up after about 20 ms */ /* Poll again later */
if (ehci->ASS_poll_count++ < 20) {
ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true); ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true);
++ehci->ASS_poll_count;
return; 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; ehci->ASS_poll_count = 0;
/* The status is up-to-date; restart or stop the schedule as needed */ /* The status is up-to-date; restart or stop the schedule as needed */
...@@ -159,14 +160,14 @@ static void ehci_poll_PSS(struct ehci_hcd *ehci) ...@@ -159,14 +160,14 @@ static void ehci_poll_PSS(struct ehci_hcd *ehci)
if (want != actual) { if (want != actual) {
/* Poll again later, but give up after about 20 ms */ /* Poll again later */
if (ehci->PSS_poll_count++ < 20) {
ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true); ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true);
return; 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; ehci->PSS_poll_count = 0;
/* The status is up-to-date; restart or stop the schedule as needed */ /* The status is up-to-date; restart or stop the schedule as needed */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment