Skip to contentSkip to conversation

xhci: Clear the host side toggle manually when endpoint is soft reset

PATCH New Mathias Nyman 1 participant 1 message Mar 16, 2018

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 7/9 xhci: Clear the host side toggle manually when endpoint is soft reset

Some devices use a clear endpoint halt request as a soft reset, even if the endpoint is not halted. This will clear the toggle and sequence on the device side.

xHCI however refuses to reset a non-halted endpoint, so instead we need to issue a configure endpoint command on xHCI to clear its host side toggle and sequence, and get it in sync with the device side.

This is a respin of a old patch that was reverted as it had a stale endpoint context dequeue value which caused regression. commit 27082e2654dc ("xhci: Clear the host side toggle manually when endpoint is 'soft reset'")

---
 drivers/usb/host/xhci-ring.c |   5 ++-
 drivers/usb/host/xhci.c      | 105 ++++++++++++++++++++++++++++++++++++-------
 drivers/usb/host/xhci.h      |   2 +
 3 files changed, 95 insertions(+), 17 deletions(-)
drivers/usb/host/xhci-ring.c +3 -2
index 86476c6..91a1a82 100644
@@ -1829,9 +1829,10 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
 
 	xhci_queue_reset_ep(xhci, command, slot_id, ep_index, reset_type);
 
-	if (reset_type == EP_HARD_RESET)
+	if (reset_type == EP_HARD_RESET) {
+		ep->ep_state |= EP_HARD_CLEAR_TOGGLE;
 		xhci_cleanup_stalled_ring(xhci, ep_index, stream_id, td);
-
+	}
 	xhci_ring_cmd_db(xhci);
 }
 
drivers/usb/host/xhci.c +90 -15

129 lines not on this page · raw message

drivers/usb/host/xhci.h +2 -0
index e4d7d3d..9f236da 100644
@@ -921,6 +921,8 @@ struct xhci_virt_ep {
 #define EP_HAS_STREAMS		(1 << 4)
 /* Transitioning the endpoint to not using streams, don't enqueue URBs */
 #define EP_GETTING_NO_STREAMS	(1 << 5)
+#define EP_HARD_CLEAR_TOGGLE	(1 << 6)
+#define EP_SOFT_CLEAR_TOGGLE	(1 << 7)
 	/* ----  Related to URB cancellation ---- */
 	struct list_head	cancelled_td_list;
 	/* Watchdog timer for stop endpoint command to cancel URBs */