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 <nico.huber@secunet.com> Reviewed-on: http://review.coreboot.org/1902 Reviewed-by: Patrick Georgi <patrick@georgi-clan.de> Tested-by: build bot (Jenkins)
This commit is contained in:
parent
b2db28babe
commit
af169f4dd5
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue