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