From 9fc7066effd8b31a76fb2668484cade19970f14d Mon Sep 17 00:00:00 2001 From: Matthew Leach Date: Sat, 7 Mar 2026 20:08:14 +0000 Subject: [PATCH] drivers: init: don't override probe_fns If multiple drivers are associated with a compatible string, don't override an existing probe_fn. Instead, store a list of associated probe_fns. Once a probe_fn has claimed the device stop calling the associated probe chain. --- src/drivers/init.rs | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/drivers/init.rs b/src/drivers/init.rs index 20497b2..efd82d6 100644 --- a/src/drivers/init.rs +++ b/src/drivers/init.rs @@ -3,15 +3,14 @@ use super::{ probe::{DeviceDescriptor, DeviceMatchType, ProbeFn}, }; use crate::{drivers::DM, sync::SpinLock}; -use alloc::collections::btree_map::BTreeMap; -use alloc::sync::Arc; -use libkernel::error::Result; +use alloc::{collections::btree_map::BTreeMap, sync::Arc, vec::Vec}; +use libkernel::error::{KernelError, ProbeError, Result}; use log::error; pub type InitFunc = fn(&mut PlatformBus, &mut DriverManager) -> Result<()>; pub struct PlatformBus { - probers: BTreeMap, + probers: BTreeMap>, } impl PlatformBus { @@ -24,7 +23,7 @@ impl PlatformBus { /// Called by driver `init` functions to register their ability to probe for /// certain hardware. pub fn register_platform_driver(&mut self, match_type: DeviceMatchType, probe_fn: ProbeFn) { - self.probers.insert(match_type, probe_fn); + self.probers.entry(match_type).or_default().push(probe_fn); } /// Called by the FDT prober to find the right driver and probe. @@ -53,12 +52,25 @@ impl PlatformBus { }; if let Some(match_type) = matcher - && let Some(probe_fn) = self.probers.get(&match_type) + && let Some(probe_fns) = self.probers.get(&match_type) { - // We found a match, call the probe function. - let driver = (probe_fn)(dm, descr)?; - dm.insert_driver(driver.clone()); - return Ok(Some(driver)); + // Try each registered probe function until one claims the device. + for probe_fn in probe_fns { + match (probe_fn)(dm, descr.clone()) { + Ok(driver) => { + dm.insert_driver(driver.clone()); + return Ok(Some(driver)); + } + Err(KernelError::Probe(ProbeError::NoMatch)) => { + // This driver doesn't want this device, try next. + continue; + } + Err(e) => return Err(e), + } + } + + // All probe functions returned NoMatch. + return Err(KernelError::Probe(ProbeError::NoMatch)); } Ok(None)