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)]
platform_device_manager() -> &'static PlatformDeviceManager33 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 {
pdev_name(&self) -> &str50 fn pdev_name(&self) -> &str;
51 /// 返回平台设备id,以及这个id是否是自动生成的
52 ///
53 /// 请注意,如果当前设备还没有id,应该返回
54 /// (PLATFORM_DEVID_NONE, false)
pdev_id(&self) -> (i32, bool)55 fn pdev_id(&self) -> (i32, bool) {
56 (PLATFORM_DEVID_NONE, false)
57 }
58
59 /// 设置平台设备id
set_pdev_id(&self, id: i32)60 fn set_pdev_id(&self, id: i32);
61 /// 设置id是否为自动分配
set_pdev_id_auto(&self, id_auto: bool)62 fn set_pdev_id_auto(&self, id_auto: bool);
63
64 /// @brief: 判断设备是否初始化
65 /// @parameter: None
66 /// @return: 如果已经初始化,返回true,否则,返回false
67 #[allow(dead_code)]
is_initialized(&self) -> bool68 fn is_initialized(&self) -> bool;
69
70 /// @brief: 设置设备状态
71 /// @parameter set_state: 设备状态
72 /// @return: None
set_state(&self, set_state: DeviceState)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
device_add(&self, pdev: Arc<dyn PlatformDevice>) -> Result<(), SystemError>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总线实例
new( data: DevicePrivateData, parent: Option<Weak<dyn KObject>>, ) -> Arc<PlatformBusDevice>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)]
compatible_table(&self) -> CompatibleTable152 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)]
is_initialized(&self) -> bool161 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)]
set_state(&self, set_state: BusState)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)]
get_state(&self) -> BusState181 fn get_state(&self) -> BusState {
182 let state = self.inner.lock().state;
183 return state;
184 }
185
inner(&self) -> SpinLockGuard<InnerPlatformBusDevice>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 {
new(data: DevicePrivateData) -> Self202 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 {
as_any_ref(&self) -> &dyn core::any::Any214 fn as_any_ref(&self) -> &dyn core::any::Any {
215 self
216 }
217
parent(&self) -> Option<Weak<dyn KObject>>218 fn parent(&self) -> Option<Weak<dyn KObject>> {
219 self.inner().kobject_common.parent.clone()
220 }
221
inode(&self) -> Option<Arc<KernFSInode>>222 fn inode(&self) -> Option<Arc<KernFSInode>> {
223 self.inner().kobject_common.kern_inode.clone()
224 }
225
set_inode(&self, inode: Option<Arc<KernFSInode>>)226 fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
227 self.inner().kobject_common.kern_inode = inode;
228 }
229
kobj_type(&self) -> Option<&'static dyn KObjType>230 fn kobj_type(&self) -> Option<&'static dyn KObjType> {
231 self.inner().kobject_common.kobj_type
232 }
233
set_kobj_type(&self, ktype: Option<&'static dyn KObjType>)234 fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
235 self.inner().kobject_common.kobj_type = ktype;
236 }
237
kset(&self) -> Option<Arc<KSet>>238 fn kset(&self) -> Option<Arc<KSet>> {
239 self.inner().kobject_common.kset.clone()
240 }
241
kobj_state(&self) -> RwLockReadGuard<KObjectState>242 fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
243 self.kobj_state.read()
244 }
245
kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>246 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
247 self.kobj_state.write()
248 }
249
set_kobj_state(&self, state: KObjectState)250 fn set_kobj_state(&self, state: KObjectState) {
251 *self.kobj_state.write() = state;
252 }
253
name(&self) -> String254 fn name(&self) -> String {
255 self.inner().name.clone()
256 }
257
set_name(&self, name: String)258 fn set_name(&self, name: String) {
259 self.inner().name = name;
260 }
261
set_kset(&self, kset: Option<Arc<KSet>>)262 fn set_kset(&self, kset: Option<Arc<KSet>>) {
263 self.inner().kobject_common.kset = kset;
264 }
265
set_parent(&self, parent: Option<Weak<dyn KObject>>)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)]
dev_type(&self) -> DeviceType275 fn dev_type(&self) -> DeviceType {
276 return DeviceType::Bus;
277 }
278
279 #[inline]
id_table(&self) -> IdTable280 fn id_table(&self) -> IdTable {
281 IdTable::new("platform".to_string(), None)
282 }
283
bus(&self) -> Option<Weak<dyn Bus>>284 fn bus(&self) -> Option<Weak<dyn Bus>> {
285 self.inner().device_common.bus.clone()
286 }
287
set_bus(&self, bus: Option<Weak<dyn Bus>>)288 fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
289 self.inner().device_common.bus = bus;
290 }
291
driver(&self) -> Option<Arc<dyn Driver>>292 fn driver(&self) -> Option<Arc<dyn Driver>> {
293 self.inner().device_common.driver.clone()?.upgrade()
294 }
295
296 #[inline]
is_dead(&self) -> bool297 fn is_dead(&self) -> bool {
298 false
299 }
300
set_driver(&self, driver: Option<Weak<dyn Driver>>)301 fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
302 self.inner().device_common.driver = driver;
303 }
304
can_match(&self) -> bool305 fn can_match(&self) -> bool {
306 todo!()
307 }
308
set_can_match(&self, _can_match: bool)309 fn set_can_match(&self, _can_match: bool) {
310 todo!()
311 }
312
state_synced(&self) -> bool313 fn state_synced(&self) -> bool {
314 todo!()
315 }
316
set_class(&self, class: Option<Weak<dyn Class>>)317 fn set_class(&self, class: Option<Weak<dyn Class>>) {
318 self.inner().device_common.class = class;
319 }
320
dev_parent(&self) -> Option<Weak<dyn Device>>321 fn dev_parent(&self) -> Option<Weak<dyn Device>> {
322 self.inner().device_common.get_parent_weak_or_clear()
323 }
324
set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>)325 fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
326 self.inner().device_common.parent = dev_parent;
327 }
328 }
329