summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2014-01-24 16:09:10 +0100
committerStefan Agner <stefan.agner@toradex.com>2014-01-24 16:09:18 +0100
commit445d016fb9b25c4acb71253428190970544171df (patch)
treea5585d765b2fcd33f46a9103ae6000623018f48f
parent2715f5b1512225a774523483bfa61b87447a21d4 (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.c18
-rw-r--r--drivers/usb/host/ehci.h2
2 files changed, 10 insertions, 10 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index eedc824461..db7230a434 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 3ac27e0f26..0d1bf21e83 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 */