The Set TR Deq Slot Not Enabled error occurs when the Endpoint State is disabled. In this state, the slot's Doorbell register is disabled, meaning it cannot receive or handle Transfer Descriptors (TDs). Because the slot cannot receive or handle TDs, it should not have any TDs. Consequently, all cancelled TDs are released. (The goto 'td_cleanup' is used for other cases in later patches) Case 'COMP_SLOT_NOT_ENABLED_ERROR' (11) is moved between 'COMP_TRB_ERROR' (5) and 'COMP_CONTEXT_STATE_ERROR' (19). xHCI specification, rev 1.2: Slot State section 4.5.3 Signed-off-by: Niklas Neronin <niklas.neronin@xxxxxxxxxxxxxxx> --- drivers/usb/host/xhci-ring.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 7bd559294742..79c15dbae43b 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1461,6 +1461,9 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, xhci_warn(xhci, "Set TR Deq error stream %u boundary check failed TRB @%pad slot %d ep %u\n", stream_id, &deq, slot_id, ep_index); break; + case COMP_SLOT_NOT_ENABLED_ERROR: + xhci_warn(xhci, "Set TR Deq error slot %d is Disabled\n", slot_id); + goto td_cleanup; case COMP_CONTEXT_STATE_ERROR: xhci_warn(xhci, "WARN Set TR Deq Ptr cmd failed due to incorrect slot or ep state.\n"); ep_state = GET_EP_CTX_STATE(ep_ctx); @@ -1470,10 +1473,6 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, "Slot state = %u, EP state = %u", slot_state, ep_state); break; - case COMP_SLOT_NOT_ENABLED_ERROR: - xhci_warn(xhci, "WARN Set TR Deq Ptr cmd failed because slot %u was not enabled.\n", - slot_id); - break; default: xhci_warn(xhci, "WARN Set TR Deq Ptr cmd with unknown completion code of %u.\n", cmd_comp_code); @@ -1554,6 +1553,17 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, xhci_dbg(ep->xhci, "%s: All TDs cleared, ring doorbell\n", __func__); ring_doorbell_for_active_rings(xhci, slot_id, ep_index); } + return; +td_cleanup: + ep->ep_state &= ~SET_DEQ_PENDING; + ep->queued_deq_seg = NULL; + ep->queued_deq_ptr = NULL; + + list_for_each_entry_safe(td, tmp_td, &ep->cancelled_td_list, cancelled_td_list) { + td->cancel_status = TD_CLEARED; + ep_ring = xhci_urb_to_transfer_ring(xhci, td->urb); + xhci_td_cleanup(xhci, td, ep_ring, td->status); + } } static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id, -- 2.50.1