xref: /DragonOS/kernel/src/driver/base/map/mod.rs (revision c75ef4e2126c180bf04c08635ffa5a278619c035)
1 use core::ops::{Deref, DerefMut};
2 
3 use super::{
4     device::device_number::{DeviceNumber, Major},
5     kobject::KObject,
6 };
7 use crate::libs::spinlock::{SpinLock, SpinLockGuard};
8 use alloc::{collections::BTreeMap, sync::Arc, vec::Vec};
9 
10 const KOBJMAP_HASH_SIZE: usize = 255;
11 pub(crate) const DEV_MAJOR_HASH_SIZE: u32 = 255;
12 pub(crate) const DEV_MAJOR_MAX: Major = Major::new(512);
13 
14 /* Marks the bottom of the first segment of free char majors */
15 pub(crate) const DEV_MAJOR_DYN_END: Major = Major::new(234);
16 /* Marks the top and bottom of the second segment of free char majors */
17 pub(crate) const DEV_MAJOR_DYN_EXT_START: Major = Major::new(511);
18 pub(crate) const DEV_MAJOR_DYN_EXT_END: Major = Major::new(384);
19 
20 /// @brief: 字符设备与块设备管理结构体
21 #[derive(Debug, Clone)]
22 struct Probe(Arc<dyn KObject>);
23 
24 impl Probe {
25     /// @brief: 新建probe实例
26     /// @parameter: data: probe实例
27     /// @return: probe实例
28     pub fn new(data: Arc<dyn KObject>) -> Self {
29         Self(data)
30     }
31 }
32 
33 /// @brief: 字符设备和块设备管理实例(锁)
34 #[derive(Debug)]
35 pub struct LockedKObjMap(SpinLock<KObjMap>);
36 
37 impl Default for LockedKObjMap {
38     fn default() -> Self {
39         Self(SpinLock::new(KObjMap::default()))
40     }
41 }
42 
43 /// @brief: 字符设备和块设备管理实例
44 #[derive(Debug, Clone)]
45 struct KObjMap(Vec<BTreeMap<DeviceNumber, Probe>>);
46 
47 impl Default for KObjMap {
48     fn default() -> Self {
49         Self(vec![BTreeMap::new(); KOBJMAP_HASH_SIZE])
50     }
51 }
52 
53 /// @brief: obj设备注册
54 /// @parameter: domain: 管理实例
55 ///             dev_t: 设备号
56 ///             range: 次设备号范围
57 ///             data: 设备实例
58 /// @return: none
59 pub fn kobj_map(
60     domain: Arc<LockedKObjMap>,
61     dev_t: DeviceNumber,
62     range: usize,
63     data: Arc<dyn KObject>,
64 ) {
65     if let Some(map) = domain
66         .0
67         .lock()
68         .0
69         .get_mut((dev_t.major().data() % 255) as usize)
70     {
71         for i in 0..range {
72             map.insert(
73                 DeviceNumber::new(dev_t.major(), dev_t.minor() + i as u32),
74                 Probe::new(data.clone()),
75             );
76         }
77     }
78 }
79 
80 /// @brief: obj设备注销
81 /// @parameter: domain: 管理实例
82 ///             dev_t: 设备号
83 ///             range: 次设备号范围
84 /// @return: none
85 pub fn kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize) {
86     if let Some(map) = domain
87         .0
88         .lock()
89         .0
90         .get_mut((dev_t.major().data() % 255) as usize)
91     {
92         for i in 0..range {
93             let rm_dev_t = &DeviceNumber::new(dev_t.major(), dev_t.minor() + i as u32);
94             match map.get(rm_dev_t) {
95                 Some(_) => {
96                     map.remove(rm_dev_t);
97                 }
98                 None => {}
99             }
100         }
101     }
102 }
103 
104 /// @brief: 设备查找
105 /// @parameter: domain: 管理实例
106 ///             dev_t: 设备号
107 /// @return: 查找成功,返回设备实例,否则返回None
108 #[allow(dead_code)]
109 pub fn kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Arc<dyn KObject>> {
110     if let Some(map) = domain.0.lock().0.get((dev_t.major().data() % 255) as usize) {
111         match map.get(&dev_t) {
112             Some(value) => {
113                 return Some(value.0.clone());
114             }
115             None => {
116                 return None;
117             }
118         }
119     }
120     return None;
121 }
122 
123 // 管理字符设备号的map(加锁)
124 pub struct LockedDevsMap(SpinLock<DevsMap>);
125 
126 impl Default for LockedDevsMap {
127     fn default() -> Self {
128         LockedDevsMap(SpinLock::new(DevsMap::default()))
129     }
130 }
131 
132 impl LockedDevsMap {
133     #[inline(always)]
134     pub fn lock(&self) -> SpinLockGuard<DevsMap> {
135         self.0.lock()
136     }
137 }
138 
139 // 管理字符设备号的map
140 #[derive(Debug)]
141 pub struct DevsMap(Vec<Vec<DeviceStruct>>);
142 
143 impl Default for DevsMap {
144     fn default() -> Self {
145         DevsMap(vec![Vec::new(); DEV_MAJOR_HASH_SIZE as usize])
146     }
147 }
148 
149 impl Deref for DevsMap {
150     type Target = Vec<Vec<DeviceStruct>>;
151 
152     fn deref(&self) -> &Self::Target {
153         &self.0
154     }
155 }
156 
157 impl DerefMut for DevsMap {
158     fn deref_mut(&mut self) -> &mut Self::Target {
159         &mut self.0
160     }
161 }
162 
163 // 字符设备在系统中的实例,devfs通过该结构与实际字符设备进行联系
164 #[allow(dead_code)]
165 #[derive(Debug, Clone)]
166 pub struct DeviceStruct {
167     dev_t: DeviceNumber, //起始设备号
168     minorct: u32,        // 次设备号数量
169     name: &'static str,  //字符设备名
170 }
171 
172 impl DeviceStruct {
173     /// @brief: 创建实例
174     /// @parameter: dev_t: 设备号
175     ///             minorct: 次设备号数量
176     ///             name: 字符设备名
177     ///             char: 字符设备实例
178     /// @return: 实例
179     ///
180     #[allow(dead_code)]
181     pub fn new(dev_t: DeviceNumber, minorct: u32, name: &'static str) -> Self {
182         Self {
183             dev_t,
184             minorct,
185             name,
186         }
187     }
188 
189     /// @brief: 获取起始次设备号
190     /// @parameter: None
191     /// @return: 起始设备号
192     ///
193     #[allow(dead_code)]
194     pub fn device_number(&self) -> DeviceNumber {
195         self.dev_t
196     }
197 
198     /// @brief: 获取起始次设备号
199     /// @parameter: None
200     /// @return: 起始设备号
201     ///
202     #[allow(dead_code)]
203     pub fn base_minor(&self) -> u32 {
204         self.dev_t.minor()
205     }
206 
207     /// @brief: 获取次设备号数量
208     /// @parameter: None
209     /// @return: 次设备号数量
210     #[allow(dead_code)]
211     pub fn minorct(&self) -> u32 {
212         self.minorct
213     }
214 }
215