[PATCH 1/6] usb: xhci: Document endpoint state management
From: Michal Pecio
Date: Mon Mar 10 2025 - 04:37:14 EST
Add systematic comments describing xhci_virt_ep.ep_state flags and
their relation to xHC endpoint state.
Add a few paragraphs about how they are used to track and manage the
state of endpoints.
Signed-off-by: Michal Pecio <michal.pecio@xxxxxxxxx>
---
drivers/usb/host/xhci.h | 44 +++++++++++++++++++++++++++++------------
1 file changed, 31 insertions(+), 13 deletions(-)
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 56ed1b817f91..46bbdc97cc4b 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -662,20 +662,18 @@ struct xhci_virt_ep {
*/
struct xhci_ring *new_ring;
unsigned int err_count;
+ /* Endpoint state, state transitions, pending operations. See also notes below. */
unsigned int ep_state;
-#define SET_DEQ_PENDING (1 << 0)
-#define EP_HALTED (1 << 1) /* Halted host ep handling */
-#define EP_STOP_CMD_PENDING (1 << 2) /* For URB cancellation */
-/* Transitioning the endpoint to using streams, don't enqueue URBs */
-#define EP_GETTING_STREAMS (1 << 3)
-#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)
-/* usb_hub_clear_tt_buffer is in progress */
-#define EP_CLEARING_TT (1 << 8)
-#define EP_STALLED (1 << 9) /* For stall handling */
+#define SET_DEQ_PENDING BIT(0) /* EP Stopped, Set TR Dequeue pending */
+#define EP_HALTED BIT(1) /* EP Halted -> Stopped, Reset Endpoint pending */
+#define EP_STOP_CMD_PENDING BIT(2) /* EP Running -> Stopped, Stop Endpoint pending */
+#define EP_GETTING_STREAMS BIT(3) /* Transitioning to streams, no URBs allowed */
+#define EP_HAS_STREAMS BIT(4) /* Streams are enabled */
+#define EP_GETTING_NO_STREAMS BIT(5) /* Transitioning to no streams, no URBs allowed */
+#define EP_HARD_CLEAR_TOGGLE BIT(6) /* Toggle is being or has been cleared by reset */
+#define EP_SOFT_CLEAR_TOGGLE BIT(7) /* Software toggle clearing, no URBs allowed */
+#define EP_CLEARING_TT BIT(8) /* EP not Running, Transaction Translator reset */
+#define EP_STALLED BIT(9) /* EP not Running, waiting for usb_clear_halt() */
/* ---- Related to URB cancellation ---- */
struct list_head cancelled_td_list;
struct xhci_hcd *xhci;
@@ -703,6 +701,26 @@ struct xhci_virt_ep {
bool use_extended_tbc;
};
+/*
+ * Endpoint state notes.
+ * xHCI 4.8.3 defines three basic states of an enabled endpoint: Running, Halted, Stopped.
+ * The fourth Error state is avoided by not queuing invalid TRBs. This seems to work so far.
+ *
+ * 4.8.3 warns that Endpoint Context EP State field may be stale, and it doesn't indicate ongoing
+ * transitions anyway. Some xhci_virt_ep.ep_state flags are used to keep track of known transitions
+ * and various operations which imply or require the endpoint to be in a particular state.
+ *
+ * Notably missing is the Stopped -> Running transition started by a doorbell ring. 4.8.3 suggests
+ * that it is instantenous, but on some common HCs it may not be. There is no universal way to know
+ * when it completes. Transfer events imply completion, but don't arrive if the device NAKs/NRDYs.
+ * Stop Endpoint fails if the transition isn't complete. Polling the Endpoint Context is an option.
+ *
+ * xhci_ring_ep_doorbell() inspects the flags to decide if the endpoint can be restarted. Another
+ * user is xhci_urb_dequeue(), which must not attempt to stop a Stopped endpoint, due to HW bugs.
+ * An endpoint with pending URBs and no flags preventing restart must be Running for this to work.
+ * Call xhci_ring_doorbell_for_active_rings() or similar after clearing any such flag.
+ */
+
enum xhci_overhead_type {
LS_OVERHEAD_TYPE = 0,
FS_OVERHEAD_TYPE,
--
2.48.1