reorg: move the USB client to library/device/usb (drop runtime.usb)

The USB class-driver transfer client was library/runtime/usb.zig, re-exported
as runtime.usb — which compiled the USB client and usb-transfer-protocol into
every user binary (init, fat, the compositor…), none of which speak USB. It is
bus-family logic, not core runtime.

Move it to its domain home, library/device/usb/usb.zig (module "usb"), alongside
the usb-abi and usb-ids data modules; fix its internal imports to go through the
runtime module; and re-export usb.abi / usb.ids so a class driver reaches the
whole USB domain through one import. runtime.usb and runtime's
usb-transfer-protocol import are removed; the three class drivers
(usb-hid keyboard/mouse, usb-storage) import module "usb" directly.

zig build + test green; usb-hid, usb-storage pass.
This commit is contained in:
Daniel Samson
2026-07-22 20:46:51 +01:00
parent a7f0c1a450
commit 1d1234c963
6 changed files with 48 additions and 25 deletions
+6 -5
View File
@@ -4,7 +4,7 @@
//! keyboard interface (class 3, subclass 1, protocol 1); its assigned device id
//! arrives as argv[1] and an optional layout name ("us", "gb", ...) as argv[2].
//! It owns no hardware: it opens its device through the USB transfer protocol
//! (`runtime.usb`), asks the device for the boot protocol, subscribes to its
//! (`usb`), asks the device for the boot protocol, subscribes to its
//! interrupt-IN endpoint, and turns each 8-byte boot report into input-protocol
//! events, published to the input service — the USB analogue of ps2-bus/keyboard.
//!
@@ -16,6 +16,7 @@
const std = @import("std");
const runtime = @import("runtime");
const usb = @import("usb");
const usb_abi = @import("usb-abi");
const xkb = @import("xkeyboard-config");
const hid = @import("hid-report.zig");
@@ -73,11 +74,11 @@ pub fn main(init: runtime.process.Init) void {
// Hello the manager first (meet the spawn deadline), then open the device.
if (runtime.device_manager.hello(.device, device_id) == null) return;
var device = runtime.usb.open(device_id) orelse {
var device = usb.open(device_id) orelse {
std.log.info("could not open device {d}", .{device_id});
return;
};
const endpoint = device.findEndpoint(runtime.usb.transfer_type_interrupt, true) orelse {
const endpoint = device.findEndpoint(usb.transfer_type_interrupt, true) orelse {
_ = runtime.system.write("/system/drivers/usb-hid/keyboard: no interrupt-IN endpoint\n");
return;
};
@@ -108,9 +109,9 @@ pub fn main(init: runtime.process.Init) void {
if (signals.has(.terminate)) return;
continue;
}
if (!got.isMessage() or got.len < @sizeOf(runtime.usb.InterruptReport)) continue;
if (!got.isMessage() or got.len < @sizeOf(usb.InterruptReport)) continue;
const message = std.mem.bytesToValue(runtime.usb.InterruptReport, receive[0..@sizeOf(runtime.usb.InterruptReport)]);
const message = std.mem.bytesToValue(usb.InterruptReport, receive[0..@sizeOf(usb.InterruptReport)]);
if (message.length < @sizeOf(hid.KeyboardReport)) continue;
const report = std.mem.bytesToValue(hid.KeyboardReport, message.data[0..@sizeOf(hid.KeyboardReport)]);
const transitions = decoder.feed(report);
+6 -5
View File
@@ -3,7 +3,7 @@
//! Spawned by the device manager when the xHCI bus driver reports a HID / boot /
//! mouse interface (class 3, subclass 1, protocol 2); its assigned device id
//! arrives as argv[1]. Like the keyboard driver it owns no hardware: it opens its
//! device through the USB transfer protocol (`runtime.usb`), asks for the boot
//! device through the USB transfer protocol (`usb`), asks for the boot
//! protocol, subscribes to its interrupt-IN endpoint, and turns each 3- or 4-byte
//! boot report into input-protocol mouse events published to the input service.
//!
@@ -12,6 +12,7 @@
const std = @import("std");
const runtime = @import("runtime");
const usb = @import("usb");
const usb_abi = @import("usb-abi");
const hid = @import("hid-report.zig");
const ipc = runtime.ipc;
@@ -38,11 +39,11 @@ pub fn main(init: runtime.process.Init) void {
};
if (runtime.device_manager.hello(.device, device_id) == null) return;
var device = runtime.usb.open(device_id) orelse {
var device = usb.open(device_id) orelse {
std.log.info("could not open device {d}", .{device_id});
return;
};
const endpoint = device.findEndpoint(runtime.usb.transfer_type_interrupt, true) orelse {
const endpoint = device.findEndpoint(usb.transfer_type_interrupt, true) orelse {
_ = runtime.system.write("/system/drivers/usb-hid/mouse: no interrupt-IN endpoint\n");
return;
};
@@ -70,9 +71,9 @@ pub fn main(init: runtime.process.Init) void {
if (signals.has(.terminate)) return;
continue;
}
if (!got.isMessage() or got.len < @sizeOf(runtime.usb.InterruptReport)) continue;
if (!got.isMessage() or got.len < @sizeOf(usb.InterruptReport)) continue;
const message = std.mem.bytesToValue(runtime.usb.InterruptReport, receive[0..@sizeOf(runtime.usb.InterruptReport)]);
const message = std.mem.bytesToValue(usb.InterruptReport, receive[0..@sizeOf(usb.InterruptReport)]);
const length = @min(message.length, message.data.len);
const report = hid.parseMouse(message.data[0..length]) orelse continue;
const mask = buttonMask(report.buttons);