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