summaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2009-05-20 11:11:52 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2009-09-08 10:36:18 +0200
commit77a3b6a96a58800646861c91516b11e12fa55455 (patch)
tree1579e2412eacda9cd13f62b558c8556da0763d5a /drivers/usb
parent2bb0a3c4dcd9f0b571d875f11ae342f8acb9c95e (diff)
downloadbarebox-77a3b6a96a58800646861c91516b11e12fa55455.tar.gz
barebox-77a3b6a96a58800646861c91516b11e12fa55455.tar.xz
ehci: Restore state after td timeout
Clear overlay token after TD timeout so that the next transfer works. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/usb_ehci_core.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/usb/usb_ehci_core.c b/drivers/usb/usb_ehci_core.c
index 590004c623..b4ee3b9394 100644
--- a/drivers/usb/usb_ehci_core.c
+++ b/drivers/usb/usb_ehci_core.c
@@ -30,6 +30,7 @@
#include <init.h>
#include <xfuncs.h>
#include <clock.h>
+#include <errno.h>
#include "usb_ehci.h"
@@ -467,9 +468,15 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
/* Invalidate dcache */
ehci_invalidate_dcache(ehci->qh_list);
token = hc32_to_cpu(vtd->qt_token);
- if (is_timeout(start, SECOND)) {
- printf("TD timeout\n");
- break;
+ if (is_timeout(start, SECOND >> 2)) {
+ /* Disable async schedule. */
+ cmd = ehci_readl(&ehci->hcor->or_usbcmd);
+ cmd &= ~CMD_ASE;
+ ehci_writel(&ehci->hcor->or_usbcmd, cmd);
+
+ ret = handshake(&ehci->hcor->or_usbsts, STD_ASS, 0, 100 * 1000);
+ ehci_writel(&qh->qh_overlay.qt_token, 0);
+ return -ETIMEDOUT;
}
} while (token & 0x80);