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: 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 #[allow(dead_code)] 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.dev_parent().is_none() { 83 pdev.set_dev_parent(Some(Arc::downgrade( 84 &(platform_bus_device() as Arc<dyn Device>), 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 let platform_bus_device = Self { 140 inner: SpinLock::new(InnerPlatformBusDevice::new(data)), 141 kobj_state: LockedKObjectState::new(None), 142 }; 143 platform_bus_device.set_parent(parent); 144 return Arc::new(platform_bus_device); 145 } 146 147 /// @brief: 获取总线的匹配表 148 /// @parameter: None 149 /// @return: platform总线匹配表 150 #[inline] 151 #[allow(dead_code)] 152 fn compatible_table(&self) -> CompatibleTable { 153 CompatibleTable::new(vec!["platform"]) 154 } 155 156 /// @brief: 判断总线是否初始化 157 /// @parameter: None 158 /// @return: 已初始化,返回true,否则,返回false 159 #[inline] 160 #[allow(dead_code)] 161 fn is_initialized(&self) -> bool { 162 let state = self.inner.lock().state; 163 matches!(state, BusState::Initialized) 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 fn inner(&self) -> SpinLockGuard<InnerPlatformBusDevice> { 187 self.inner.lock() 188 } 189 } 190 191 #[allow(dead_code)] 192 #[derive(Debug)] 193 pub struct InnerPlatformBusDevice { 194 name: String, 195 data: DevicePrivateData, 196 state: BusState, // 总线状态 197 kobject_common: KObjectCommonData, 198 device_common: DeviceCommonData, 199 } 200 201 impl InnerPlatformBusDevice { 202 pub fn new(data: DevicePrivateData) -> Self { 203 Self { 204 data, 205 name: "platform".to_string(), 206 state: BusState::NotInitialized, 207 kobject_common: KObjectCommonData::default(), 208 device_common: DeviceCommonData::default(), 209 } 210 } 211 } 212 213 impl KObject for PlatformBusDevice { 214 fn as_any_ref(&self) -> &dyn core::any::Any { 215 self 216 } 217 218 fn parent(&self) -> Option<Weak<dyn KObject>> { 219 self.inner().kobject_common.parent.clone() 220 } 221 222 fn inode(&self) -> Option<Arc<KernFSInode>> { 223 self.inner().kobject_common.kern_inode.clone() 224 } 225 226 fn set_inode(&self, inode: Option<Arc<KernFSInode>>) { 227 self.inner().kobject_common.kern_inode = inode; 228 } 229 230 fn kobj_type(&self) -> Option<&'static dyn KObjType> { 231 self.inner().kobject_common.kobj_type 232 } 233 234 fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { 235 self.inner().kobject_common.kobj_type = ktype; 236 } 237 238 fn kset(&self) -> Option<Arc<KSet>> { 239 self.inner().kobject_common.kset.clone() 240 } 241 242 fn kobj_state(&self) -> RwLockReadGuard<KObjectState> { 243 self.kobj_state.read() 244 } 245 246 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> { 247 self.kobj_state.write() 248 } 249 250 fn set_kobj_state(&self, state: KObjectState) { 251 *self.kobj_state.write() = state; 252 } 253 254 fn name(&self) -> String { 255 self.inner().name.clone() 256 } 257 258 fn set_name(&self, name: String) { 259 self.inner().name = name; 260 } 261 262 fn set_kset(&self, kset: Option<Arc<KSet>>) { 263 self.inner().kobject_common.kset = kset; 264 } 265 266 fn set_parent(&self, parent: Option<Weak<dyn KObject>>) { 267 self.inner().kobject_common.parent = parent; 268 } 269 } 270 271 /// @brief: 为Platform实现Device trait,platform总线也是一种设备,属于总线设备类型 272 impl Device for PlatformBusDevice { 273 #[inline] 274 #[allow(dead_code)] 275 fn dev_type(&self) -> DeviceType { 276 return DeviceType::Bus; 277 } 278 279 #[inline] 280 fn id_table(&self) -> IdTable { 281 IdTable::new("platform".to_string(), None) 282 } 283 284 fn bus(&self) -> Option<Weak<dyn Bus>> { 285 self.inner().device_common.bus.clone() 286 } 287 288 fn set_bus(&self, bus: Option<Weak<dyn Bus>>) { 289 self.inner().device_common.bus = bus; 290 } 291 292 fn driver(&self) -> Option<Arc<dyn Driver>> { 293 self.inner().device_common.driver.clone()?.upgrade() 294 } 295 296 #[inline] 297 fn is_dead(&self) -> bool { 298 false 299 } 300 301 fn set_driver(&self, driver: Option<Weak<dyn Driver>>) { 302 self.inner().device_common.driver = driver; 303 } 304 305 fn can_match(&self) -> bool { 306 todo!() 307 } 308 309 fn set_can_match(&self, _can_match: bool) { 310 todo!() 311 } 312 313 fn state_synced(&self) -> bool { 314 todo!() 315 } 316 317 fn set_class(&self, class: Option<Weak<dyn Class>>) { 318 self.inner().device_common.class = class; 319 } 320 321 fn dev_parent(&self) -> Option<Weak<dyn Device>> { 322 self.inner().device_common.get_parent_weak_or_clear() 323 } 324 325 fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) { 326 self.inner().device_common.parent = dev_parent; 327 } 328 } 329