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