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