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