From 51ee4a84300200c51303ef15b84981b2edb6ec47 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Fri, 29 Jan 2021 15:00:43 +0200 Subject: [PATCH] xhci: Check for pending reset endpoint command before queueing a new one. A halted endpoint can be detected both when transfer events complete, and in stop endpoint command completion. Both these handlers will start clearing up the halted endpoint and queue a reset endpoint command. It's possible to get both events for the same halted endpoint if right after a URB cancel queues a stop endpoint command the endpoint stalls. Use the EP_HALTED flag to prevent resetting the endpoint twice. Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20210129130044.206855-27-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 1440041..26f5557 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -873,8 +873,6 @@ static void xhci_handle_halted_endpoint(struct xhci_hcd *xhci, if (ep->vdev->flags & VDEV_PORT_ERROR) return; - ep->ep_state |= EP_HALTED; - /* add td to cancelled list and let reset ep handler take care of it */ if (reset_type == EP_HARD_RESET) { ep->ep_state |= EP_HARD_CLEAR_TOGGLE; @@ -884,10 +882,17 @@ static void xhci_handle_halted_endpoint(struct xhci_hcd *xhci, } } + if (ep->ep_state & EP_HALTED) { + xhci_dbg(xhci, "Reset ep command already pending\n"); + return; + } + err = xhci_reset_halted_ep(xhci, slot_id, ep->ep_index, reset_type); if (err) return; + ep->ep_state |= EP_HALTED; + xhci_ring_cmd_db(xhci); } @@ -2575,7 +2580,6 @@ static int handle_tx_event(struct xhci_hcd *xhci, case COMP_STALL_ERROR: xhci_dbg(xhci, "Stalled endpoint for slot %u ep %u\n", slot_id, ep_index); - ep->ep_state |= EP_HALTED; status = -EPIPE; break; case COMP_SPLIT_TRANSACTION_ERROR: -- 2.7.4