xref: /DragonOS/kernel/src/driver/base/map/mod.rs (revision b5b571e02693d91eb6918d3b7561e088c3e7ee81)
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实例
new(data: Arc<dyn KObject>) -> Self28     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 {
default() -> Self38     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 {
default() -> Self48     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
kobj_map( domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize, data: Arc<dyn KObject>, )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
kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize)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             if map.get(rm_dev_t).is_some() {
95                 map.remove(rm_dev_t);
96             }
97         }
98     }
99 }
100 
101 /// @brief: 设备查找
102 /// @parameter: domain: 管理实例
103 ///             dev_t: 设备号
104 /// @return: 查找成功,返回设备实例,否则返回None
105 #[allow(dead_code)]
kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Arc<dyn KObject>>106 pub fn kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Arc<dyn KObject>> {
107     if let Some(map) = domain.0.lock().0.get((dev_t.major().data() % 255) as usize) {
108         match map.get(&dev_t) {
109             Some(value) => {
110                 return Some(value.0.clone());
111             }
112             None => {
113                 return None;
114             }
115         }
116     }
117     return None;
118 }
119 
120 // 管理字符设备号的map(加锁)
121 pub struct LockedDevsMap(SpinLock<DevsMap>);
122 
123 impl Default for LockedDevsMap {
default() -> Self124     fn default() -> Self {
125         LockedDevsMap(SpinLock::new(DevsMap::default()))
126     }
127 }
128 
129 impl LockedDevsMap {
130     #[inline(always)]
lock(&self) -> SpinLockGuard<DevsMap>131     pub fn lock(&self) -> SpinLockGuard<DevsMap> {
132         self.0.lock()
133     }
134 }
135 
136 // 管理字符设备号的map
137 #[derive(Debug)]
138 pub struct DevsMap(Vec<Vec<DeviceStruct>>);
139 
140 impl Default for DevsMap {
default() -> Self141     fn default() -> Self {
142         DevsMap(vec![Vec::new(); DEV_MAJOR_HASH_SIZE as usize])
143     }
144 }
145 
146 impl Deref for DevsMap {
147     type Target = Vec<Vec<DeviceStruct>>;
148 
deref(&self) -> &Self::Target149     fn deref(&self) -> &Self::Target {
150         &self.0
151     }
152 }
153 
154 impl DerefMut for DevsMap {
deref_mut(&mut self) -> &mut Self::Target155     fn deref_mut(&mut self) -> &mut Self::Target {
156         &mut self.0
157     }
158 }
159 
160 // 字符设备在系统中的实例,devfs通过该结构与实际字符设备进行联系
161 #[allow(dead_code)]
162 #[derive(Debug, Clone)]
163 pub struct DeviceStruct {
164     dev_t: DeviceNumber, //起始设备号
165     minorct: u32,        // 次设备号数量
166     name: &'static str,  //字符设备名
167 }
168 
169 impl DeviceStruct {
170     /// @brief: 创建实例
171     /// @parameter: dev_t: 设备号
172     ///             minorct: 次设备号数量
173     ///             name: 字符设备名
174     ///             char: 字符设备实例
175     /// @return: 实例
176     ///
177     #[allow(dead_code)]
new(dev_t: DeviceNumber, minorct: u32, name: &'static str) -> Self178     pub fn new(dev_t: DeviceNumber, minorct: u32, name: &'static str) -> Self {
179         Self {
180             dev_t,
181             minorct,
182             name,
183         }
184     }
185 
186     /// @brief: 获取起始次设备号
187     /// @parameter: None
188     /// @return: 起始设备号
189     ///
190     #[allow(dead_code)]
device_number(&self) -> DeviceNumber191     pub fn device_number(&self) -> DeviceNumber {
192         self.dev_t
193     }
194 
195     /// @brief: 获取起始次设备号
196     /// @parameter: None
197     /// @return: 起始设备号
198     ///
199     #[allow(dead_code)]
base_minor(&self) -> u32200     pub fn base_minor(&self) -> u32 {
201         self.dev_t.minor()
202     }
203 
204     /// @brief: 获取次设备号数量
205     /// @parameter: None
206     /// @return: 次设备号数量
207     #[allow(dead_code)]
minorct(&self) -> u32208     pub fn minorct(&self) -> u32 {
209         self.minorct
210     }
211 }
212