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