#![expect(unused_variables)]
use alloc::{collections::VecDeque, sync::Arc, vec::Vec};
use core::fmt::Debug;
use log::{debug, error};
use super::{device_info::PciDeviceId, PciCommonDevice};
use crate::bus::BusProbeError;
pub trait PciDevice: Sync + Send + Debug {
fn device_id(&self) -> PciDeviceId;
}
pub trait PciDriver: Sync + Send + Debug {
#[expect(clippy::result_large_err)]
fn probe(
&self,
device: PciCommonDevice,
) -> Result<Arc<dyn PciDevice>, (BusProbeError, PciCommonDevice)>;
}
pub struct PciBus {
common_devices: VecDeque<PciCommonDevice>,
devices: Vec<Arc<dyn PciDevice>>,
drivers: Vec<Arc<dyn PciDriver>>,
}
impl PciBus {
pub fn register_driver(&mut self, driver: Arc<dyn PciDriver>) {
debug!("Register driver:{:#x?}", driver);
let length = self.common_devices.len();
for i in (0..length).rev() {
let common_device = self.common_devices.pop_front().unwrap();
let device_id = *common_device.device_id();
let device = match driver.probe(common_device) {
Ok(device) => {
debug_assert!(device_id == device.device_id());
self.devices.push(device);
continue;
}
Err((err, common_device)) => {
if err != BusProbeError::DeviceNotMatch {
error!("PCI device construction failed, reason: {:?}", err);
}
debug_assert!(device_id == *common_device.device_id());
common_device
}
};
self.common_devices.push_back(device);
}
self.drivers.push(driver);
}
pub(super) fn register_common_device(&mut self, mut common_device: PciCommonDevice) {
debug!("Find pci common devices:{:x?}", common_device);
let device_id = *common_device.device_id();
for driver in self.drivers.iter() {
common_device = match driver.probe(common_device) {
Ok(device) => {
debug_assert!(device_id == device.device_id());
self.devices.push(device);
return;
}
Err((err, common_device)) => {
if err != BusProbeError::DeviceNotMatch {
error!("PCI device construction failed, reason: {:?}", err);
}
debug_assert!(device_id == *common_device.device_id());
common_device
}
};
}
self.common_devices.push_back(common_device);
}
pub(super) const fn new() -> Self {
Self {
common_devices: VecDeque::new(),
devices: Vec::new(),
drivers: Vec::new(),
}
}
}