reorg: move device-manager-protocol to library/protocol + direct import
device-manager-protocol -> library/protocol/device-manager/. Its consumers (pci-bus, usb-xhci-bus, the acpi discovery service, device-manager, device-list, crash-test, and the not-yet-built intel-integrated display sub-driver) import the module directly instead of through runtime.device_manager_protocol, which is deleted. runtime.device_manager (the hello client) already imported the module by name and is unchanged. zig build + test green; device-manager, driver-restart, device-list, pci-scan pass.
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
//! The device-manager protocol (docs/device-manager.md): what drivers and
|
||||
//! applications say to the device manager over its well-known endpoint. The
|
||||
//! vfs-protocol pattern — extern-struct messages, a version in the handshake,
|
||||
//! reserved fields — so both sides depend on the contract by name. Deliberately
|
||||
//! contains nothing lifecycle-shaped: stopping, liveness (the zero-length ping),
|
||||
//! and exit reasons are the universal vocabulary of
|
||||
//! docs/process-lifecycle.md, not this protocol.
|
||||
|
||||
/// The protocol version a driver states in its hello. A manager that cannot
|
||||
/// serve a driver's version refuses the hello, and the mismatch is loud at
|
||||
/// startup instead of quiet corruption later.
|
||||
pub const version: u16 = 1;
|
||||
|
||||
/// What kind of driver is talking (docs/driver-model.md's shapes).
|
||||
pub const Role = enum(u8) {
|
||||
/// Owns a controller and reports the devices behind it (`child_added`).
|
||||
bus = 1,
|
||||
/// Serves one device, reached through a bus's transfer protocol.
|
||||
device = 2,
|
||||
};
|
||||
|
||||
/// The message kinds.
|
||||
pub const Operation = enum(u8) {
|
||||
hello = 1,
|
||||
child_added = 2,
|
||||
child_removed = 3,
|
||||
enumerate = 4,
|
||||
subscribe = 5,
|
||||
};
|
||||
|
||||
/// `Hello.device_id` for a driver that serves no enumerated device (a test
|
||||
/// fixture, a synthetic source).
|
||||
pub const no_device: u64 = ~@as(u64, 0);
|
||||
|
||||
/// The handshake, sent once by every driver the manager spawns — the manager's
|
||||
/// one self-enforced deadline: spawned and silent past it means wrong binary,
|
||||
/// wrong version, or wedged before main, and the stop sequence follows.
|
||||
pub const Hello = extern struct {
|
||||
operation: u8 = @intFromEnum(Operation.hello),
|
||||
/// A Role value.
|
||||
role: u8,
|
||||
/// The protocol version this driver was built against (`version`).
|
||||
version: u16 = version,
|
||||
reserved: u32 = 0,
|
||||
/// The device this driver was assigned (its argv[1]), or `no_device`.
|
||||
device_id: u64,
|
||||
};
|
||||
|
||||
pub const hello_size = @sizeOf(Hello);
|
||||
|
||||
/// The manager's answer to a hello. Nonzero status = refused (version mismatch,
|
||||
/// unknown sender); a refused driver should exit cleanly.
|
||||
pub const HelloReply = extern struct {
|
||||
status: i32,
|
||||
reserved: u32 = 0,
|
||||
};
|
||||
|
||||
pub const reply_size = @sizeOf(HelloReply);
|
||||
|
||||
/// A bus driver reporting one device it discovered behind its controller
|
||||
/// (docs/device-manager.md "the tree"). Identity is the bus's native language —
|
||||
/// for USB a port-speed class; the (class, subclass, protocol) triple joins it
|
||||
/// once control transfers exist (the USB track). The manager mirrors the child
|
||||
/// into its tree; when the reporting driver dies, the manager prunes everything
|
||||
/// it reported (the children describe protocol state that died with it) and the
|
||||
/// restarted instance rediscovers and re-reports.
|
||||
pub const ChildAdded = extern struct {
|
||||
operation: u8 = @intFromEnum(Operation.child_added),
|
||||
reserved0: u8 = 0,
|
||||
reserved1: u16 = 0,
|
||||
reserved2: u32 = 0,
|
||||
/// The reporting driver's own device (the controller) — the child's parent.
|
||||
parent: u64,
|
||||
/// Where on the bus (for USB: the root port number, 1-based).
|
||||
bus_address: u64,
|
||||
/// Bus-specific identity (for USB: the PORTSC port-speed class; for PCI:
|
||||
/// the class triple; for ACPI devices, 0 — identity is the hid below).
|
||||
identity: u64,
|
||||
/// The kernel device id this child was `device_register`ed as — what the
|
||||
/// manager hands a matched driver as its argv assignment — or `no_device`
|
||||
/// for an unregistered leaf (a USB port before the descriptor track).
|
||||
device_id: u64 = no_device,
|
||||
/// The ACPI hardware id (`_HID`), EISA-decoded (e.g. "PNP0303"), for devices
|
||||
/// discovered by firmware string rather than a numeric bus identity. Empty
|
||||
/// (all zero) otherwise. Widens for FDT `compatible` strings later.
|
||||
hid: [8]u8 = .{0} ** 8,
|
||||
};
|
||||
|
||||
pub const child_added_size = @sizeOf(ChildAdded);
|
||||
|
||||
/// A bus driver reporting a device gone (hot-unplug). Not yet sent by any
|
||||
/// driver — the port scan has no unplug interrupt — but the manager handles it;
|
||||
/// death-pruning covers removal until hotplug lands.
|
||||
pub const ChildRemoved = extern struct {
|
||||
operation: u8 = @intFromEnum(Operation.child_removed),
|
||||
reserved0: u8 = 0,
|
||||
reserved1: u16 = 0,
|
||||
reserved2: u32 = 0,
|
||||
parent: u64,
|
||||
bus_address: u64,
|
||||
};
|
||||
|
||||
pub const child_removed_size = @sizeOf(ChildRemoved);
|
||||
|
||||
/// The manager's answer to a tree report.
|
||||
pub const ReportReply = extern struct {
|
||||
status: i32,
|
||||
reserved: u32 = 0,
|
||||
};
|
||||
|
||||
/// An application asking for the tree (M18.3): the reply is an EnumerateReply
|
||||
/// header followed by `count` ChildEntry records.
|
||||
pub const Enumerate = extern struct {
|
||||
operation: u8 = @intFromEnum(Operation.enumerate),
|
||||
reserved0: u8 = 0,
|
||||
reserved1: u16 = 0,
|
||||
reserved2: u32 = 0,
|
||||
};
|
||||
|
||||
pub const EnumerateReply = extern struct {
|
||||
status: i32,
|
||||
/// ChildEntry records following this header.
|
||||
count: u32,
|
||||
};
|
||||
|
||||
pub const ChildEntry = extern struct {
|
||||
parent: u64,
|
||||
bus_address: u64,
|
||||
identity: u64,
|
||||
};
|
||||
|
||||
/// An application subscribing to published add/remove events (the input-service
|
||||
/// pattern): the subscriber's endpoint rides as the call's **capability**, and
|
||||
/// events arrive on it as buffered messages whose payload is the same
|
||||
/// ChildAdded / ChildRemoved struct the bus drivers send — one encoding, both
|
||||
/// directions.
|
||||
pub const Subscribe = extern struct {
|
||||
operation: u8 = @intFromEnum(Operation.subscribe),
|
||||
reserved0: u8 = 0,
|
||||
reserved1: u16 = 0,
|
||||
reserved2: u32 = 0,
|
||||
};
|
||||
|
||||
/// Upper bound on any message in this protocol — sizes the endpoint buffers.
|
||||
/// Capped by the kernel's IPC MESSAGE_MAXIMUM (256): an EnumerateReply carries
|
||||
/// up to ten ChildEntry records per call, plenty for the mirror's current
|
||||
/// bounds; paging joins the protocol if a tree ever outgrows one message.
|
||||
pub const message_maximum = 256;
|
||||
Reference in New Issue
Block a user