mod.rs 8.5 KB

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