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, 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] PlatformDevice)]`, 48 /// 否则运行时将报错“该对象不是PlatformDevice” 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(Arc::downgrade(&(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(pdev.pdev_name().to_string()); 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://code.dragonos.org.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 matches!(state, BusState::Initialized) 162 } 163 164 /// @brief: 设置总线状态 165 /// @parameter set_state: 总线状态BusState 166 /// @return: None 167 #[inline] 168 #[allow(dead_code)] 169 fn set_state(&self, set_state: BusState) { 170 let state = &mut self.inner.lock().state; 171 *state = set_state; 172 } 173 174 /// @brief: 获取总线状态 175 /// @parameter: None 176 /// @return: 总线状态 177 #[inline] 178 #[allow(dead_code)] 179 fn get_state(&self) -> BusState { 180 let state = self.inner.lock().state; 181 return state; 182 } 183 } 184 185 #[allow(dead_code)] 186 #[derive(Debug, Clone)] 187 pub struct InnerPlatformBusDevice { 188 name: String, 189 data: DevicePrivateData, 190 state: BusState, // 总线状态 191 parent: Option<Weak<dyn KObject>>, // 总线的父对象 192 193 kernfs_inode: Option<Arc<KernFSInode>>, 194 /// 当前设备挂载到的总线 195 bus: Option<Weak<dyn Bus>>, 196 /// 当前设备已经匹配的驱动 197 driver: Option<Weak<dyn Driver>>, 198 199 ktype: Option<&'static dyn KObjType>, 200 kset: Option<Arc<KSet>>, 201 } 202 203 impl InnerPlatformBusDevice { 204 pub fn new(data: DevicePrivateData, parent: Option<Weak<dyn KObject>>) -> Self { 205 Self { 206 data, 207 name: "platform".to_string(), 208 state: BusState::NotInitialized, 209 parent, 210 kernfs_inode: None, 211 bus: None, 212 driver: None, 213 ktype: None, 214 kset: None, 215 } 216 } 217 } 218 219 impl KObject for PlatformBusDevice { 220 fn as_any_ref(&self) -> &dyn core::any::Any { 221 self 222 } 223 224 fn parent(&self) -> Option<Weak<dyn KObject>> { 225 self.inner.lock().parent.clone() 226 } 227 228 fn inode(&self) -> Option<Arc<KernFSInode>> { 229 self.inner.lock().kernfs_inode.clone() 230 } 231 232 fn set_inode(&self, inode: Option<Arc<KernFSInode>>) { 233 self.inner.lock().kernfs_inode = inode; 234 } 235 236 fn kobj_type(&self) -> Option<&'static dyn KObjType> { 237 self.inner.lock().ktype 238 } 239 240 fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { 241 self.inner.lock().ktype = ktype; 242 } 243 244 fn kset(&self) -> Option<Arc<KSet>> { 245 self.inner.lock().kset.clone() 246 } 247 248 fn kobj_state(&self) -> RwLockReadGuard<KObjectState> { 249 self.kobj_state.read() 250 } 251 252 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> { 253 self.kobj_state.write() 254 } 255 256 fn set_kobj_state(&self, state: KObjectState) { 257 *self.kobj_state.write() = state; 258 } 259 260 fn name(&self) -> String { 261 self.inner.lock().name.clone() 262 } 263 264 fn set_name(&self, name: String) { 265 self.inner.lock().name = name; 266 } 267 268 fn set_kset(&self, kset: Option<Arc<KSet>>) { 269 self.inner.lock().kset = kset; 270 } 271 272 fn set_parent(&self, parent: Option<Weak<dyn KObject>>) { 273 self.inner.lock().parent = parent; 274 } 275 } 276 277 /// @brief: 为Platform实现Device trait,platform总线也是一种设备,属于总线设备类型 278 impl Device for PlatformBusDevice { 279 #[inline] 280 #[allow(dead_code)] 281 fn dev_type(&self) -> DeviceType { 282 return DeviceType::Bus; 283 } 284 285 #[inline] 286 fn id_table(&self) -> IdTable { 287 IdTable::new("platform".to_string(), None) 288 } 289 290 fn bus(&self) -> Option<Weak<dyn Bus>> { 291 self.inner.lock().bus.clone() 292 } 293 294 fn set_bus(&self, bus: Option<Weak<dyn Bus>>) { 295 self.inner.lock().bus = bus; 296 } 297 298 fn driver(&self) -> Option<Arc<dyn Driver>> { 299 self.inner.lock().driver.clone()?.upgrade() 300 } 301 302 #[inline] 303 fn is_dead(&self) -> bool { 304 false 305 } 306 307 fn set_driver(&self, driver: Option<Weak<dyn Driver>>) { 308 self.inner.lock().driver = driver; 309 } 310 311 fn can_match(&self) -> bool { 312 todo!() 313 } 314 315 fn set_can_match(&self, _can_match: bool) { 316 todo!() 317 } 318 319 fn state_synced(&self) -> bool { 320 todo!() 321 } 322 323 fn set_class(&self, _class: Option<Weak<dyn Class>>) { 324 todo!() 325 } 326 } 327