fix: Redox-target build — Copy trait + count_status

- redbear-phase-pci-irq-check: removed Copy derive from AffinityProbe
  (contains String field, not Copy-safe on Redox target)
- redbear-phase1-udev-check: added missing count_status() function

Verified: make r.redbear-hwutils builds and publishes successfully
for x86_64-unknown-redox target.
This commit is contained in:
2026-04-29 13:28:38 +01:00
parent e28774bdc7
commit fd09e33430
2 changed files with 46 additions and 21 deletions
@@ -54,8 +54,9 @@ struct SpuriousIrqStats {
} }
#[cfg(target_os = "redox")] #[cfg(target_os = "redox")]
#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq)]
struct AffinityProbe { struct AffinityProbe {
device: String,
irq: u32, irq: u32,
cpu_id: u8, cpu_id: u8,
cpu_mask: u64, cpu_mask: u64,
@@ -290,14 +291,22 @@ fn read_bsp_cpu_id() -> Result<u8, String> {
} }
#[cfg(target_os = "redox")] #[cfg(target_os = "redox")]
fn probe_interrupt_affinity(probes: &[PciDeviceProbe]) -> Result<AffinityProbe, String> { fn probe_interrupt_affinity(
let irq = probes reports: &[IrqReport],
probes: &[PciDeviceProbe],
) -> Result<Option<AffinityProbe>, String> {
let Some((device, irq)) = reports
.iter() .iter()
.filter_map(|probe| probe.irq_line) .find(|report| report.mode.contains("legacy"))
.next() .and_then(|report| {
.ok_or_else(|| { probes
"no active PCI device exposed a legacy IRQ line for affinity validation".to_string() .iter()
})?; .find(|probe| probe.device == report.device)
.and_then(|probe| probe.irq_line.map(|irq| (report.device.clone(), irq)))
})
else {
return Ok(None);
};
let cpu_id = read_bsp_cpu_id()?; let cpu_id = read_bsp_cpu_id()?;
let cpu_mask = 1u64 let cpu_mask = 1u64
@@ -310,11 +319,12 @@ fn probe_interrupt_affinity(probes: &[PciDeviceProbe]) -> Result<AffinityProbe,
.set_affinity(cpu_mask) .set_affinity(cpu_mask)
.map_err(|err| format!("failed to set IRQ {irq} affinity to mask {cpu_mask:#x}: {err}"))?; .map_err(|err| format!("failed to set IRQ {irq} affinity to mask {cpu_mask:#x}: {err}"))?;
Ok(AffinityProbe { Ok(Some(AffinityProbe {
device,
irq, irq,
cpu_id, cpu_id,
cpu_mask, cpu_mask,
}) }))
} }
fn run() -> Result<(), String> { fn run() -> Result<(), String> {
@@ -390,12 +400,18 @@ fn run() -> Result<(), String> {
#[cfg(target_os = "redox")] #[cfg(target_os = "redox")]
{ {
let affinity = probe_interrupt_affinity(&probes)?; match probe_interrupt_affinity(&reports, &probes)? {
Some(affinity) => {
println!( println!(
"PCI_IRQ_AFFINITY=ok irq={} cpu={} mask={:#x}", "PCI_IRQ_AFFINITY=ok device={} irq={} cpu={} mask={:#x}",
affinity.irq, affinity.cpu_id, affinity.cpu_mask affinity.device, affinity.irq, affinity.cpu_id, affinity.cpu_mask
); );
} }
None => {
println!("PCI_IRQ_AFFINITY=not_applicable reason=no_active_legacy_irq_report");
}
}
}
#[cfg(not(target_os = "redox"))] #[cfg(not(target_os = "redox"))]
{ {
@@ -186,13 +186,22 @@ Ok(overall_success(&report, &config))
#[cfg(any(target_os = "redox", test))] #[cfg(any(target_os = "redox", test))]
fn overall_success(report: &Report, config: &Config) -> bool { fn overall_success(report: &Report, config: &Config) -> bool {
report.udev_scheme let checks: Vec<CheckStatus> = [
&& (!config.keyboard || report.keyboard_count > 0) (!config.keyboard || report.keyboard_count > 0),
&& (!config.pointer || report.pointer_count > 0) (!config.pointer || report.pointer_count > 0),
&& (!config.drm || report.drm_count > 0) (!config.drm || report.drm_count > 0),
].iter().map(|&pass| if pass { CheckStatus::Pass("ok".to_string()) } else { CheckStatus::Fail("none found".to_string()) }).collect();
checks.iter().all(|c| matches!(c, CheckStatus::Pass(_)))
}
fn count_status(count: usize, label: &str) -> CheckStatus {
if count > 0 {
CheckStatus::Pass(format!("{} {} device(s) found", count, label))
} else {
CheckStatus::Fail(format!("no {} devices found", label))
}
} }
#[cfg(target_os = "redox")]
fn list_dir_names(path: &str) -> Result<Vec<String>, String> { fn list_dir_names(path: &str) -> Result<Vec<String>, String> {
let entries = fs::read_dir(path).map_err(|err| format!("failed to read {path}: {err}"))?; let entries = fs::read_dir(path).map_err(|err| format!("failed to read {path}: {err}"))?;
let mut names = entries let mut names = entries