1 From 9d3afd87557637a37135aa6e370dea846b839c2d Mon Sep 17 00:00:00 2001
2 From: Jonathan Bell <jonathan@raspberrypi.com>
3 Date: Mon, 11 Nov 2024 10:30:38 +0000
4 Subject: [PATCH] drivers: usb: xhci: set HID bit in streaming endpoint
7 The xHC may commence Host Initiated Data Moves for streaming endpoints -
8 see USB3.2 spec s8.12.1.4.2.4. However, this behaviour is typically
9 counterproductive as the submission of UAS URBs in {Status, Data,
10 Command} order and 1 outstanding IO per stream ID means the device never
11 enters Move Data after a HIMD for Status or Data stages with the same
12 stream ID. For OUT transfers this is especially inefficient as the host
13 will start transmitting multiple bulk packets as a burst, all of which
14 get NAKed by the device - wasting bandwidth.
16 Also, some buggy UAS adapters don't properly handle the EP flow control
17 state this creates - e.g. RTL9210.
19 Set Host Initiated Data Move Disable to always defer stream selection to
20 the device. xHC implementations may treat this field as "don't care,
21 forced to 1" anyway - xHCI 1.2 s4.12.1.
23 Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
25 drivers/usb/host/xhci-mem.c | 8 ++++++++
26 drivers/usb/host/xhci.h | 2 ++
27 2 files changed, 10 insertions(+)
29 --- a/drivers/usb/host/xhci-mem.c
30 +++ b/drivers/usb/host/xhci-mem.c
31 @@ -715,6 +715,14 @@ void xhci_setup_streams_ep_input_ctx(str
32 ep_ctx->ep_info &= cpu_to_le32(~EP_MAXPSTREAMS_MASK);
33 ep_ctx->ep_info |= cpu_to_le32(EP_MAXPSTREAMS(max_primary_streams)
37 + * Set Host Initiated Data Move Disable to always defer stream
38 + * selection to the device. xHC implementations may treat this
39 + * field as "don't care, forced to 1" anyway - xHCI 1.2 s4.12.1.
41 + ep_ctx->ep_info2 |= EP_HID;
43 ep_ctx->deq = cpu_to_le64(stream_info->ctx_array_dma);
46 --- a/drivers/usb/host/xhci.h
47 +++ b/drivers/usb/host/xhci.h
48 @@ -465,6 +465,8 @@ struct xhci_ep_ctx {
49 #define CTX_TO_EP_MAXPSTREAMS(p) (((p) & EP_MAXPSTREAMS_MASK) >> 10)
50 /* Endpoint is set up with a Linear Stream Array (vs. Secondary Stream Array) */
51 #define EP_HAS_LSA (1 << 15)
52 +/* Host initiated data move disable in info2 */
53 +#define EP_HID (1 << 7)
54 /* hosts with LEC=1 use bits 31:24 as ESIT high bits. */
55 #define CTX_TO_MAX_ESIT_PAYLOAD_HI(p) (((p) >> 24) & 0xff)