driver.rs 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. use super::{
  2. device::{PCIDevice, PCIE_DEVICES},
  3. error::PciError,
  4. };
  5. use crate::{kernel::constants::EEXIST, KResult};
  6. use alloc::{
  7. collections::btree_map::{self, BTreeMap},
  8. sync::Arc,
  9. };
  10. use eonix_sync::Spin;
  11. static PCIE_DRIVERS: Spin<BTreeMap<u32, Arc<dyn PCIDriver>>> = Spin::new(BTreeMap::new());
  12. pub trait PCIDriver: Send + Sync {
  13. fn vendor_id(&self) -> u16;
  14. fn device_id(&self) -> u16;
  15. fn handle_device(&self, device: Arc<PCIDevice<'static>>) -> Result<(), PciError>;
  16. }
  17. pub fn register_driver(driver: impl PCIDriver + 'static) -> KResult<()> {
  18. let index = (driver.vendor_id() as u32) << 16 | driver.device_id() as u32;
  19. let driver = Arc::new(driver);
  20. match PCIE_DRIVERS.lock().entry(index) {
  21. btree_map::Entry::Vacant(vacant_entry) => vacant_entry.insert(driver.clone()),
  22. btree_map::Entry::Occupied(_) => Err(EEXIST)?,
  23. };
  24. let device = PCIE_DEVICES.lock().find(&index).clone_pointer();
  25. if let Some(device) = device {
  26. driver.handle_device(device)?;
  27. };
  28. Ok(())
  29. }