diff options
author | Christian Eggers <ceggers@arri.de> | 2020-08-12 10:35:59 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2020-08-14 15:20:56 +0200 |
commit | 69776f1f0a955518e6f6d8275c967962789e7ea3 (patch) | |
tree | a0b3e263e87a74da9a0a8e8be7abaa02778b9ae0 | |
parent | f9f67c7827c90d9f54d392673e459679f7ce3bd6 (diff) | |
download | barebox-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.c | 21 | ||||
-rw-r--r-- | drivers/usb/host/ehci.h | 1 |
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; |