usb: recognize and configure hubs, power downstream ports (B4a)

First slice of hub support (docs/usb-hub.md), handled IN the xhci-bus
because a device behind a hub is reached by the CONTROLLER via a route
string in its slot context — topology only exists inside the driver
that owns the controller. When the scan enumerates a class-9 device it
now calls setupHub: read the hub descriptor for the downstream port
count and TT arrangement, tell the controller the slot is a hub
(Configure Endpoint with the slot add-flag sets the Hub bit, Number of
Ports, and MTT/TT-Think-Time per xHCI 4.6.6), SET_HUB_DEPTH for a
SuperSpeed hub so it can compose route strings, and SET_FEATURE
PORT_POWER every downstream port.

The Device gains topology fields (route string, root port, parent hub
slot/port for the TT) and buildAddressInputContext now fills them, so
the Address Device path is ready for downstream devices — those are
enumerated in B4b. A root-port device gets route 0 and its own port as
the chain root, unchanged behavior.

Verified in QEMU with a hub on a second controller and a device behind
it (a usb-hub QEMU case, since the boot controller's auto-assigned
devices collide on the low ports): 'hub slot 1: 8 downstream ports
powered (USB2 single-TT)'. Full suite 89/89. The user's SuperSpeed
Genesys hub is the real-hardware target, flagged separately (QEMU's
USB2 hub doesn't model the compound USB3 hub).
This commit is contained in:
Daniel Samson
2026-07-21 21:56:59 +01:00
parent 983b4ed05a
commit 92b03b8d07
4 changed files with 326 additions and 4 deletions
+17
View File
@@ -461,6 +461,23 @@ CASES = [
# usb-kbd/usb-mouse ride the default boot xHCI bus (see qemu_args).
"expect": r"(?=[\s\S]*usb-hid-keyboard: ok)(?=[\s\S]*usb-hid-mouse: ok)",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# USB hub (B4a/B4b, docs/usb-hub.md): a USB2 hub on the xHCI bus with a
# keyboard behind it (a STATIC boot topology — no hot-plug event needed).
# B4a: the hub enumerates and powers its downstream ports. B4b extends the
# expect to the downstream keyboard binding usb-hid-keyboard.
{"name": "usb-hub",
"build_case": "usb-hid",
"smp": 4,
"timeout": 150,
# A SECOND xhci controller carries the hub topology, isolated from the boot
# controller's auto-assigned devices (whose ports the hub would collide
# with). danos spawns a second usb-xhci-bus for it. The hub sits on port 1,
# the keyboard on the hub's downstream port 1 (port=1.1).
"qemu_extra": ["-device", "qemu-xhci,id=xhci2",
"-device", "usb-hub,bus=xhci2.0,port=1",
"-device", "usb-kbd,bus=xhci2.0,port=1.1"],
"expect": r"hub slot \d+: \d+ downstream ports powered",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# USB mass storage end to end: the boot usb-storage device (the FAT32 image,
# which has a real 0x55AA boot sector) is enough — the manager spawns
# usb-storage, which opens the device, runs the Bulk-Only / SCSI bring-up,