Skip to content

Commit 9b6a126

Browse files
matnymangregkh
authored andcommitted
xhci: Fix giving back cancelled URBs even if halted endpoint can't reset
Commit 9ebf300 ("xhci: Fix halted endpoint at stop endpoint command completion") in 5.12 changes how cancelled URBs are given back. To cancel a URB xhci driver needs to stop the endpoint first. To clear a halted endpoint xhci driver needs to reset the endpoint. In rare cases when an endpoint halt (error) races with a endpoint stop we need to clear the reset before removing, and giving back the cancelled URB. The above change in 5.12 takes care of this, but it also relies on the reset endpoint completion handler to give back the cancelled URBs. There are cases when driver refuses to queue reset endpoint commands, for example when a link suddenly goes to an inactive error state. In this case the cancelled URB is never given back. Fix this by giving back the URB in the stop endpoint if queuing a reset endpoint command fails. Fixes: 9ebf300 ("xhci: Fix halted endpoint at stop endpoint command completion") CC: <[email protected]> # 5.12 Signed-off-by: Mathias Nyman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent b813511 commit 9b6a126

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

drivers/usb/host/xhci-ring.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,7 @@ static int xhci_reset_halted_ep(struct xhci_hcd *xhci, unsigned int slot_id,
862862
return ret;
863863
}
864864

865-
static void xhci_handle_halted_endpoint(struct xhci_hcd *xhci,
865+
static int xhci_handle_halted_endpoint(struct xhci_hcd *xhci,
866866
struct xhci_virt_ep *ep, unsigned int stream_id,
867867
struct xhci_td *td,
868868
enum xhci_ep_reset_type reset_type)
@@ -875,7 +875,7 @@ static void xhci_handle_halted_endpoint(struct xhci_hcd *xhci,
875875
* Device will be reset soon to recover the link so don't do anything
876876
*/
877877
if (ep->vdev->flags & VDEV_PORT_ERROR)
878-
return;
878+
return -ENODEV;
879879

880880
/* add td to cancelled list and let reset ep handler take care of it */
881881
if (reset_type == EP_HARD_RESET) {
@@ -888,16 +888,18 @@ static void xhci_handle_halted_endpoint(struct xhci_hcd *xhci,
888888

889889
if (ep->ep_state & EP_HALTED) {
890890
xhci_dbg(xhci, "Reset ep command already pending\n");
891-
return;
891+
return 0;
892892
}
893893

894894
err = xhci_reset_halted_ep(xhci, slot_id, ep->ep_index, reset_type);
895895
if (err)
896-
return;
896+
return err;
897897

898898
ep->ep_state |= EP_HALTED;
899899

900900
xhci_ring_cmd_db(xhci);
901+
902+
return 0;
901903
}
902904

903905
/*
@@ -1014,6 +1016,7 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
10141016
struct xhci_td *td = NULL;
10151017
enum xhci_ep_reset_type reset_type;
10161018
struct xhci_command *command;
1019+
int err;
10171020

10181021
if (unlikely(TRB_TO_SUSPEND_PORT(le32_to_cpu(trb->generic.field[3])))) {
10191022
if (!xhci->devs[slot_id])
@@ -1058,7 +1061,10 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
10581061
td->status = -EPROTO;
10591062
}
10601063
/* reset ep, reset handler cleans up cancelled tds */
1061-
xhci_handle_halted_endpoint(xhci, ep, 0, td, reset_type);
1064+
err = xhci_handle_halted_endpoint(xhci, ep, 0, td,
1065+
reset_type);
1066+
if (err)
1067+
break;
10621068
xhci_stop_watchdog_timer_in_irq(xhci, ep);
10631069
return;
10641070
case EP_STATE_RUNNING:

0 commit comments

Comments
 (0)