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