Skip to content

Commit 9e3a287

Browse files
Michal Peciogregkh
authored andcommitted
usb: xhci: Fix Short Packet handling rework ignoring errors
A Short Packet event before the last TRB of a TD is followed by another event on the final TRB on spec-compliant HCs, which is most of them. A 'last_td_was_short' flag was added to know if a TD has just completed as Short Packet and another event is to come. The flag was cleared after seeing the event (unless no TDs are pending, but that's a separate bug) or seeing a new TD complete as something other than Short Packet. A rework replaced the flag with an 'old_trb_comp_code' variable. When an event doesn't match the pending TD and the previous event was Short Packet, the new event is silently ignored. To preserve old behavior, 'old_trb_comp_code' should be cleared at this point, but instead it is being set to current comp code, which is often Short Packet again. This can cause more events to be silently ignored, even though they are no longer connected with the old TD that completed short and indicate a serious problem with the driver or the xHC. Common device classes like UAC in async mode, UVC, serial or the UAS status pipe complete as Short Packet routinely and could be affected. Clear 'old_trb_comp_code' to zero, which is an invalid completion code and the same value the variable starts with. This restores original behavior on Short Packet and also works for illegal Etron events, which the code has been extended to cover too. Fixes: b331a3d ("xhci: Handle spurious events on Etron host isoc enpoints") Signed-off-by: Michal Pecio <[email protected]> Signed-off-by: Mathias Nyman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent b513cc1 commit 9e3a287

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

drivers/usb/host/xhci-ring.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2913,7 +2913,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
29132913
if (xhci_spurious_success_tx_event(xhci, ep_ring)) {
29142914
xhci_dbg(xhci, "Spurious event dma %pad, comp_code %u after %u\n",
29152915
&ep_trb_dma, trb_comp_code, ep_ring->old_trb_comp_code);
2916-
ep_ring->old_trb_comp_code = trb_comp_code;
2916+
ep_ring->old_trb_comp_code = 0;
29172917
return 0;
29182918
}
29192919

0 commit comments

Comments
 (0)