aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiklas Neronin <[email protected]>2024-06-26 15:48:31 +0300
committerGreg Kroah-Hartman <[email protected]>2024-06-27 16:08:06 +0200
commit132dcf65fc2d5a308fc44833dbb7f73a211a02e9 (patch)
treefa8553ceb9859c7f67aa4ba23236a4bada469fc6
parent5ea8a885c85edee318c8daa8f0a5ecb5e409ecd6 (diff)
usb: xhci: remove infinite loop prevention
If a buggy HW reports some unpredicted event (for example, an overrun event following a MSE event while the EP ring is actually not empty), the driver will never find the TD, and it will loop until the TD list is empty. Before commits [1][2], the spin lock was released when giving back a URB in the do-while loop. This could cause more TD to be added to TD list, causing an infinite loop. Because of commits [1][2] the spin lock is not released any more, thus the infinite loop prevention is unnecessary and is removed. [1], commit 0c03d89d0c71 ("xhci: Giveback urb in finish_td directly") [2], commit 36dc01657b49 ("usb: host: xhci: Support running urb giveback in tasklet context") Signed-off-by: Niklas Neronin <[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]>
-rw-r--r--drivers/usb/host/xhci-ring.c15
1 files changed, 0 insertions, 15 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 8289f69a6978..7baa9dc706a1 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2611,7 +2611,6 @@ static int handle_tx_event(struct xhci_hcd *xhci,
int status = -EINPROGRESS;
struct xhci_ep_ctx *ep_ctx;
u32 trb_comp_code;
- int td_num = 0;
slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1;
@@ -2637,10 +2636,6 @@ static int handle_tx_event(struct xhci_hcd *xhci,
if (!ep_ring)
return handle_transferless_tx_event(xhci, ep, trb_comp_code);
- /* Count current td numbers if ep->skip is set */
- if (ep->skip)
- td_num += list_count_nodes(&ep_ring->td_list);
-
/* Look for common error cases */
switch (trb_comp_code) {
/* Skip codes that require special handling depending on
@@ -2799,18 +2794,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
return 0;
}
- /* We've skipped all the TDs on the ep ring when ep->skip set */
- if (ep->skip && td_num == 0) {
- ep->skip = false;
- xhci_dbg(xhci, "All tds on the ep_ring skipped. Clear skip flag for slot %u ep %u.\n",
- slot_id, ep_index);
- return 0;
- }
-
td = list_first_entry(&ep_ring->td_list, struct xhci_td,
td_list);
- if (ep->skip)
- td_num--;
/* Is this a TRB in the currently executing TD? */
ep_seg = trb_in_td(xhci, td, ep_trb_dma, false);