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