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