1 use alloc::{ 2 string::{String, ToString}, 3 sync::{Arc, Weak}, 4 }; 5 use intertrait::cast::CastArc; 6 use log::error; 7 8 use super::{ 9 platform_bus_device, platform_device::PlatformDevice, platform_driver::PlatformDriver, 10 }; 11 use crate::{ 12 driver::{ 13 acpi::acpi_manager, 14 base::{ 15 device::{bus::Bus, driver::Driver, Device}, 16 kobject::KObject, 17 subsys::SubSysPrivate, 18 }, 19 }, 20 filesystem::{ 21 sysfs::{Attribute, AttributeGroup}, 22 vfs::syscall::ModeType, 23 }, 24 }; 25 use system_error::SystemError; 26 27 #[derive(Debug)] 28 pub struct PlatformBus { 29 private: SubSysPrivate, 30 } 31 32 impl PlatformBus { 33 pub fn new() -> Arc<Self> { 34 let w: Weak<Self> = Weak::new(); 35 let private = SubSysPrivate::new("platform".to_string(), Some(w), None, &[]); 36 let bus = Arc::new(Self { private }); 37 bus.subsystem() 38 .set_bus(Some(Arc::downgrade(&(bus.clone() as Arc<dyn Bus>)))); 39 40 return bus; 41 } 42 } 43 44 impl Bus for PlatformBus { 45 fn name(&self) -> String { 46 return "platform".to_string(); 47 } 48 49 fn dev_name(&self) -> String { 50 return self.name(); 51 } 52 53 fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] { 54 return &[&PlatformDeviceAttrGroup]; 55 } 56 57 fn subsystem(&self) -> &SubSysPrivate { 58 return &self.private; 59 } 60 61 fn probe(&self, device: &Arc<dyn Device>) -> Result<(), SystemError> { 62 let drv = device.driver().ok_or(SystemError::EINVAL)?; 63 let pdrv = drv.cast::<dyn PlatformDriver>().map_err(|_|{ 64 error!("PlatformBus::probe() failed: device.driver() is not a PlatformDriver. Device: '{:?}'", device.name()); 65 SystemError::EINVAL 66 })?; 67 68 let pdev = device.clone().cast::<dyn PlatformDevice>().map_err(|_| { 69 error!( 70 "PlatformBus::probe() failed: device is not a PlatformDevice. Device: '{:?}'", 71 device.name() 72 ); 73 SystemError::EINVAL 74 })?; 75 76 return pdrv.probe(&pdev); 77 } 78 79 fn remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> { 80 todo!() 81 } 82 83 fn sync_state(&self, _device: &Arc<dyn Device>) { 84 todo!() 85 } 86 87 fn shutdown(&self, _device: &Arc<dyn Device>) { 88 todo!() 89 } 90 91 fn resume(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> { 92 todo!() 93 } 94 95 /// 96 /// match platform device to platform driver. 97 /// 98 /// ## 参数 99 /// 100 /// * `device` - platform device 101 /// * `driver` - platform driver 102 /// 103 /// ## 返回 104 /// 105 /// - `Ok(true)` - 匹配成功 106 /// - `Ok(false)` - 匹配失败 107 /// - `Err(_)` - 由于内部错误导致匹配失败 108 /// 109 /// Platform device IDs are assumed to be encoded like this: 110 /// "<name><instance>", where <name> is a short description of the type of 111 /// device, like "pci" or "floppy", and <instance> is the enumerated 112 /// instance of the device, like '0' or '42'. Driver IDs are simply 113 /// "<name>". So, extract the <name> from the platform_device structure, 114 /// and compare it against the name of the driver. Return whether they match 115 /// or not. 116 /// 117 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/platform.c#1331 118 /// 119 /// 120 fn match_device( 121 &self, 122 device: &Arc<dyn Device>, 123 driver: &Arc<dyn Driver>, 124 ) -> Result<bool, SystemError> { 125 // 尝试从 ACPI 中匹配 126 if let Ok(x) = acpi_manager().driver_match_device(driver, device) { 127 if x { 128 return Ok(true); 129 } 130 } 131 132 // 尝试从 ID table 中匹配 133 if let Some(drv_id_table) = driver.id_table() { 134 let pdev = device 135 .clone() 136 .cast::<dyn PlatformDevice>() 137 .map_err(|_| SystemError::EINVAL)?; 138 if drv_id_table.name().eq(&pdev.name()) { 139 return Ok(true); 140 } 141 } 142 143 // 尝试根据设备名称匹配 144 return Ok(device.name().eq(&driver.name())); 145 } 146 147 fn root_device(&self) -> Option<Weak<dyn Device>> { 148 let root_device = platform_bus_device() as Arc<dyn Device>; 149 return Some(Arc::downgrade(&root_device)); 150 } 151 } 152 153 #[derive(Debug)] 154 pub struct PlatformDeviceAttrGroup; 155 156 impl AttributeGroup for PlatformDeviceAttrGroup { 157 fn name(&self) -> Option<&str> { 158 None 159 } 160 161 fn attrs(&self) -> &[&'static dyn Attribute] { 162 // todo: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/platform.c?r=&mo=38425&fi=1511#1311 163 return &[]; 164 } 165 166 fn is_visible(&self, _kobj: Arc<dyn KObject>, attr: &dyn Attribute) -> Option<ModeType> { 167 return Some(attr.mode()); 168 } 169 } 170