usb: a hub yanked from a root port takes its subtree with it (H2)
The hot-plug matrix's predicted bug, found on first contact: tearDownPort never recursed into a departing hub's children — only tearDownHubDevice (a hub leaving one level down) did. Yank a populated hub from a root port and the downstream slots stayed live against vanished hardware, their class drivers were never reaped, and the replugged hub found its port still occupied, so nothing ever re-enumerated: the subtree was gone for the boot. tearDownPort now recurses children-first, exactly like tearDownHubDevice. The usb-hub-yank case is the discrimination: one device_del removes a hub carrying a keyboard AND a mouse, both drivers must be reaped, and the re-added hub must rebind both — it failed against the unfixed bus and passes with the recursion.
This commit is contained in:
@@ -1009,6 +1009,34 @@ CASES = [
|
||||
r"[\s\S]*device-manager: delegated device \d+ to /system/drivers/usb-hid-keyboard"
|
||||
r"[\s\S]*usb-hid-keyboard: ok)",
|
||||
"fail": r"DANOS-TEST-RESULT: FAIL"},
|
||||
# Hot-plug matrix H2 (docs/hot-plug-matrix-plan.md): yank a POPULATED hub.
|
||||
# One device_del removes the hub with a keyboard and a mouse behind it — the
|
||||
# bus's recursive teardown (tearDownHubDevice, children first) must report
|
||||
# every downstream interface removed, the manager must reap BOTH bound
|
||||
# drivers, and re-adding the hub and both devices must rebuild the subtree.
|
||||
# The reaping lines only exist post-yank, so `reaping X ... X: ok` chains
|
||||
# are unambiguously second-generation.
|
||||
{"name": "usb-hub-yank",
|
||||
"build_case": "usb-hid",
|
||||
"smp": 4,
|
||||
"timeout": 150,
|
||||
"qemu_extra": ["-device", "qemu-xhci,id=xhci2",
|
||||
"-device", "usb-hub,bus=xhci2.0,port=1,id=yhub",
|
||||
"-device", "usb-kbd,bus=xhci2.0,port=1.1,id=ykbd",
|
||||
"-device", "usb-mouse,bus=xhci2.0,port=1.2,id=ymouse"],
|
||||
"qmp_sequence": [
|
||||
{"delay": 8, "command": "device_del", "arguments": {"id": "yhub"}},
|
||||
{"delay": 14, "command": "device_add",
|
||||
"arguments": {"driver": "usb-hub", "bus": "xhci2.0", "port": "1", "id": "yhub2"}},
|
||||
{"delay": 17, "command": "device_add",
|
||||
"arguments": {"driver": "usb-kbd", "bus": "xhci2.0", "port": "1.1", "id": "ykbd2"}},
|
||||
{"delay": 18, "command": "device_add",
|
||||
"arguments": {"driver": "usb-mouse", "bus": "xhci2.0", "port": "1.2", "id": "ymouse2"}},
|
||||
],
|
||||
"expect": r"(?s)(?=.*hub device slot \d+ disconnected)"
|
||||
r"(?=.*device-manager: reaping \S*usb-hid-keyboard[\s\S]*usb-hid-keyboard: ok)"
|
||||
r"(?=.*device-manager: reaping \S*usb-hid-mouse[\s\S]*usb-hid-mouse: ok)",
|
||||
"fail": r"DANOS-TEST-RESULT: FAIL"},
|
||||
# The kernel VFS root (M-F): the mount table serves the initrd at /system —
|
||||
# path resolution, node status/read (an ELF magic), and directory listing,
|
||||
# asserted kernel-side.
|
||||
|
||||
Reference in New Issue
Block a user