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实例
new(data: Arc<dyn KObject>) -> Self15 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 {
default() -> Self25 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 {
default() -> Self35 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
kobj_map( domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize, data: Arc<dyn KObject>, )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
kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize)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)]
kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Arc<dyn KObject>>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