xref: /DragonOS/kernel/src/driver/base/map/mod.rs (revision c566df451ce6dbf2af684333e68b39fdfff86498)
1ae5ede03SLoGin use core::ops::{Deref, DerefMut};
2b087521eSChiichen 
306d5e247SLoGin use super::{
4*c566df45SLoGin     device::device_number::{DeviceNumber, Major},
506d5e247SLoGin     kobject::KObject,
606d5e247SLoGin };
7ae5ede03SLoGin use crate::libs::spinlock::{SpinLock, SpinLockGuard};
80663027bSTingHuang use alloc::{collections::BTreeMap, sync::Arc, vec::Vec};
90663027bSTingHuang 
100663027bSTingHuang const KOBJMAP_HASH_SIZE: usize = 255;
11*c566df45SLoGin pub(crate) const DEV_MAJOR_HASH_SIZE: u32 = 255;
12*c566df45SLoGin pub(crate) const DEV_MAJOR_MAX: Major = Major::new(512);
13*c566df45SLoGin 
14b087521eSChiichen /* Marks the bottom of the first segment of free char majors */
15*c566df45SLoGin pub(crate) const DEV_MAJOR_DYN_END: Major = Major::new(234);
16b087521eSChiichen /* Marks the top and bottom of the second segment of free char majors */
17*c566df45SLoGin pub(crate) const DEV_MAJOR_DYN_EXT_START: Major = Major::new(511);
18*c566df45SLoGin pub(crate) const DEV_MAJOR_DYN_EXT_END: Major = Major::new(384);
190663027bSTingHuang 
200663027bSTingHuang /// @brief: 字符设备与块设备管理结构体
210663027bSTingHuang #[derive(Debug, Clone)]
220663027bSTingHuang struct Probe(Arc<dyn KObject>);
230663027bSTingHuang 
240663027bSTingHuang impl Probe {
250663027bSTingHuang     /// @brief: 新建probe实例
260663027bSTingHuang     /// @parameter: data: probe实例
270663027bSTingHuang     /// @return: probe实例
280663027bSTingHuang     pub fn new(data: Arc<dyn KObject>) -> Self {
290663027bSTingHuang         Self(data)
300663027bSTingHuang     }
310663027bSTingHuang }
320663027bSTingHuang 
330663027bSTingHuang /// @brief: 字符设备和块设备管理实例(锁)
340663027bSTingHuang #[derive(Debug)]
350663027bSTingHuang pub struct LockedKObjMap(SpinLock<KObjMap>);
360663027bSTingHuang 
370663027bSTingHuang impl Default for LockedKObjMap {
380663027bSTingHuang     fn default() -> Self {
390663027bSTingHuang         Self(SpinLock::new(KObjMap::default()))
400663027bSTingHuang     }
410663027bSTingHuang }
420663027bSTingHuang 
430663027bSTingHuang /// @brief: 字符设备和块设备管理实例
440663027bSTingHuang #[derive(Debug, Clone)]
450663027bSTingHuang struct KObjMap(Vec<BTreeMap<DeviceNumber, Probe>>);
460663027bSTingHuang 
470663027bSTingHuang impl Default for KObjMap {
480663027bSTingHuang     fn default() -> Self {
490663027bSTingHuang         Self(vec![BTreeMap::new(); KOBJMAP_HASH_SIZE])
500663027bSTingHuang     }
510663027bSTingHuang }
520663027bSTingHuang 
530663027bSTingHuang /// @brief: obj设备注册
540663027bSTingHuang /// @parameter: domain: 管理实例
550663027bSTingHuang ///             dev_t: 设备号
560663027bSTingHuang ///             range: 次设备号范围
570663027bSTingHuang ///             data: 设备实例
580663027bSTingHuang /// @return: none
590663027bSTingHuang pub fn kobj_map(
600663027bSTingHuang     domain: Arc<LockedKObjMap>,
610663027bSTingHuang     dev_t: DeviceNumber,
620663027bSTingHuang     range: usize,
630663027bSTingHuang     data: Arc<dyn KObject>,
640663027bSTingHuang ) {
65*c566df45SLoGin     if let Some(map) = domain
66*c566df45SLoGin         .0
67*c566df45SLoGin         .lock()
68*c566df45SLoGin         .0
69*c566df45SLoGin         .get_mut((dev_t.major().data() % 255) as usize)
70*c566df45SLoGin     {
710663027bSTingHuang         for i in 0..range {
720663027bSTingHuang             map.insert(
73*c566df45SLoGin                 DeviceNumber::new(dev_t.major(), dev_t.minor() + i as u32),
740663027bSTingHuang                 Probe::new(data.clone()),
750663027bSTingHuang             );
760663027bSTingHuang         }
770663027bSTingHuang     }
780663027bSTingHuang }
790663027bSTingHuang 
800663027bSTingHuang /// @brief: obj设备注销
810663027bSTingHuang /// @parameter: domain: 管理实例
820663027bSTingHuang ///             dev_t: 设备号
830663027bSTingHuang ///             range: 次设备号范围
840663027bSTingHuang /// @return: none
850663027bSTingHuang pub fn kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize) {
86*c566df45SLoGin     if let Some(map) = domain
87*c566df45SLoGin         .0
88*c566df45SLoGin         .lock()
89*c566df45SLoGin         .0
90*c566df45SLoGin         .get_mut((dev_t.major().data() % 255) as usize)
91*c566df45SLoGin     {
920663027bSTingHuang         for i in 0..range {
93*c566df45SLoGin             let rm_dev_t = &DeviceNumber::new(dev_t.major(), dev_t.minor() + i as u32);
940663027bSTingHuang             match map.get(rm_dev_t) {
950663027bSTingHuang                 Some(_) => {
960663027bSTingHuang                     map.remove(rm_dev_t);
970663027bSTingHuang                 }
980663027bSTingHuang                 None => {}
990663027bSTingHuang             }
1000663027bSTingHuang         }
1010663027bSTingHuang     }
1020663027bSTingHuang }
1030663027bSTingHuang 
1040663027bSTingHuang /// @brief: 设备查找
1050663027bSTingHuang /// @parameter: domain: 管理实例
1060663027bSTingHuang ///             dev_t: 设备号
1070663027bSTingHuang /// @return: 查找成功,返回设备实例,否则返回None
1080663027bSTingHuang #[allow(dead_code)]
1090663027bSTingHuang pub fn kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Arc<dyn KObject>> {
110*c566df45SLoGin     if let Some(map) = domain.0.lock().0.get((dev_t.major().data() % 255) as usize) {
1110663027bSTingHuang         match map.get(&dev_t) {
1120663027bSTingHuang             Some(value) => {
1130663027bSTingHuang                 return Some(value.0.clone());
1140663027bSTingHuang             }
1150663027bSTingHuang             None => {
1160663027bSTingHuang                 return None;
1170663027bSTingHuang             }
1180663027bSTingHuang         }
1190663027bSTingHuang     }
1200663027bSTingHuang     return None;
1210663027bSTingHuang }
122b087521eSChiichen 
123b087521eSChiichen // 管理字符设备号的map(加锁)
124b087521eSChiichen pub struct LockedDevsMap(SpinLock<DevsMap>);
125b087521eSChiichen 
126b087521eSChiichen impl Default for LockedDevsMap {
127b087521eSChiichen     fn default() -> Self {
128b087521eSChiichen         LockedDevsMap(SpinLock::new(DevsMap::default()))
129b087521eSChiichen     }
130b087521eSChiichen }
131b087521eSChiichen 
132ae5ede03SLoGin impl LockedDevsMap {
133ae5ede03SLoGin     #[inline(always)]
134ae5ede03SLoGin     pub fn lock(&self) -> SpinLockGuard<DevsMap> {
135ae5ede03SLoGin         self.0.lock()
136ae5ede03SLoGin     }
137ae5ede03SLoGin }
138ae5ede03SLoGin 
139b087521eSChiichen // 管理字符设备号的map
140b087521eSChiichen #[derive(Debug)]
141ae5ede03SLoGin pub struct DevsMap(Vec<Vec<DeviceStruct>>);
142b087521eSChiichen 
143b087521eSChiichen impl Default for DevsMap {
144b087521eSChiichen     fn default() -> Self {
145*c566df45SLoGin         DevsMap(vec![Vec::new(); DEV_MAJOR_HASH_SIZE as usize])
146b087521eSChiichen     }
147b087521eSChiichen }
148b087521eSChiichen 
149ae5ede03SLoGin impl Deref for DevsMap {
150ae5ede03SLoGin     type Target = Vec<Vec<DeviceStruct>>;
151ae5ede03SLoGin 
152ae5ede03SLoGin     fn deref(&self) -> &Self::Target {
153ae5ede03SLoGin         &self.0
154ae5ede03SLoGin     }
155ae5ede03SLoGin }
156ae5ede03SLoGin 
157ae5ede03SLoGin impl DerefMut for DevsMap {
158ae5ede03SLoGin     fn deref_mut(&mut self) -> &mut Self::Target {
159ae5ede03SLoGin         &mut self.0
160ae5ede03SLoGin     }
161ae5ede03SLoGin }
162ae5ede03SLoGin 
163b087521eSChiichen // 字符设备在系统中的实例,devfs通过该结构与实际字符设备进行联系
164b087521eSChiichen #[allow(dead_code)]
165b087521eSChiichen #[derive(Debug, Clone)]
166b087521eSChiichen pub struct DeviceStruct {
167b087521eSChiichen     dev_t: DeviceNumber, //起始设备号
168*c566df45SLoGin     minorct: u32,        // 次设备号数量
169b087521eSChiichen     name: &'static str,  //字符设备名
170b087521eSChiichen }
171b087521eSChiichen 
172b087521eSChiichen impl DeviceStruct {
173b087521eSChiichen     /// @brief: 创建实例
174b087521eSChiichen     /// @parameter: dev_t: 设备号
175b087521eSChiichen     ///             minorct: 次设备号数量
176b087521eSChiichen     ///             name: 字符设备名
177b087521eSChiichen     ///             char: 字符设备实例
178b087521eSChiichen     /// @return: 实例
179b087521eSChiichen     ///
180b087521eSChiichen     #[allow(dead_code)]
181*c566df45SLoGin     pub fn new(dev_t: DeviceNumber, minorct: u32, name: &'static str) -> Self {
182b087521eSChiichen         Self {
183b087521eSChiichen             dev_t,
184b087521eSChiichen             minorct,
185b087521eSChiichen             name,
186b087521eSChiichen         }
187b087521eSChiichen     }
188b087521eSChiichen 
189b087521eSChiichen     /// @brief: 获取起始次设备号
190b087521eSChiichen     /// @parameter: None
191b087521eSChiichen     /// @return: 起始设备号
192b087521eSChiichen     ///
193b087521eSChiichen     #[allow(dead_code)]
194b087521eSChiichen     pub fn device_number(&self) -> DeviceNumber {
195b087521eSChiichen         self.dev_t
196b087521eSChiichen     }
197b087521eSChiichen 
198b087521eSChiichen     /// @brief: 获取起始次设备号
199b087521eSChiichen     /// @parameter: None
200b087521eSChiichen     /// @return: 起始设备号
201b087521eSChiichen     ///
202b087521eSChiichen     #[allow(dead_code)]
203*c566df45SLoGin     pub fn base_minor(&self) -> u32 {
204b087521eSChiichen         self.dev_t.minor()
205b087521eSChiichen     }
206b087521eSChiichen 
207b087521eSChiichen     /// @brief: 获取次设备号数量
208b087521eSChiichen     /// @parameter: None
209b087521eSChiichen     /// @return: 次设备号数量
210b087521eSChiichen     #[allow(dead_code)]
211*c566df45SLoGin     pub fn minorct(&self) -> u32 {
212b087521eSChiichen         self.minorct
213b087521eSChiichen     }
214b087521eSChiichen }
215