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