1 use alloc::{ 2 string::{String, ToString}, 3 sync::{Arc, Weak}, 4 }; 5 use ida::IdAllocator; 6 7 use crate::{ 8 driver::base::{ 9 class::Class, 10 device::{ 11 bus::{Bus, BusState}, 12 device_manager, 13 driver::Driver, 14 Device, DeviceNumber, DevicePrivateData, DeviceType, IdTable, 15 }, 16 kobject::{KObjType, KObject, KObjectState, LockedKObjectState}, 17 kset::KSet, 18 }, 19 filesystem::kernfs::KernFSInode, 20 libs::{ 21 rwlock::{RwLockReadGuard, RwLockWriteGuard}, 22 spinlock::SpinLock, 23 }, 24 }; 25 use system_error::SystemError; 26 27 use super::{super::device::DeviceState, platform_bus, platform_bus_device, CompatibleTable}; 28 29 /// 平台设备id分配器 30 static PLATFORM_DEVID_IDA: IdAllocator = IdAllocator::new(0, i32::MAX as usize); 31 32 #[inline(always)] 33 pub fn platform_device_manager() -> &'static PlatformDeviceManager { 34 &PlatformDeviceManager 35 } 36 37 /// 没有平台设备id 38 pub const PLATFORM_DEVID_NONE: i32 = -1; 39 /// 请求自动分配这个平台设备id 40 pub const PLATFORM_DEVID_AUTO: i32 = -2; 41 42 /// @brief: 实现该trait的设备实例应挂载在platform总线上, 43 /// 同时应该实现Device trait 44 /// 45 /// ## 注意 46 /// 47 /// 应当在所有实现这个trait的结构体上方,添加 `#[cast_to([sync] PlatformDriver)]`, 48 /// 否则运行时将报错“该对象不是PlatformDriver” 49 pub trait PlatformDevice: Device { 50 fn pdev_name(&self) -> &str; 51 /// 返回平台设备id,以及这个id是否是自动生成的 52 /// 53 /// 请注意,如果当前设备还没有id,应该返回 54 /// (PLATFORM_DEVID_NONE, false) 55 fn pdev_id(&self) -> (i32, bool) { 56 (PLATFORM_DEVID_NONE, false) 57 } 58 59 /// 设置平台设备id 60 fn set_pdev_id(&self, id: i32); 61 /// 设置id是否为自动分配 62 fn set_pdev_id_auto(&self, id_auto: bool); 63 64 fn compatible_table(&self) -> CompatibleTable; 65 /// @brief: 判断设备是否初始化 66 /// @parameter: None 67 /// @return: 如果已经初始化,返回true,否则,返回false 68 fn is_initialized(&self) -> bool; 69 70 /// @brief: 设置设备状态 71 /// @parameter set_state: 设备状态 72 /// @return: None 73 fn set_state(&self, set_state: DeviceState); 74 } 75 76 #[derive(Debug)] 77 pub struct PlatformDeviceManager; 78 79 impl PlatformDeviceManager { 80 /// platform_device_add - add a platform device to device hierarchy 81 pub fn device_add(&self, pdev: Arc<dyn PlatformDevice>) -> Result<(), SystemError> { 82 if pdev.parent().is_none() { 83 pdev.set_parent(Some(Arc::downgrade( 84 &(platform_bus_device() as Arc<dyn KObject>), 85 ))); 86 } 87 88 pdev.set_bus(Some(platform_bus() as Arc<dyn Bus>)); 89 90 let id = pdev.pdev_id().0; 91 match id { 92 PLATFORM_DEVID_NONE => { 93 pdev.set_name(format!("{}", pdev.pdev_name())); 94 } 95 PLATFORM_DEVID_AUTO => { 96 let id = PLATFORM_DEVID_IDA.alloc().ok_or(SystemError::EOVERFLOW)?; 97 pdev.set_pdev_id(id as i32); 98 pdev.set_pdev_id_auto(true); 99 pdev.set_name(format!("{}.{}.auto", pdev.pdev_name(), pdev.pdev_id().0)); 100 } 101 _ => { 102 pdev.set_name(format!("{}.{}", pdev.pdev_name(), id)); 103 } 104 } 105 106 // todo: 插入资源: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/platform.c?fi=platform_device_add#691 107 let r = device_manager().add_device(pdev.clone() as Arc<dyn Device>); 108 if r.is_ok() { 109 pdev.set_state(DeviceState::Initialized); 110 return Ok(()); // success 111 } else { 112 // failed 113 let pdevid = pdev.pdev_id(); 114 if pdevid.1 { 115 PLATFORM_DEVID_IDA.free(pdevid.0 as usize); 116 pdev.set_pdev_id(PLATFORM_DEVID_AUTO); 117 } 118 119 return r; 120 } 121 } 122 } 123 124 #[derive(Debug)] 125 #[cast_to([sync] Device)] 126 pub struct PlatformBusDevice { 127 inner: SpinLock<InnerPlatformBusDevice>, 128 kobj_state: LockedKObjectState, 129 } 130 131 impl PlatformBusDevice { 132 /// @brief: 创建一个加锁的platform总线实例 133 /// @parameter: None 134 /// @return: platform总线实例 135 pub fn new( 136 data: DevicePrivateData, 137 parent: Option<Weak<dyn KObject>>, 138 ) -> Arc<PlatformBusDevice> { 139 return Arc::new(PlatformBusDevice { 140 inner: SpinLock::new(InnerPlatformBusDevice::new(data, parent)), 141 kobj_state: LockedKObjectState::new(None), 142 }); 143 } 144 145 /// @brief: 获取总线的匹配表 146 /// @parameter: None 147 /// @return: platform总线匹配表 148 #[inline] 149 #[allow(dead_code)] 150 fn compatible_table(&self) -> CompatibleTable { 151 CompatibleTable::new(vec!["platform"]) 152 } 153 154 /// @brief: 判断总线是否初始化 155 /// @parameter: None 156 /// @return: 已初始化,返回true,否则,返回false 157 #[inline] 158 #[allow(dead_code)] 159 fn is_initialized(&self) -> bool { 160 let state = self.inner.lock().state; 161 match state { 162 BusState::Initialized => true, 163 _ => false, 164 } 165 } 166 167 /// @brief: 设置总线状态 168 /// @parameter set_state: 总线状态BusState 169 /// @return: None 170 #[inline] 171 #[allow(dead_code)] 172 fn set_state(&self, set_state: BusState) { 173 let state = &mut self.inner.lock().state; 174 *state = set_state; 175 } 176 177 /// @brief: 获取总线状态 178 /// @parameter: None 179 /// @return: 总线状态 180 #[inline] 181 #[allow(dead_code)] 182 fn get_state(&self) -> BusState { 183 let state = self.inner.lock().state; 184 return state; 185 } 186 } 187 188 #[allow(dead_code)] 189 #[derive(Debug, Clone)] 190 pub struct InnerPlatformBusDevice { 191 name: String, 192 data: DevicePrivateData, 193 state: BusState, // 总线状态 194 parent: Option<Weak<dyn KObject>>, // 总线的父对象 195 196 kernfs_inode: Option<Arc<KernFSInode>>, 197 /// 当前设备挂载到的总线 198 bus: Option<Arc<dyn Bus>>, 199 /// 当前设备已经匹配的驱动 200 driver: Option<Weak<dyn Driver>>, 201 202 ktype: Option<&'static dyn KObjType>, 203 kset: Option<Arc<KSet>>, 204 } 205 206 impl InnerPlatformBusDevice { 207 pub fn new(data: DevicePrivateData, parent: Option<Weak<dyn KObject>>) -> Self { 208 Self { 209 data, 210 name: "platform".to_string(), 211 state: BusState::NotInitialized, 212 parent, 213 kernfs_inode: None, 214 bus: None, 215 driver: None, 216 ktype: None, 217 kset: None, 218 } 219 } 220 } 221 222 impl KObject for PlatformBusDevice { 223 fn as_any_ref(&self) -> &dyn core::any::Any { 224 self 225 } 226 227 fn parent(&self) -> Option<Weak<dyn KObject>> { 228 self.inner.lock().parent.clone() 229 } 230 231 fn inode(&self) -> Option<Arc<KernFSInode>> { 232 self.inner.lock().kernfs_inode.clone() 233 } 234 235 fn set_inode(&self, inode: Option<Arc<KernFSInode>>) { 236 self.inner.lock().kernfs_inode = inode; 237 } 238 239 fn kobj_type(&self) -> Option<&'static dyn KObjType> { 240 self.inner.lock().ktype.clone() 241 } 242 243 fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { 244 self.inner.lock().ktype = ktype; 245 } 246 247 fn kset(&self) -> Option<Arc<KSet>> { 248 self.inner.lock().kset.clone() 249 } 250 251 fn kobj_state(&self) -> RwLockReadGuard<KObjectState> { 252 self.kobj_state.read() 253 } 254 255 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> { 256 self.kobj_state.write() 257 } 258 259 fn set_kobj_state(&self, state: KObjectState) { 260 *self.kobj_state.write() = state; 261 } 262 263 fn name(&self) -> String { 264 self.inner.lock().name.clone() 265 } 266 267 fn set_name(&self, name: String) { 268 self.inner.lock().name = name; 269 } 270 271 fn set_kset(&self, kset: Option<Arc<KSet>>) { 272 self.inner.lock().kset = kset; 273 } 274 275 fn set_parent(&self, parent: Option<Weak<dyn KObject>>) { 276 self.inner.lock().parent = parent; 277 } 278 } 279 280 /// @brief: 为Platform实现Device trait,platform总线也是一种设备,属于总线设备类型 281 impl Device for PlatformBusDevice { 282 #[inline] 283 #[allow(dead_code)] 284 fn dev_type(&self) -> DeviceType { 285 return DeviceType::Bus; 286 } 287 288 #[inline] 289 #[allow(dead_code)] 290 fn id_table(&self) -> IdTable { 291 IdTable::new("platform".to_string(), Some(DeviceNumber::new(0))) 292 } 293 294 fn bus(&self) -> Option<Arc<dyn Bus>> { 295 self.inner.lock().bus.clone() 296 } 297 298 fn set_bus(&self, bus: Option<Arc<dyn Bus>>) { 299 self.inner.lock().bus = bus; 300 } 301 302 fn driver(&self) -> Option<Arc<dyn Driver>> { 303 self.inner.lock().driver.clone()?.upgrade() 304 } 305 306 #[inline] 307 fn is_dead(&self) -> bool { 308 false 309 } 310 311 fn set_driver(&self, driver: Option<Weak<dyn Driver>>) { 312 self.inner.lock().driver = driver; 313 } 314 315 fn can_match(&self) -> bool { 316 todo!() 317 } 318 319 fn set_can_match(&self, _can_match: bool) { 320 todo!() 321 } 322 323 fn state_synced(&self) -> bool { 324 todo!() 325 } 326 327 fn set_class(&self, _class: Option<Arc<dyn Class>>) { 328 todo!() 329 } 330 } 331