Files
danos/library/runtime/device-manager.zig
T
Daniel Samson 7d540c4b2f reorg: normalise every protocol alias to its module name
Finish the direct-import convention: a protocol is now aliased to its module
name in snake_case in every file that imports one — consumers and the runtime
client wrappers alike. This kills the last of the alias variety (the generic
`protocol`, plus `power` and `transfer`), so `device_manager_protocol.Hello`
means the same thing everywhere and grepping a module name finds all its uses.

Pure rename (identifier uses only; prose references left untouched via a
guarded pattern). 14 files, 299/299 lines.

zig build + test green; 16 QEMU cases pass (smoke, device-manager,
driver-restart, device-list, pci-scan, usb-hid, usb-storage, display-service,
display-native, display-reattach, input, acpi-ps2, vfs, fat-mount,
power-button, orderly-shutdown).
2026-07-22 21:17:54 +01:00

60 lines
2.8 KiB
Zig

//! Client side of the device-manager protocol (docs/device-manager.md): the
//! calls a supervised driver makes *to* the manager, as opposed to
//! `device-manager-protocol.zig`, which is the wire contract both sides share.
//!
//! Today this is just the hello handshake every spawned driver owes. The
//! manager arms a hello deadline when it spawns a driver
//! (system/services/device-manager/device-manager.zig): a driver that stays
//! silent past it is assumed wedged before `main` and stopped, so every driver
//! calls `hello` early in its startup. The retry-lookup-call-check this used to
//! be — copied byte-for-byte into each bus and class driver — lives here once.
const std = @import("std");
const ipc = @import("ipc.zig");
const system = @import("system.zig");
const device_manager_protocol = @import("device-manager-protocol");
/// What kind of driver is announcing itself (a bus that reports children, or a
/// leaf device). Re-exported so callers name it without importing the protocol.
pub const Role = device_manager_protocol.Role;
/// Endpoint lookups while the manager is still registering, and the pause
/// between them: 100 x 20 ms = ~2 s, comfortably inside the manager's 3 s hello
/// deadline (device-manager.zig `hello_deadline_ms`).
const lookup_attempts: u32 = 100;
const lookup_pause_ms: u64 = 20;
/// Say hello to the device manager and return its endpoint, or null if there is
/// no manager (best-effort standalone bring-up) or it refused the handshake
/// (version mismatch, unknown sender). Bus drivers keep the returned handle to
/// report children through; a driver that runs fine unsupervised discards it
/// with `_ =`, and a driver that requires supervision bails on null.
///
/// Logs the outcome itself (attribution is the kernel's, via the process's
/// binary path), so callers stay a single line.
pub fn hello(role: Role, device_id: u64) ?ipc.Handle {
var attempts: u32 = 0;
const manager = while (attempts < lookup_attempts) : (attempts += 1) {
if (ipc.lookup(.device_manager)) |handle| break handle;
system.sleep(lookup_pause_ms);
} else {
std.log.info("no device manager to hello", .{});
return null;
};
const message = device_manager_protocol.Hello{ .role = @intFromEnum(role), .device_id = device_id };
var reply: [device_manager_protocol.reply_size]u8 = undefined;
const length = ipc.call(manager, std.mem.asBytes(&message), &reply) catch {
std.log.info("hello call failed", .{});
return null;
};
if (length < device_manager_protocol.reply_size or
std.mem.bytesToValue(device_manager_protocol.HelloReply, reply[0..device_manager_protocol.reply_size]).status != 0)
{
std.log.info("hello refused", .{});
return null;
}
std.log.info("hello acknowledged", .{});
return manager;
}