diff options
author | Julius Werner <jwerner@chromium.org> | 2014-01-24 16:09:10 +0100 |
---|---|---|
committer | Stefan Agner <stefan.agner@toradex.com> | 2014-01-24 16:09:18 +0100 |
commit | 445d016fb9b25c4acb71253428190970544171df (patch) | |
tree | a5585d765b2fcd33f46a9103ae6000623018f48f | |
parent | 2715f5b1512225a774523483bfa61b87447a21d4 (diff) |
gen: usb: Fix EHCI periodic list handling
Our custom handling for periodic endpoints had some bugs in it:
allocating the wrong amount of memory, setting a bit only on low-speed
devices that needs to be present on all of them, and mixing up whether
to reenable the list after changing it between error and success cases.
This patch (hopefully) fixes all of them.
BRANCH=None
BUG=None
TEST=Make sure USB keyboard support in U-Boot works.
Change-Id: I0b302007a620927f596f30a48f420eb67371f78f
Signed-off-by: Julius Werner <jwe...@chromium.org>
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 18 | ||||
-rw-r--r-- | drivers/usb/host/ehci.h | 2 |
2 files changed, 10 insertions, 10 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index eedc824461e..db7230a4349 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1018,7 +1018,7 @@ enable_periodic(struct ehci_ctrl *ctrl) ehci_writel(&hcor->or_usbcmd, cmd); int ret = handshake((uint32_t *)&hcor->or_usbsts, - STD_PSS, STD_PSS, 100 * 1000); + STS_PSS, STS_PSS, 100 * 1000); if (ret < 0) { printf("EHCI failed: timeout when enabling periodic list\n"); return -1; @@ -1037,9 +1037,9 @@ disable_periodic(struct ehci_ctrl *ctrl) ehci_writel(&hcor->or_usbcmd, cmd); int ret = handshake((uint32_t *)&hcor->or_usbsts, - STD_PSS, 0, 100 * 1000); + STS_PSS, 0, 100 * 1000); if (ret < 0) { - printf("EHCI failed: timeout when enabling periodic list\n"); + printf("EHCI failed: timeout when disabling periodic list\n"); return -1; } return 0; @@ -1080,7 +1080,7 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize, goto fail2; } result->current = result->first; - result->last = result->first + elementsize - 1; + result->last = result->first + queuesize - 1; result->tds = memalign(32, sizeof(struct qTD) * queuesize); if (!result->tds) { debug("ehci intr queue: out of memory\n"); @@ -1105,14 +1105,14 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize, (usb_pipespeed(pipe) << 12) | /* EPS */ (usb_pipeendpoint(pipe) << 8) | /* Endpoint Number */ (usb_pipedevice(pipe) << 0); - qh->qh_endpt2 = (1 << 30); /* 1 Tx per mframe */ + qh->qh_endpt2 = (1 << 30) | /* 1 Tx per mframe */ + (1 << 0); /* S-mask: microframe 0 */ if (usb_pipespeed(pipe) < 2) { /* full or low speed */ debug("TT: port: %d, hub address: %d\n", dev->portnr, dev->parent->devnum); qh->qh_endpt2 |= (dev->portnr << 23) | (dev->parent->devnum << 16) | - (0x1c << 8) | /* C-mask: microframes 2-4 */ - (1 << 0); /* S-mask: microframe 0 */ + (0x1c << 8); /* C-mask: microframes 2-4 */ } td->qt_next = QT_NEXT_TERMINATE; @@ -1210,13 +1210,13 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue) debug("found candidate. removing from chain\n"); cur->qh_link = queue->last->qh_link; result = 0; - goto out; + break; } cur = NEXT_QH(cur); if (get_timer(0) > timeout) { printf("Timeout destroying interrupt endpoint queue\n"); result = -1; - break; + goto out; } } diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 3ac27e0f268..0d1bf21e839 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -69,7 +69,7 @@ struct ehci_hcor { #define CMD_RUN (1 << 0) /* start/stop HC */ uint32_t or_usbsts; #define STD_ASS (1 << 15) -#define STD_PSS (1 << 14) +#define STS_PSS (1 << 14) #define STS_HALT (1 << 12) uint32_t or_usbintr; #define INTR_UE (1 << 0) /* USB interrupt enable */ |