1 use core::ops::{Deref, DerefMut}; 2 3 use super::device::{mkdev, DeviceNumber, KObject}; 4 use crate::libs::spinlock::{SpinLock, SpinLockGuard}; 5 use alloc::{collections::BTreeMap, sync::Arc, vec::Vec}; 6 7 const KOBJMAP_HASH_SIZE: usize = 255; 8 pub(crate) const DEV_MAJOR_HASH_SIZE: usize = 255; 9 pub(crate) const DEV_MAJOR_MAX: usize = 512; 10 pub(crate) const MINOR_BITS: usize = 20; 11 pub(crate) const MINOR_MASK: usize = 1 << MINOR_BITS - 1; 12 /* Marks the bottom of the first segment of free char majors */ 13 pub(crate) const DEV_MAJOR_DYN_END: usize = 234; 14 /* Marks the top and bottom of the second segment of free char majors */ 15 pub(crate) const DEV_MAJOR_DYN_EXT_START: usize = 511; 16 pub(crate) const DEV_MAJOR_DYN_EXT_END: usize = 384; 17 18 /// @brief: 字符设备与块设备管理结构体 19 #[derive(Debug, Clone)] 20 struct Probe(Arc<dyn KObject>); 21 22 impl Probe { 23 /// @brief: 新建probe实例 24 /// @parameter: data: probe实例 25 /// @return: probe实例 26 pub fn new(data: Arc<dyn KObject>) -> Self { 27 Self(data) 28 } 29 } 30 31 /// @brief: 字符设备和块设备管理实例(锁) 32 #[derive(Debug)] 33 pub struct LockedKObjMap(SpinLock<KObjMap>); 34 35 impl Default for LockedKObjMap { 36 fn default() -> Self { 37 Self(SpinLock::new(KObjMap::default())) 38 } 39 } 40 41 /// @brief: 字符设备和块设备管理实例 42 #[derive(Debug, Clone)] 43 struct KObjMap(Vec<BTreeMap<DeviceNumber, Probe>>); 44 45 impl Default for KObjMap { 46 fn default() -> Self { 47 Self(vec![BTreeMap::new(); KOBJMAP_HASH_SIZE]) 48 } 49 } 50 51 /// @brief: obj设备注册 52 /// @parameter: domain: 管理实例 53 /// dev_t: 设备号 54 /// range: 次设备号范围 55 /// data: 设备实例 56 /// @return: none 57 pub fn kobj_map( 58 domain: Arc<LockedKObjMap>, 59 dev_t: DeviceNumber, 60 range: usize, 61 data: Arc<dyn KObject>, 62 ) { 63 if let Some(map) = domain.0.lock().0.get_mut(dev_t.major() % 255) { 64 for i in 0..range { 65 map.insert( 66 mkdev(dev_t.major(), dev_t.minor() + i), 67 Probe::new(data.clone()), 68 ); 69 } 70 } 71 } 72 73 /// @brief: obj设备注销 74 /// @parameter: domain: 管理实例 75 /// dev_t: 设备号 76 /// range: 次设备号范围 77 /// @return: none 78 pub fn kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize) { 79 if let Some(map) = domain.0.lock().0.get_mut(dev_t.major() % 255) { 80 for i in 0..range { 81 let rm_dev_t = &DeviceNumber::new(Into::<usize>::into(dev_t) + i); 82 match map.get(rm_dev_t) { 83 Some(_) => { 84 map.remove(rm_dev_t); 85 } 86 None => {} 87 } 88 } 89 } 90 } 91 92 /// @brief: 设备查找 93 /// @parameter: domain: 管理实例 94 /// dev_t: 设备号 95 /// @return: 查找成功,返回设备实例,否则返回None 96 #[allow(dead_code)] 97 pub fn kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Arc<dyn KObject>> { 98 if let Some(map) = domain.0.lock().0.get(dev_t.major() % 255) { 99 match map.get(&dev_t) { 100 Some(value) => { 101 return Some(value.0.clone()); 102 } 103 None => { 104 return None; 105 } 106 } 107 } 108 return None; 109 } 110 111 // 管理字符设备号的map(加锁) 112 pub struct LockedDevsMap(SpinLock<DevsMap>); 113 114 impl Default for LockedDevsMap { 115 fn default() -> Self { 116 LockedDevsMap(SpinLock::new(DevsMap::default())) 117 } 118 } 119 120 impl LockedDevsMap { 121 #[inline(always)] 122 pub fn lock(&self) -> SpinLockGuard<DevsMap> { 123 self.0.lock() 124 } 125 } 126 127 // 管理字符设备号的map 128 #[derive(Debug)] 129 pub struct DevsMap(Vec<Vec<DeviceStruct>>); 130 131 impl Default for DevsMap { 132 fn default() -> Self { 133 DevsMap(vec![Vec::new(); DEV_MAJOR_HASH_SIZE]) 134 } 135 } 136 137 impl Deref for DevsMap { 138 type Target = Vec<Vec<DeviceStruct>>; 139 140 fn deref(&self) -> &Self::Target { 141 &self.0 142 } 143 } 144 145 impl DerefMut for DevsMap { 146 fn deref_mut(&mut self) -> &mut Self::Target { 147 &mut self.0 148 } 149 } 150 151 // 字符设备在系统中的实例,devfs通过该结构与实际字符设备进行联系 152 #[allow(dead_code)] 153 #[derive(Debug, Clone)] 154 pub struct DeviceStruct { 155 dev_t: DeviceNumber, //起始设备号 156 minorct: usize, // 次设备号数量 157 name: &'static str, //字符设备名 158 } 159 160 impl DeviceStruct { 161 /// @brief: 创建实例 162 /// @parameter: dev_t: 设备号 163 /// minorct: 次设备号数量 164 /// name: 字符设备名 165 /// char: 字符设备实例 166 /// @return: 实例 167 /// 168 #[allow(dead_code)] 169 pub fn new(dev_t: DeviceNumber, minorct: usize, name: &'static str) -> Self { 170 Self { 171 dev_t, 172 minorct, 173 name, 174 } 175 } 176 177 /// @brief: 获取起始次设备号 178 /// @parameter: None 179 /// @return: 起始设备号 180 /// 181 #[allow(dead_code)] 182 pub fn device_number(&self) -> DeviceNumber { 183 self.dev_t 184 } 185 186 /// @brief: 获取起始次设备号 187 /// @parameter: None 188 /// @return: 起始设备号 189 /// 190 #[allow(dead_code)] 191 pub fn base_minor(&self) -> usize { 192 self.dev_t.minor() 193 } 194 195 /// @brief: 获取次设备号数量 196 /// @parameter: None 197 /// @return: 次设备号数量 198 #[allow(dead_code)] 199 pub fn minorct(&self) -> usize { 200 self.minorct 201 } 202 } 203