1 use alloc::{ 2 string::{String, ToString}, 3 sync::{Arc, Weak}, 4 }; 5 use intertrait::cast::CastArc; 6 7 use crate::{ 8 driver::{ 9 acpi::glue::acpi_device_notify, 10 base::map::{LockedDevsMap, LockedKObjMap}, 11 }, 12 filesystem::{ 13 sysfs::{ 14 file::sysfs_emit_str, sysfs_instance, Attribute, AttributeGroup, SysFSOps, 15 SysFSOpsSupport, 16 }, 17 vfs::syscall::ModeType, 18 }, 19 syscall::SystemError, 20 }; 21 use core::fmt::Debug; 22 use core::intrinsics::unlikely; 23 24 use self::{ 25 bus::{bus_add_device, bus_probe_device, Bus}, 26 driver::Driver, 27 }; 28 29 use super::{ 30 kobject::{KObjType, KObject, KObjectManager, KObjectState}, 31 kset::KSet, 32 swnode::software_node_notify, 33 }; 34 35 pub mod bus; 36 pub mod dd; 37 pub mod driver; 38 pub mod init; 39 40 static mut DEVICE_MANAGER: Option<DeviceManager> = None; 41 42 #[inline(always)] 43 pub fn device_manager() -> &'static DeviceManager { 44 unsafe { DEVICE_MANAGER.as_ref().unwrap() } 45 } 46 47 lazy_static! { 48 // 全局字符设备号管理实例 49 pub static ref CHARDEVS: Arc<LockedDevsMap> = Arc::new(LockedDevsMap::default()); 50 51 // 全局块设备管理实例 52 pub static ref BLOCKDEVS: Arc<LockedDevsMap> = Arc::new(LockedDevsMap::default()); 53 54 // 全局设备管理实例 55 pub static ref DEVMAP: Arc<LockedKObjMap> = Arc::new(LockedKObjMap::default()); 56 57 } 58 59 /// `/sys/devices` 的 kset 实例 60 static mut DEVICES_KSET_INSTANCE: Option<Arc<KSet>> = None; 61 /// `/sys/dev` 的 kset 实例 62 static mut DEV_KSET_INSTANCE: Option<Arc<KSet>> = None; 63 /// `/sys/dev/block` 的 kset 实例 64 static mut DEV_BLOCK_KSET_INSTANCE: Option<Arc<KSet>> = None; 65 /// `/sys/dev/char` 的 kset 实例 66 static mut DEV_CHAR_KSET_INSTANCE: Option<Arc<KSet>> = None; 67 68 #[inline(always)] 69 pub(super) fn sys_devices_kset() -> Arc<KSet> { 70 unsafe { DEVICES_KSET_INSTANCE.as_ref().unwrap().clone() } 71 } 72 73 #[inline(always)] 74 pub(super) fn sys_dev_kset() -> Arc<KSet> { 75 unsafe { DEV_KSET_INSTANCE.as_ref().unwrap().clone() } 76 } 77 78 #[inline(always)] 79 #[allow(dead_code)] 80 pub(super) fn sys_dev_block_kset() -> Arc<KSet> { 81 unsafe { DEV_BLOCK_KSET_INSTANCE.as_ref().unwrap().clone() } 82 } 83 84 #[inline(always)] 85 pub(self) fn sys_dev_char_kset() -> Arc<KSet> { 86 unsafe { DEV_CHAR_KSET_INSTANCE.as_ref().unwrap().clone() } 87 } 88 89 /// 设备应该实现的操作 90 /// 91 /// ## 注意 92 /// 93 /// 由于设备驱动模型需要从Arc<dyn KObject>转换为Arc<dyn Device>, 94 /// 因此,所有的实现了Device trait的结构体,都应该在结构体上方标注`#[cast_to([sync] Device)]`, 95 /// 96 /// 否则在释放设备资源的时候,会由于无法转换为Arc<dyn Device>而导致资源泄露,并且release回调函数也不会被调用。 97 pub trait Device: KObject { 98 // TODO: 待实现 open, close 99 100 /// @brief: 获取设备类型 101 /// @parameter: None 102 /// @return: 实现该trait的设备所属类型 103 fn dev_type(&self) -> DeviceType; 104 105 /// @brief: 获取设备标识 106 /// @parameter: None 107 /// @return: 该设备唯一标识 108 fn id_table(&self) -> IdTable; 109 110 /// 设备释放时的回调函数 111 fn release(&self) { 112 let name = self.name(); 113 kwarn!( 114 "device {} does not have a release() function, it is broken and must be fixed.", 115 name 116 ); 117 } 118 119 /// 获取当前设备所属的总线 120 fn bus(&self) -> Option<Arc<dyn Bus>> { 121 return None; 122 } 123 124 /// 设置当前设备所属的总线 125 /// 126 /// (一定要传入Arc,因为bus的subsysprivate里面存储的是Device的Weak指针) 127 fn set_bus(&self, bus: Option<Arc<dyn Bus>>); 128 129 /// 返回已经与当前设备匹配好的驱动程序 130 fn driver(&self) -> Option<Arc<dyn Driver>>; 131 132 fn set_driver(&self, driver: Option<Weak<dyn Driver>>); 133 134 /// 当前设备是否已经挂掉了 135 fn is_dead(&self) -> bool; 136 137 /// 当前设备是否处于可以被匹配的状态 138 /// 139 /// The device has matched with a driver at least once or it is in 140 /// a bus (like AMBA) which can't check for matching drivers until 141 /// other devices probe successfully. 142 fn can_match(&self) -> bool; 143 144 fn set_can_match(&self, can_match: bool); 145 146 /// The hardware state of this device has been synced to match 147 /// the software state of this device by calling the driver/bus 148 /// sync_state() callback. 149 fn state_synced(&self) -> bool; 150 } 151 152 impl dyn Device { 153 #[inline(always)] 154 pub fn is_registered(&self) -> bool { 155 self.kobj_state().contains(KObjectState::IN_SYSFS) 156 } 157 } 158 159 // 暂定是不可修改的,在初始化的时候就要确定。以后可能会包括例如硬件中断包含的信息 160 #[allow(dead_code)] 161 #[derive(Debug, Clone)] 162 pub struct DevicePrivateData { 163 id_table: IdTable, 164 state: DeviceState, 165 } 166 167 #[allow(dead_code)] 168 impl DevicePrivateData { 169 pub fn new(id_table: IdTable, state: DeviceState) -> Self { 170 Self { id_table, state } 171 } 172 173 pub fn id_table(&self) -> &IdTable { 174 &self.id_table 175 } 176 177 pub fn state(&self) -> DeviceState { 178 self.state 179 } 180 181 pub fn set_state(&mut self, state: DeviceState) { 182 self.state = state; 183 } 184 } 185 186 int_like!(DeviceNumber, usize); 187 188 impl Default for DeviceNumber { 189 fn default() -> Self { 190 DeviceNumber(0) 191 } 192 } 193 194 impl From<usize> for DeviceNumber { 195 fn from(dev_t: usize) -> Self { 196 DeviceNumber(dev_t) 197 } 198 } 199 200 impl Into<usize> for DeviceNumber { 201 fn into(self) -> usize { 202 self.0 203 } 204 } 205 206 impl core::hash::Hash for DeviceNumber { 207 fn hash<H: core::hash::Hasher>(&self, state: &mut H) { 208 self.0.hash(state); 209 } 210 } 211 212 impl DeviceNumber { 213 /// @brief: 获取主设备号 214 /// @parameter: none 215 /// @return: 主设备号 216 pub fn major(&self) -> usize { 217 (self.0 >> 8) & 0xffffff 218 } 219 220 /// @brief: 获取次设备号 221 /// @parameter: none 222 /// @return: 次设备号 223 pub fn minor(&self) -> usize { 224 self.0 & 0xff 225 } 226 227 #[inline] 228 #[allow(dead_code)] 229 pub fn from_major_minor(major: usize, minor: usize) -> usize { 230 ((major & 0xffffff) << 8) | (minor & 0xff) 231 } 232 } 233 234 /// @brief: 根据主次设备号创建设备号实例 235 /// @parameter: major: 主设备号 236 /// minor: 次设备号 237 /// @return: 设备号实例 238 pub fn mkdev(major: usize, minor: usize) -> DeviceNumber { 239 DeviceNumber(((major & 0xfff) << 20) | (minor & 0xfffff)) 240 } 241 242 /// @brief: 设备类型 243 #[allow(dead_code)] 244 #[derive(Debug, Eq, PartialEq)] 245 pub enum DeviceType { 246 Bus, 247 Net, 248 Gpu, 249 Input, 250 Block, 251 Rtc, 252 Serial, 253 Intc, 254 PlatformDev, 255 } 256 257 /// @brief: 设备标识符类型 258 #[derive(Debug, Clone, Hash, PartialOrd, PartialEq, Ord, Eq)] 259 pub struct IdTable(String, DeviceNumber); 260 261 /// @brief: 设备标识符操作方法集 262 impl IdTable { 263 /// @brief: 创建一个新的设备标识符 264 /// @parameter name: 设备名 265 /// @parameter id: 设备id 266 /// @return: 设备标识符 267 pub fn new(name: String, id: DeviceNumber) -> IdTable { 268 Self(name, id) 269 } 270 271 /// @brief: 将设备标识符转换成name 272 /// @parameter None 273 /// @return: 设备名 274 pub fn name(&self) -> String { 275 return format!("{}:{}", self.0, self.1 .0); 276 } 277 278 pub fn device_number(&self) -> DeviceNumber { 279 return self.1; 280 } 281 } 282 283 impl Default for IdTable { 284 fn default() -> Self { 285 IdTable("unknown".to_string(), DeviceNumber::new(0)) 286 } 287 } 288 289 // 以现在的模型,设备在加载到系统中就是已经初始化的状态了,因此可以考虑把这个删掉 290 /// @brief: 设备当前状态 291 #[derive(Debug, Clone, Copy, Eq, PartialEq)] 292 pub enum DeviceState { 293 NotInitialized = 0, 294 Initialized = 1, 295 UnDefined = 2, 296 } 297 298 /// @brief: 设备错误类型 299 #[allow(dead_code)] 300 #[derive(Debug, Copy, Clone)] 301 pub enum DeviceError { 302 DriverExists, // 设备已存在 303 DeviceExists, // 驱动已存在 304 InitializeFailed, // 初始化错误 305 NotInitialized, // 未初始化的设备 306 NoDeviceForDriver, // 没有合适的设备匹配驱动 307 NoDriverForDevice, // 没有合适的驱动匹配设备 308 RegisterError, // 注册失败 309 UnsupportedOperation, // 不支持的操作 310 } 311 312 impl Into<SystemError> for DeviceError { 313 fn into(self) -> SystemError { 314 match self { 315 DeviceError::DriverExists => SystemError::EEXIST, 316 DeviceError::DeviceExists => SystemError::EEXIST, 317 DeviceError::InitializeFailed => SystemError::EIO, 318 DeviceError::NotInitialized => SystemError::ENODEV, 319 DeviceError::NoDeviceForDriver => SystemError::ENODEV, 320 DeviceError::NoDriverForDevice => SystemError::ENODEV, 321 DeviceError::RegisterError => SystemError::EIO, 322 DeviceError::UnsupportedOperation => SystemError::EIO, 323 } 324 } 325 } 326 327 /// @brief: 将u32类型转换为设备状态类型 328 impl From<u32> for DeviceState { 329 fn from(state: u32) -> Self { 330 match state { 331 0 => DeviceState::NotInitialized, 332 1 => DeviceState::Initialized, 333 _ => todo!(), 334 } 335 } 336 } 337 338 /// @brief: 将设备状态转换为u32类型 339 impl From<DeviceState> for u32 { 340 fn from(state: DeviceState) -> Self { 341 match state { 342 DeviceState::NotInitialized => 0, 343 DeviceState::Initialized => 1, 344 DeviceState::UnDefined => 2, 345 } 346 } 347 } 348 349 #[derive(Debug)] 350 pub struct DeviceKObjType; 351 352 impl KObjType for DeviceKObjType { 353 // https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#2307 354 fn release(&self, kobj: Arc<dyn KObject>) { 355 let dev = kobj.cast::<dyn Device>().unwrap(); 356 /* 357 * Some platform devices are driven without driver attached 358 * and managed resources may have been acquired. Make sure 359 * all resources are released. 360 * 361 * Drivers still can add resources into device after device 362 * is deleted but alive, so release devres here to avoid 363 * possible memory leak. 364 */ 365 366 // todo: 在引入devres之后再实现 367 // devres_release_all(kobj); 368 dev.release(); 369 } 370 371 fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { 372 None 373 } 374 375 fn sysfs_ops(&self) -> Option<&dyn SysFSOps> { 376 Some(&DeviceSysFSOps) 377 } 378 } 379 380 #[derive(Debug)] 381 pub(super) struct DeviceSysFSOps; 382 383 impl SysFSOps for DeviceSysFSOps { 384 fn store( 385 &self, 386 kobj: Arc<dyn KObject>, 387 attr: &dyn Attribute, 388 buf: &[u8], 389 ) -> Result<usize, SystemError> { 390 return attr.store(kobj, buf); 391 } 392 393 fn show( 394 &self, 395 kobj: Arc<dyn KObject>, 396 attr: &dyn Attribute, 397 buf: &mut [u8], 398 ) -> Result<usize, SystemError> { 399 return attr.show(kobj, buf); 400 } 401 } 402 403 /// @brief Device管理器 404 #[derive(Debug)] 405 pub struct DeviceManager; 406 407 impl DeviceManager { 408 /// @brief: 创建一个新的设备管理器 409 /// @parameter: None 410 /// @return: DeviceManager实体 411 #[inline] 412 const fn new() -> DeviceManager { 413 return Self; 414 } 415 416 pub fn register(&self, device: Arc<dyn Device>) -> Result<(), SystemError> { 417 self.device_initialize(&device); 418 return self.add_device(device); 419 } 420 421 /// device_initialize - init device structure. 422 pub fn device_initialize(&self, device: &Arc<dyn Device>) { 423 device.set_kset(Some(sys_devices_kset())); 424 device.set_kobj_type(Some(&DeviceKObjType)); 425 } 426 427 /// @brief: 添加设备 428 /// @parameter id_table: 总线标识符,用于唯一标识该总线 429 /// @parameter dev: 设备实例 430 /// @return: None 431 /// 432 /// https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#3398 433 /// 434 /// todo: 完善错误处理逻辑:如果添加失败,需要将之前添加的内容全部回滚 435 #[inline] 436 #[allow(dead_code)] 437 pub fn add_device(&self, device: Arc<dyn Device>) -> Result<(), SystemError> { 438 // todo: 引入class后,在这里处理与parent相关的逻辑 439 440 KObjectManager::add_kobj(device.clone() as Arc<dyn KObject>, None).map_err(|e| { 441 kerror!("add device '{:?}' failed: {:?}", device.name(), e); 442 e 443 })?; 444 445 self.device_platform_notify(&device); 446 447 self.add_class_symlinks(&device)?; 448 449 self.add_attrs(&device)?; 450 451 bus_add_device(&device)?; 452 453 if device.id_table().device_number().major() != 0 { 454 self.create_file(&device, &DeviceAttrDev)?; 455 456 self.create_sys_dev_entry(&device)?; 457 } 458 459 // todo: Notify clients of device addition.This call must come 460 // after dpm_sysfs_add() and before kobject_uevent(). 461 // 参考:https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#3491 462 463 // todo: 发送uevent 464 465 // probe drivers for a new device 466 bus_probe_device(&device); 467 468 return Ok(()); 469 } 470 471 /// @brief: 卸载设备 472 /// @parameter id_table: 总线标识符,用于唯一标识该设备 473 /// @return: None 474 #[inline] 475 #[allow(dead_code)] 476 pub fn remove_device(&self, _id_table: &IdTable) { 477 todo!() 478 } 479 480 /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#542 481 fn remove(&self, _dev: &Arc<dyn Device>) { 482 todo!("DeviceManager::remove") 483 } 484 485 /// @brief: 获取设备 486 /// @parameter id_table: 设备标识符,用于唯一标识该设备 487 /// @return: 设备实例 488 #[inline] 489 #[allow(dead_code)] 490 pub fn find_device_by_idtable(&self, _id_table: &IdTable) -> Option<Arc<dyn Device>> { 491 todo!("find_device_by_idtable") 492 } 493 494 fn device_platform_notify(&self, dev: &Arc<dyn Device>) { 495 acpi_device_notify(dev); 496 software_node_notify(dev); 497 } 498 499 fn add_class_symlinks(&self, _dev: &Arc<dyn Device>) -> Result<(), SystemError> { 500 // todo: 引入class后,在这里处理与class相关的逻辑 501 // https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#3224 502 503 return Ok(()); 504 } 505 506 /// 在sysfs中,为指定的设备创建属性文件 507 /// 508 /// ## 参数 509 /// 510 /// - `dev`: 设备 511 fn add_attrs(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> { 512 let kobj_type = dev.kobj_type(); 513 if kobj_type.is_none() { 514 return Ok(()); 515 } 516 517 let kobj_type = kobj_type.unwrap(); 518 519 let attr_groups = kobj_type.attribute_groups(); 520 521 if attr_groups.is_none() { 522 return Ok(()); 523 } 524 525 self.add_groups(dev, attr_groups.unwrap())?; 526 527 return Ok(()); 528 } 529 530 /// 在sysfs中,为指定的设备创建属性组,以及属性组中的属性文件 531 /// 532 /// ## 参数 533 /// 534 /// - `dev`: 设备 535 /// - `attr_groups`: 属性组 536 pub fn add_groups( 537 &self, 538 dev: &Arc<dyn Device>, 539 attr_groups: &'static [&dyn AttributeGroup], 540 ) -> Result<(), SystemError> { 541 let kobj = dev.clone() as Arc<dyn KObject>; 542 return sysfs_instance().create_groups(&kobj, attr_groups); 543 } 544 545 /// 为设备在sysfs中创建属性文件 546 /// 547 /// ## 参数 548 /// 549 /// - `dev`: 设备 550 /// - `attr`: 属性 551 pub fn create_file( 552 &self, 553 dev: &Arc<dyn Device>, 554 attr: &'static dyn Attribute, 555 ) -> Result<(), SystemError> { 556 if unlikely( 557 attr.mode().contains(ModeType::S_IRUGO) 558 && (!attr.support().contains(SysFSOpsSupport::SHOW)), 559 ) { 560 kwarn!( 561 "Attribute '{}': read permission without 'show'", 562 attr.name() 563 ); 564 } 565 if unlikely( 566 attr.mode().contains(ModeType::S_IWUGO) 567 && (!attr.support().contains(SysFSOpsSupport::STORE)), 568 ) { 569 kwarn!( 570 "Attribute '{}': write permission without 'store'", 571 attr.name() 572 ); 573 } 574 575 let kobj = dev.clone() as Arc<dyn KObject>; 576 577 return sysfs_instance().create_file(&kobj, attr); 578 } 579 580 /// 在/sys/dev下,或者设备所属的class下,为指定的设备创建链接 581 fn create_sys_dev_entry(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> { 582 let target_kobj = self.device_to_dev_kobj(dev); 583 let name = dev.id_table().name(); 584 let current_kobj = dev.clone() as Arc<dyn KObject>; 585 return sysfs_instance().create_link(Some(¤t_kobj), &target_kobj, name); 586 } 587 588 /// Delete symlink for device in `/sys/dev` or `/sys/class/<class_name>` 589 #[allow(dead_code)] 590 fn remove_sys_dev_entry(&self, dev: &Arc<dyn Device>) { 591 let kobj = self.device_to_dev_kobj(dev); 592 let name = dev.id_table().name(); 593 sysfs_instance().remove_link(&kobj, name); 594 } 595 596 /// device_to_dev_kobj - select a /sys/dev/ directory for the device 597 /// 598 /// By default we select char/ for new entries. 599 /// 600 /// ## 参数 601 /// 602 /// - `dev`: 设备 603 fn device_to_dev_kobj(&self, _dev: &Arc<dyn Device>) -> Arc<dyn KObject> { 604 // todo: 处理class的逻辑 605 let kobj = sys_dev_char_kset().as_kobject(); 606 return kobj; 607 } 608 609 /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c?fi=device_links_force_bind#1226 610 pub fn device_links_force_bind(&self, _dev: &Arc<dyn Device>) { 611 todo!("device_links_force_bind") 612 } 613 614 /// 把device对象的一些结构进行默认初始化 615 /// 616 /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c?fi=device_initialize#2976 617 pub fn device_default_initialize(&self, dev: &Arc<dyn Device>) { 618 dev.set_kset(Some(sys_devices_kset())); 619 return; 620 } 621 622 /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c?r=&mo=29885&fi=1100#1100 623 pub fn device_driver_attach( 624 &self, 625 _driver: &Arc<dyn Driver>, 626 _dev: &Arc<dyn Device>, 627 ) -> Result<(), SystemError> { 628 todo!("device_driver_attach") 629 } 630 631 /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c?r=&mo=35401&fi=1313#1313 632 pub fn device_driver_detach(&self, _dev: &Arc<dyn Device>) { 633 todo!("device_driver_detach") 634 } 635 } 636 637 /// @brief: 设备注册 638 /// @parameter: name: 设备名 639 /// @return: 操作成功,返回(),操作失败,返回错误码 640 pub fn device_register<T: Device>(device: Arc<T>) -> Result<(), SystemError> { 641 return device_manager().register(device); 642 } 643 644 /// @brief: 设备卸载 645 /// @parameter: name: 设备名 646 /// @return: 操作成功,返回(),操作失败,返回错误码 647 pub fn device_unregister<T: Device>(_device: Arc<T>) { 648 // DEVICE_MANAGER.add_device(device.id_table(), device.clone()); 649 // match sys_device_unregister(&device.id_table().name()) { 650 // Ok(_) => { 651 // device.set_inode(None); 652 // return Ok(()); 653 // } 654 // Err(_) => Err(DeviceError::RegisterError), 655 // } 656 todo!("device_unregister") 657 } 658 659 /// 设备文件夹下的`dev`文件的属性 660 #[derive(Debug, Clone, Copy)] 661 pub struct DeviceAttrDev; 662 663 impl Attribute for DeviceAttrDev { 664 fn mode(&self) -> ModeType { 665 // 0o444 666 return ModeType::S_IRUGO; 667 } 668 669 fn name(&self) -> &str { 670 "dev" 671 } 672 673 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 674 let dev = kobj.cast::<dyn Device>().map_err(|kobj| { 675 kerror!( 676 "Intertrait casting not implemented for kobj: {}", 677 kobj.name() 678 ); 679 SystemError::EOPNOTSUPP_OR_ENOTSUP 680 })?; 681 682 let device_number = dev.id_table().device_number(); 683 let s = format!("{}:{}\n", device_number.major(), device_number.minor()); 684 685 return sysfs_emit_str(buf, &s); 686 } 687 688 fn support(&self) -> SysFSOpsSupport { 689 SysFSOpsSupport::SHOW 690 } 691 } 692 693 /// 设备匹配器 694 /// 695 /// 用于匹配设备是否符合某个条件 696 /// 697 /// ## 参数 698 /// 699 /// - `T` - 匹配器的数据类型 700 /// - `data` - 匹配器的数据 701 pub trait DeviceMatcher<T>: Debug { 702 fn match_device(&self, device: &Arc<dyn Device>, data: T) -> bool; 703 } 704 705 /// 用于根据名称匹配设备的匹配器 706 #[derive(Debug)] 707 pub struct DeviceMatchName; 708 709 impl DeviceMatcher<&str> for DeviceMatchName { 710 #[inline] 711 fn match_device(&self, device: &Arc<dyn Device>, data: &str) -> bool { 712 return device.name() == data; 713 } 714 } 715