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 ) )
|
( event->cons >> shift ) ) & XHCI_TRB_C ) )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Consume this TRB */
|
||||||
|
event->cons++;
|
||||||
|
|
||||||
/* Handle TRB */
|
/* Handle TRB */
|
||||||
type = ( trb->common.type & XHCI_TRB_TYPE_MASK );
|
type = ( trb->common.type & XHCI_TRB_TYPE_MASK );
|
||||||
switch ( type ) {
|
switch ( type ) {
|
||||||
|
@ -1733,14 +1736,11 @@ static void xhci_event_poll ( struct xhci_device *xhci ) {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DBGC ( xhci, "XHCI %s unrecognised event %#x\n:",
|
DBGC ( xhci, "XHCI %s unrecognised event %#x\n:",
|
||||||
xhci->name, event->cons );
|
xhci->name, ( event->cons - 1 ) );
|
||||||
DBGC_HDA ( xhci, virt_to_phys ( trb ),
|
DBGC_HDA ( xhci, virt_to_phys ( trb ),
|
||||||
trb, sizeof ( *trb ) );
|
trb, sizeof ( *trb ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Consume this TRB */
|
|
||||||
event->cons++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update dequeue pointer if applicable */
|
/* Update dequeue pointer if applicable */
|
||||||
|
|
Loading…
Reference in New Issue