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