xref: /DragonOS/kernel/src/driver/base/platform/platform_device.rs (revision c75089286e9d49cef8d039446bf570c1bd4d2550)
1 use alloc::{
2     string::{String, ToString},
3     sync::{Arc, Weak},
4 };
5 use ida::IdAllocator;
6 
7 use crate::{
8     driver::base::{
9         device::{
10             bus::{Bus, BusState},
11             device_manager,
12             driver::Driver,
13             Device, DeviceNumber, DevicePrivateData, DeviceType, IdTable,
14         },
15         kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
16         kset::KSet,
17     },
18     filesystem::kernfs::KernFSInode,
19     libs::{
20         rwlock::{RwLockReadGuard, RwLockWriteGuard},
21         spinlock::SpinLock,
22     },
23     syscall::SystemError,
24 };
25 
26 use super::{super::device::DeviceState, platform_bus, platform_bus_device, CompatibleTable};
27 
28 /// 平台设备id分配器
29 static PLATFORM_DEVID_IDA: IdAllocator = IdAllocator::new(0, i32::MAX as usize);
30 
31 #[inline(always)]
32 pub fn platform_device_manager() -> &'static PlatformDeviceManager {
33     &PlatformDeviceManager
34 }
35 
36 /// 没有平台设备id
37 pub const PLATFORM_DEVID_NONE: i32 = -1;
38 /// 请求自动分配这个平台设备id
39 pub const PLATFORM_DEVID_AUTO: i32 = -2;
40 
41 /// @brief: 实现该trait的设备实例应挂载在platform总线上,
42 ///         同时应该实现Device trait
43 ///
44 /// ## 注意
45 ///
46 /// 应当在所有实现这个trait的结构体上方,添加 `#[cast_to([sync] PlatformDriver)]`,
47 /// 否则运行时将报错“该对象不是PlatformDriver”
48 pub trait PlatformDevice: Device {
49     fn pdev_name(&self) -> &str;
50     /// 返回平台设备id,以及这个id是否是自动生成的
51     ///
52     /// 请注意,如果当前设备还没有id,应该返回
53     /// (PLATFORM_DEVID_NONE, false)
54     fn pdev_id(&self) -> (i32, bool) {
55         (PLATFORM_DEVID_NONE, false)
56     }
57 
58     /// 设置平台设备id
59     fn set_pdev_id(&self, id: i32);
60     /// 设置id是否为自动分配
61     fn set_pdev_id_auto(&self, id_auto: bool);
62 
63     fn compatible_table(&self) -> CompatibleTable;
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(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(format!("{}", pdev.pdev_name()));
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://opengrok.ringotek.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         match state {
161             BusState::Initialized => true,
162             _ => false,
163         }
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 
187 #[allow(dead_code)]
188 #[derive(Debug, Clone)]
189 pub struct InnerPlatformBusDevice {
190     name: String,
191     data: DevicePrivateData,
192     state: BusState,                   // 总线状态
193     parent: Option<Weak<dyn KObject>>, // 总线的父对象
194 
195     kernfs_inode: Option<Arc<KernFSInode>>,
196     /// 当前设备挂载到的总线
197     bus: Option<Arc<dyn Bus>>,
198     /// 当前设备已经匹配的驱动
199     driver: Option<Weak<dyn Driver>>,
200 
201     ktype: Option<&'static dyn KObjType>,
202     kset: Option<Arc<KSet>>,
203 }
204 
205 impl InnerPlatformBusDevice {
206     pub fn new(data: DevicePrivateData, parent: Option<Weak<dyn KObject>>) -> Self {
207         Self {
208             data,
209             name: "platform".to_string(),
210             state: BusState::NotInitialized,
211             parent,
212             kernfs_inode: None,
213             bus: None,
214             driver: None,
215             ktype: None,
216             kset: None,
217         }
218     }
219 }
220 
221 impl KObject for PlatformBusDevice {
222     fn as_any_ref(&self) -> &dyn core::any::Any {
223         self
224     }
225 
226     fn parent(&self) -> Option<Weak<dyn KObject>> {
227         self.inner.lock().parent.clone()
228     }
229 
230     fn inode(&self) -> Option<Arc<KernFSInode>> {
231         self.inner.lock().kernfs_inode.clone()
232     }
233 
234     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
235         self.inner.lock().kernfs_inode = inode;
236     }
237 
238     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
239         self.inner.lock().ktype.clone()
240     }
241 
242     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
243         self.inner.lock().ktype = ktype;
244     }
245 
246     fn kset(&self) -> Option<Arc<KSet>> {
247         self.inner.lock().kset.clone()
248     }
249 
250     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
251         self.kobj_state.read()
252     }
253 
254     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
255         self.kobj_state.write()
256     }
257 
258     fn set_kobj_state(&self, state: KObjectState) {
259         *self.kobj_state.write() = state;
260     }
261 
262     fn name(&self) -> String {
263         self.inner.lock().name.clone()
264     }
265 
266     fn set_name(&self, name: String) {
267         self.inner.lock().name = name;
268     }
269 
270     fn set_kset(&self, kset: Option<Arc<KSet>>) {
271         self.inner.lock().kset = kset;
272     }
273 
274     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
275         self.inner.lock().parent = parent;
276     }
277 }
278 
279 /// @brief: 为Platform实现Device trait,platform总线也是一种设备,属于总线设备类型
280 impl Device for PlatformBusDevice {
281     #[inline]
282     #[allow(dead_code)]
283     fn dev_type(&self) -> DeviceType {
284         return DeviceType::Bus;
285     }
286 
287     #[inline]
288     #[allow(dead_code)]
289     fn id_table(&self) -> IdTable {
290         IdTable::new("platform".to_string(), DeviceNumber::new(0))
291     }
292 
293     fn bus(&self) -> Option<Arc<dyn Bus>> {
294         self.inner.lock().bus.clone()
295     }
296 
297     fn set_bus(&self, bus: Option<Arc<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