Skip to content

Commit

Permalink
USB: EHCI: remove ASS/PSS polling timeout
Browse files Browse the repository at this point in the history
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: Alan Stern <stern@rowland.harvard.edu>
Tested-by: Piergiorgio Sartor <piergiorgio.sartor@nexgo.de>
CC: <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Jan 25, 2013
1 parent a28dde6 commit 55bcdce
Showing 1 changed file with 15 additions and 14 deletions.
29 changes: 15 additions & 14 deletions drivers/usb/host/ehci-timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,15 @@ static void ehci_poll_ASS(struct ehci_hcd *ehci)

if (want != actual) {

/* 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);
/* Poll again later */
ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true);
++ehci->ASS_poll_count;
return;
}

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 */
Expand Down Expand Up @@ -159,14 +160,14 @@ static void ehci_poll_PSS(struct ehci_hcd *ehci)

if (want != actual) {

/* 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);
/* Poll again later */
ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true);
return;
}

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 */
Expand Down

0 comments on commit 55bcdce

Please sign in to comment.