4.13-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Lu Baolu <baolu...@linux.intel.com>

commit 810a624bd1b64b13ddcc2eb5c1880526a750a870 upstream.

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>
Signed-off-by: Mathias Nyman <mathias.ny...@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 drivers/usb/host/xhci-ring.c |   20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2578,15 +2578,21 @@ static int handle_tx_event(struct xhci_h
                                (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_trb,
+                                                            EP_HARD_RESET);
                        goto cleanup;
                }
 


Reply via email to