xref: /DragonOS/kernel/src/driver/base/device/mod.rs (revision 06d5e247267cb65b84a80f219853ccd0f384b16e)
1 use alloc::{
2     string::{String, ToString},
3     sync::Arc,
4 };
5 use intertrait::cast::CastArc;
6 
7 use crate::{
8     driver::{
9         acpi::glue::acpi_device_notify,
10         base::map::{LockedDevsMap, LockedKObjMap},
11         Driver,
12     },
13     filesystem::{
14         sysfs::{sysfs_instance, Attribute, AttributeGroup, SysFSOps, SysFSOpsSupport},
15         vfs::syscall::ModeType,
16     },
17     syscall::SystemError,
18 };
19 use core::fmt::Debug;
20 use core::intrinsics::unlikely;
21 
22 use self::bus::{bus_add_device, bus_probe_device, Bus};
23 
24 use super::{
25     kobject::{KObjType, KObject, KObjectManager},
26     kset::KSet,
27     platform::CompatibleTable,
28     swnode::software_node_notify,
29 };
30 
31 pub mod bus;
32 pub mod dd;
33 pub mod driver;
34 pub mod init;
35 
36 static mut DEVICE_MANAGER: Option<DeviceManager> = None;
37 
38 #[inline(always)]
39 pub fn device_manager() -> &'static DeviceManager {
40     unsafe { DEVICE_MANAGER.as_ref().unwrap() }
41 }
42 
43 lazy_static! {
44     // 全局字符设备号管理实例
45     pub static ref CHARDEVS: Arc<LockedDevsMap> = Arc::new(LockedDevsMap::default());
46 
47     // 全局块设备管理实例
48     pub static ref BLOCKDEVS: Arc<LockedDevsMap> = Arc::new(LockedDevsMap::default());
49 
50     // 全局设备管理实例
51     pub static ref DEVMAP: Arc<LockedKObjMap> = Arc::new(LockedKObjMap::default());
52 
53 }
54 
55 /// `/sys/devices` 的 kset 实例
56 static mut DEVICES_KSET_INSTANCE: Option<Arc<KSet>> = None;
57 /// `/sys/dev` 的 kset 实例
58 static mut DEV_KSET_INSTANCE: Option<Arc<KSet>> = None;
59 /// `/sys/dev/block` 的 kset 实例
60 static mut DEV_BLOCK_KSET_INSTANCE: Option<Arc<KSet>> = None;
61 /// `/sys/dev/char` 的 kset 实例
62 static mut DEV_CHAR_KSET_INSTANCE: Option<Arc<KSet>> = None;
63 
64 #[inline(always)]
65 pub(super) fn sys_devices_kset() -> Arc<KSet> {
66     unsafe { DEVICES_KSET_INSTANCE.as_ref().unwrap().clone() }
67 }
68 
69 #[inline(always)]
70 pub(super) fn sys_dev_kset() -> Arc<KSet> {
71     unsafe { DEV_KSET_INSTANCE.as_ref().unwrap().clone() }
72 }
73 
74 #[inline(always)]
75 #[allow(dead_code)]
76 pub(super) fn sys_dev_block_kset() -> Arc<KSet> {
77     unsafe { DEV_BLOCK_KSET_INSTANCE.as_ref().unwrap().clone() }
78 }
79 
80 #[inline(always)]
81 pub(self) fn sys_dev_char_kset() -> Arc<KSet> {
82     unsafe { DEV_CHAR_KSET_INSTANCE.as_ref().unwrap().clone() }
83 }
84 
85 /// 设备应该实现的操作
86 ///
87 /// ## 注意
88 ///
89 /// 由于设备驱动模型需要从Arc<dyn KObject>转换为Arc<dyn Device>,
90 /// 因此,所有的实现了Device trait的结构体,都应该在结构体上方标注`#[[sync] Device]`,
91 ///
92 /// 否则在释放设备资源的时候,会由于无法转换为Arc<dyn Device>而导致资源泄露,并且release回调函数也不会被调用。
93 pub trait Device: KObject {
94     // TODO: 待实现 open, close
95 
96     /// @brief: 获取设备类型
97     /// @parameter: None
98     /// @return: 实现该trait的设备所属类型
99     fn dev_type(&self) -> DeviceType;
100 
101     /// @brief: 获取设备标识
102     /// @parameter: None
103     /// @return: 该设备唯一标识
104     fn id_table(&self) -> IdTable;
105 
106     /// 设备释放时的回调函数
107     fn release(&self) {
108         let name = self.name();
109         kwarn!(
110             "device {} does not have a release() function, it is broken and must be fixed.",
111             name
112         );
113     }
114 
115     /// 获取当前设备所属的总线
116     fn bus(&self) -> Option<Arc<dyn Bus>> {
117         return None;
118     }
119 
120     /// 返回已经与当前设备匹配好的驱动程序
121     fn driver(&self) -> Option<Arc<dyn Driver>>;
122 
123     fn set_driver(&self, driver: Option<Arc<dyn Driver>>);
124 
125     /// 当前设备是否已经挂掉了
126     fn is_dead(&self) -> bool;
127 }
128 
129 // 暂定是不可修改的,在初始化的时候就要确定。以后可能会包括例如硬件中断包含的信息
130 #[allow(dead_code)]
131 #[derive(Debug, Clone)]
132 pub struct DevicePrivateData {
133     id_table: IdTable,
134     resource: Option<DeviceResource>,
135     compatible_table: CompatibleTable,
136     state: DeviceState,
137 }
138 
139 impl DevicePrivateData {
140     pub fn new(
141         id_table: IdTable,
142         resource: Option<DeviceResource>,
143         compatible_table: CompatibleTable,
144         state: DeviceState,
145     ) -> Self {
146         Self {
147             id_table,
148             resource,
149             compatible_table,
150             state,
151         }
152     }
153 
154     pub fn id_table(&self) -> &IdTable {
155         &self.id_table
156     }
157 
158     pub fn state(&self) -> DeviceState {
159         self.state
160     }
161 
162     #[allow(dead_code)]
163     pub fn resource(&self) -> Option<&DeviceResource> {
164         self.resource.as_ref()
165     }
166 
167     pub fn compatible_table(&self) -> &CompatibleTable {
168         &self.compatible_table
169     }
170 
171     pub fn set_state(&mut self, state: DeviceState) {
172         self.state = state;
173     }
174 }
175 
176 #[derive(Debug, Clone)]
177 pub struct DeviceResource {
178     //可能会用来保存例如 IRQ PWM 内存地址等需要申请的资源,将来由资源管理器+Framework框架进行管理。
179 }
180 
181 impl Default for DeviceResource {
182     fn default() -> Self {
183         return Self {};
184     }
185 }
186 
187 int_like!(DeviceNumber, usize);
188 
189 impl Default for DeviceNumber {
190     fn default() -> Self {
191         DeviceNumber(0)
192     }
193 }
194 
195 impl From<usize> for DeviceNumber {
196     fn from(dev_t: usize) -> Self {
197         DeviceNumber(dev_t)
198     }
199 }
200 
201 impl Into<usize> for DeviceNumber {
202     fn into(self) -> usize {
203         self.0
204     }
205 }
206 
207 impl core::hash::Hash for DeviceNumber {
208     fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
209         self.0.hash(state);
210     }
211 }
212 
213 impl DeviceNumber {
214     /// @brief: 获取主设备号
215     /// @parameter: none
216     /// @return: 主设备号
217     pub fn major(&self) -> usize {
218         (self.0 >> 8) & 0xffffff
219     }
220 
221     /// @brief: 获取次设备号
222     /// @parameter: none
223     /// @return: 次设备号
224     pub fn minor(&self) -> usize {
225         self.0 & 0xff
226     }
227 
228     pub fn from_major_minor(major: usize, minor: usize) -> usize {
229         ((major & 0xffffff) << 8) | (minor & 0xff)
230     }
231 }
232 
233 /// @brief: 根据主次设备号创建设备号实例
234 /// @parameter: major: 主设备号
235 ///             minor: 次设备号
236 /// @return: 设备号实例
237 pub fn mkdev(major: usize, minor: usize) -> DeviceNumber {
238     DeviceNumber(((major & 0xfff) << 20) | (minor & 0xfffff))
239 }
240 
241 /// @brief: 设备类型
242 #[allow(dead_code)]
243 #[derive(Debug, Eq, PartialEq)]
244 pub enum DeviceType {
245     Bus,
246     Net,
247     Gpu,
248     Input,
249     Block,
250     Rtc,
251     Serial,
252     Intc,
253     PlatformDev,
254 }
255 
256 /// @brief: 设备标识符类型
257 #[derive(Debug, Clone, Hash, PartialOrd, PartialEq, Ord, Eq)]
258 pub struct IdTable(String, DeviceNumber);
259 
260 /// @brief: 设备标识符操作方法集
261 impl IdTable {
262     /// @brief: 创建一个新的设备标识符
263     /// @parameter name: 设备名
264     /// @parameter id: 设备id
265     /// @return: 设备标识符
266     pub fn new(name: String, id: DeviceNumber) -> IdTable {
267         Self(name, id)
268     }
269 
270     /// @brief: 将设备标识符转换成name
271     /// @parameter None
272     /// @return: 设备名
273     pub fn name(&self) -> String {
274         return format!("{}:{}", self.0, self.1 .0);
275     }
276 
277     pub fn device_number(&self) -> DeviceNumber {
278         return self.1;
279     }
280 }
281 
282 impl Default for IdTable {
283     fn default() -> Self {
284         IdTable("unknown".to_string(), DeviceNumber::new(0))
285     }
286 }
287 
288 // 以现在的模型,设备在加载到系统中就是已经初始化的状态了,因此可以考虑把这个删掉
289 /// @brief: 设备当前状态
290 #[derive(Debug, Clone, Copy)]
291 pub enum DeviceState {
292     NotInitialized = 0,
293     Initialized = 1,
294     UnDefined = 2,
295 }
296 
297 /// @brief: 设备错误类型
298 #[allow(dead_code)]
299 #[derive(Debug, Copy, Clone)]
300 pub enum DeviceError {
301     DriverExists,         // 设备已存在
302     DeviceExists,         // 驱动已存在
303     InitializeFailed,     // 初始化错误
304     NotInitialized,       // 未初始化的设备
305     NoDeviceForDriver,    // 没有合适的设备匹配驱动
306     NoDriverForDevice,    // 没有合适的驱动匹配设备
307     RegisterError,        // 注册失败
308     UnsupportedOperation, // 不支持的操作
309 }
310 
311 impl Into<SystemError> for DeviceError {
312     fn into(self) -> SystemError {
313         match self {
314             DeviceError::DriverExists => SystemError::EEXIST,
315             DeviceError::DeviceExists => SystemError::EEXIST,
316             DeviceError::InitializeFailed => SystemError::EIO,
317             DeviceError::NotInitialized => SystemError::ENODEV,
318             DeviceError::NoDeviceForDriver => SystemError::ENODEV,
319             DeviceError::NoDriverForDevice => SystemError::ENODEV,
320             DeviceError::RegisterError => SystemError::EIO,
321             DeviceError::UnsupportedOperation => SystemError::EIO,
322         }
323     }
324 }
325 
326 /// @brief: 将u32类型转换为设备状态类型
327 impl From<u32> for DeviceState {
328     fn from(state: u32) -> Self {
329         match state {
330             0 => DeviceState::NotInitialized,
331             1 => DeviceState::Initialized,
332             _ => todo!(),
333         }
334     }
335 }
336 
337 /// @brief: 将设备状态转换为u32类型
338 impl From<DeviceState> for u32 {
339     fn from(state: DeviceState) -> Self {
340         match state {
341             DeviceState::NotInitialized => 0,
342             DeviceState::Initialized => 1,
343             DeviceState::UnDefined => 2,
344         }
345     }
346 }
347 
348 #[derive(Debug)]
349 pub struct DeviceKObjType;
350 
351 impl KObjType for DeviceKObjType {
352     // https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#2307
353     fn release(&self, kobj: Arc<dyn KObject>) {
354         let dev = kobj.cast::<dyn Device>().unwrap();
355         /*
356          * Some platform devices are driven without driver attached
357          * and managed resources may have been acquired.  Make sure
358          * all resources are released.
359          *
360          * Drivers still can add resources into device after device
361          * is deleted but alive, so release devres here to avoid
362          * possible memory leak.
363          */
364 
365         // todo: 在引入devres之后再实现
366         // devres_release_all(kobj);
367         dev.release();
368     }
369 
370     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
371         None
372     }
373 
374     fn sysfs_ops(&self) -> Option<&dyn SysFSOps> {
375         Some(&DeviceSysFSOps)
376     }
377 }
378 
379 #[derive(Debug)]
380 pub(super) struct DeviceSysFSOps;
381 
382 impl SysFSOps for DeviceSysFSOps {
383     fn store(
384         &self,
385         kobj: Arc<dyn KObject>,
386         attr: &dyn Attribute,
387         buf: &[u8],
388     ) -> Result<usize, SystemError> {
389         return attr.store(kobj, buf);
390     }
391 
392     fn show(
393         &self,
394         kobj: Arc<dyn KObject>,
395         attr: &dyn Attribute,
396         buf: &mut [u8],
397     ) -> Result<usize, SystemError> {
398         return attr.show(kobj, buf);
399     }
400 }
401 
402 /// @brief Device管理器
403 #[derive(Debug)]
404 pub struct DeviceManager;
405 
406 impl DeviceManager {
407     /// @brief: 创建一个新的设备管理器
408     /// @parameter: None
409     /// @return: DeviceManager实体
410     #[inline]
411     const fn new() -> DeviceManager {
412         return Self;
413     }
414 
415     /// @brief: 添加设备
416     /// @parameter id_table: 总线标识符,用于唯一标识该总线
417     /// @parameter dev: 设备实例
418     /// @return: None
419     ///
420     /// https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#3398
421     ///
422     /// todo: 完善错误处理逻辑:如果添加失败,需要将之前添加的内容全部回滚
423     #[inline]
424     #[allow(dead_code)]
425     pub fn add_device(&self, device: Arc<dyn Device>) -> Result<(), SystemError> {
426         // todo: 引入class后,在这里处理与parent相关的逻辑
427 
428         KObjectManager::add_kobj(device.clone() as Arc<dyn KObject>, None).map_err(|e| {
429             kerror!("add device '{:?}' failed: {:?}", device.name(), e);
430             e
431         })?;
432 
433         self.device_platform_notify(&device);
434 
435         self.add_class_symlinks(&device)?;
436 
437         self.add_attrs(&device)?;
438 
439         bus_add_device(&device)?;
440 
441         if device.id_table().device_number().major() != 0 {
442             self.create_file(&device, &DeviceAttrDev)?;
443 
444             self.create_sys_dev_entry(&device)?;
445         }
446 
447         // todo: Notify clients of device addition.This call must come
448         //  after dpm_sysfs_add() and before kobject_uevent().
449         // 参考:https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#3491
450 
451         // todo: 发送uevent
452 
453         // probe drivers for a new device
454         bus_probe_device(&device);
455 
456         return Ok(());
457     }
458 
459     /// @brief: 卸载设备
460     /// @parameter id_table: 总线标识符,用于唯一标识该设备
461     /// @return: None
462     #[inline]
463     #[allow(dead_code)]
464     pub fn remove_device(&self, _id_table: &IdTable) {
465         todo!()
466     }
467 
468     /// @brief: 获取设备
469     /// @parameter id_table: 设备标识符,用于唯一标识该设备
470     /// @return: 设备实例
471     #[inline]
472     #[allow(dead_code)]
473     pub fn find_device_by_idtable(&self, _id_table: &IdTable) -> Option<Arc<dyn Device>> {
474         todo!("find_device_by_idtable")
475     }
476 
477     fn device_platform_notify(&self, dev: &Arc<dyn Device>) {
478         acpi_device_notify(dev);
479         software_node_notify(dev);
480     }
481 
482     fn add_class_symlinks(&self, _dev: &Arc<dyn Device>) -> Result<(), SystemError> {
483         // todo: 引入class后,在这里处理与class相关的逻辑
484         // https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#3224
485 
486         return Ok(());
487     }
488 
489     /// 在sysfs中,为指定的设备创建属性文件
490     ///
491     /// ## 参数
492     ///
493     /// - `dev`: 设备
494     fn add_attrs(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> {
495         let kobj_type = dev.kobj_type();
496         if kobj_type.is_none() {
497             return Ok(());
498         }
499 
500         let kobj_type = kobj_type.unwrap();
501 
502         let attr_groups = kobj_type.attribute_groups();
503 
504         if attr_groups.is_none() {
505             return Ok(());
506         }
507 
508         self.add_groups(dev, attr_groups.unwrap())?;
509 
510         return Ok(());
511     }
512 
513     /// 在sysfs中,为指定的设备创建属性组,以及属性组中的属性文件
514     ///
515     /// ## 参数
516     ///
517     /// - `dev`: 设备
518     /// - `attr_groups`: 属性组
519     pub fn add_groups(
520         &self,
521         dev: &Arc<dyn Device>,
522         attr_groups: &'static [&dyn AttributeGroup],
523     ) -> Result<(), SystemError> {
524         let dev = dev.clone();
525         let binding = dev.arc_any();
526         let kobj: &Arc<dyn KObject> = binding.downcast_ref().unwrap();
527         return sysfs_instance().create_groups(kobj, attr_groups);
528     }
529 
530     /// 为设备在sysfs中创建属性文件
531     ///
532     /// ## 参数
533     ///
534     /// - `dev`: 设备
535     /// - `attr`: 属性
536     pub fn create_file(
537         &self,
538         dev: &Arc<dyn Device>,
539         attr: &'static dyn Attribute,
540     ) -> Result<(), SystemError> {
541         if unlikely(
542             attr.mode().contains(ModeType::S_IRUGO)
543                 && (!attr.support().contains(SysFSOpsSupport::SHOW)),
544         ) {
545             kwarn!(
546                 "Attribute '{}': read permission without 'show'",
547                 attr.name()
548             );
549         }
550         if unlikely(
551             attr.mode().contains(ModeType::S_IWUGO)
552                 && (!attr.support().contains(SysFSOpsSupport::STORE)),
553         ) {
554             kwarn!(
555                 "Attribute '{}': write permission without 'store'",
556                 attr.name()
557             );
558         }
559 
560         let kobj = dev.clone() as Arc<dyn KObject>;
561 
562         return sysfs_instance().create_file(&kobj, attr);
563     }
564 
565     /// 在/sys/dev下,或者设备所属的class下,为指定的设备创建链接
566     fn create_sys_dev_entry(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> {
567         let target_kobj = self.device_to_dev_kobj(dev);
568         let name = dev.id_table().name();
569         let current_kobj = dev.clone() as Arc<dyn KObject>;
570         return sysfs_instance().create_link(&current_kobj, &target_kobj, name);
571     }
572 
573     /// Delete symlink for device in `/sys/dev` or `/sys/class/<class_name>`
574     #[allow(dead_code)]
575     fn remove_sys_dev_entry(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> {
576         let kobj = self.device_to_dev_kobj(dev);
577         let name = dev.id_table().name();
578         return sysfs_instance().remove_link(&kobj, name);
579     }
580 
581     /// device_to_dev_kobj - select a /sys/dev/ directory for the device
582     ///
583     /// By default we select char/ for new entries.
584     ///
585     /// ## 参数
586     ///
587     /// - `dev`: 设备
588     fn device_to_dev_kobj(&self, _dev: &Arc<dyn Device>) -> Arc<dyn KObject> {
589         // todo: 处理class的逻辑
590         let kobj = sys_dev_char_kset().as_kobject();
591         return kobj;
592     }
593 
594     /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c?fi=device_links_force_bind#1226
595     pub fn device_links_force_bind(&self, _dev: &Arc<dyn Device>) {
596         todo!("device_links_force_bind")
597     }
598 }
599 
600 /// @brief: 设备注册
601 /// @parameter: name: 设备名
602 /// @return: 操作成功,返回(),操作失败,返回错误码
603 pub fn device_register<T: Device>(device: Arc<T>) -> Result<(), SystemError> {
604     return device_manager().add_device(device);
605 }
606 
607 /// @brief: 设备卸载
608 /// @parameter: name: 设备名
609 /// @return: 操作成功,返回(),操作失败,返回错误码
610 pub fn device_unregister<T: Device>(_device: Arc<T>) {
611     // DEVICE_MANAGER.add_device(device.id_table(), device.clone());
612     // match sys_device_unregister(&device.id_table().name()) {
613     //     Ok(_) => {
614     //         device.set_inode(None);
615     //         return Ok(());
616     //     }
617     //     Err(_) => Err(DeviceError::RegisterError),
618     // }
619     todo!("device_unregister")
620 }
621 
622 /// 设备文件夹下的`dev`文件的属性
623 #[derive(Debug, Clone, Copy)]
624 pub struct DeviceAttrDev;
625 
626 impl Attribute for DeviceAttrDev {
627     fn mode(&self) -> ModeType {
628         // 0o444
629         return ModeType::S_IRUGO;
630     }
631 
632     fn name(&self) -> &str {
633         "dev"
634     }
635 
636     fn show(&self, kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
637         let dev = kobj.cast::<dyn Device>().map_err(|kobj| {
638             kerror!(
639                 "Intertrait casting not implemented for kobj: {}",
640                 kobj.name()
641             );
642             SystemError::EOPNOTSUPP_OR_ENOTSUP
643         })?;
644 
645         return Ok(dev.id_table().device_number().into());
646     }
647 
648     fn support(&self) -> SysFSOpsSupport {
649         SysFSOpsSupport::SHOW
650     }
651 }
652 
653 /// 设备匹配器
654 ///
655 /// 用于匹配设备是否符合某个条件
656 ///
657 /// ## 参数
658 ///
659 /// - `T` - 匹配器的数据类型
660 /// - `data` - 匹配器的数据
661 pub trait DeviceMatcher<T>: Debug {
662     fn match_device(&self, device: &Arc<dyn Device>, data: T) -> bool;
663 }
664 
665 /// 用于根据名称匹配设备的匹配器
666 #[derive(Debug)]
667 pub struct DeviceMatchName;
668 
669 impl DeviceMatcher<&str> for DeviceMatchName {
670     #[inline]
671     fn match_device(&self, device: &Arc<dyn Device>, data: &str) -> bool {
672         return device.name() == data;
673     }
674 }
675