establishment: usb-transfer stops being a name

P1 of docs/establishment-planes-plan.md. The bus no longer binds
/protocol/usb-transfer — the bind race made whichever instance came second
unreachable, which on a real three-controller Ryzen meant a mouse no class
driver could reach ("could not open device 50"). Each instance hands its
serving endpoint up in the hello that already delegates its controller, and
class drivers receive their OWN controller's channel from helloForChannel —
routed by the manager's lineage, retried while a provider is mid-restart,
on one manager handle so retries never spend handle-table slots.

usb.open(bus, id) now takes the channel it used to look up; the name rows
leave protocol.csv with the code (bind 67, opens 119/120/122); the
conformance fixture's prose stops claiming the bus binds; and the stale
input-client import leaves the bus with the channel one.

Gate: 19 QEMU cases green (usb family, hubs, both IOMMU variants, fat chain,
boot-from-USB, orderly shutdown, conformance).
This commit is contained in:
Daniel Samson
2026-08-09 11:48:31 +01:00
parent 77fe4d220e
commit d603d40b5c
10 changed files with 84 additions and 67 deletions
+4 -2
View File
@@ -83,8 +83,10 @@ var bring_up_failed = false;
fn initialise(endpoint: ipc.Handle) bool {
_ = endpoint;
if (device_manager.hello(.device, device_id) == null) return false;
device = usb.open(device_id) orelse {
// The hello both meets the spawn deadline and brings back the channel to
// THIS device's controller — routed by lineage, never found by name.
const bus = device_manager.helloForChannel(.device, device_id) orelse return false;
device = usb.open(bus, device_id) orelse {
std.log.info("could not open device {d}", .{device_id});
return false;
};