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