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