xref: /DragonOS/kernel/src/driver/base/char/mod.rs (revision ae5ede03bebe5c4b593ad7a350f0945f1367be7c)
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