xref: /DragonOS/kernel/src/driver/base/class.rs (revision 81294aa2e6b257f0de5e3c28c3f3c89798330836)
1 use alloc::{string::ToString, sync::Arc};
2 
3 use core::fmt::Debug;
4 
5 use super::{
6     device::{sys_dev_char_kset, Device, DeviceMatchName, DeviceMatcher},
7     kobject::{KObjType, KObject},
8     kset::KSet,
9     subsys::SubSysPrivate,
10 };
11 use crate::filesystem::sysfs::{sysfs_instance, Attribute, AttributeGroup, SysFSOps};
12 use system_error::SystemError;
13 
14 /// `/sys/class`的kset
15 static mut CLASS_KSET_INSTANCE: Option<Arc<KSet>> = None;
16 
17 #[inline(always)]
18 #[allow(dead_code)]
19 pub fn sys_class_kset() -> Arc<KSet> {
20     unsafe { CLASS_KSET_INSTANCE.clone().unwrap() }
21 }
22 
23 /// 初始化`/sys/class`的kset
24 pub(super) fn classes_init() -> Result<(), SystemError> {
25     let class_kset = KSet::new("class".to_string());
26     class_kset
27         .register(None)
28         .expect("register class kset failed");
29     unsafe {
30         CLASS_KSET_INSTANCE = Some(class_kset);
31     }
32 
33     return Ok(());
34 }
35 
36 /// 设备分类
37 ///
38 /// 类是对设备的高级视图,它抽象了低级实现细节。
39 ///
40 /// 比如,驱动程序可能看到一个SCSI硬盘或一个ATA硬盘,但在类的这个级别,它们都只是硬盘。
41 /// 类允许用户空间根据设备的功能而不是它们如何连接或工作来操作设备。
42 ///
43 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/device/class.h#54
44 pub trait Class: Debug + Send + Sync {
45     /// 获取类的名称
46     fn name(&self) -> &'static str;
47 
48     /// 属于该类的设备的基本属性。
49     fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
50         return &[];
51     }
52 
53     /// 当前类的基本属性。
54     fn class_groups(&self) -> &'static [&'static dyn AttributeGroup] {
55         return &[];
56     }
57 
58     /// 表示此类的kobject,并将它链接到层次结构中。
59     ///
60     /// 当前class的所有设备,将会挂载到的`/sys/dev/`内的某个目录下。
61     fn dev_kobj(&self) -> Option<Arc<dyn KObject>>;
62 
63     fn set_dev_kobj(&self, kobj: Arc<dyn KObject>);
64 
65     /// subsystem应当拥有的数据
66     fn subsystem(&self) -> &SubSysPrivate;
67 
68     /// Called to release this class
69     fn class_release(&self) {}
70 }
71 
72 impl dyn Class {
73     /// 在class内,根据条件寻找一个特定的设备
74     ///
75     /// ## 参数
76     ///
77     /// - `matcher` - 匹配器
78     /// - `data` - 传给匹配器的数据
79     #[allow(dead_code)]
80     pub fn find_device<T: Copy>(
81         &self,
82         matcher: &dyn DeviceMatcher<T>,
83         data: T,
84     ) -> Option<Arc<dyn Device>> {
85         let subsys = self.subsystem();
86         let guard = subsys.devices();
87         for dev in guard.iter() {
88             let dev = dev.upgrade();
89             if let Some(dev) = dev {
90                 if matcher.match_device(&dev, data) {
91                     return Some(dev.clone());
92                 }
93             }
94         }
95         return None;
96     }
97 
98     /// 根据名称匹配设备
99     ///
100     /// ## 参数
101     ///
102     /// - name 设备名称
103     #[allow(dead_code)]
104     pub fn find_device_by_name(&self, name: &str) -> Option<Arc<dyn Device>> {
105         return self.find_device(&DeviceMatchName, name);
106     }
107 }
108 
109 #[inline(always)]
110 pub fn class_manager() -> &'static ClassManager {
111     return &ClassManager;
112 }
113 pub struct ClassManager;
114 
115 impl ClassManager {
116     /// 注册一个设备类
117     ///
118     /// 该方法会将设备类注册到`/sys/class`目录下,
119     /// 并创建它的默认属性组对应的文件。
120     ///
121     /// ## 参数
122     ///
123     /// - `class` - 设备类
124     pub fn class_register(&self, class: &Arc<dyn Class>) -> Result<(), SystemError> {
125         let subsystem = class.subsystem();
126         let subsys = subsystem.subsys();
127         subsys.set_name(class.name().to_string());
128 
129         if class.dev_kobj().is_none() {
130             class.set_dev_kobj(sys_dev_char_kset() as Arc<dyn KObject>);
131         }
132 
133         subsys.set_kobj_type(Some(&ClassKObjbectType));
134         subsystem.set_class(Some(Arc::downgrade(class)));
135 
136         subsys.register(Some(sys_class_kset()))?;
137 
138         sysfs_instance().create_groups(&(subsys as Arc<dyn KObject>), class.class_groups())?;
139 
140         return Ok(());
141     }
142 
143     /// 注销一个设备类
144     #[allow(dead_code)]
145     pub fn class_unregister(&self, class: &Arc<dyn Class>) {
146         let subsystem = class.subsystem();
147         let subsys = subsystem.subsys();
148         sysfs_instance().remove_groups(&(subsys.clone() as Arc<dyn KObject>), class.class_groups());
149         subsys.unregister();
150     }
151 }
152 
153 #[derive(Debug)]
154 pub struct ClassKObjbectType;
155 
156 impl KObjType for ClassKObjbectType {
157     fn sysfs_ops(&self) -> Option<&dyn SysFSOps> {
158         Some(&ClassSysFSOps)
159     }
160 
161     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
162         None
163     }
164 }
165 
166 #[derive(Debug)]
167 struct ClassSysFSOps;
168 
169 impl SysFSOps for ClassSysFSOps {
170     fn show(
171         &self,
172         _kobj: Arc<dyn KObject>,
173         _attr: &dyn Attribute,
174         _buf: &mut [u8],
175     ) -> Result<usize, SystemError> {
176         todo!()
177     }
178 
179     fn store(
180         &self,
181         _kobj: Arc<dyn KObject>,
182         _attr: &dyn Attribute,
183         _buf: &[u8],
184     ) -> Result<usize, SystemError> {
185         todo!()
186     }
187 }
188