From 18408b0666e5f886dbb859f04ec2e70e696dd6f7 Mon Sep 17 00:00:00 2001 From: Daniel Samson <12231216+daniel-samson@users.noreply.github.com> Date: Tue, 21 Jul 2026 22:50:11 +0100 Subject: [PATCH] usb: [diagnostic] dump all root-port PORTSC + log port-change events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Branch-only debugging for the real SuperSpeed compound hub: the spin fix (27f87cb) stopped the hang — the SS hub's 4 SuperSpeed ports now enumerate (all empty, correct: the full-speed keyboard isn't a SuperSpeed device) — but the USB2 COMPANION hub, where the keyboard actually lives, never appears. Only root ports 19 (SS hub) and 21 (SS storage) connect. Dump every root port's raw PORTSC at scan (connect/enable/link-state/ speed) and log every root port-change event, so the next boot shows whether the companion is connected on a USB2 port we misread, connects late as a port-change event, or is simply absent. Diagnostic logging — to be removed once the companion path works. --- system/drivers/usb-xhci-bus/usb-xhci-bus.zig | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/system/drivers/usb-xhci-bus/usb-xhci-bus.zig b/system/drivers/usb-xhci-bus/usb-xhci-bus.zig index 339e646..5a24e70 100644 --- a/system/drivers/usb-xhci-bus/usb-xhci-bus.zig +++ b/system/drivers/usb-xhci-bus/usb-xhci-bus.zig @@ -196,6 +196,18 @@ fn scanPorts(manager: runtime.ipc.Handle) void { }; std.log.info("{d} root-hub ports", .{engine.max_ports}); + // Diagnostic: dump every root port's raw PORTSC (CCS = connect, PED = + // enabled, PLS = link state, speed) so a USB2 companion hub that isn't + // enumerating is visible — is it connected on a port we misread, or absent? + { + var p: u32 = 1; + while (p <= engine.max_ports) : (p += 1) { + const portsc = engine.portStatus(p); + if (portsc & 1 != 0 or (portsc >> 5) & 0xF != 5) // connected, or not in the disabled/disconnected link state + std.log.info("PORTSC[{d}] = 0x{x:0>8} ccs={d} ped={d} pls={d} speed={d}", .{ p, portsc, portsc & 1, (portsc >> 1) & 1, (portsc >> 5) & 0xF, (portsc >> 10) & 0xF }); + } + } + var port: u32 = 1; var connected: u32 = 0; while (port <= engine.max_ports) : (port += 1) { @@ -493,7 +505,9 @@ fn onNotification(badge: u64) void { engine.pump(); while (engine.takePortChange()) |port| { const manager = manager_handle orelse break; - if (engine.portConnected(port)) { + const connected = engine.portConnected(port); + std.log.info("root port {d} change: {s} (PORTSC 0x{x:0>8})", .{ port, if (connected) "connected" else "empty", engine.portStatus(port) }); + if (connected) { if (engine.deviceOnPort(port) == null) bringUpPort(manager, engine, port); } else { tearDownPort(manager, engine, port);