diff options
author | Nico Huber <nico.huber@secunet.com> | 2012-11-20 17:49:00 +0100 |
---|---|---|
committer | Patrick Georgi <patrick@georgi-clan.de> | 2012-11-24 08:43:49 +0100 |
commit | 8c4d2f36a339ba34c532e29696f2c5b70fb04957 (patch) | |
tree | 5b93035eca2db4f38a646d87e92829bab29a1a42 | |
parent | ce407e470d36bd446e7e1f02884c97a98423d5c4 (diff) |
libpayload: Handle underruns in UHCI interrupt queues
If usb_poll() isn't called fast enough, the UHCI controller marks an
underrun interrupt queue as done (terminating the queue at the head).
We can recover from this situation, when usb_poll() gets called again,
and the queue is processed.
Change-Id: Id56c9df44d6dbd53cd30ad89dfb5bf5977799829
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: http://review.coreboot.org/1898
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
-rw-r--r-- | payloads/libpayload/drivers/usb/uhci.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/payloads/libpayload/drivers/usb/uhci.c b/payloads/libpayload/drivers/usb/uhci.c index bfa53f6049..386392b53f 100644 --- a/payloads/libpayload/drivers/usb/uhci.c +++ b/payloads/libpayload/drivers/usb/uhci.c @@ -590,6 +590,11 @@ uhci_poll_intr_queue (void *q_) q->lastread = (q->lastread + 1) % q->total; return &q->data[current*q->reqsize]; } + /* reset queue if we fully processed it after underrun */ + else if (q->qh->elementlinkptr & FLISTP_TERMINATE) { + usb_debug("resetting underrun uhci interrupt queue.\n"); + q->qh->elementlinkptr = virt_to_phys(q->tds + q->lastread); + } return NULL; } |