summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Eggers <ceggers@arri.de>2020-08-12 10:35:59 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2020-08-14 15:20:56 +0200
commit69776f1f0a955518e6f6d8275c967962789e7ea3 (patch)
treea0b3e263e87a74da9a0a8e8be7abaa02778b9ae0
parentf9f67c7827c90d9f54d392673e459679f7ce3bd6 (diff)
downloadbarebox-69776f1f0a955518e6f6d8275c967962789e7ea3.tar.gz
barebox-69776f1f0a955518e6f6d8275c967962789e7ea3.tar.xz
Revert "usb: host: ehci: Use to USBSTS to wait for transfer completion"
Since 6044d6c08e, some USB mass storage devices (in my case some USB memory sticks and one SD card reader) are not detected anymore. Waiting once for USBSTS::USBINT is not sufficient as it takes multiple USBINT events until QT_TOKEN_STATUS_ACTIVE is cleared. Fixes: 6044d6c08e ("usb: host: ehci: Use to USBSTS to wait for transfer completion") Signed-off-by: Christian Eggers <ceggers@arri.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--drivers/usb/host/ehci-hcd.c21
-rw-r--r--drivers/usb/host/ehci.h1
2 files changed, 14 insertions, 8 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index ead63b2c9f..38999927c5 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -308,12 +308,14 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
dma_addr_t buffer_dma, req_dma;
struct QH *qh = &ehci->qh_list[1];
struct qTD *td;
+ volatile struct qTD *vtd;
uint32_t *tdp;
uint32_t endpt, token, usbsts;
uint32_t status;
uint32_t toggle;
bool c;
int ret;
+ uint64_t start, timeout_val;
dev_dbg(ehci->dev, "pipe=%lx, buffer=%p, length=%d, req=%p\n", pipe,
@@ -442,13 +444,18 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
return ret;
}
- ret = handshake(&ehci->hcor->or_usbsts, STS_USBINT, STS_USBINT,
- timeout_ms * 1000);
- if (ret < 0) {
- ehci_enable_async_schedule(ehci, false);
- ehci_writel(&qh->qt_token, 0);
- return -ETIMEDOUT;
- }
+ /* Wait for TDs to be processed. */
+ timeout_val = timeout_ms * MSECOND;
+ start = get_time_ns();
+ vtd = td;
+ do {
+ token = hc32_to_cpu(vtd->qt_token);
+ if (is_timeout_non_interruptible(start, timeout_val)) {
+ ehci_enable_async_schedule(ehci, false);
+ ehci_writel(&qh->qt_token, 0);
+ return -ETIMEDOUT;
+ }
+ } while (token & QT_TOKEN_STATUS_ACTIVE);
if (req)
dma_unmap_single(ehci->dev, req_dma, sizeof(*req),
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index e88e37e14c..4b9092d1fe 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -53,7 +53,6 @@ struct ehci_hcor {
#define STD_ASS (1 << 15)
#define STS_PSS (1 << 14)
#define STS_HALT (1 << 12)
-#define STS_USBINT BIT(0)
uint32_t or_usbintr;
uint32_t or_frindex;
uint32_t or_ctrldssegment;