1ae5ede03SLoGin use core::ops::{Deref, DerefMut}; 2b087521eSChiichen 306d5e247SLoGin use super::{ 4*c566df45SLoGin device::device_number::{DeviceNumber, Major}, 506d5e247SLoGin kobject::KObject, 606d5e247SLoGin }; 7ae5ede03SLoGin use crate::libs::spinlock::{SpinLock, SpinLockGuard}; 80663027bSTingHuang use alloc::{collections::BTreeMap, sync::Arc, vec::Vec}; 90663027bSTingHuang 100663027bSTingHuang const KOBJMAP_HASH_SIZE: usize = 255; 11*c566df45SLoGin pub(crate) const DEV_MAJOR_HASH_SIZE: u32 = 255; 12*c566df45SLoGin pub(crate) const DEV_MAJOR_MAX: Major = Major::new(512); 13*c566df45SLoGin 14b087521eSChiichen /* Marks the bottom of the first segment of free char majors */ 15*c566df45SLoGin pub(crate) const DEV_MAJOR_DYN_END: Major = Major::new(234); 16b087521eSChiichen /* Marks the top and bottom of the second segment of free char majors */ 17*c566df45SLoGin pub(crate) const DEV_MAJOR_DYN_EXT_START: Major = Major::new(511); 18*c566df45SLoGin pub(crate) const DEV_MAJOR_DYN_EXT_END: Major = Major::new(384); 190663027bSTingHuang 200663027bSTingHuang /// @brief: 字符设备与块设备管理结构体 210663027bSTingHuang #[derive(Debug, Clone)] 220663027bSTingHuang struct Probe(Arc<dyn KObject>); 230663027bSTingHuang 240663027bSTingHuang impl Probe { 250663027bSTingHuang /// @brief: 新建probe实例 260663027bSTingHuang /// @parameter: data: probe实例 270663027bSTingHuang /// @return: probe实例 280663027bSTingHuang pub fn new(data: Arc<dyn KObject>) -> Self { 290663027bSTingHuang Self(data) 300663027bSTingHuang } 310663027bSTingHuang } 320663027bSTingHuang 330663027bSTingHuang /// @brief: 字符设备和块设备管理实例(锁) 340663027bSTingHuang #[derive(Debug)] 350663027bSTingHuang pub struct LockedKObjMap(SpinLock<KObjMap>); 360663027bSTingHuang 370663027bSTingHuang impl Default for LockedKObjMap { 380663027bSTingHuang fn default() -> Self { 390663027bSTingHuang Self(SpinLock::new(KObjMap::default())) 400663027bSTingHuang } 410663027bSTingHuang } 420663027bSTingHuang 430663027bSTingHuang /// @brief: 字符设备和块设备管理实例 440663027bSTingHuang #[derive(Debug, Clone)] 450663027bSTingHuang struct KObjMap(Vec<BTreeMap<DeviceNumber, Probe>>); 460663027bSTingHuang 470663027bSTingHuang impl Default for KObjMap { 480663027bSTingHuang fn default() -> Self { 490663027bSTingHuang Self(vec![BTreeMap::new(); KOBJMAP_HASH_SIZE]) 500663027bSTingHuang } 510663027bSTingHuang } 520663027bSTingHuang 530663027bSTingHuang /// @brief: obj设备注册 540663027bSTingHuang /// @parameter: domain: 管理实例 550663027bSTingHuang /// dev_t: 设备号 560663027bSTingHuang /// range: 次设备号范围 570663027bSTingHuang /// data: 设备实例 580663027bSTingHuang /// @return: none 590663027bSTingHuang pub fn kobj_map( 600663027bSTingHuang domain: Arc<LockedKObjMap>, 610663027bSTingHuang dev_t: DeviceNumber, 620663027bSTingHuang range: usize, 630663027bSTingHuang data: Arc<dyn KObject>, 640663027bSTingHuang ) { 65*c566df45SLoGin if let Some(map) = domain 66*c566df45SLoGin .0 67*c566df45SLoGin .lock() 68*c566df45SLoGin .0 69*c566df45SLoGin .get_mut((dev_t.major().data() % 255) as usize) 70*c566df45SLoGin { 710663027bSTingHuang for i in 0..range { 720663027bSTingHuang map.insert( 73*c566df45SLoGin DeviceNumber::new(dev_t.major(), dev_t.minor() + i as u32), 740663027bSTingHuang Probe::new(data.clone()), 750663027bSTingHuang ); 760663027bSTingHuang } 770663027bSTingHuang } 780663027bSTingHuang } 790663027bSTingHuang 800663027bSTingHuang /// @brief: obj设备注销 810663027bSTingHuang /// @parameter: domain: 管理实例 820663027bSTingHuang /// dev_t: 设备号 830663027bSTingHuang /// range: 次设备号范围 840663027bSTingHuang /// @return: none 850663027bSTingHuang pub fn kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize) { 86*c566df45SLoGin if let Some(map) = domain 87*c566df45SLoGin .0 88*c566df45SLoGin .lock() 89*c566df45SLoGin .0 90*c566df45SLoGin .get_mut((dev_t.major().data() % 255) as usize) 91*c566df45SLoGin { 920663027bSTingHuang for i in 0..range { 93*c566df45SLoGin let rm_dev_t = &DeviceNumber::new(dev_t.major(), dev_t.minor() + i as u32); 940663027bSTingHuang match map.get(rm_dev_t) { 950663027bSTingHuang Some(_) => { 960663027bSTingHuang map.remove(rm_dev_t); 970663027bSTingHuang } 980663027bSTingHuang None => {} 990663027bSTingHuang } 1000663027bSTingHuang } 1010663027bSTingHuang } 1020663027bSTingHuang } 1030663027bSTingHuang 1040663027bSTingHuang /// @brief: 设备查找 1050663027bSTingHuang /// @parameter: domain: 管理实例 1060663027bSTingHuang /// dev_t: 设备号 1070663027bSTingHuang /// @return: 查找成功,返回设备实例,否则返回None 1080663027bSTingHuang #[allow(dead_code)] 1090663027bSTingHuang pub fn kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Arc<dyn KObject>> { 110*c566df45SLoGin if let Some(map) = domain.0.lock().0.get((dev_t.major().data() % 255) as usize) { 1110663027bSTingHuang match map.get(&dev_t) { 1120663027bSTingHuang Some(value) => { 1130663027bSTingHuang return Some(value.0.clone()); 1140663027bSTingHuang } 1150663027bSTingHuang None => { 1160663027bSTingHuang return None; 1170663027bSTingHuang } 1180663027bSTingHuang } 1190663027bSTingHuang } 1200663027bSTingHuang return None; 1210663027bSTingHuang } 122b087521eSChiichen 123b087521eSChiichen // 管理字符设备号的map(加锁) 124b087521eSChiichen pub struct LockedDevsMap(SpinLock<DevsMap>); 125b087521eSChiichen 126b087521eSChiichen impl Default for LockedDevsMap { 127b087521eSChiichen fn default() -> Self { 128b087521eSChiichen LockedDevsMap(SpinLock::new(DevsMap::default())) 129b087521eSChiichen } 130b087521eSChiichen } 131b087521eSChiichen 132ae5ede03SLoGin impl LockedDevsMap { 133ae5ede03SLoGin #[inline(always)] 134ae5ede03SLoGin pub fn lock(&self) -> SpinLockGuard<DevsMap> { 135ae5ede03SLoGin self.0.lock() 136ae5ede03SLoGin } 137ae5ede03SLoGin } 138ae5ede03SLoGin 139b087521eSChiichen // 管理字符设备号的map 140b087521eSChiichen #[derive(Debug)] 141ae5ede03SLoGin pub struct DevsMap(Vec<Vec<DeviceStruct>>); 142b087521eSChiichen 143b087521eSChiichen impl Default for DevsMap { 144b087521eSChiichen fn default() -> Self { 145*c566df45SLoGin DevsMap(vec![Vec::new(); DEV_MAJOR_HASH_SIZE as usize]) 146b087521eSChiichen } 147b087521eSChiichen } 148b087521eSChiichen 149ae5ede03SLoGin impl Deref for DevsMap { 150ae5ede03SLoGin type Target = Vec<Vec<DeviceStruct>>; 151ae5ede03SLoGin 152ae5ede03SLoGin fn deref(&self) -> &Self::Target { 153ae5ede03SLoGin &self.0 154ae5ede03SLoGin } 155ae5ede03SLoGin } 156ae5ede03SLoGin 157ae5ede03SLoGin impl DerefMut for DevsMap { 158ae5ede03SLoGin fn deref_mut(&mut self) -> &mut Self::Target { 159ae5ede03SLoGin &mut self.0 160ae5ede03SLoGin } 161ae5ede03SLoGin } 162ae5ede03SLoGin 163b087521eSChiichen // 字符设备在系统中的实例,devfs通过该结构与实际字符设备进行联系 164b087521eSChiichen #[allow(dead_code)] 165b087521eSChiichen #[derive(Debug, Clone)] 166b087521eSChiichen pub struct DeviceStruct { 167b087521eSChiichen dev_t: DeviceNumber, //起始设备号 168*c566df45SLoGin minorct: u32, // 次设备号数量 169b087521eSChiichen name: &'static str, //字符设备名 170b087521eSChiichen } 171b087521eSChiichen 172b087521eSChiichen impl DeviceStruct { 173b087521eSChiichen /// @brief: 创建实例 174b087521eSChiichen /// @parameter: dev_t: 设备号 175b087521eSChiichen /// minorct: 次设备号数量 176b087521eSChiichen /// name: 字符设备名 177b087521eSChiichen /// char: 字符设备实例 178b087521eSChiichen /// @return: 实例 179b087521eSChiichen /// 180b087521eSChiichen #[allow(dead_code)] 181*c566df45SLoGin pub fn new(dev_t: DeviceNumber, minorct: u32, name: &'static str) -> Self { 182b087521eSChiichen Self { 183b087521eSChiichen dev_t, 184b087521eSChiichen minorct, 185b087521eSChiichen name, 186b087521eSChiichen } 187b087521eSChiichen } 188b087521eSChiichen 189b087521eSChiichen /// @brief: 获取起始次设备号 190b087521eSChiichen /// @parameter: None 191b087521eSChiichen /// @return: 起始设备号 192b087521eSChiichen /// 193b087521eSChiichen #[allow(dead_code)] 194b087521eSChiichen pub fn device_number(&self) -> DeviceNumber { 195b087521eSChiichen self.dev_t 196b087521eSChiichen } 197b087521eSChiichen 198b087521eSChiichen /// @brief: 获取起始次设备号 199b087521eSChiichen /// @parameter: None 200b087521eSChiichen /// @return: 起始设备号 201b087521eSChiichen /// 202b087521eSChiichen #[allow(dead_code)] 203*c566df45SLoGin pub fn base_minor(&self) -> u32 { 204b087521eSChiichen self.dev_t.minor() 205b087521eSChiichen } 206b087521eSChiichen 207b087521eSChiichen /// @brief: 获取次设备号数量 208b087521eSChiichen /// @parameter: None 209b087521eSChiichen /// @return: 次设备号数量 210b087521eSChiichen #[allow(dead_code)] 211*c566df45SLoGin pub fn minorct(&self) -> u32 { 212b087521eSChiichen self.minorct 213b087521eSChiichen } 214b087521eSChiichen } 215