Nico Huber ([email protected]) just uploaded a new patch set to gerrit, 
which you can find at http://review.coreboot.org/1902

-gerrit

commit 7f59b31c4efaadebd2897b302c381b80f7925cab
Author: Nico Huber <[email protected]>
Date:   Thu Nov 22 11:14:03 2012 +0100

    libpayload: ehci: Prevent some race conditions
    
    Prevent race conditions, when an interrupt-queue underrun occurred and
    the controller is currently working on our queue head or a transfer is
    still in progress.
    
    Change-Id: Ia14f80a08071306ee5d1349780be081bfacb206a
    Signed-off-by: Nico Huber <[email protected]>
---
 payloads/libpayload/drivers/usb/ehci.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/payloads/libpayload/drivers/usb/ehci.c 
b/payloads/libpayload/drivers/usb/ehci.c
index 4ff137e..6a1cfb5 100644
--- a/payloads/libpayload/drivers/usb/ehci.c
+++ b/payloads/libpayload/drivers/usb/ehci.c
@@ -626,8 +626,14 @@ static u8 *ehci_poll_intr_queue(void *const queue)
                intrq->head = intrq->head->next;
        }
        /* reset queue if we fully processed it after underrun */
-       else if (intrq->qh.td.next_qtd & QTD_TERMINATE) {
+       else if ((intrq->qh.td.next_qtd & QTD_TERMINATE) &&
+                       /* to prevent race conditions:
+                          not our head and not active */
+                       (intrq->qh.current_td_ptr !=
+                        virt_to_phys(&intrq->head->td)) &&
+                       !(intrq->qh.td.token & QTD_ACTIVE)) {
                usb_debug("resetting underrun ehci interrupt queue.\n");
+               intrq->qh.current_td_ptr = 0;
                memset((void *)&intrq->qh.td, 0, sizeof(intrq->qh.td));
                intrq->qh.td.next_qtd = virt_to_phys(&intrq->head->td);
        }

-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to