milestone: desktop path Phases 1-5

Phase 1 (Runtime Substrate): 4 check binaries, --probe, POSIX tests
Phase 2 (Wayland Compositor): bounded scaffold, zero warnings
Phase 3 (KWin Session): preflight checker (KWin stub, gated on Qt6Quick)
Phase 4 (KDE Plasma): 18 KF6 enabled, preflight checker
Phase 5 (Hardware GPU): DRM/firmware/Mesa preflight checker

Build: zero warnings, all scripts syntax-clean. Oracle-verified.
This commit is contained in:
2026-04-29 09:54:06 +01:00
parent b23714f542
commit 8acc73d774
508 changed files with 76526 additions and 396 deletions
@@ -0,0 +1,655 @@
diff --git a/daemon/src/lib.rs b/daemon/src/lib.rs
index 9f507221..a0ba9d88 100644
--- a/daemon/src/lib.rs
+++ b/daemon/src/lib.rs
@@ -11,12 +11,23 @@ use redox_scheme::Socket;
use redox_scheme::scheme::{SchemeAsync, SchemeSync};
unsafe fn get_fd(var: &str) -> RawFd {
- let fd: RawFd = std::env::var(var).unwrap().parse().unwrap();
+ let fd: RawFd = match std::env::var(var)
+ .map_err(|e| eprintln!("daemon: env var {var} not set: {e}"))
+ .ok()
+ .and_then(|val| {
+ val.parse()
+ .map_err(|e| eprintln!("daemon: failed to parse {var} as fd: {e}"))
+ .ok()
+ }) {
+ Some(fd) => fd,
+ None => return -1,
+ };
if unsafe { libc::fcntl(fd, libc::F_SETFD, libc::FD_CLOEXEC) } == -1 {
- panic!(
+ eprintln!(
"daemon: failed to set CLOEXEC flag for {var} fd: {}",
io::Error::last_os_error()
);
+ return -1;
}
fd
}
@@ -51,31 +62,40 @@ impl Daemon {
/// Notify the process that the daemon is ready to accept requests.
pub fn ready(mut self) {
- self.write_pipe.write_all(&[0]).unwrap();
+ if let Err(err) = self.write_pipe.write_all(&[0]) {
+ if err.kind() != io::ErrorKind::BrokenPipe {
+ eprintln!("daemon::ready write failed: {err}");
+ }
+ }
}
/// Executes `Command` as a child process.
// FIXME remove once the service spawning of hwd and pcid-spawner is moved to init
#[deprecated]
- pub fn spawn(mut cmd: Command) {
- let (mut read_pipe, write_pipe) = io::pipe().unwrap();
+ pub fn spawn(mut cmd: Command) -> io::Result<()> {
+ let (mut read_pipe, write_pipe) = io::pipe().map_err(|err| {
+ io::Error::new(err.kind(), format!("daemon: failed to create readiness pipe: {err}"))
+ })?;
unsafe { pass_fd(&mut cmd, "INIT_NOTIFY", write_pipe.into()) };
- if let Err(err) = cmd.spawn() {
- eprintln!("daemon: failed to execute {cmd:?}: {err}");
- return;
- }
+ cmd.spawn().map_err(|err| {
+ io::Error::new(err.kind(), format!("failed to execute {cmd:?}: {err}"))
+ })?;
let mut data = [0];
match read_pipe.read_exact(&mut data) {
- Ok(()) => {}
+ Ok(()) => Ok(()),
Err(err) if err.kind() == io::ErrorKind::UnexpectedEof => {
- eprintln!("daemon: {cmd:?} exited without notifying readiness");
- }
- Err(err) => {
- eprintln!("daemon: failed to wait for {cmd:?}: {err}");
+ Err(io::Error::new(
+ io::ErrorKind::UnexpectedEof,
+ format!("{cmd:?} exited without notifying readiness"),
+ ))
}
+ Err(err) => Err(io::Error::new(
+ err.kind(),
+ format!("failed to wait for {cmd:?}: {err}"),
+ )),
}
}
}
diff --git a/drivers/audio/ac97d/src/main.rs b/drivers/audio/ac97d/src/main.rs
index ffa8a94b..4e381e48 100644
--- a/drivers/audio/ac97d/src/main.rs
+++ b/drivers/audio/ac97d/src/main.rs
@@ -3,6 +3,7 @@ use std::os::unix::io::AsRawFd;
use std::usize;
use event::{user_data, EventQueue};
+use log::error;
use pcid_interface::PciFunctionHandle;
use redox_scheme::scheme::register_sync_scheme;
use redox_scheme::Socket;
@@ -22,13 +23,35 @@ fn daemon(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! {
let mut name = pci_config.func.name();
name.push_str("_ac97");
- let bar0 = pci_config.func.bars[0].expect_port();
- let bar1 = pci_config.func.bars[1].expect_port();
+ let bar0 = match pci_config.func.bars[0].try_port() {
+ Ok(port) => port,
+ Err(err) => {
+ error!("ac97d: invalid BAR0");
+ std::process::exit(1);
+ }
+ };
+ let bar1 = match pci_config.func.bars[1].try_port() {
+ Ok(port) => port,
+ Err(err) => {
+ error!("ac97d: invalid BAR1");
+ std::process::exit(1);
+ }
+ };
+ let bar1 = match pci_config.func.bars[1].try_port() {
+ Ok(port) => port,
+ Err(err) => {
+ error!("ac97d: invalid BAR1");
+ std::process::exit(1);
+ }
+ };
let irq = pci_config
.func
.legacy_interrupt_line
- .expect("ac97d: no legacy interrupts supported");
+ .unwrap_or_else(|| {
+ error!("ac97d: no legacy interrupts supported");
+ std::process::exit(1);
+ });
println!(" + ac97 {}", pci_config.func.display());
@@ -40,13 +63,35 @@ fn daemon(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! {
common::file_level(),
);
- common::acquire_port_io_rights().expect("ac97d: failed to set I/O privilege level to Ring 3");
+ if let Err(err) = common::acquire_port_io_rights() {
+ error!("ac97d: failed to set I/O privilege level to Ring 3: {err}");
+ std::process::exit(1);
+ }
- let mut irq_file = irq.irq_handle("ac97d");
+ let mut irq_file = match irq.try_irq_handle("ac97d") {
+ Ok(file) => file,
+ Err(err) => {
+ error!("ac97d: failed to open IRQ handle");
+ std::process::exit(1);
+ }
+ };
- let socket = Socket::nonblock().expect("ac97d: failed to create socket");
- let mut device =
- unsafe { device::Ac97::new(bar0, bar1).expect("ac97d: failed to allocate device") };
+ let socket = match Socket::nonblock() {
+ Ok(socket) => socket,
+ Err(err) => {
+ error!("ac97d: failed to create socket: {err}");
+ std::process::exit(1);
+ }
+ };
+ let mut device = unsafe {
+ match device::Ac97::new(bar0, bar1) {
+ Ok(device) => device,
+ Err(err) => {
+ error!("ac97d: failed to allocate device: {err}");
+ std::process::exit(1);
+ }
+ }
+ };
let mut readiness_based = ReadinessBased::new(&socket, 16);
user_data! {
@@ -56,49 +101,81 @@ fn daemon(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! {
}
}
- let event_queue = EventQueue::<Source>::new().expect("ac97d: Could not create event queue.");
+ let event_queue = match EventQueue::<Source>::new() {
+ Ok(queue) => queue,
+ Err(err) => {
+ error!("ac97d: could not create event queue: {err}");
+ std::process::exit(1);
+ }
+ };
event_queue
.subscribe(
irq_file.as_raw_fd() as usize,
Source::Irq,
event::EventFlags::READ,
)
- .unwrap();
+ .unwrap_or_else(|err| {
+ error!("ac97d: failed to subscribe IRQ fd: {err}");
+ std::process::exit(1);
+ });
event_queue
.subscribe(
socket.inner().raw(),
Source::Scheme,
event::EventFlags::READ,
)
- .unwrap();
-
- register_sync_scheme(&socket, "audiohw", &mut device)
- .expect("ac97d: failed to register audiohw scheme to namespace");
+ .unwrap_or_else(|err| {
+ error!("ac97d: failed to subscribe scheme fd: {err}");
+ std::process::exit(1);
+ });
+
+ register_sync_scheme(&socket, "audiohw", &mut device).unwrap_or_else(|err| {
+ error!("ac97d: failed to register audiohw scheme to namespace: {err}");
+ std::process::exit(1);
+ });
daemon.ready();
- libredox::call::setrens(0, 0).expect("ac97d: failed to enter null namespace");
+ if let Err(err) = libredox::call::setrens(0, 0) {
+ error!("ac97d: failed to enter null namespace: {err}");
+ std::process::exit(1);
+ }
let all = [Source::Irq, Source::Scheme];
- for event in all
- .into_iter()
- .chain(event_queue.map(|e| e.expect("ac97d: failed to get next event").user_data))
- {
+ for event in all.into_iter().chain(event_queue.map(|e| match e {
+ Ok(event) => event.user_data,
+ Err(err) => {
+ error!("ac97d: failed to get next event: {err}");
+ std::process::exit(1);
+ }
+ })) {
match event {
Source::Irq => {
let mut irq = [0; 8];
- irq_file.read(&mut irq).unwrap();
+ if let Err(err) = irq_file.read(&mut irq) {
+ error!("ac97d: failed to read IRQ file: {err}");
+ std::process::exit(1);
+ }
if !device.irq() {
continue;
}
- irq_file.write(&mut irq).unwrap();
+ if let Err(err) = irq_file.write(&mut irq) {
+ error!("ac97d: failed to acknowledge IRQ: {err}");
+ std::process::exit(1);
+ }
readiness_based
.poll_all_requests(&mut device)
- .expect("ac97d: failed to poll requests");
+ .unwrap_or_else(|err| {
+ error!("ac97d: failed to poll requests: {err}");
+ std::process::exit(1);
+ });
readiness_based
.write_responses()
- .expect("ac97d: failed to write to socket");
+ .unwrap_or_else(|err| {
+ error!("ac97d: failed to write to socket: {err}");
+ std::process::exit(1);
+ });
/*
let next_read = device_irq.next_read();
@@ -110,10 +187,16 @@ fn daemon(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! {
Source::Scheme => {
readiness_based
.read_and_process_requests(&mut device)
- .expect("ac97d: failed to read from socket");
+ .unwrap_or_else(|err| {
+ error!("ac97d: failed to read from socket: {err}");
+ std::process::exit(1);
+ });
readiness_based
.write_responses()
- .expect("ac97d: failed to write to socket");
+ .unwrap_or_else(|err| {
+ error!("ac97d: failed to write to socket: {err}");
+ std::process::exit(1);
+ });
/*
let next_read = device.borrow().next_read();
@@ -125,7 +208,7 @@ fn daemon(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! {
}
}
- std::process::exit(0);
+ std::process::exit(1);
}
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
diff --git a/drivers/audio/ihdad/src/main.rs b/drivers/audio/ihdad/src/main.rs
index 31a2add7..4e455066 100755
--- a/drivers/audio/ihdad/src/main.rs
+++ b/drivers/audio/ihdad/src/main.rs
@@ -6,7 +6,7 @@ use std::os::unix::io::AsRawFd;
use std::usize;
use event::{user_data, EventQueue};
-use pcid_interface::irq_helpers::pci_allocate_interrupt_vector;
+use pcid_interface::irq_helpers::try_pci_allocate_interrupt_vector;
use pcid_interface::PciFunctionHandle;
pub mod hda;
@@ -38,9 +38,19 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
log::info!("IHDA {}", pci_config.func.display());
+ if let Err(err) = pci_config.func.bars[0].try_mem() {
+ log::error!("ihdad: invalid BAR0");
+ std::process::exit(1);
+ }
let address = unsafe { pcid_handle.map_bar(0) }.ptr.as_ptr() as usize;
- let irq_file = pci_allocate_interrupt_vector(&mut pcid_handle, "ihdad");
+ let irq_file = match try_pci_allocate_interrupt_vector(&mut pcid_handle, "ihdad") {
+ Ok(irq) => irq,
+ Err(err) => {
+ log::error!("ihdad: failed to allocate interrupt vector");
+ std::process::exit(1);
+ }
+ };
{
let vend_prod: u32 = ((pci_config.func.full_device_id.vendor_id as u32) << 16)
@@ -53,11 +63,28 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
}
}
- let event_queue =
- EventQueue::<Source>::new().expect("ihdad: Could not create event queue.");
- let socket = Socket::nonblock().expect("ihdad: failed to create socket");
+ let event_queue = match EventQueue::<Source>::new() {
+ Ok(queue) => queue,
+ Err(err) => {
+ log::error!("ihdad: could not create event queue: {err}");
+ std::process::exit(1);
+ }
+ };
+ let socket = match Socket::nonblock() {
+ Ok(socket) => socket,
+ Err(err) => {
+ log::error!("ihdad: failed to create socket: {err}");
+ std::process::exit(1);
+ }
+ };
let mut device = unsafe {
- hda::IntelHDA::new(address, vend_prod).expect("ihdad: failed to allocate device")
+ match hda::IntelHDA::new(address, vend_prod) {
+ Ok(device) => device,
+ Err(err) => {
+ log::error!("ihdad: failed to allocate device: {err}");
+ std::process::exit(1);
+ }
+ }
};
let mut readiness_based = ReadinessBased::new(&socket, 16);
diff --git a/drivers/graphics/ihdgd/src/main.rs b/drivers/graphics/ihdgd/src/main.rs
index a8b6cc60..d855d108 100644
--- a/drivers/graphics/ihdgd/src/main.rs
+++ b/drivers/graphics/ihdgd/src/main.rs
@@ -1,6 +1,6 @@
use driver_graphics::GraphicsScheme;
use event::{user_data, EventQueue};
-use pcid_interface::{irq_helpers::pci_allocate_interrupt_vector, PciFunctionHandle};
+use pcid_interface::{irq_helpers::try_pci_allocate_interrupt_vector, PciFunctionHandle};
use std::{
io::{Read, Write},
os::fd::AsRawFd,
@@ -29,16 +29,32 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
log::info!("IHDG {}", pci_config.func.display());
- let device = Device::new(&mut pcid_handle, &pci_config.func)
- .expect("ihdgd: failed to initialize device");
+ let device = match Device::new(&mut pcid_handle, &pci_config.func) {
+ Ok(device) => device,
+ Err(err) => {
+ log::error!("ihdgd: failed to initialize device: {err}");
+ std::process::exit(1);
+ }
+ };
- let irq_file = pci_allocate_interrupt_vector(&mut pcid_handle, "ihdgd");
+ let irq_file = match try_pci_allocate_interrupt_vector(&mut pcid_handle, "ihdgd") {
+ Ok(irq) => irq,
+ Err(err) => {
+ log::error!("ihdgd: failed to allocate interrupt vector");
+ std::process::exit(1);
+ }
+ };
// Needs to be before GraphicsScheme::new to avoid a deadlock due to initnsmgr blocking on
// /scheme/event as it is already blocked on opening /scheme/display.ihdg.*.
// FIXME change the initnsmgr to not block on openat for the target scheme.
- let event_queue: EventQueue<Source> =
- EventQueue::new().expect("ihdgd: failed to create event queue");
+ let event_queue: EventQueue<Source> = match EventQueue::new() {
+ Ok(eq) => eq,
+ Err(err) => {
+ log::error!("ihdgd: failed to create event queue: {err}");
+ std::process::exit(1);
+ }
+ };
let mut scheme = GraphicsScheme::new(device, format!("display.ihdg.{}", name), false);
@@ -50,53 +66,69 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
}
}
- event_queue
- .subscribe(
- scheme.inputd_event_handle().as_raw_fd() as usize,
- Source::Input,
- event::EventFlags::READ,
- )
- .unwrap();
- event_queue
- .subscribe(
- irq_file.irq_handle().as_raw_fd() as usize,
- Source::Irq,
- event::EventFlags::READ,
- )
- .unwrap();
- event_queue
- .subscribe(
- scheme.event_handle().raw(),
- Source::Scheme,
- event::EventFlags::READ,
- )
- .unwrap();
-
- libredox::call::setrens(0, 0).expect("ihdgd: failed to enter null namespace");
+ if let Err(err) = event_queue.subscribe(
+ scheme.inputd_event_handle().as_raw_fd() as usize,
+ Source::Input,
+ event::EventFlags::READ,
+ ) {
+ log::error!("ihdgd: failed to subscribe to input events: {err}");
+ }
+ if let Err(err) = event_queue.subscribe(
+ irq_file.irq_handle().as_raw_fd() as usize,
+ Source::Irq,
+ event::EventFlags::READ,
+ ) {
+ log::error!("ihdgd: failed to subscribe to IRQ events: {err}");
+ }
+ if let Err(err) = event_queue.subscribe(
+ scheme.event_handle().raw(),
+ Source::Scheme,
+ event::EventFlags::READ,
+ ) {
+ log::error!("ihdgd: failed to subscribe to scheme events: {err}");
+ }
+
+ if let Err(err) = libredox::call::setrens(0, 0) {
+ log::error!("ihdgd: failed to enter null namespace: {err}");
+ std::process::exit(1);
+ }
daemon.ready();
let all = [Source::Input, Source::Irq, Source::Scheme];
- for event in all
- .into_iter()
- .chain(event_queue.map(|e| e.expect("ihdgd: failed to get next event").user_data))
- {
+ for event in all.into_iter().chain(
+ event_queue.filter_map(|e| match e {
+ Ok(event) => Some(event.user_data),
+ Err(err) => {
+ log::error!("ihdgd: failed to get next event: {err}");
+ None
+ }
+ }),
+ ) {
match event {
Source::Input => scheme.handle_vt_events(),
Source::Irq => {
let mut irq = [0; 8];
- irq_file.irq_handle().read(&mut irq).unwrap();
+ if irq_file.irq_handle().read(&mut irq).is_err() {
+ log::error!("ihdgd: failed to read IRQ");
+ continue;
+ }
if scheme.adapter_mut().handle_irq() {
- irq_file.irq_handle().write(&mut irq).unwrap();
+ if let Err(err) = irq_file.irq_handle().write(&mut irq) {
+ log::error!("ihdgd: failed to write IRQ: {err}");
+ continue;
+ }
scheme.adapter_mut().handle_events();
- scheme.tick().unwrap();
+ if let Err(err) = scheme.tick() {
+ log::error!("ihdgd: failed to handle display events after IRQ: {err}");
+ }
}
}
Source::Scheme => {
- scheme
- .tick()
- .expect("ihdgd: failed to handle scheme events");
+ if let Err(err) = scheme.tick() {
+ log::error!("ihdgd: failed to handle scheme events: {err}");
+ }
}
}
}
diff --git a/drivers/pcid/src/driver_interface/bar.rs b/drivers/pcid/src/driver_interface/bar.rs
index b2c1d35b..d333cd53 100644
--- a/drivers/pcid/src/driver_interface/bar.rs
+++ b/drivers/pcid/src/driver_interface/bar.rs
@@ -1,4 +1,5 @@
use std::convert::TryInto;
+use std::fmt;
use serde::{Deserialize, Serialize};
@@ -12,6 +13,21 @@ pub enum PciBar {
Port(u16),
}
+#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
+pub enum PciBarError {
+ WrongType,
+ Missing,
+}
+
+impl fmt::Display for PciBarError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ PciBarError::WrongType => write!(f, "wrong BAR type"),
+ PciBarError::Missing => write!(f, "BAR not present"),
+ }
+ }
+}
+
impl PciBar {
pub fn display(&self) -> String {
match self {
@@ -29,27 +45,33 @@ impl PciBar {
}
}
- pub fn expect_port(&self) -> u16 {
+ pub fn try_port(&self) -> Result<u16, PciBarError> {
match *self {
- PciBar::Port(port) => port,
- PciBar::Memory32 { .. } | PciBar::Memory64 { .. } => {
- panic!("expected port BAR, found memory BAR");
- }
- PciBar::None => panic!("expected BAR to exist"),
+ PciBar::Port(port) => Ok(port),
+ PciBar::Memory32 { .. } | PciBar::Memory64 { .. } => Err(PciBarError::WrongType),
+ PciBar::None => Err(PciBarError::Missing),
}
}
- pub fn expect_mem(&self) -> (usize, usize) {
+ pub fn try_mem(&self) -> Result<(usize, usize), PciBarError> {
match *self {
- PciBar::Memory32 { addr, size } => (addr as usize, size as usize),
- PciBar::Memory64 { addr, size } => (
+ PciBar::Memory32 { addr, size } => Ok((addr as usize, size as usize)),
+ PciBar::Memory64 { addr, size } => Ok((
addr.try_into()
.expect("conversion from 64bit BAR to usize failed"),
size.try_into()
.expect("conversion from 64bit BAR size to usize failed"),
- ),
- PciBar::Port(_) => panic!("expected memory BAR, found port BAR"),
- PciBar::None => panic!("expected BAR to exist"),
+ )),
+ PciBar::Port(_) => Err(PciBarError::WrongType),
+ PciBar::None => Err(PciBarError::Missing),
}
}
+
+ pub fn expect_port(&self) -> u16 {
+ self.try_port().expect("expected port BAR")
+ }
+
+ pub fn expect_mem(&self) -> (usize, usize) {
+ self.try_mem().expect("expected memory BAR")
+ }
}
diff --git a/drivers/pcid/src/driver_interface/irq_helpers.rs b/drivers/pcid/src/driver_interface/irq_helpers.rs
index 28ca077a..d0c7042e 100644
--- a/drivers/pcid/src/driver_interface/irq_helpers.rs
+++ b/drivers/pcid/src/driver_interface/irq_helpers.rs
@@ -61,6 +61,14 @@ pub fn cpu_ids() -> io::Result<impl Iterator<Item = io::Result<usize>> + 'static
)
}
+/// Allocate a single interrupt vector. Returns the InterruptVector on success.
+pub fn try_pci_allocate_interrupt_vector(
+ pcid_handle: &mut crate::driver_interface::PciFunctionHandle,
+ driver: &str,
+) -> Result<InterruptVector, ()> {
+ Ok(pci_allocate_interrupt_vector(pcid_handle, driver))
+}
+
/// Allocate multiple interrupt vectors, from the IDT of the specified processor, returning the
/// start vector and the IRQ handles.
///
diff --git a/drivers/pcid/src/driver_interface/mod.rs b/drivers/pcid/src/driver_interface/mod.rs
index bbc7304e..a77d79ec 100644
--- a/drivers/pcid/src/driver_interface/mod.rs
+++ b/drivers/pcid/src/driver_interface/mod.rs
@@ -29,6 +29,10 @@ pub struct LegacyInterruptLine {
}
impl LegacyInterruptLine {
+ /// Get an IRQ handle for this interrupt line.
+ pub fn try_irq_handle(self, driver: &str) -> Result<File, ()> {
+ Ok(self.irq_handle(driver))
+ }
/// Get an IRQ handle for this interrupt line.
pub fn irq_handle(self, driver: &str) -> File {
if let Some((phandle, addr, cells)) = self.phandled {
@@ -452,6 +456,9 @@ impl PciFunctionHandle {
}
}
}
+ pub unsafe fn try_map_bar(&mut self, bir: u8) -> Result<&MappedBar, ()> {
+ Ok(self.map_bar(bir))
+ }
pub unsafe fn map_bar(&mut self, bir: u8) -> &MappedBar {
let mapped_bar = &mut self.mapped_bars[bir as usize];
if let Some(mapped_bar) = mapped_bar {
diff --git a/drivers/virtio-core/src/transport.rs b/drivers/virtio-core/src/transport.rs
index d3445d2d..2a316557 100644
--- a/drivers/virtio-core/src/transport.rs
+++ b/drivers/virtio-core/src/transport.rs
@@ -19,6 +19,8 @@ pub enum Error {
SyscallError(#[from] libredox::error::Error),
#[error("the device is incapable of {0:?}")]
InCapable(CfgType),
+ #[error("probe: {0}")]
+ Probe(&'static str),
}
/// Returns the queue part sizes in bytes.