mirror of https://github.com/ipxe/ipxe.git
[xhci] Consume event TRB before reporting completion to USB core
Reporting a completion via usb_complete() will pass control outside the scope of xhci.c, and could potentially result in a further call to xhci_event_poll() before returning from usb_complete(). Since we currently update the event consumer counter only after calling usb_complete(), this can result in duplicate completions and consequent corruption of the submission TRB ring structures. Fix by updating the event ring consumer counter before passing control to usb_complete(). Reported-by: Andreas Hammarskjöld <junior@2PintSoftware.com> Tested-by: Andreas Hammarskjöld <junior@2PintSoftware.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/68/merge
parent
6737a8795f
commit
8dbb73a779
|
@ -1711,6 +1711,9 @@ static void xhci_event_poll ( struct xhci_device *xhci ) {
|
|||
( event->cons >> shift ) ) & XHCI_TRB_C ) )
|
||||
break;
|
||||
|
||||
/* Consume this TRB */
|
||||
event->cons++;
|
||||
|
||||
/* Handle TRB */
|
||||
type = ( trb->common.type & XHCI_TRB_TYPE_MASK );
|
||||
switch ( type ) {
|
||||
|
@ -1733,14 +1736,11 @@ static void xhci_event_poll ( struct xhci_device *xhci ) {
|
|||
|
||||
default:
|
||||
DBGC ( xhci, "XHCI %s unrecognised event %#x\n:",
|
||||
xhci->name, event->cons );
|
||||
xhci->name, ( event->cons - 1 ) );
|
||||
DBGC_HDA ( xhci, virt_to_phys ( trb ),
|
||||
trb, sizeof ( *trb ) );
|
||||
break;
|
||||
}
|
||||
|
||||
/* Consume this TRB */
|
||||
event->cons++;
|
||||
}
|
||||
|
||||
/* Update dequeue pointer if applicable */
|
||||
|
|
Loading…
Reference in New Issue