[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 4/8] hw/usb/xhci: Support TR NOOP commands
From: |
Nicholas Piggin |
Subject: |
[PATCH v2 4/8] hw/usb/xhci: Support TR NOOP commands |
Date: |
Sat, 18 Jan 2025 17:08:49 +1000 |
Implement XHCI TR NOOP commands by setting up then immediately
completing the packet.
The IBM AIX XHCI HCD driver uses NOOP commands to check driver and
hardware health, which works after this change.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
hw/usb/hcd-xhci.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index c68cf268365..256bee6c72f 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1662,6 +1662,20 @@ static int xhci_fire_transfer(XHCIState *xhci,
XHCITransfer *xfer, XHCIEPContext
return xhci_submit(xhci, xfer, epctx);
}
+static int xhci_noop_transfer(XHCIState *xhci, XHCITransfer *xfer)
+{
+ /*
+ * TR NOOP conceptually probably better not call into USB subsystem
+ * (usb_packet_setup() via xhci_setup_packet()). In practice it
+ * works and avoids code duplication.
+ */
+ if (xhci_setup_packet(xfer) < 0) {
+ return -1;
+ }
+ xhci_try_complete_packet(xfer);
+ return 0;
+}
+
static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
unsigned int epid, unsigned int streamid)
{
@@ -1784,6 +1798,8 @@ static void xhci_kick_epctx(XHCIEPContext *epctx,
unsigned int streamid)
epctx->kick_active++;
while (1) {
+ bool noop = false;
+
length = xhci_ring_chain_length(xhci, ring);
if (length <= 0) {
if (epctx->type == ET_ISO_OUT || epctx->type == ET_ISO_IN) {
@@ -1812,10 +1828,20 @@ static void xhci_kick_epctx(XHCIEPContext *epctx,
unsigned int streamid)
epctx->kick_active--;
return;
}
+ if (type == TR_NOOP) {
+ noop = true;
+ }
}
xfer->streamid = streamid;
- if (epctx->epid == 1) {
+ if (noop) {
+ if (length != 1) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: NOOP TR TRB within TRB chain!\n", __func__);
+ /* Undefined behavior, we no-op the entire chain */
+ }
+ xhci_noop_transfer(xhci, xfer);
+ } else if (epctx->epid == 1) {
xhci_fire_ctl_transfer(xhci, xfer);
} else {
xhci_fire_transfer(xhci, xfer, epctx);
--
2.45.2
- [PATCH v2 0/8] usb/xhci: TR NOOP, TI HCD device, more qtests, Nicholas Piggin, 2025/01/18
- [PATCH v2 1/8] hw/usb/xhci: Move HCD constants to a header and add register constants, Nicholas Piggin, 2025/01/18
- [PATCH v2 2/8] hw/usb/xhci: Rename and move HCD register region constants to header, Nicholas Piggin, 2025/01/18
- [PATCH v2 3/8] tests/qtest/xhci: Add controller and device setup and ring tests, Nicholas Piggin, 2025/01/18
- [PATCH v2 4/8] hw/usb/xhci: Support TR NOOP commands,
Nicholas Piggin <=
- [PATCH v2 5/8] tests/qtest/xhci: add a test for TR NOOP commands, Nicholas Piggin, 2025/01/18
- [PATCH v2 6/8] tests/qtest/xhci: test the qemu-xhci device, Nicholas Piggin, 2025/01/18
- [PATCH v2 7/8] hw/usb/hcd-xhci-pci: Make PCI device more configurable, Nicholas Piggin, 2025/01/18
- [PATCH v2 8/8] hw/usb/hcd-xhci-pci: Add TI TUSB73X0 XHCI controller model, Nicholas Piggin, 2025/01/18