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