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