1 use core::cmp::Ordering; 2 3 use super::{ 4 block::block_device::BlockDevice, 5 char::CharDevice, 6 device::{mkdev, DeviceNumber, IdTable, KObject, BLOCKDEVS, CHARDEVS, DEVICE_MANAGER, DEVMAP}, 7 }; 8 use crate::{kerror, libs::spinlock::SpinLock, syscall::SystemError}; 9 use alloc::{collections::BTreeMap, sync::Arc, vec::Vec}; 10 11 const KOBJMAP_HASH_SIZE: usize = 255; 12 const DEV_MAJOR_HASH_SIZE: usize = 255; 13 const DEV_MAJOR_MAX: usize = 512; 14 const MINOR_BITS: usize = 20; 15 const MINOR_MASK: usize = 1 << MINOR_BITS - 1; 16 /* Marks the bottom of the first segment of free char majors */ 17 const DEV_MAJOR_DYN_END: usize = 234; 18 /* Marks the top and bottom of the second segment of free char majors */ 19 const DEV_MAJOR_DYN_EXT_START: usize = 511; 20 const DEV_MAJOR_DYN_EXT_END: usize = 384; 21 22 /// @brief: 字符设备与块设备管理结构体 23 #[derive(Debug, Clone)] 24 struct Probe(Arc<dyn KObject>); 25 26 impl Probe { 27 /// @brief: 新建probe实例 28 /// @parameter: data: probe实例 29 /// @return: probe实例 30 pub fn new(data: Arc<dyn KObject>) -> Self { 31 Self(data) 32 } 33 } 34 35 /// @brief: 字符设备和块设备管理实例(锁) 36 #[derive(Debug)] 37 pub struct LockedKObjMap(SpinLock<KObjMap>); 38 39 impl Default for LockedKObjMap { 40 fn default() -> Self { 41 Self(SpinLock::new(KObjMap::default())) 42 } 43 } 44 45 /// @brief: 字符设备和块设备管理实例 46 #[derive(Debug, Clone)] 47 struct KObjMap(Vec<BTreeMap<DeviceNumber, Probe>>); 48 49 impl Default for KObjMap { 50 fn default() -> Self { 51 Self(vec![BTreeMap::new(); KOBJMAP_HASH_SIZE]) 52 } 53 } 54 55 /// @brief: obj设备注册 56 /// @parameter: domain: 管理实例 57 /// dev_t: 设备号 58 /// range: 次设备号范围 59 /// data: 设备实例 60 /// @return: none 61 pub fn kobj_map( 62 domain: Arc<LockedKObjMap>, 63 dev_t: DeviceNumber, 64 range: usize, 65 data: Arc<dyn KObject>, 66 ) { 67 if let Some(map) = domain.0.lock().0.get_mut(dev_t.major() % 255) { 68 for i in 0..range { 69 map.insert( 70 mkdev(dev_t.major(), dev_t.minor() + i), 71 Probe::new(data.clone()), 72 ); 73 } 74 } 75 } 76 77 /// @brief: obj设备注销 78 /// @parameter: domain: 管理实例 79 /// dev_t: 设备号 80 /// range: 次设备号范围 81 /// @return: none 82 pub fn kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize) { 83 if let Some(map) = domain.0.lock().0.get_mut(dev_t.major() % 255) { 84 for i in 0..range { 85 let rm_dev_t = &DeviceNumber::new(Into::<usize>::into(dev_t) + i); 86 match map.get(rm_dev_t) { 87 Some(_) => { 88 map.remove(rm_dev_t); 89 } 90 None => {} 91 } 92 } 93 } 94 } 95 96 /// @brief: 设备查找 97 /// @parameter: domain: 管理实例 98 /// dev_t: 设备号 99 /// @return: 查找成功,返回设备实例,否则返回None 100 #[allow(dead_code)] 101 pub fn kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Arc<dyn KObject>> { 102 if let Some(map) = domain.0.lock().0.get(dev_t.major() % 255) { 103 match map.get(&dev_t) { 104 Some(value) => { 105 return Some(value.0.clone()); 106 } 107 None => { 108 return None; 109 } 110 } 111 } 112 return None; 113 } 114 115 // 管理字符设备号的map(加锁) 116 pub struct LockedDevsMap(SpinLock<DevsMap>); 117 118 impl Default for LockedDevsMap { 119 fn default() -> Self { 120 LockedDevsMap(SpinLock::new(DevsMap::default())) 121 } 122 } 123 124 // 管理字符设备号的map 125 #[derive(Debug)] 126 struct DevsMap(Vec<Vec<DeviceStruct>>); 127 128 impl Default for DevsMap { 129 fn default() -> Self { 130 DevsMap(vec![Vec::new(); DEV_MAJOR_HASH_SIZE]) 131 } 132 } 133 134 // 字符设备在系统中的实例,devfs通过该结构与实际字符设备进行联系 135 #[allow(dead_code)] 136 #[derive(Debug, Clone)] 137 pub struct DeviceStruct { 138 dev_t: DeviceNumber, //起始设备号 139 minorct: usize, // 次设备号数量 140 name: &'static str, //字符设备名 141 } 142 143 impl DeviceStruct { 144 /// @brief: 创建实例 145 /// @parameter: dev_t: 设备号 146 /// minorct: 次设备号数量 147 /// name: 字符设备名 148 /// char: 字符设备实例 149 /// @return: 实例 150 /// 151 #[allow(dead_code)] 152 pub fn new(dev_t: DeviceNumber, minorct: usize, name: &'static str) -> Self { 153 Self { 154 dev_t, 155 minorct, 156 name, 157 } 158 } 159 160 /// @brief: 获取起始次设备号 161 /// @parameter: None 162 /// @return: 起始设备号 163 /// 164 #[allow(dead_code)] 165 pub fn device_number(&self) -> DeviceNumber { 166 self.dev_t 167 } 168 169 /// @brief: 获取起始次设备号 170 /// @parameter: None 171 /// @return: 起始设备号 172 /// 173 #[allow(dead_code)] 174 pub fn base_minor(&self) -> usize { 175 self.dev_t.minor() 176 } 177 178 /// @brief: 获取次设备号数量 179 /// @parameter: None 180 /// @return: 次设备号数量 181 #[allow(dead_code)] 182 pub fn minorct(&self) -> usize { 183 self.minorct 184 } 185 } 186 187 // 这下面是考虑到 块设备的注册和字符设备的注册在设备号的自动分配上要有所区别, 188 // 暂时没有去查具体是怎么做区分的,因此暂时还是一样的 189 190 /// @brief 块设备框架函数集 191 pub struct BlockDeviceOps; 192 193 impl BlockDeviceOps { 194 /// @brief: 主设备号转下标 195 /// @parameter: major: 主设备号 196 /// @return: 返回下标 197 #[allow(dead_code)] 198 fn major_to_index(major: usize) -> usize { 199 return major % DEV_MAJOR_HASH_SIZE; 200 } 201 202 /// @brief: 动态获取主设备号 203 /// @parameter: None 204 /// @return: 如果成功,返回主设备号,否则,返回错误码 205 #[allow(dead_code)] 206 fn find_dynamic_major() -> Result<usize, SystemError> { 207 let blockdevs = BLOCKDEVS.0.lock(); 208 // 寻找主设备号为234~255的设备 209 for index in (DEV_MAJOR_DYN_END..DEV_MAJOR_HASH_SIZE).rev() { 210 if let Some(item) = blockdevs.0.get(index) { 211 if item.is_empty() { 212 return Ok(index); // 返回可用的主设备号 213 } 214 } 215 } 216 // 寻找主设备号在384~511的设备 217 for index in (DEV_MAJOR_DYN_EXT_END + 1..DEV_MAJOR_DYN_EXT_START + 1).rev() { 218 if let Some(blockdevss) = blockdevs.0.get(Self::major_to_index(index)) { 219 let mut flag = true; 220 for item in blockdevss { 221 if item.device_number().major() == index { 222 flag = false; 223 break; 224 } 225 } 226 if flag { 227 // 如果数组中不存在主设备号等于index的设备 228 return Ok(index); // 返回可用的主设备号 229 } 230 } 231 } 232 return Err(SystemError::EBUSY); 233 } 234 235 /// @brief: 注册设备号,该函数需要指定主设备号 236 /// @parameter: from: 主设备号 237 /// count: 次设备号数量 238 /// name: 字符设备名 239 /// @return: 如果注册成功,返回设备号,否则,返回错误码 240 #[allow(dead_code)] 241 pub fn register_blockdev_region( 242 from: DeviceNumber, 243 count: usize, 244 name: &'static str, 245 ) -> Result<DeviceNumber, SystemError> { 246 Self::__register_blockdev_region(from, count, name) 247 } 248 249 /// @brief: 注册设备号,该函数自动分配主设备号 250 /// @parameter: baseminor: 主设备号 251 /// count: 次设备号数量 252 /// name: 字符设备名 253 /// @return: 如果注册成功,返回,否则,返回false 254 #[allow(dead_code)] 255 pub fn alloc_blockdev_region( 256 baseminor: usize, 257 count: usize, 258 name: &'static str, 259 ) -> Result<DeviceNumber, SystemError> { 260 Self::__register_blockdev_region(mkdev(0, baseminor), count, name) 261 } 262 263 /// @brief: 注册设备号 264 /// @parameter: device_number: 设备号,主设备号如果为0,则动态分配 265 /// minorct: 次设备号数量 266 /// name: 字符设备名 267 /// @return: 如果注册成功,返回设备号,否则,返回错误码 268 fn __register_blockdev_region( 269 device_number: DeviceNumber, 270 minorct: usize, 271 name: &'static str, 272 ) -> Result<DeviceNumber, SystemError> { 273 let mut major = device_number.major(); 274 let baseminor = device_number.minor(); 275 if major >= DEV_MAJOR_MAX { 276 kerror!( 277 "DEV {} major requested {} is greater than the maximum {}\n", 278 name, 279 major, 280 DEV_MAJOR_MAX - 1 281 ); 282 } 283 if minorct > MINOR_MASK + 1 - baseminor { 284 kerror!("DEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n", 285 name, baseminor, baseminor + minorct - 1, 0, MINOR_MASK); 286 } 287 let blockdev = DeviceStruct::new(mkdev(major, baseminor), minorct, name); 288 if major == 0 { 289 // 如果主设备号为0,则自动分配主设备号 290 major = Self::find_dynamic_major().expect("Find synamic major error.\n"); 291 } 292 if let Some(items) = BLOCKDEVS.0.lock().0.get_mut(Self::major_to_index(major)) { 293 let mut insert_index: usize = 0; 294 for (index, item) in items.iter().enumerate() { 295 insert_index = index; 296 match item.device_number().major().cmp(&major) { 297 Ordering::Less => continue, 298 Ordering::Greater => { 299 break; // 大于则向后插入 300 } 301 Ordering::Equal => { 302 if item.device_number().minor() + item.minorct() <= baseminor { 303 continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值 304 } 305 if item.base_minor() >= baseminor + minorct { 306 break; // 在此处插入 307 } 308 return Err(SystemError::EBUSY); // 存在重合的次设备号 309 } 310 } 311 } 312 items.insert(insert_index, blockdev); 313 } 314 return Ok(mkdev(major, baseminor)); 315 } 316 317 /// @brief: 注销设备号 318 /// @parameter: major: 主设备号,如果为0,动态分配 319 /// baseminor: 起始次设备号 320 /// minorct: 次设备号数量 321 /// @return: 如果注销成功,返回(),否则,返回错误码 322 fn __unregister_blockdev_region( 323 device_number: DeviceNumber, 324 minorct: usize, 325 ) -> Result<(), SystemError> { 326 if let Some(items) = BLOCKDEVS 327 .0 328 .lock() 329 .0 330 .get_mut(Self::major_to_index(device_number.major())) 331 { 332 for (index, item) in items.iter().enumerate() { 333 if item.device_number() == device_number && item.minorct() == minorct { 334 // 设备号和数量都相等 335 items.remove(index); 336 return Ok(()); 337 } 338 } 339 } 340 return Err(SystemError::EBUSY); 341 } 342 343 /// @brief: 块设备注册 344 /// @parameter: cdev: 字符设备实例 345 /// dev_t: 字符设备号 346 /// range: 次设备号范围 347 /// @return: none 348 #[allow(dead_code)] 349 pub fn bdev_add(bdev: Arc<dyn BlockDevice>, id_table: IdTable) { 350 if Into::<usize>::into(id_table.device_number()) == 0 { 351 kerror!("Device number can't be 0!\n"); 352 } 353 DEVICE_MANAGER.add_device(id_table, bdev.device()) 354 } 355 356 /// @brief: block设备注销 357 /// @parameter: dev_t: 字符设备号 358 /// range: 次设备号范围 359 /// @return: none 360 #[allow(dead_code)] 361 pub fn bdev_del(_devnum: DeviceNumber, _range: usize) {} 362 } 363 364 /// @brief 字符设备框架函数集 365 pub struct CharDevOps; 366 367 impl CharDevOps { 368 /// @brief: 主设备号转下标 369 /// @parameter: major: 主设备号 370 /// @return: 返回下标 371 #[allow(dead_code)] 372 fn major_to_index(major: usize) -> usize { 373 return major % DEV_MAJOR_HASH_SIZE; 374 } 375 376 /// @brief: 动态获取主设备号 377 /// @parameter: None 378 /// @return: 如果成功,返回主设备号,否则,返回错误码 379 #[allow(dead_code)] 380 fn find_dynamic_major() -> Result<usize, SystemError> { 381 let chardevs = CHARDEVS.0.lock(); 382 // 寻找主设备号为234~255的设备 383 for index in (DEV_MAJOR_DYN_END..DEV_MAJOR_HASH_SIZE).rev() { 384 if let Some(item) = chardevs.0.get(index) { 385 if item.is_empty() { 386 return Ok(index); // 返回可用的主设备号 387 } 388 } 389 } 390 // 寻找主设备号在384~511的设备 391 for index in (DEV_MAJOR_DYN_EXT_END + 1..DEV_MAJOR_DYN_EXT_START + 1).rev() { 392 if let Some(chardevss) = chardevs.0.get(Self::major_to_index(index)) { 393 let mut flag = true; 394 for item in chardevss { 395 if item.device_number().major() == index { 396 flag = false; 397 break; 398 } 399 } 400 if flag { 401 // 如果数组中不存在主设备号等于index的设备 402 return Ok(index); // 返回可用的主设备号 403 } 404 } 405 } 406 return Err(SystemError::EBUSY); 407 } 408 409 /// @brief: 注册设备号,该函数需要指定主设备号 410 /// @parameter: from: 主设备号 411 /// count: 次设备号数量 412 /// name: 字符设备名 413 /// @return: 如果注册成功,返回设备号,否则,返回错误码 414 #[allow(dead_code)] 415 pub fn register_chardev_region( 416 from: DeviceNumber, 417 count: usize, 418 name: &'static str, 419 ) -> Result<DeviceNumber, SystemError> { 420 Self::__register_chardev_region(from, count, name) 421 } 422 423 /// @brief: 注册设备号,该函数自动分配主设备号 424 /// @parameter: baseminor: 次设备号 425 /// count: 次设备号数量 426 /// name: 字符设备名 427 /// @return: 如果注册成功,返回,否则,返回false 428 #[allow(dead_code)] 429 pub fn alloc_chardev_region( 430 baseminor: usize, 431 count: usize, 432 name: &'static str, 433 ) -> Result<DeviceNumber, SystemError> { 434 Self::__register_chardev_region(mkdev(0, baseminor), count, name) 435 } 436 437 /// @brief: 注册设备号 438 /// @parameter: device_number: 设备号,主设备号如果为0,则动态分配 439 /// minorct: 次设备号数量 440 /// name: 字符设备名 441 /// @return: 如果注册成功,返回设备号,否则,返回错误码 442 fn __register_chardev_region( 443 device_number: DeviceNumber, 444 minorct: usize, 445 name: &'static str, 446 ) -> Result<DeviceNumber, SystemError> { 447 let mut major = device_number.major(); 448 let baseminor = device_number.minor(); 449 if major >= DEV_MAJOR_MAX { 450 kerror!( 451 "DEV {} major requested {} is greater than the maximum {}\n", 452 name, 453 major, 454 DEV_MAJOR_MAX - 1 455 ); 456 } 457 if minorct > MINOR_MASK + 1 - baseminor { 458 kerror!("DEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n", 459 name, baseminor, baseminor + minorct - 1, 0, MINOR_MASK); 460 } 461 let chardev = DeviceStruct::new(mkdev(major, baseminor), minorct, name); 462 if major == 0 { 463 // 如果主设备号为0,则自动分配主设备号 464 major = Self::find_dynamic_major().expect("Find synamic major error.\n"); 465 } 466 if let Some(items) = CHARDEVS.0.lock().0.get_mut(Self::major_to_index(major)) { 467 let mut insert_index: usize = 0; 468 for (index, item) in items.iter().enumerate() { 469 insert_index = index; 470 match item.device_number().major().cmp(&major) { 471 Ordering::Less => continue, 472 Ordering::Greater => { 473 break; // 大于则向后插入 474 } 475 Ordering::Equal => { 476 if item.device_number().minor() + item.minorct() <= baseminor { 477 continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值 478 } 479 if item.base_minor() >= baseminor + minorct { 480 break; // 在此处插入 481 } 482 return Err(SystemError::EBUSY); // 存在重合的次设备号 483 } 484 } 485 } 486 items.insert(insert_index, chardev); 487 } 488 return Ok(mkdev(major, baseminor)); 489 } 490 491 /// @brief: 注销设备号 492 /// @parameter: major: 主设备号,如果为0,动态分配 493 /// baseminor: 起始次设备号 494 /// minorct: 次设备号数量 495 /// @return: 如果注销成功,返回(),否则,返回错误码 496 fn __unregister_chardev_region( 497 device_number: DeviceNumber, 498 minorct: usize, 499 ) -> Result<(), SystemError> { 500 if let Some(items) = CHARDEVS 501 .0 502 .lock() 503 .0 504 .get_mut(Self::major_to_index(device_number.major())) 505 { 506 for (index, item) in items.iter().enumerate() { 507 if item.device_number() == device_number && item.minorct() == minorct { 508 // 设备号和数量都相等 509 items.remove(index); 510 return Ok(()); 511 } 512 } 513 } 514 return Err(SystemError::EBUSY); 515 } 516 517 /// @brief: 字符设备注册 518 /// @parameter: cdev: 字符设备实例 519 /// dev_t: 字符设备号 520 /// range: 次设备号范围 521 /// @return: none 522 #[allow(dead_code)] 523 pub fn cdev_add(cdev: Arc<dyn CharDevice>, id_table: IdTable, range: usize) { 524 if Into::<usize>::into(id_table.device_number()) == 0 { 525 kerror!("Device number can't be 0!\n"); 526 } 527 DEVICE_MANAGER.add_device(id_table.clone(), cdev.clone()); 528 kobj_map( 529 DEVMAP.clone(), 530 id_table.device_number(), 531 range, 532 cdev.clone(), 533 ) 534 } 535 536 /// @brief: 字符设备注销 537 /// @parameter: dev_t: 字符设备号 538 /// range: 次设备号范围 539 /// @return: none 540 #[allow(dead_code)] 541 pub fn cdev_del(id_table: IdTable, range: usize) { 542 DEVICE_MANAGER.remove_device(&id_table); 543 kobj_unmap(DEVMAP.clone(), id_table.device_number(), range); 544 } 545 } 546