xref: /DragonOS/kernel/src/driver/base/platform/platform_device.rs (revision 013ffb708fab7760ea999c1edf462c69ac68f0ac)
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)]
platform_device_manager() -> &'static PlatformDeviceManager34 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 {
pdev_name(&self) -> &str51     fn pdev_name(&self) -> &str;
52     /// 返回平台设备id,以及这个id是否是自动生成的
53     ///
54     /// 请注意,如果当前设备还没有id,应该返回
55     /// (PLATFORM_DEVID_NONE, false)
pdev_id(&self) -> (i32, bool)56     fn pdev_id(&self) -> (i32, bool) {
57         (PLATFORM_DEVID_NONE, false)
58     }
59 
60     /// 设置平台设备id
set_pdev_id(&self, id: i32)61     fn set_pdev_id(&self, id: i32);
62     /// 设置id是否为自动分配
set_pdev_id_auto(&self, id_auto: bool)63     fn set_pdev_id_auto(&self, id_auto: bool);
64 
65     /// @brief: 判断设备是否初始化
66     /// @parameter: None
67     /// @return: 如果已经初始化,返回true,否则,返回false
68     #[allow(dead_code)]
is_initialized(&self) -> bool69     fn is_initialized(&self) -> bool;
70 
71     /// @brief: 设置设备状态
72     /// @parameter set_state: 设备状态
73     /// @return: None
set_state(&self, set_state: DeviceState)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
device_add(&self, pdev: Arc<dyn PlatformDevice>) -> Result<(), SystemError>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总线实例
new( data: DevicePrivateData, parent: Option<Weak<dyn KObject>>, ) -> Arc<PlatformBusDevice>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)]
compatible_table(&self) -> CompatibleTable156     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)]
is_initialized(&self) -> bool165     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)]
set_state(&self, set_state: BusState)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)]
get_state(&self) -> BusState185     fn get_state(&self) -> BusState {
186         let state = self.inner.lock().state;
187         return state;
188     }
189 
inner(&self) -> SpinLockGuard<InnerPlatformBusDevice>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 {
new(data: DevicePrivateData) -> Self206     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 {
as_any_ref(&self) -> &dyn core::any::Any218     fn as_any_ref(&self) -> &dyn core::any::Any {
219         self
220     }
221 
parent(&self) -> Option<Weak<dyn KObject>>222     fn parent(&self) -> Option<Weak<dyn KObject>> {
223         self.inner().kobject_common.parent.clone()
224     }
225 
inode(&self) -> Option<Arc<KernFSInode>>226     fn inode(&self) -> Option<Arc<KernFSInode>> {
227         self.inner().kobject_common.kern_inode.clone()
228     }
229 
set_inode(&self, inode: Option<Arc<KernFSInode>>)230     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
231         self.inner().kobject_common.kern_inode = inode;
232     }
233 
kobj_type(&self) -> Option<&'static dyn KObjType>234     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
235         self.inner().kobject_common.kobj_type
236     }
237 
set_kobj_type(&self, ktype: Option<&'static dyn KObjType>)238     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
239         self.inner().kobject_common.kobj_type = ktype;
240     }
241 
kset(&self) -> Option<Arc<KSet>>242     fn kset(&self) -> Option<Arc<KSet>> {
243         self.inner().kobject_common.kset.clone()
244     }
245 
kobj_state(&self) -> RwLockReadGuard<KObjectState>246     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
247         self.kobj_state.read()
248     }
249 
kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>250     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
251         self.kobj_state.write()
252     }
253 
set_kobj_state(&self, state: KObjectState)254     fn set_kobj_state(&self, state: KObjectState) {
255         *self.kobj_state.write() = state;
256     }
257 
name(&self) -> String258     fn name(&self) -> String {
259         self.inner().name.clone()
260     }
261 
set_name(&self, name: String)262     fn set_name(&self, name: String) {
263         self.inner().name = name;
264     }
265 
set_kset(&self, kset: Option<Arc<KSet>>)266     fn set_kset(&self, kset: Option<Arc<KSet>>) {
267         self.inner().kobject_common.kset = kset;
268     }
269 
set_parent(&self, parent: Option<Weak<dyn KObject>>)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)]
dev_type(&self) -> DeviceType279     fn dev_type(&self) -> DeviceType {
280         return DeviceType::Bus;
281     }
282 
283     #[inline]
id_table(&self) -> IdTable284     fn id_table(&self) -> IdTable {
285         IdTable::new("platform".to_string(), None)
286     }
287 
bus(&self) -> Option<Weak<dyn Bus>>288     fn bus(&self) -> Option<Weak<dyn Bus>> {
289         self.inner().device_common.bus.clone()
290     }
291 
set_bus(&self, bus: Option<Weak<dyn Bus>>)292     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
293         self.inner().device_common.bus = bus;
294     }
295 
driver(&self) -> Option<Arc<dyn Driver>>296     fn driver(&self) -> Option<Arc<dyn Driver>> {
297         self.inner().device_common.driver.clone()?.upgrade()
298     }
299 
300     #[inline]
is_dead(&self) -> bool301     fn is_dead(&self) -> bool {
302         false
303     }
304 
set_driver(&self, driver: Option<Weak<dyn Driver>>)305     fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
306         self.inner().device_common.driver = driver;
307     }
308 
can_match(&self) -> bool309     fn can_match(&self) -> bool {
310         todo!()
311     }
312 
set_can_match(&self, _can_match: bool)313     fn set_can_match(&self, _can_match: bool) {
314         todo!()
315     }
316 
state_synced(&self) -> bool317     fn state_synced(&self) -> bool {
318         todo!()
319     }
320 
set_class(&self, class: Option<Weak<dyn Class>>)321     fn set_class(&self, class: Option<Weak<dyn Class>>) {
322         self.inner().device_common.class = class;
323     }
324 
dev_parent(&self) -> Option<Weak<dyn Device>>325     fn dev_parent(&self) -> Option<Weak<dyn Device>> {
326         self.inner().device_common.get_parent_weak_or_clear()
327     }
328 
set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>)329     fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
330         self.inner().device_common.parent = dev_parent;
331     }
332 }
333