usb: readable PORTSC decode, link-state names, and device string descriptors

Make the USB diagnostic logs scannable by eye:
- usb-ids gains speedName + linkStateName (USB3 PORTSC link states: U0,
  RxDetect, Polling, ...), host-tested with usb-ids.
- The PORTSC dump decodes the register instead of printing hex flags:
    PORTSC[3] 0x00021203: connected, enabled, link=U0, power=on, SuperSpeed
    PORTSC[5] 0x00020ee1: connected, disabled, link=Polling, power=on, High-speed
  (the raw word stays for reference). A USB2 device reads connected+
  disabled+Polling until reset — so the user's next log shows at a glance
  whether the companion port ever reaches that state.
- The library reads STRING descriptors (readString, UTF-16LE -> ASCII,
  English langid), and the device line now names the maker + product:
    port 5 device: Hub "Genesys Logic USB3.0 Hub" (0x05e3:0x0626), 1 interface(s)
  instead of a bare vendor/product id pair.

Full USB case set green (hub regexes follow the new 'device: <class>
"<maker> <product>"' format). Branch diagnostics for the SuperSpeed
compound-hub investigation.
This commit is contained in:
Daniel Samson
2026-07-21 23:19:18 +01:00
parent 4ea4a040d2
commit ab732dc455
4 changed files with 85 additions and 6 deletions
+14 -2
View File
@@ -230,9 +230,15 @@ fn bringUpPort(manager: runtime.ipc.Handle, engine: *library.Controller, port: u
std.log.info("port {d} enumeration failed", .{port});
return;
}
std.log.info("port {d} device: {s} vendor 0x{x:0>4} product 0x{x:0>4}, {d} interface(s)", .{
var maker_buffer: [64]u8 = undefined;
var product_buffer: [64]u8 = undefined;
const maker = engine.readString(usb_device, @intFromEnum(usb_device.device_descriptor.manufacturer_index), &maker_buffer) orelse "?";
const product = engine.readString(usb_device, @intFromEnum(usb_device.device_descriptor.product_index), &product_buffer) orelse "?";
std.log.info("port {d} device: {s} \"{s} {s}\" (0x{x:0>4}:0x{x:0>4}), {d} interface(s)", .{
port,
usb_ids.className(usb_device.device_descriptor.device_class),
maker,
product,
usb_device.device_descriptor.vendor_id,
usb_device.device_descriptor.product_id,
usb_device.interface_count,
@@ -280,9 +286,15 @@ fn bringUpBehindHub(manager: runtime.ipc.Handle, engine: *library.Controller, hu
std.log.info("hub slot {d} port {d}: enumeration failed", .{ hub.slot_id, port });
return;
}
std.log.info("hub slot {d} port {d} device: {s} vendor 0x{x:0>4} product 0x{x:0>4}, {d} interface(s)", .{
var maker_buffer: [64]u8 = undefined;
var product_buffer: [64]u8 = undefined;
const maker = engine.readString(usb_device, @intFromEnum(usb_device.device_descriptor.manufacturer_index), &maker_buffer) orelse "?";
const product = engine.readString(usb_device, @intFromEnum(usb_device.device_descriptor.product_index), &product_buffer) orelse "?";
std.log.info("hub slot {d} port {d} device: {s} \"{s} {s}\" (0x{x:0>4}:0x{x:0>4}), {d} interface(s)", .{
hub.slot_id, port,
usb_ids.className(usb_device.device_descriptor.device_class),
maker,
product,
usb_device.device_descriptor.vendor_id,
usb_device.device_descriptor.product_id,
usb_device.interface_count,