1ae5ede03SLoGin use alloc::sync::Arc; 2*2eab6dd7S曾俊 use log::error; 30663027bSTingHuang 491e9d4abSLoGin use system_error::SystemError; 5ae5ede03SLoGin 6ae5ede03SLoGin use super::{ 7c566df45SLoGin device::{ 8c566df45SLoGin device_manager, 9c566df45SLoGin device_number::{DeviceNumber, Major}, 10c566df45SLoGin Device, IdTable, CHARDEVS, DEVMAP, 11c566df45SLoGin }, 12ae5ede03SLoGin map::{ 13ae5ede03SLoGin kobj_map, kobj_unmap, DeviceStruct, DEV_MAJOR_DYN_END, DEV_MAJOR_DYN_EXT_END, 14c566df45SLoGin DEV_MAJOR_DYN_EXT_START, DEV_MAJOR_HASH_SIZE, DEV_MAJOR_MAX, 15ae5ede03SLoGin }, 16ae5ede03SLoGin }; 170663027bSTingHuang 18b087521eSChiichen pub trait CharDevice: Device { 19b087521eSChiichen /// Notice buffer对应设备按字节划分,使用u8类型 20b087521eSChiichen /// Notice offset应该从0开始计数 210663027bSTingHuang 22b087521eSChiichen /// @brief: 从设备的第offset个字节开始,读取len个byte,存放到buf中 23b087521eSChiichen /// @parameter offset: 起始字节偏移量 24b087521eSChiichen /// @parameter len: 读取字节的数量 25b087521eSChiichen /// @parameter buf: 目标数组 26b087521eSChiichen /// @return: 如果操作成功,返回操作的长度(单位是字节);否则返回错误码;如果操作异常,但是并没有检查出什么错误,将返回已操作的长度 read(&self, len: usize, buf: &mut [u8]) -> Result<usize, SystemError>27b087521eSChiichen fn read(&self, len: usize, buf: &mut [u8]) -> Result<usize, SystemError>; 280663027bSTingHuang 29b087521eSChiichen /// @brief: 从设备的第offset个字节开始,把buf数组的len个byte,写入到设备中 30b087521eSChiichen /// @parameter offset: 起始字节偏移量 31b087521eSChiichen /// @parameter len: 读取字节的数量 32b087521eSChiichen /// @parameter buf: 目标数组 33b087521eSChiichen /// @return: 如果操作成功,返回操作的长度(单位是字节);否则返回错误码;如果操作异常,但是并没有检查出什么错误,将返回已操作的长度 write(&self, len: usize, buf: &[u8]) -> Result<usize, SystemError>34b087521eSChiichen fn write(&self, len: usize, buf: &[u8]) -> Result<usize, SystemError>; 350663027bSTingHuang 36b087521eSChiichen /// @brief: 同步信息,把所有的dirty数据写回设备 - 待实现 sync(&self) -> Result<(), SystemError>37b087521eSChiichen fn sync(&self) -> Result<(), SystemError>; 380663027bSTingHuang } 39ae5ede03SLoGin 40ae5ede03SLoGin /// @brief 字符设备框架函数集 41ae5ede03SLoGin pub struct CharDevOps; 42ae5ede03SLoGin 43ae5ede03SLoGin impl CharDevOps { 44ae5ede03SLoGin /// @brief: 主设备号转下标 45ae5ede03SLoGin /// @parameter: major: 主设备号 46ae5ede03SLoGin /// @return: 返回下标 47ae5ede03SLoGin #[allow(dead_code)] major_to_index(major: Major) -> usize48c566df45SLoGin fn major_to_index(major: Major) -> usize { 49c566df45SLoGin return (major.data() % DEV_MAJOR_HASH_SIZE) as usize; 50ae5ede03SLoGin } 51ae5ede03SLoGin 52ae5ede03SLoGin /// @brief: 动态获取主设备号 53ae5ede03SLoGin /// @parameter: None 54ae5ede03SLoGin /// @return: 如果成功,返回主设备号,否则,返回错误码 55ae5ede03SLoGin #[allow(dead_code)] find_dynamic_major() -> Result<Major, SystemError>56c566df45SLoGin fn find_dynamic_major() -> Result<Major, SystemError> { 57ae5ede03SLoGin let chardevs = CHARDEVS.lock(); 58ae5ede03SLoGin // 寻找主设备号为234~255的设备 59c566df45SLoGin for index in (DEV_MAJOR_DYN_END.data()..DEV_MAJOR_HASH_SIZE).rev() { 60c566df45SLoGin if let Some(item) = chardevs.get(index as usize) { 61ae5ede03SLoGin if item.is_empty() { 62c566df45SLoGin return Ok(Major::new(index)); // 返回可用的主设备号 63ae5ede03SLoGin } 64ae5ede03SLoGin } 65ae5ede03SLoGin } 66ae5ede03SLoGin // 寻找主设备号在384~511的设备 67c566df45SLoGin for index in 68c566df45SLoGin ((DEV_MAJOR_DYN_EXT_END.data() + 1)..(DEV_MAJOR_DYN_EXT_START.data() + 1)).rev() 69c566df45SLoGin { 70c566df45SLoGin if let Some(chardevss) = chardevs.get(Self::major_to_index(Major::new(index))) { 71ae5ede03SLoGin let mut flag = true; 72ae5ede03SLoGin for item in chardevss { 73c566df45SLoGin if item.device_number().major().data() == index { 74ae5ede03SLoGin flag = false; 75ae5ede03SLoGin break; 76ae5ede03SLoGin } 77ae5ede03SLoGin } 78ae5ede03SLoGin if flag { 79ae5ede03SLoGin // 如果数组中不存在主设备号等于index的设备 80c566df45SLoGin return Ok(Major::new(index)); // 返回可用的主设备号 81ae5ede03SLoGin } 82ae5ede03SLoGin } 83ae5ede03SLoGin } 84ae5ede03SLoGin return Err(SystemError::EBUSY); 85ae5ede03SLoGin } 86ae5ede03SLoGin 87ae5ede03SLoGin /// @brief: 注册设备号,该函数需要指定主设备号 88ae5ede03SLoGin /// @parameter: from: 主设备号 89ae5ede03SLoGin /// count: 次设备号数量 90ae5ede03SLoGin /// name: 字符设备名 91ae5ede03SLoGin /// @return: 如果注册成功,返回设备号,否则,返回错误码 92ae5ede03SLoGin #[allow(dead_code)] register_chardev_region( from: DeviceNumber, count: u32, name: &'static str, ) -> Result<DeviceNumber, SystemError>93ae5ede03SLoGin pub fn register_chardev_region( 94ae5ede03SLoGin from: DeviceNumber, 95c566df45SLoGin count: u32, 96ae5ede03SLoGin name: &'static str, 97ae5ede03SLoGin ) -> Result<DeviceNumber, SystemError> { 98ae5ede03SLoGin Self::__register_chardev_region(from, count, name) 99ae5ede03SLoGin } 100ae5ede03SLoGin 101ae5ede03SLoGin /// @brief: 注册设备号,该函数自动分配主设备号 102ae5ede03SLoGin /// @parameter: baseminor: 次设备号 103ae5ede03SLoGin /// count: 次设备号数量 104ae5ede03SLoGin /// name: 字符设备名 105ae5ede03SLoGin /// @return: 如果注册成功,返回,否则,返回false 106ae5ede03SLoGin #[allow(dead_code)] alloc_chardev_region( baseminor: u32, count: u32, name: &'static str, ) -> Result<DeviceNumber, SystemError>107ae5ede03SLoGin pub fn alloc_chardev_region( 108c566df45SLoGin baseminor: u32, 109c566df45SLoGin count: u32, 110ae5ede03SLoGin name: &'static str, 111ae5ede03SLoGin ) -> Result<DeviceNumber, SystemError> { 112c566df45SLoGin Self::__register_chardev_region( 113c566df45SLoGin DeviceNumber::new(Major::UNNAMED_MAJOR, baseminor), 114c566df45SLoGin count, 115c566df45SLoGin name, 116c566df45SLoGin ) 117ae5ede03SLoGin } 118ae5ede03SLoGin 119ae5ede03SLoGin /// @brief: 注册设备号 120ae5ede03SLoGin /// @parameter: device_number: 设备号,主设备号如果为0,则动态分配 121ae5ede03SLoGin /// minorct: 次设备号数量 122ae5ede03SLoGin /// name: 字符设备名 123ae5ede03SLoGin /// @return: 如果注册成功,返回设备号,否则,返回错误码 __register_chardev_region( device_number: DeviceNumber, minorct: u32, name: &'static str, ) -> Result<DeviceNumber, SystemError>124ae5ede03SLoGin fn __register_chardev_region( 125ae5ede03SLoGin device_number: DeviceNumber, 126c566df45SLoGin minorct: u32, 127ae5ede03SLoGin name: &'static str, 128ae5ede03SLoGin ) -> Result<DeviceNumber, SystemError> { 129ae5ede03SLoGin let mut major = device_number.major(); 130ae5ede03SLoGin let baseminor = device_number.minor(); 131ae5ede03SLoGin if major >= DEV_MAJOR_MAX { 132*2eab6dd7S曾俊 error!( 133c566df45SLoGin "DEV {} major requested {:?} is greater than the maximum {}\n", 134ae5ede03SLoGin name, 135ae5ede03SLoGin major, 136c566df45SLoGin DEV_MAJOR_MAX.data() - 1 137ae5ede03SLoGin ); 138ae5ede03SLoGin } 139c566df45SLoGin if minorct > DeviceNumber::MINOR_MASK + 1 - baseminor { 140*2eab6dd7S曾俊 error!("DEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n", 141c566df45SLoGin name, baseminor, baseminor + minorct - 1, 0, DeviceNumber::MINOR_MASK); 142ae5ede03SLoGin } 143c566df45SLoGin let chardev = DeviceStruct::new(DeviceNumber::new(major, baseminor), minorct, name); 144c566df45SLoGin if major == Major::UNNAMED_MAJOR { 145ae5ede03SLoGin // 如果主设备号为0,则自动分配主设备号 146ae5ede03SLoGin major = Self::find_dynamic_major().expect("Find synamic major error.\n"); 147ae5ede03SLoGin } 148ae5ede03SLoGin if let Some(items) = CHARDEVS.lock().get_mut(Self::major_to_index(major)) { 149ae5ede03SLoGin let mut insert_index: usize = 0; 150ae5ede03SLoGin for (index, item) in items.iter().enumerate() { 151ae5ede03SLoGin insert_index = index; 152ae5ede03SLoGin match item.device_number().major().cmp(&major) { 153ae5ede03SLoGin core::cmp::Ordering::Less => continue, 154ae5ede03SLoGin core::cmp::Ordering::Greater => { 155ae5ede03SLoGin break; // 大于则向后插入 156ae5ede03SLoGin } 157ae5ede03SLoGin core::cmp::Ordering::Equal => { 158ae5ede03SLoGin if item.device_number().minor() + item.minorct() <= baseminor { 159ae5ede03SLoGin continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值 160ae5ede03SLoGin } 161ae5ede03SLoGin if item.base_minor() >= baseminor + minorct { 162ae5ede03SLoGin break; // 在此处插入 163ae5ede03SLoGin } 164ae5ede03SLoGin return Err(SystemError::EBUSY); // 存在重合的次设备号 165ae5ede03SLoGin } 166ae5ede03SLoGin } 167ae5ede03SLoGin } 168ae5ede03SLoGin items.insert(insert_index, chardev); 169ae5ede03SLoGin } 170c566df45SLoGin 171c566df45SLoGin return Ok(DeviceNumber::new(major, baseminor)); 172ae5ede03SLoGin } 173ae5ede03SLoGin 174ae5ede03SLoGin /// @brief: 注销设备号 175ae5ede03SLoGin /// @parameter: major: 主设备号,如果为0,动态分配 176ae5ede03SLoGin /// baseminor: 起始次设备号 177ae5ede03SLoGin /// minorct: 次设备号数量 178ae5ede03SLoGin /// @return: 如果注销成功,返回(),否则,返回错误码 __unregister_chardev_region( device_number: DeviceNumber, minorct: u32, ) -> Result<(), SystemError>179ae5ede03SLoGin fn __unregister_chardev_region( 180ae5ede03SLoGin device_number: DeviceNumber, 181c566df45SLoGin minorct: u32, 182ae5ede03SLoGin ) -> Result<(), SystemError> { 183ae5ede03SLoGin if let Some(items) = CHARDEVS 184ae5ede03SLoGin .lock() 185ae5ede03SLoGin .get_mut(Self::major_to_index(device_number.major())) 186ae5ede03SLoGin { 187ae5ede03SLoGin for (index, item) in items.iter().enumerate() { 188ae5ede03SLoGin if item.device_number() == device_number && item.minorct() == minorct { 189ae5ede03SLoGin // 设备号和数量都相等 190ae5ede03SLoGin items.remove(index); 191ae5ede03SLoGin return Ok(()); 192ae5ede03SLoGin } 193ae5ede03SLoGin } 194ae5ede03SLoGin } 195ae5ede03SLoGin return Err(SystemError::EBUSY); 196ae5ede03SLoGin } 197ae5ede03SLoGin 198ae5ede03SLoGin /// @brief: 字符设备注册 199ae5ede03SLoGin /// @parameter: cdev: 字符设备实例 200ae5ede03SLoGin /// dev_t: 字符设备号 201ae5ede03SLoGin /// range: 次设备号范围 202ae5ede03SLoGin /// @return: none 203ae5ede03SLoGin #[allow(dead_code)] cdev_add( cdev: Arc<dyn CharDevice>, id_table: IdTable, range: usize, ) -> Result<(), SystemError>20406d5e247SLoGin pub fn cdev_add( 20506d5e247SLoGin cdev: Arc<dyn CharDevice>, 20606d5e247SLoGin id_table: IdTable, 20706d5e247SLoGin range: usize, 20806d5e247SLoGin ) -> Result<(), SystemError> { 209c566df45SLoGin if id_table.device_number().data() == 0 { 210*2eab6dd7S曾俊 error!("Device number can't be 0!\n"); 211ae5ede03SLoGin } 21206d5e247SLoGin device_manager().add_device(cdev.clone())?; 213ae5ede03SLoGin kobj_map( 214ae5ede03SLoGin DEVMAP.clone(), 215ae5ede03SLoGin id_table.device_number(), 216ae5ede03SLoGin range, 217ae5ede03SLoGin cdev.clone(), 21806d5e247SLoGin ); 21906d5e247SLoGin 22006d5e247SLoGin return Ok(()); 221ae5ede03SLoGin } 222ae5ede03SLoGin 223ae5ede03SLoGin /// @brief: 字符设备注销 224ae5ede03SLoGin /// @parameter: dev_t: 字符设备号 225ae5ede03SLoGin /// range: 次设备号范围 226ae5ede03SLoGin /// @return: none 227ae5ede03SLoGin #[allow(dead_code)] cdev_del(id_table: IdTable, range: usize)228ae5ede03SLoGin pub fn cdev_del(id_table: IdTable, range: usize) { 22906d5e247SLoGin device_manager().remove_device(&id_table); 230ae5ede03SLoGin kobj_unmap(DEVMAP.clone(), id_table.device_number(), range); 231ae5ede03SLoGin } 232ae5ede03SLoGin } 233