From: Kuangyi Chiang <ki.chiang65@gmail.com>
To: gregkh@linuxfoundation.org, mathias.nyman@intel.com
Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
ki.chiang65@gmail.com, stable@vger.kernel.org
Subject: [PATCH 2/3] xhci: Fix control transfer error on Etron xHCI host
Date: Wed, 11 Sep 2024 13:17:14 +0800 [thread overview]
Message-ID: <20240911051716.6572-2-ki.chiang65@gmail.com> (raw)
In-Reply-To: <20240911051716.6572-1-ki.chiang65@gmail.com>
Performing a stability stress test on a USB3.0 2.5G ethernet adapter
results in errors like this:
[ 91.441469] r8152 2-3:1.0 eth3: get_registers -71
[ 91.458659] r8152 2-3:1.0 eth3: get_registers -71
[ 91.475911] r8152 2-3:1.0 eth3: get_registers -71
[ 91.493203] r8152 2-3:1.0 eth3: get_registers -71
[ 91.510421] r8152 2-3:1.0 eth3: get_registers -71
The r8152 driver will periodically issue lots of control-IN requests
to access the status of ethernet adapter hardware registers during
the test.
This happens when the xHCI driver enqueue a control TD (which cross
over the Link TRB between two ring segments, as shown) in the endpoint
zero's transfer ring. Seems the Etron xHCI host can not perform this
TD correctly, causing the USB transfer error occurred, maybe the upper
driver retry that control-IN request can solve problem, but not all
drivers do this.
| |
-------
| TRB | Setup Stage
-------
| TRB | Link
-------
-------
| TRB | Data Stage
-------
| TRB | Status Stage
-------
| |
To work around this, the xHCI driver should enqueue a No Op TRB if
next available TRB is the Link TRB in the ring segment, this can
prevent the Setup and Data Stage TRB to be breaked by the Link TRB.
Add a new quirk flag XHCI_NO_BREAK_CTRL_TD to invoke the workaround
in xhci_queue_ctrl_tx().
Both EJ168 and EJ188 have the same problem, applying this patch then
the problem is gone.
Fixes: d0e96f5a71a0 ("USB: xhci: Control transfer support.")
Cc: <stable@vger.kernel.org>
Signed-off-by: Kuangyi Chiang <ki.chiang65@gmail.com>
---
drivers/usb/host/xhci-pci.c | 2 ++
drivers/usb/host/xhci-ring.c | 13 +++++++++++++
drivers/usb/host/xhci.h | 1 +
3 files changed, 16 insertions(+)
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 2fa7f32c2bf9..dda873f3fee7 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -398,12 +398,14 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
xhci->quirks |= XHCI_RESET_ON_RESUME;
xhci->quirks |= XHCI_BROKEN_STREAMS;
xhci->quirks |= XHCI_NO_RESET_DEVICE;
+ xhci->quirks |= XHCI_NO_BREAK_CTRL_TD;
}
if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
pdev->device == PCI_DEVICE_ID_EJ188) {
xhci->quirks |= XHCI_RESET_ON_RESUME;
xhci->quirks |= XHCI_BROKEN_STREAMS;
xhci->quirks |= XHCI_NO_RESET_DEVICE;
+ xhci->quirks |= XHCI_NO_BREAK_CTRL_TD;
}
if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 4ea2c3e072a9..1c387d4dc152 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3727,6 +3727,19 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
if (!urb->setup_packet)
return -EINVAL;
+ if (xhci->quirks & XHCI_NO_BREAK_CTRL_TD) {
+ /*
+ * If next available TRB is the Link TRB in the ring segment then
+ * enqueue a No Op TRB, this can prevent the Setup and Data Stage
+ * TRB to be breaked by the Link TRB.
+ */
+ if (trb_is_link(ep_ring->enqueue + 1)) {
+ field = TRB_TYPE(TRB_TR_NOOP) | ep_ring->cycle_state;
+ queue_trb(xhci, ep_ring, false, 0, 0,
+ TRB_INTR_TARGET(0), field);
+ }
+ }
+
/* 1 TRB for setup, 1 for status */
num_trbs = 2;
/*
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 1272d725270a..aedbe8fee8be 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1629,6 +1629,7 @@ struct xhci_hcd {
#define XHCI_ZHAOXIN_HOST BIT_ULL(46)
#define XHCI_WRITE_64_HI_LO BIT_ULL(47)
#define XHCI_NO_RESET_DEVICE BIT_ULL(48)
+#define XHCI_NO_BREAK_CTRL_TD BIT_ULL(49)
unsigned int num_active_eps;
unsigned int limit_active_eps;
--
2.25.1
next prev parent reply other threads:[~2024-09-11 5:18 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-11 5:17 [PATCH 3/3] xhci: Don't perform Soft Retry for Etron xHCI host Kuangyi Chiang
2024-09-11 5:17 ` Kuangyi Chiang [this message]
2024-09-11 7:52 ` [PATCH 2/3] xhci: Fix control transfer error on " Michał Pecio
2024-09-11 15:09 ` Mathias Nyman
2024-09-12 6:19 ` Kuangyi Chiang
2024-09-11 15:07 ` Mathias Nyman
2024-09-13 5:25 ` Kuangyi Chiang
2024-09-11 5:17 ` [PATCH 1/3] xhci: Don't issue Reset Device command to " Kuangyi Chiang
2024-09-11 5:17 ` [PATCH 0/3] xhci: Some improvement for " Kuangyi Chiang
2024-09-11 7:38 ` Michał Pecio
2024-09-12 5:52 ` Kuangyi Chiang
2024-09-12 7:12 ` Michał Pecio
2024-09-16 2:04 ` Kuangyi Chiang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240911051716.6572-2-ki.chiang65@gmail.com \
--to=ki.chiang65@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=mathias.nyman@intel.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox