1 use core::intrinsics::unlikely; 2 3 use alloc::{string::ToString, sync::Arc}; 4 use intertrait::cast::CastArc; 5 6 use crate::{ 7 driver::base::kobject::KObject, 8 filesystem::{ 9 sysfs::{ 10 file::sysfs_emit_str, sysfs_instance, Attribute, SysFSOpsSupport, SYSFS_ATTR_MODE_WO, 11 }, 12 vfs::syscall::ModeType, 13 }, 14 libs::wait_queue::WaitQueue, 15 }; 16 use system_error::SystemError; 17 18 use super::{ 19 bus::BusNotifyEvent, 20 device_manager, 21 driver::{driver_manager, Driver, DriverManager}, 22 Device, DeviceManager, 23 }; 24 25 static PROBE_WAIT_QUEUE: WaitQueue = WaitQueue::default(); 26 27 impl DeviceManager { 28 /// 尝试把一个设备与一个驱动匹配 29 /// 30 /// 当前函数会遍历整个bus的驱动列表,并且尝试把设备与每一个驱动进行匹配。 31 /// 一旦有一个驱动匹配成功,就会返回。 32 /// 33 /// ## 参数 34 /// 35 /// - `dev`: 设备 36 /// 37 /// ## 返回 38 /// 39 /// - Ok(true): 匹配成功 40 /// - Ok(false): 没有匹配成功 41 /// - Err(SystemError::ENODEV): 设备还没被注册 42 /// 43 /// ## 参考 44 /// 45 /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#1049 46 pub fn device_attach(&self, dev: &Arc<dyn Device>) -> Result<bool, SystemError> { 47 return self.do_device_attach(dev, false); 48 } 49 50 pub fn device_initial_probe(&self, dev: &Arc<dyn Device>) -> Result<bool, SystemError> { 51 return self.do_device_attach(dev, true); 52 } 53 54 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#978 55 fn do_device_attach( 56 &self, 57 dev: &Arc<dyn Device>, 58 allow_async: bool, 59 ) -> Result<bool, SystemError> { 60 if unlikely(allow_async) { 61 // todo!("do_device_attach: allow_async") 62 kwarn!("do_device_attach: allow_async is true, but currently not supported"); 63 } 64 if dev.is_dead() { 65 return Ok(false); 66 } 67 68 kwarn!("do_device_attach: dev: '{}'", dev.name()); 69 70 let mut do_async = false; 71 let mut r = Ok(false); 72 73 if dev.driver().is_some() { 74 if self.device_is_bound(dev) { 75 kdebug!( 76 "do_device_attach: device '{}' is already bound.", 77 dev.name() 78 ); 79 return Ok(true); 80 } 81 82 if self.device_bind_driver(dev).is_ok() { 83 return Ok(true); 84 } else { 85 dev.set_driver(None); 86 return Ok(false); 87 } 88 } else { 89 kdebug!("do_device_attach: device '{}' is not bound.", dev.name()); 90 let bus = dev 91 .bus() 92 .and_then(|bus| bus.upgrade()) 93 .ok_or(SystemError::EINVAL)?; 94 let mut data = DeviceAttachData::new(dev.clone(), allow_async, false); 95 let mut flag = false; 96 for driver in bus.subsystem().drivers().iter() { 97 let r = self.do_device_attach_driver(driver, &mut data); 98 if unlikely(r.is_err()) { 99 flag = false; 100 break; 101 } else if r.unwrap() { 102 flag = true; 103 break; 104 } 105 } 106 107 if flag { 108 r = Ok(true); 109 } 110 111 if !flag && allow_async && data.have_async { 112 // If we could not find appropriate driver 113 // synchronously and we are allowed to do 114 // async probes and there are drivers that 115 // want to probe asynchronously, we'll 116 // try them. 117 118 do_async = true; 119 kdebug!( 120 "do_device_attach: try scheduling asynchronous probe for device: {}", 121 dev.name() 122 ); 123 } 124 } 125 126 if do_async { 127 todo!("do_device_attach: do_async") 128 } 129 return r; 130 } 131 132 /// 匹配设备和驱动 133 /// 134 /// ## 参数 135 /// 136 /// - `driver`: 驱动 137 /// - `data`: 匹配数据 138 /// 139 /// ## 返回 140 /// 141 /// - Ok(true): 匹配成功 142 /// - Ok(false): 没有匹配成功 143 /// - Err(SystemError): 匹配过程中出现意外错误,没有匹配成功 144 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#899 145 fn do_device_attach_driver( 146 &self, 147 driver: &Arc<dyn Driver>, 148 data: &mut DeviceAttachData, 149 ) -> Result<bool, SystemError> { 150 if let Some(bus) = driver.bus().and_then(|bus| bus.upgrade()) { 151 let r = bus.match_device(&data.dev, driver); 152 153 if let Err(e) = r { 154 // 如果不是ENOSYS,则总线出错 155 if e != SystemError::ENOSYS { 156 kdebug!( 157 "do_device_attach_driver: bus.match_device() failed, dev: '{}', err: {:?}", 158 data.dev.name(), 159 e 160 ); 161 return Err(e); 162 } 163 } else if !r.unwrap() { 164 return Ok(false); 165 } 166 } 167 168 let async_allowed = driver.allows_async_probing(); 169 if data.check_async && async_allowed != data.want_async { 170 return Ok(false); 171 } 172 173 return driver_manager() 174 .probe_device(driver, &data.dev) 175 .map(|_| true); 176 } 177 178 /// 检查设备是否绑定到驱动程序 179 /// 180 /// ## 参数 181 /// 182 /// - `dev`: 设备 183 /// 184 /// ## 返回 185 /// 186 /// 如果传递的设备已成功完成对驱动程序的探测,则返回true,否则返回false。 187 pub fn device_is_bound(&self, dev: &Arc<dyn Device>) -> bool { 188 return driver_manager().driver_is_bound(dev); 189 } 190 191 /// 把一个驱动绑定到设备上 192 /// 193 /// 允许手动绑定驱动到设备上。调用者需要设置好dev.driver(),保证其不为None 194 /// 195 /// ## 参数 196 /// 197 /// - `dev`: 设备 198 /// 199 /// ## 建议 200 /// 201 /// 使用device_manager().driver_attach()会更好 202 /// 203 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#496 204 pub fn device_bind_driver(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> { 205 let r = driver_manager().driver_sysfs_add(dev); 206 if r.is_ok() { 207 self.device_links_force_bind(dev); 208 driver_manager().driver_bound(dev); 209 } else if let Some(bus) = dev.bus().and_then(|bus| bus.upgrade()) { 210 bus.subsystem().bus_notifier().call_chain( 211 BusNotifyEvent::DriverNotBound, 212 Some(dev), 213 None, 214 ); 215 } 216 217 if let Err(e) = r.as_ref() { 218 kerror!( 219 "device_bind_driver: driver_sysfs_add failed, dev: '{}', err: {:?}", 220 dev.name(), 221 e 222 ); 223 } 224 return r; 225 } 226 227 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#528 228 fn unbind_cleanup(&self, dev: &Arc<dyn Device>) { 229 dev.set_driver(None); 230 // todo: 添加更多操作,清理数据 231 } 232 } 233 234 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#866 235 #[derive(Debug)] 236 #[allow(dead_code)] 237 struct DeviceAttachData { 238 dev: Arc<dyn Device>, 239 240 /// Indicates whether we are considering asynchronous probing or 241 /// not. Only initial binding after device or driver registration 242 /// (including deferral processing) may be done asynchronously, the 243 /// rest is always synchronous, as we expect it is being done by 244 /// request from userspace. 245 check_async: bool, 246 247 /// Indicates if we are binding synchronous or asynchronous drivers. 248 /// When asynchronous probing is enabled we'll execute 2 passes 249 /// over drivers: first pass doing synchronous probing and second 250 /// doing asynchronous probing (if synchronous did not succeed - 251 /// most likely because there was no driver requiring synchronous 252 /// probing - and we found asynchronous driver during first pass). 253 /// The 2 passes are done because we can't shoot asynchronous 254 /// probe for given device and driver from bus_for_each_drv() since 255 /// driver pointer is not guaranteed to stay valid once 256 /// bus_for_each_drv() iterates to the next driver on the bus. 257 want_async: bool, 258 259 /// We'll set have_async to 'true' if, while scanning for matching 260 /// driver, we'll encounter one that requests asynchronous probing. 261 have_async: bool, 262 } 263 264 impl DeviceAttachData { 265 pub fn new(dev: Arc<dyn Device>, check_async: bool, want_async: bool) -> Self { 266 Self { 267 dev, 268 check_async, 269 want_async, 270 have_async: false, 271 } 272 } 273 274 #[allow(dead_code)] 275 #[inline(always)] 276 fn set_have_async(&mut self) { 277 self.have_async = true; 278 } 279 } 280 281 impl DriverManager { 282 /// 尝试把驱动绑定到现有的设备上 283 /// 284 /// 这个函数会遍历驱动现有的全部设备,然后尝试把他们匹配。 285 /// 一旦有一个设备匹配成功,就会返回,并且设备的driver字段会被设置。 286 pub fn driver_attach(&self, driver: &Arc<dyn Driver>) -> Result<(), SystemError> { 287 let bus = driver 288 .bus() 289 .and_then(|bus| bus.upgrade()) 290 .ok_or(SystemError::EINVAL)?; 291 for dev in bus.subsystem().devices().iter() { 292 self.do_driver_attach(dev, driver); 293 } 294 295 return Ok(()); 296 } 297 298 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#1134 299 #[inline(never)] 300 fn do_driver_attach(&self, device: &Arc<dyn Device>, driver: &Arc<dyn Driver>) -> bool { 301 let r = self.match_device(driver, device).unwrap_or(false); 302 if !r { 303 // 不匹配 304 return false; 305 } 306 307 if driver.allows_async_probing() { 308 unimplemented!( 309 "do_driver_attach: probe driver '{}' asynchronously", 310 driver.name() 311 ); 312 } 313 314 if self.probe_device(driver, device).is_err() { 315 return false; 316 } 317 318 return true; 319 } 320 321 #[inline(always)] 322 pub fn match_device( 323 &self, 324 driver: &Arc<dyn Driver>, 325 device: &Arc<dyn Device>, 326 ) -> Result<bool, SystemError> { 327 return driver 328 .bus() 329 .and_then(|bus| bus.upgrade()) 330 .unwrap() 331 .match_device(device, driver); 332 } 333 334 /// 尝试把设备和驱动绑定在一起 335 /// 336 /// 337 /// ## 返回 338 /// 339 /// - Ok(): 绑定成功 340 /// - Err(ENODEV): 设备未注册 341 /// - Err(EBUSY): 设备已经绑定到驱动上 342 /// 343 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#802 344 fn probe_device( 345 &self, 346 driver: &Arc<dyn Driver>, 347 device: &Arc<dyn Device>, 348 ) -> Result<(), SystemError> { 349 let r = self.do_probe_device(driver, device); 350 PROBE_WAIT_QUEUE.wakeup_all(None); 351 return r; 352 } 353 354 fn do_probe_device( 355 &self, 356 driver: &Arc<dyn Driver>, 357 device: &Arc<dyn Device>, 358 ) -> Result<(), SystemError> { 359 if device.is_dead() || (!device.is_registered()) { 360 return Err(SystemError::ENODEV); 361 } 362 if device.driver().is_some() { 363 return Err(SystemError::EBUSY); 364 } 365 366 device.set_can_match(true); 367 368 self.really_probe(driver, device)?; 369 370 return Ok(()); 371 } 372 373 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#584 374 fn really_probe( 375 &self, 376 driver: &Arc<dyn Driver>, 377 device: &Arc<dyn Device>, 378 ) -> Result<(), SystemError> { 379 let bind_failed = || { 380 device_manager().unbind_cleanup(device); 381 }; 382 383 let sysfs_failed = || { 384 if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) { 385 bus.subsystem().bus_notifier().call_chain( 386 BusNotifyEvent::DriverNotBound, 387 Some(device), 388 None, 389 ); 390 } 391 }; 392 393 let probe_failed = || { 394 self.remove_from_sysfs(device); 395 }; 396 397 let dev_groups_failed = || { 398 device_manager().remove(device); 399 }; 400 401 device.set_driver(Some(Arc::downgrade(driver))); 402 403 self.add_to_sysfs(device).map_err(|e| { 404 kerror!( 405 "really_probe: add_to_sysfs failed, dev: '{}', err: {:?}", 406 device.name(), 407 e 408 ); 409 sysfs_failed(); 410 bind_failed(); 411 e 412 })?; 413 414 self.call_driver_probe(device, driver).map_err(|e| { 415 kerror!( 416 "really_probe: call_driver_probe failed, dev: '{}', err: {:?}", 417 device.name(), 418 e 419 ); 420 421 probe_failed(); 422 sysfs_failed(); 423 bind_failed(); 424 e 425 })?; 426 427 device_manager() 428 .add_groups(device, driver.dev_groups()) 429 .map_err(|e| { 430 kerror!( 431 "really_probe: add_groups failed, dev: '{}', err: {:?}", 432 device.name(), 433 e 434 ); 435 dev_groups_failed(); 436 probe_failed(); 437 sysfs_failed(); 438 bind_failed(); 439 e 440 })?; 441 442 // 我们假设所有的设备都有 sync_state 这个属性。如果没有的话,也创建属性文件。 443 device_manager() 444 .create_file(device, &DeviceAttrStateSynced) 445 .map_err(|e| { 446 kerror!( 447 "really_probe: create_file failed, dev: '{}', err: {:?}", 448 device.name(), 449 e 450 ); 451 dev_groups_failed(); 452 probe_failed(); 453 sysfs_failed(); 454 bind_failed(); 455 e 456 })?; 457 458 self.driver_bound(device); 459 460 return Ok(()); 461 } 462 463 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#434 464 fn add_to_sysfs(&self, device: &Arc<dyn Device>) -> Result<(), SystemError> { 465 let driver = device.driver().ok_or(SystemError::EINVAL)?; 466 467 if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) { 468 bus.subsystem().bus_notifier().call_chain( 469 BusNotifyEvent::BindDriver, 470 Some(device), 471 None, 472 ); 473 } 474 475 let driver_kobj = driver.clone() as Arc<dyn KObject>; 476 let device_kobj = device.clone() as Arc<dyn KObject>; 477 478 sysfs_instance().create_link(Some(&driver_kobj), &device_kobj, device.name())?; 479 480 let fail_rm_dev_link = || { 481 sysfs_instance().remove_link(&driver_kobj, device.name()); 482 }; 483 484 sysfs_instance() 485 .create_link(Some(&device_kobj), &driver_kobj, "driver".to_string()) 486 .map_err(|e| { 487 fail_rm_dev_link(); 488 e 489 })?; 490 491 device_manager() 492 .create_file(device, &DeviceAttrCoredump) 493 .map_err(|e| { 494 sysfs_instance().remove_link(&device_kobj, "driver".to_string()); 495 fail_rm_dev_link(); 496 e 497 })?; 498 499 return Ok(()); 500 } 501 502 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#469 503 fn remove_from_sysfs(&self, _device: &Arc<dyn Device>) { 504 todo!("remove_from_sysfs") 505 } 506 507 fn call_driver_probe( 508 &self, 509 device: &Arc<dyn Device>, 510 driver: &Arc<dyn Driver>, 511 ) -> Result<(), SystemError> { 512 let bus = device 513 .bus() 514 .and_then(|bus| bus.upgrade()) 515 .ok_or(SystemError::EINVAL)?; 516 let r = bus.probe(device); 517 if r == Err(SystemError::ENOSYS) { 518 kerror!( 519 "call_driver_probe: bus.probe() failed, dev: '{}', err: {:?}", 520 device.name(), 521 r 522 ); 523 return r; 524 } 525 526 if r.is_ok() { 527 return Ok(()); 528 } 529 530 let err = r.unwrap_err(); 531 match err { 532 SystemError::ENODEV | SystemError::ENXIO => { 533 kdebug!( 534 "driver'{}': probe of {} rejects match {:?}", 535 driver.name(), 536 device.name(), 537 err 538 ); 539 } 540 541 _ => { 542 kwarn!( 543 "driver'{}': probe of {} failed with error {:?}", 544 driver.name(), 545 device.name(), 546 err 547 ); 548 } 549 } 550 551 return Err(err); 552 } 553 554 /// 当设备被成功探测,进行了'设备->驱动'绑定后,调用这个函数,完成'驱动->设备'的绑定 555 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#393 556 fn driver_bound(&self, device: &Arc<dyn Device>) { 557 if self.driver_is_bound(device) { 558 kwarn!("driver_bound: device '{}' is already bound.", device.name()); 559 return; 560 } 561 562 let driver = device.driver().unwrap(); 563 driver.add_device(device.clone()); 564 565 if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) { 566 bus.subsystem().bus_notifier().call_chain( 567 BusNotifyEvent::BoundDriver, 568 Some(device), 569 None, 570 ); 571 } 572 573 // todo: 发送kobj bind的uevent 574 } 575 576 fn driver_is_bound(&self, device: &Arc<dyn Device>) -> bool { 577 if let Some(driver) = device.driver() { 578 if driver.find_device_by_name(&device.name()).is_some() { 579 return true; 580 } 581 } 582 583 return false; 584 } 585 } 586 587 /// 设备文件夹下的`dev`文件的属性 588 #[derive(Debug, Clone, Copy)] 589 pub struct DeviceAttrStateSynced; 590 591 impl Attribute for DeviceAttrStateSynced { 592 fn mode(&self) -> ModeType { 593 // 0o444 594 return ModeType::S_IRUGO; 595 } 596 597 fn name(&self) -> &str { 598 "state_synced" 599 } 600 601 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 602 let dev = kobj.cast::<dyn Device>().map_err(|kobj| { 603 kerror!( 604 "Intertrait casting not implemented for kobj: {}", 605 kobj.name() 606 ); 607 SystemError::ENOSYS 608 })?; 609 610 let val = dev.state_synced(); 611 let val = if val { 1 } else { 0 }; 612 return sysfs_emit_str(buf, format!("{}\n", val).as_str()); 613 } 614 615 fn support(&self) -> SysFSOpsSupport { 616 SysFSOpsSupport::ATTR_SHOW 617 } 618 } 619 620 #[derive(Debug)] 621 pub(super) struct DeviceAttrCoredump; 622 623 impl Attribute for DeviceAttrCoredump { 624 fn name(&self) -> &str { 625 "coredump" 626 } 627 628 fn mode(&self) -> ModeType { 629 SYSFS_ATTR_MODE_WO 630 } 631 632 fn support(&self) -> SysFSOpsSupport { 633 SysFSOpsSupport::ATTR_STORE 634 } 635 636 fn store(&self, kobj: Arc<dyn KObject>, buf: &[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::ENOSYS 643 })?; 644 645 let drv = dev.driver().ok_or(SystemError::EINVAL)?; 646 drv.coredump(&dev)?; 647 648 return Ok(buf.len()); 649 } 650 } 651