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实例 15 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 { 25 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 { 35 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 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 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)] 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