mod.rs 8.8 KB

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