summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Pecio <michal.pecio@gmail.com>2025-03-11 17:45:51 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-05-02 07:44:35 +0200
commit3a259d74f57a255eb09b38dc250a5db40f1e3acc (patch)
tree12843e31aea0d88178eecc950008021f7b0e5bd0
parent0725a991727dd732062faa19e511d848a9fc8f84 (diff)
downloadlinux-3a259d74f57a255eb09b38dc250a5db40f1e3acc.tar.gz
linux-3a259d74f57a255eb09b38dc250a5db40f1e3acc.tar.bz2
linux-3a259d74f57a255eb09b38dc250a5db40f1e3acc.zip
usb: xhci: Avoid Stop Endpoint retry loop if the endpoint seems Running
[ Upstream commit 28a76fcc4c85dd39633fb96edb643c91820133e3 ] Nothing prevents a broken HC from claiming that an endpoint is Running and repeatedly rejecting Stop Endpoint with Context State Error. Avoid infinite retries and give back cancelled TDs. No such cases known so far, but HCs have bugs. Signed-off-by: Michal Pecio <michal.pecio@gmail.com> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Link: https://lore.kernel.org/r/20250311154551.4035726-4-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/usb/host/xhci-ring.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 64bf50ea62a4..cd94b0a4e021 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1183,16 +1183,19 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
* Stopped state, but it will soon change to Running.
*
* Assume this bug on unexpected Stop Endpoint failures.
- * Keep retrying until the EP starts and stops again, on
- * chips where this is known to help. Wait for 100ms.
+ * Keep retrying until the EP starts and stops again.
*/
- if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100)))
- break;
fallthrough;
case EP_STATE_RUNNING:
/* Race, HW handled stop ep cmd before ep was running */
xhci_dbg(xhci, "Stop ep completion ctx error, ctx_state %d\n",
GET_EP_CTX_STATE(ep_ctx));
+ /*
+ * Don't retry forever if we guessed wrong or a defective HC never starts
+ * the EP or says 'Running' but fails the command. We must give back TDs.
+ */
+ if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100)))
+ break;
command = xhci_alloc_command(xhci, false, GFP_ATOMIC);
if (!command)