From 1886d5692e52d57ffc49784c7fdc04785c209e0f Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Thu, 25 May 2023 15:29:31 -0400 Subject: [PATCH] XHCI: Handle an unlikely corner case in CancelQueuedTransfers. See inline comment with reference to the XHCI specification. --- src/add-ons/kernel/busses/usb/xhci.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp b/src/add-ons/kernel/busses/usb/xhci.cpp index c05af73810..bd1a84bc54 100644 --- a/src/add-ons/kernel/busses/usb/xhci.cpp +++ b/src/add-ons/kernel/busses/usb/xhci.cpp @@ -1106,8 +1106,15 @@ XHCI::CancelQueuedTransfers(Pipe *pipe, bool force) // order to avoid a deadlock, we must unlock the endpoint. endpointLocker.Unlock(); status_t status = StopEndpoint(false, endpoint); + if (status != B_OK && status != B_DEV_STALLED) { + // It is possible that the endpoint was stopped by the controller at the + // same time our STOP command was in progress, causing a "Context State" + // error. In that case, try again; if the endpoint is already stopped, + // StopEndpoint will notice this. (XHCI 1.2 § 4.6.9 p137.) + status = StopEndpoint(false, endpoint); + } if (status == B_DEV_STALLED) { - // Only exit from a Halted state is a reset. (XHCI 1.2 § 4.8.3 p163.) + // Only exit from a Halted state is a RESET. (XHCI 1.2 § 4.8.3 p163.) TRACE_ERROR("cancel queued transfers: halted endpoint, reset!\n"); status = ResetEndpoint(false, endpoint); }