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