When a URB is cancled, xhci driver turns the untransferred trbs
into no-ops.  If an endpoint stalls on a no-op trb that belongs
to the cancelled URB, the event handler won't reset the endpoint.
Hence, it will stay halted.

Link: http://marc.info/?l=linux-usb&m=149582598330127&w=2

Signed-off-by: Lu Baolu <baolu...@linux.intel.com>
---
 drivers/usb/host/xhci-ring.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index c75cfe7..b1de9f2 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2577,15 +2577,20 @@ static int handle_tx_event(struct xhci_hcd *xhci,
                                (struct xhci_generic_trb *) ep_trb);
 
                /*
-                * No-op TRB should not trigger interrupts.
-                * If ep_trb is a no-op TRB, it means the
-                * corresponding TD has been cancelled. Just ignore
-                * the TD.
+                * No-op TRB could trigger interrupts in a case where
+                * a URB was killed and a STALL_ERROR happens right
+                * after the endpoint ring stopped. Reset the halted
+                * endpoint. Otherwise, the endpoint remains stalled
+                * indefinitely.
                 */
                if (trb_is_noop(ep_trb)) {
-                       xhci_dbg(xhci,
-                                "ep_trb is a no-op TRB. Skip it for slot %u ep 
%u\n",
-                                slot_id, ep_index);
+                       if (trb_comp_code == COMP_STALL_ERROR ||
+                           xhci_requires_manual_halt_cleanup(xhci, ep_ctx,
+                                                             trb_comp_code))
+                               xhci_cleanup_halted_endpoint(xhci, slot_id,
+                                                            ep_index,
+                                                            ep_ring->stream_id,
+                                                            td, EP_HARD_RESET);
                        goto cleanup;
                }
 
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to