xref: /DragonOS/kernel/src/driver/base/map/mod.rs (revision be63f3b2b6b472daa3ee17180aa607409cb9d182)
1 use super::device::{mkdev, DeviceNumber, KObject};
2 use crate::libs::spinlock::SpinLock;
3 use alloc::{collections::BTreeMap, sync::Arc, vec::Vec};
4 
5 const KOBJMAP_HASH_SIZE: usize = 255;
6 
7 /// @brief: 字符设备与块设备管理结构体
8 #[derive(Debug, Clone)]
9 struct Probe(Arc<dyn KObject>);
10 
11 impl Probe {
12     /// @brief: 新建probe实例
13     /// @parameter: data: probe实例
14     /// @return: probe实例
15     pub fn new(data: Arc<dyn KObject>) -> Self {
16         Self(data)
17     }
18 }
19 
20 /// @brief: 字符设备和块设备管理实例(锁)
21 #[derive(Debug)]
22 pub struct LockedKObjMap(SpinLock<KObjMap>);
23 
24 impl Default for LockedKObjMap {
25     fn default() -> Self {
26         Self(SpinLock::new(KObjMap::default()))
27     }
28 }
29 
30 /// @brief: 字符设备和块设备管理实例
31 #[derive(Debug, Clone)]
32 struct KObjMap(Vec<BTreeMap<DeviceNumber, Probe>>);
33 
34 impl Default for KObjMap {
35     fn default() -> Self {
36         Self(vec![BTreeMap::new(); KOBJMAP_HASH_SIZE])
37     }
38 }
39 
40 /// @brief: obj设备注册
41 /// @parameter: domain: 管理实例
42 ///             dev_t: 设备号
43 ///             range: 次设备号范围
44 ///             data: 设备实例
45 /// @return: none
46 pub fn kobj_map(
47     domain: Arc<LockedKObjMap>,
48     dev_t: DeviceNumber,
49     range: usize,
50     data: Arc<dyn KObject>,
51 ) {
52     if let Some(map) = domain.0.lock().0.get_mut(dev_t.major() % 255) {
53         for i in 0..range {
54             map.insert(
55                 mkdev(dev_t.major(), dev_t.minor() + i),
56                 Probe::new(data.clone()),
57             );
58         }
59     }
60 }
61 
62 /// @brief: obj设备注销
63 /// @parameter: domain: 管理实例
64 ///             dev_t: 设备号
65 ///             range: 次设备号范围
66 /// @return: none
67 pub fn kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize) {
68     if let Some(map) = domain.0.lock().0.get_mut(dev_t.major() % 255) {
69         for i in 0..range {
70             let rm_dev_t = &DeviceNumber::new(Into::<usize>::into(dev_t) + i);
71             match map.get(rm_dev_t) {
72                 Some(_) => {
73                     map.remove(rm_dev_t);
74                 }
75                 None => {}
76             }
77         }
78     }
79 }
80 
81 /// @brief: 设备查找
82 /// @parameter: domain: 管理实例
83 ///             dev_t: 设备号
84 /// @return: 查找成功,返回设备实例,否则返回None
85 #[allow(dead_code)]
86 pub fn kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Arc<dyn KObject>> {
87     if let Some(map) = domain.0.lock().0.get(dev_t.major() % 255) {
88         match map.get(&dev_t) {
89             Some(value) => {
90                 return Some(value.0.clone());
91             }
92             None => {
93                 return None;
94             }
95         }
96     }
97     return None;
98 }
99