diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2006-05-12 11:41:59 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-06-21 18:04:11 -0400 |
commit | b761d9d867bcc29e8de3e62d1d72b27e75078ca6 (patch) | |
tree | 40b8f2e530bd9bbece14007a3d887bbe12e8afde /drivers | |
parent | 84afddd7ac58adad00cb0e50d0af25fcf825668b (diff) |
[PATCH] UHCI: Work around old Intel bug
Some old Intel UHCI controllers have a bug that has shown up in a few
systems (the PIIX3 "Neptune" chip set). Until now there has not been
any simple way to work around the bug, but the lastest changes in
uhci-hcd have made it easy. This patch (as684) adds the work-around.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/host/uhci-q.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 2be84b3b40fe..76b0a9e95a7a 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -13,7 +13,7 @@ | |||
13 | * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface | 13 | * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface |
14 | * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com). | 14 | * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com). |
15 | * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c) | 15 | * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c) |
16 | * (C) Copyright 2004-2005 Alan Stern, stern@rowland.harvard.edu | 16 | * (C) Copyright 2004-2006 Alan Stern, stern@rowland.harvard.edu |
17 | */ | 17 | */ |
18 | 18 | ||
19 | 19 | ||
@@ -1287,6 +1287,11 @@ restart: | |||
1287 | * Check for queues that have made some forward progress. | 1287 | * Check for queues that have made some forward progress. |
1288 | * Returns 0 if the queue is not Isochronous, is ACTIVE, and | 1288 | * Returns 0 if the queue is not Isochronous, is ACTIVE, and |
1289 | * has not advanced since last examined; 1 otherwise. | 1289 | * has not advanced since last examined; 1 otherwise. |
1290 | * | ||
1291 | * Early Intel controllers have a bug which causes qh->element sometimes | ||
1292 | * not to advance when a TD completes successfully. The queue remains | ||
1293 | * stuck on the inactive completed TD. We detect such cases and advance | ||
1294 | * the element pointer by hand. | ||
1290 | */ | 1295 | */ |
1291 | static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh) | 1296 | static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh) |
1292 | { | 1297 | { |
@@ -1327,6 +1332,15 @@ static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
1327 | /* The queue hasn't advanced; check for timeout */ | 1332 | /* The queue hasn't advanced; check for timeout */ |
1328 | if (!qh->wait_expired && time_after(jiffies, | 1333 | if (!qh->wait_expired && time_after(jiffies, |
1329 | qh->advance_jiffies + QH_WAIT_TIMEOUT)) { | 1334 | qh->advance_jiffies + QH_WAIT_TIMEOUT)) { |
1335 | |||
1336 | /* Detect the Intel bug and work around it */ | ||
1337 | if (qh->post_td && qh_element(qh) == | ||
1338 | cpu_to_le32(qh->post_td->dma_handle)) { | ||
1339 | qh->element = qh->post_td->link; | ||
1340 | qh->advance_jiffies = jiffies; | ||
1341 | return 1; | ||
1342 | } | ||
1343 | |||
1330 | qh->wait_expired = 1; | 1344 | qh->wait_expired = 1; |
1331 | 1345 | ||
1332 | /* If the current URB wants FSBR, unlink it temporarily | 1346 | /* If the current URB wants FSBR, unlink it temporarily |