xref: /DragonOS/kernel/src/driver/base/device/driver.rs (revision 7eda31b2f07c6ef41dc0d2bd13051f0fce5e5976)
1 use super::{
2     bus::{bus_manager, Bus},
3     Device, DeviceMatchName, DeviceMatcher, IdTable,
4 };
5 use crate::{
6     driver::base::kobject::KObject,
7     filesystem::sysfs::{sysfs_instance, Attribute, AttributeGroup},
8     syscall::SystemError,
9 };
10 use alloc::{sync::Arc, vec::Vec};
11 use core::fmt::Debug;
12 
13 /// @brief: Driver error
14 #[allow(dead_code)]
15 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
16 pub enum DriverError {
17     ProbeError,            // 探测设备失败(该驱动不能初始化这个设备)
18     RegisterError,         // 设备注册失败
19     AllocateResourceError, // 获取设备所需资源失败
20     UnsupportedOperation,  // 不支持的操作
21     UnInitialized,         // 未初始化
22 }
23 
24 impl Into<SystemError> for DriverError {
25     fn into(self) -> SystemError {
26         match self {
27             DriverError::ProbeError => SystemError::ENODEV,
28             DriverError::RegisterError => SystemError::ENODEV,
29             DriverError::AllocateResourceError => SystemError::EIO,
30             DriverError::UnsupportedOperation => SystemError::EIO,
31             DriverError::UnInitialized => SystemError::ENODEV,
32         }
33     }
34 }
35 
36 #[inline(always)]
37 pub fn driver_manager() -> &'static DriverManager {
38     &DriverManager
39 }
40 
41 /// 驱动程序应当实现的trait
42 ///
43 /// ## 注意
44 ///
45 /// 由于设备驱动模型需要从Arc<dyn KObject>转换为Arc<dyn Driver>,
46 /// 因此,所有的实现了 Driver trait的结构体,都应该在结构体上方标注`#[cast_to([sync] Driver)]`,
47 /// 否则在运行时会报错
48 pub trait Driver: Sync + Send + Debug + KObject {
49     fn coredump(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
50         Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
51     }
52 
53     /// @brief: 获取驱动标识符
54     /// @parameter: None
55     /// @return: 该驱动驱动唯一标识符
56     fn id_table(&self) -> Option<IdTable>;
57 
58     fn devices(&self) -> Vec<Arc<dyn Device>>;
59 
60     /// 把设备加入当前驱动管理的列表中
61     fn add_device(&self, device: Arc<dyn Device>);
62 
63     /// 从当前驱动管理的列表中删除设备
64     fn delete_device(&self, device: &Arc<dyn Device>);
65 
66     /// 根据设备名称查找绑定到驱动的设备
67     ///
68     /// 该方法是一个快速查找方法,要求驱动开发者自行实现。
69     ///
70     /// 如果开发者没有实现该方法,则应当返回None
71     ///
72     /// ## 注意
73     ///
74     /// 这是一个内部方法,不应当被外部调用,若要查找设备,请使用`find_device_by_name()`
75     fn __find_device_by_name_fast(&self, _name: &str) -> Option<Arc<dyn Device>> {
76         None
77     }
78 
79     /// 是否禁用sysfs的bind/unbind属性
80     ///
81     /// ## 返回
82     ///
83     /// - true: 禁用
84     /// - false: 不禁用(默认)
85     fn suppress_bind_attrs(&self) -> bool {
86         false
87     }
88 
89     fn bus(&self) -> Option<Arc<dyn Bus>> {
90         None
91     }
92 
93     fn set_bus(&self, bus: Option<Arc<dyn Bus>>);
94 
95     fn groups(&self) -> &'static [&'static dyn AttributeGroup] {
96         &[]
97     }
98 
99     fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
100         &[]
101     }
102 
103     /// 使用什么样的策略来探测设备
104     fn probe_type(&self) -> DriverProbeType {
105         DriverProbeType::DefaultStrategy
106     }
107 }
108 
109 impl dyn Driver {
110     pub fn allows_async_probing(&self) -> bool {
111         match self.probe_type() {
112             DriverProbeType::PreferAsync => true,
113             DriverProbeType::ForceSync => false,
114             DriverProbeType::DefaultStrategy => {
115                 // todo: 判断是否请求异步探测,如果是的话,就返回true
116 
117                 // 由于目前还没有支持异步探测,因此这里暂时返回false
118                 false
119             }
120         }
121     }
122 
123     /// 根据条件寻找一个绑定到这个驱动的设备(低效实现)
124     ///
125     /// ## 参数
126     ///
127     /// - `matcher` - 匹配器
128     /// - `data` - 传给匹配器的数据
129     ///
130     /// ## 注意
131     ///
132     /// 这里的默认实现很低效,请为特定的驱动自行实现高效的查询
133     fn find_device_slow<T: Copy>(
134         &self,
135         matcher: &dyn DeviceMatcher<T>,
136         data: T,
137     ) -> Option<Arc<dyn Device>> {
138         for dev in self.devices() {
139             if matcher.match_device(&dev, data) {
140                 return Some(dev);
141             }
142         }
143 
144         return None;
145     }
146 
147     /// 根据设备名称查找绑定到驱动的设备
148     ///
149     /// ## 注意
150     ///
151     /// 这里的默认实现很低效,请为特定的驱动自行实现高效的查询
152     pub fn find_device_by_name(&self, name: &str) -> Option<Arc<dyn Device>> {
153         if let Some(r) = self.__find_device_by_name_fast(name) {
154             return Some(r);
155         }
156 
157         return self.find_device_slow(&DeviceMatchName, name);
158     }
159 }
160 
161 /// @brief: 驱动管理器
162 #[derive(Debug, Clone)]
163 pub struct DriverManager;
164 
165 impl DriverManager {
166     /// 注册设备驱动。该设备驱动应当已经设置好其bus字段
167     ///
168     /// ## 参数
169     ///
170     /// - driver: 驱动
171     ///
172     /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/driver.c#222
173     pub fn register(&self, driver: Arc<dyn Driver>) -> Result<(), SystemError> {
174         let bus = driver.bus().ok_or_else(|| {
175             kerror!(
176                 "DriverManager::register() failed: driver.bus() is None. Driver: '{:?}'",
177                 driver.name()
178             );
179             SystemError::EINVAL
180         })?;
181 
182         let drv_name = driver.name();
183         let other = bus.find_driver_by_name(&drv_name);
184         if other.is_some() {
185             kerror!(
186                 "DriverManager::register() failed: driver '{}' already registered",
187                 drv_name
188             );
189             return Err(SystemError::EBUSY);
190         }
191 
192         bus_manager().add_driver(&driver)?;
193 
194         self.add_groups(&driver, driver.groups()).map_err(|e| {
195             bus_manager().remove_driver(&driver);
196             e
197         })?;
198 
199         // todo: 发送uevent
200 
201         return Ok(());
202     }
203 
204     /// 从系统中删除一个驱动程序
205     #[allow(dead_code)]
206     pub fn unregister(&self, driver: &Arc<dyn Driver>) {
207         self.remove_groups(driver, driver.groups());
208         bus_manager().remove_driver(driver);
209     }
210 
211     /// 参考: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#434
212     pub fn driver_sysfs_add(&self, _dev: &Arc<dyn Device>) -> Result<(), SystemError> {
213         todo!("DriverManager::driver_sysfs_add()");
214     }
215 
216     pub fn add_groups(
217         &self,
218         driver: &Arc<dyn Driver>,
219         groups: &'static [&dyn AttributeGroup],
220     ) -> Result<(), SystemError> {
221         let kobj = driver.clone() as Arc<dyn KObject>;
222         return sysfs_instance().create_groups(&kobj, groups);
223     }
224 
225     pub fn remove_groups(&self, driver: &Arc<dyn Driver>, groups: &'static [&dyn AttributeGroup]) {
226         let kobj = driver.clone() as Arc<dyn KObject>;
227         sysfs_instance().remove_groups(&kobj, groups);
228     }
229 
230     /// 为指定的驱动创建一个属性文件
231     ///
232     /// ## 参数
233     ///
234     /// - `driver` 要创建属性文件的驱动
235     /// - `attr` 属性
236     pub fn create_attr_file(
237         &self,
238         driver: &Arc<dyn Driver>,
239         attr: &'static dyn Attribute,
240     ) -> Result<(), SystemError> {
241         let kobj = driver.clone() as Arc<dyn KObject>;
242         return sysfs_instance().create_file(&kobj, attr);
243     }
244 
245     /// 为指定的驱动删除一个属性文件
246     ///
247     /// 如果属性不存在,也不会报错
248     ///
249     /// ## 参数
250     ///
251     /// - `driver` 要删除属性文件的驱动
252     /// - `attr` 属性
253     pub fn remove_attr_file(&self, driver: &Arc<dyn Driver>, attr: &'static dyn Attribute) {
254         let kobj = driver.clone() as Arc<dyn KObject>;
255         sysfs_instance().remove_file(&kobj, attr);
256     }
257 }
258 
259 /// 驱动匹配器
260 ///
261 /// 用于匹配驱动是否符合某个条件
262 ///
263 /// ## 参数
264 ///
265 /// - `T` - 匹配器的数据类型
266 /// - `data` - 匹配器的数据
267 pub trait DriverMatcher<T>: Debug {
268     fn match_driver(&self, driver: &Arc<dyn Driver>, data: T) -> bool;
269 }
270 
271 /// 根据名称匹配驱动
272 #[derive(Debug)]
273 pub struct DriverMatchName;
274 
275 impl DriverMatcher<&str> for DriverMatchName {
276     #[inline(always)]
277     fn match_driver(&self, driver: &Arc<dyn Driver>, data: &str) -> bool {
278         driver.name() == data
279     }
280 }
281 
282 /// enum probe_type - device driver probe type to try
283 ///	Device drivers may opt in for special handling of their
284 ///	respective probe routines. This tells the core what to
285 ///	expect and prefer.
286 ///
287 /// Note that the end goal is to switch the kernel to use asynchronous
288 /// probing by default, so annotating drivers with
289 /// %PROBE_PREFER_ASYNCHRONOUS is a temporary measure that allows us
290 /// to speed up boot process while we are validating the rest of the
291 /// drivers.
292 #[allow(dead_code)]
293 #[derive(Debug)]
294 pub enum DriverProbeType {
295     /// Used by drivers that work equally well
296     ///	whether probed synchronously or asynchronously.
297     DefaultStrategy,
298 
299     /// Drivers for "slow" devices which
300     ///	probing order is not essential for booting the system may
301     ///	opt into executing their probes asynchronously.
302     PreferAsync,
303 
304     /// Use this to annotate drivers that need
305     ///	their probe routines to run synchronously with driver and
306     ///	device registration (with the exception of -EPROBE_DEFER
307     ///	handling - re-probing always ends up being done asynchronously).
308     ForceSync,
309 }
310 
311 impl Default for DriverProbeType {
312     fn default() -> Self {
313         DriverProbeType::DefaultStrategy
314     }
315 }
316