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], commit0c03d89d0c("xhci: Giveback urb in finish_td directly") [2], commit36dc01657b("usb: host: xhci: Support running urb giveback in tasklet context") Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Link: https://lore.kernel.org/r/20240626124835.1023046-18-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
5ea8a885c8
commit
132dcf65fc
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user