use alloc::{ string::{String, ToString}, sync::{Arc, Weak}, }; use intertrait::cast::CastArc; use super::{platform_device::PlatformDevice, platform_driver::PlatformDriver}; use crate::{ driver::{ acpi::acpi_manager, base::{ device::{bus::Bus, driver::Driver, Device}, kobject::KObject, subsys::SubSysPrivate, }, }, filesystem::{ sysfs::{Attribute, AttributeGroup}, vfs::syscall::ModeType, }, }; use system_error::SystemError; #[derive(Debug)] pub struct PlatformBus { private: SubSysPrivate, } impl PlatformBus { pub fn new() -> Arc { let w: Weak = Weak::new(); let private = SubSysPrivate::new("platform".to_string(), Some(w), None, &[]); let bus = Arc::new(Self { private }); bus.subsystem() .set_bus(Some(Arc::downgrade(&(bus.clone() as Arc)))); return bus; } } impl Bus for PlatformBus { fn name(&self) -> String { return "platform".to_string(); } fn dev_name(&self) -> String { return self.name(); } fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] { return &[&PlatformDeviceAttrGroup]; } fn subsystem(&self) -> &SubSysPrivate { return &self.private; } fn probe(&self, device: &Arc) -> Result<(), SystemError> { let drv = device.driver().ok_or(SystemError::EINVAL)?; let pdrv = drv.cast::().map_err(|_|{ kerror!("PlatformBus::probe() failed: device.driver() is not a PlatformDriver. Device: '{:?}'", device.name()); SystemError::EINVAL })?; let pdev = device.clone().cast::().map_err(|_| { kerror!( "PlatformBus::probe() failed: device is not a PlatformDevice. Device: '{:?}'", device.name() ); SystemError::EINVAL })?; return pdrv.probe(&pdev); } fn remove(&self, _device: &Arc) -> Result<(), SystemError> { todo!() } fn sync_state(&self, _device: &Arc) { todo!() } fn shutdown(&self, _device: &Arc) { todo!() } fn resume(&self, _device: &Arc) -> Result<(), SystemError> { todo!() } /// /// match platform device to platform driver. /// /// ## 参数 /// /// * `device` - platform device /// * `driver` - platform driver /// /// ## 返回 /// /// - `Ok(true)` - 匹配成功 /// - `Ok(false)` - 匹配失败 /// - `Err(_)` - 由于内部错误导致匹配失败 /// /// Platform device IDs are assumed to be encoded like this: /// "", where is a short description of the type of /// device, like "pci" or "floppy", and is the enumerated /// instance of the device, like '0' or '42'. Driver IDs are simply /// "". So, extract the from the platform_device structure, /// and compare it against the name of the driver. Return whether they match /// or not. /// /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/platform.c#1331 /// /// fn match_device( &self, device: &Arc, driver: &Arc, ) -> Result { // 尝试从 ACPI 中匹配 if let Ok(x) = acpi_manager().driver_match_device(driver, device) { if x { return Ok(true); } } // 尝试从 ID table 中匹配 if let Some(drv_id_table) = driver.id_table() { let pdev = device .clone() .cast::() .map_err(|_| SystemError::EINVAL)?; if drv_id_table.name().eq(&pdev.name()) { return Ok(true); } } // 尝试根据设备名称匹配 return Ok(device.name().eq(&driver.name())); } } #[derive(Debug)] pub struct PlatformDeviceAttrGroup; impl AttributeGroup for PlatformDeviceAttrGroup { fn name(&self) -> Option<&str> { None } fn attrs(&self) -> &[&'static dyn Attribute] { // todo: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/platform.c?r=&mo=38425&fi=1511#1311 return &[]; } fn is_visible(&self, _kobj: Arc, attr: &dyn Attribute) -> Option { return Some(attr.mode()); } }