[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 7/8] hw/usb/xhci: Support TR NOOP commands
From: |
Nicholas Piggin |
Subject: |
[PATCH 7/8] hw/usb/xhci: Support TR NOOP commands |
Date: |
Thu, 12 Dec 2024 18:35:00 +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 90273cd317e..844521e10f5 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1666,6 +1666,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)
{
@@ -1788,6 +1802,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) {
@@ -1816,10 +1832,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 1/8] qtest/pci: Enforce balanced iomap/unmap, (continued)
- [PATCH 1/8] qtest/pci: Enforce balanced iomap/unmap, Nicholas Piggin, 2024/12/12
- [PATCH 2/8] qtest/libqos/pci: Fix qpci_msix_enable sharing bar0, Nicholas Piggin, 2024/12/12
- [PATCH 3/8] pci/msix: Implement PBA writes, Nicholas Piggin, 2024/12/12
- [PATCH 4/8] tests/qtest/e1000e|igb: Fix e1000e and igb tests to re-trigger interrupts, Nicholas Piggin, 2024/12/12
- [PATCH 5/8] hw/usb/xhci: Move HCD constants to a header and add register constants, Nicholas Piggin, 2024/12/12
- [PATCH 7/8] hw/usb/xhci: Support TR NOOP commands,
Nicholas Piggin <=
- [PATCH 6/8] qtest/xhci: Add controller and device setup and ring tests, Nicholas Piggin, 2024/12/12
- [PATCH 8/8] qtest/xhci: add a test for TR NOOP commands, Nicholas Piggin, 2024/12/12