1 use core::intrinsics::unlikely; 2 3 use alloc::{string::ToString, sync::Arc}; 4 use intertrait::cast::CastArc; 5 use log::{debug, error, warn}; 6 7 use crate::{ 8 driver::base::kobject::KObject, 9 filesystem::{ 10 sysfs::{ 11 file::sysfs_emit_str, sysfs_instance, Attribute, SysFSOpsSupport, SYSFS_ATTR_MODE_WO, 12 }, 13 vfs::syscall::ModeType, 14 }, 15 libs::wait_queue::WaitQueue, 16 }; 17 use system_error::SystemError; 18 19 use super::{ 20 bus::BusNotifyEvent, 21 device_manager, 22 driver::{driver_manager, Driver, DriverManager}, 23 Device, DeviceManager, 24 }; 25 26 static PROBE_WAIT_QUEUE: WaitQueue = WaitQueue::default(); 27 28 impl DeviceManager { 29 /// 尝试把一个设备与一个驱动匹配 30 /// 31 /// 当前函数会遍历整个bus的驱动列表,并且尝试把设备与每一个驱动进行匹配。 32 /// 一旦有一个驱动匹配成功,就会返回。 33 /// 34 /// ## 参数 35 /// 36 /// - `dev`: 设备 37 /// 38 /// ## 返回 39 /// 40 /// - Ok(true): 匹配成功 41 /// - Ok(false): 没有匹配成功 42 /// - Err(SystemError::ENODEV): 设备还没被注册 43 /// 44 /// ## 参考 45 /// 46 /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#1049 47 pub fn device_attach(&self, dev: &Arc<dyn Device>) -> Result<bool, SystemError> { 48 return self.do_device_attach(dev, false); 49 } 50 51 pub fn device_initial_probe(&self, dev: &Arc<dyn Device>) -> Result<bool, SystemError> { 52 return self.do_device_attach(dev, true); 53 } 54 55 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#978 56 fn do_device_attach( 57 &self, 58 dev: &Arc<dyn Device>, 59 allow_async: bool, 60 ) -> Result<bool, SystemError> { 61 if unlikely(allow_async) { 62 // todo!("do_device_attach: allow_async") 63 warn!("do_device_attach: allow_async is true, but currently not supported"); 64 } 65 if dev.is_dead() { 66 return Ok(false); 67 } 68 69 warn!("do_device_attach: dev: '{}'", dev.name()); 70 71 let mut do_async = false; 72 let mut r = Ok(false); 73 74 if dev.driver().is_some() { 75 if self.device_is_bound(dev) { 76 debug!( 77 "do_device_attach: device '{}' is already bound.", 78 dev.name() 79 ); 80 return Ok(true); 81 } 82 83 if self.device_bind_driver(dev).is_ok() { 84 return Ok(true); 85 } else { 86 dev.set_driver(None); 87 return Ok(false); 88 } 89 } else { 90 debug!("do_device_attach: device '{}' is not bound.", dev.name()); 91 let bus = dev 92 .bus() 93 .and_then(|bus| bus.upgrade()) 94 .ok_or(SystemError::EINVAL)?; 95 let mut data = DeviceAttachData::new(dev.clone(), allow_async, false); 96 let mut flag = false; 97 for driver in bus.subsystem().drivers().iter() { 98 let r = self.do_device_attach_driver(driver, &mut data); 99 if unlikely(r.is_err()) { 100 flag = false; 101 break; 102 } else if r.unwrap() { 103 flag = true; 104 break; 105 } 106 } 107 108 if flag { 109 r = Ok(true); 110 } 111 112 if !flag && allow_async && data.have_async { 113 // If we could not find appropriate driver 114 // synchronously and we are allowed to do 115 // async probes and there are drivers that 116 // want to probe asynchronously, we'll 117 // try them. 118 119 do_async = true; 120 debug!( 121 "do_device_attach: try scheduling asynchronous probe for device: {}", 122 dev.name() 123 ); 124 } 125 } 126 127 if do_async { 128 todo!("do_device_attach: do_async") 129 } 130 return r; 131 } 132 133 /// 匹配设备和驱动 134 /// 135 /// ## 参数 136 /// 137 /// - `driver`: 驱动 138 /// - `data`: 匹配数据 139 /// 140 /// ## 返回 141 /// 142 /// - Ok(true): 匹配成功 143 /// - Ok(false): 没有匹配成功 144 /// - Err(SystemError): 匹配过程中出现意外错误,没有匹配成功 145 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#899 146 fn do_device_attach_driver( 147 &self, 148 driver: &Arc<dyn Driver>, 149 data: &mut DeviceAttachData, 150 ) -> Result<bool, SystemError> { 151 if let Some(bus) = driver.bus().and_then(|bus| bus.upgrade()) { 152 let r = bus.match_device(&data.dev, driver); 153 154 if let Err(e) = r { 155 // 如果不是ENOSYS,则总线出错 156 if e != SystemError::ENOSYS { 157 debug!( 158 "do_device_attach_driver: bus.match_device() failed, dev: '{}', err: {:?}", 159 data.dev.name(), 160 e 161 ); 162 return Err(e); 163 } 164 } else if !r.unwrap() { 165 return Ok(false); 166 } 167 } 168 169 let async_allowed = driver.allows_async_probing(); 170 if data.check_async && async_allowed != data.want_async { 171 return Ok(false); 172 } 173 174 return driver_manager() 175 .probe_device(driver, &data.dev) 176 .map(|_| true); 177 } 178 179 /// 检查设备是否绑定到驱动程序 180 /// 181 /// ## 参数 182 /// 183 /// - `dev`: 设备 184 /// 185 /// ## 返回 186 /// 187 /// 如果传递的设备已成功完成对驱动程序的探测,则返回true,否则返回false。 188 pub fn device_is_bound(&self, dev: &Arc<dyn Device>) -> bool { 189 return driver_manager().driver_is_bound(dev); 190 } 191 192 /// 把一个驱动绑定到设备上 193 /// 194 /// 允许手动绑定驱动到设备上。调用者需要设置好dev.driver(),保证其不为None 195 /// 196 /// ## 参数 197 /// 198 /// - `dev`: 设备 199 /// 200 /// ## 建议 201 /// 202 /// 使用device_manager().driver_attach()会更好 203 /// 204 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#496 205 pub fn device_bind_driver(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> { 206 let r = driver_manager().driver_sysfs_add(dev); 207 if r.is_ok() { 208 self.device_links_force_bind(dev); 209 driver_manager().driver_bound(dev); 210 } else if let Some(bus) = dev.bus().and_then(|bus| bus.upgrade()) { 211 bus.subsystem().bus_notifier().call_chain( 212 BusNotifyEvent::DriverNotBound, 213 Some(dev), 214 None, 215 ); 216 } 217 218 if let Err(e) = r.as_ref() { 219 error!( 220 "device_bind_driver: driver_sysfs_add failed, dev: '{}', err: {:?}", 221 dev.name(), 222 e 223 ); 224 } 225 return r; 226 } 227 228 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#528 229 fn unbind_cleanup(&self, dev: &Arc<dyn Device>) { 230 dev.set_driver(None); 231 // todo: 添加更多操作,清理数据 232 } 233 } 234 235 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#866 236 #[derive(Debug)] 237 #[allow(dead_code)] 238 struct DeviceAttachData { 239 dev: Arc<dyn Device>, 240 241 /// Indicates whether we are considering asynchronous probing or 242 /// not. Only initial binding after device or driver registration 243 /// (including deferral processing) may be done asynchronously, the 244 /// rest is always synchronous, as we expect it is being done by 245 /// request from userspace. 246 check_async: bool, 247 248 /// Indicates if we are binding synchronous or asynchronous drivers. 249 /// When asynchronous probing is enabled we'll execute 2 passes 250 /// over drivers: first pass doing synchronous probing and second 251 /// doing asynchronous probing (if synchronous did not succeed - 252 /// most likely because there was no driver requiring synchronous 253 /// probing - and we found asynchronous driver during first pass). 254 /// The 2 passes are done because we can't shoot asynchronous 255 /// probe for given device and driver from bus_for_each_drv() since 256 /// driver pointer is not guaranteed to stay valid once 257 /// bus_for_each_drv() iterates to the next driver on the bus. 258 want_async: bool, 259 260 /// We'll set have_async to 'true' if, while scanning for matching 261 /// driver, we'll encounter one that requests asynchronous probing. 262 have_async: bool, 263 } 264 265 impl DeviceAttachData { 266 pub fn new(dev: Arc<dyn Device>, check_async: bool, want_async: bool) -> Self { 267 Self { 268 dev, 269 check_async, 270 want_async, 271 have_async: false, 272 } 273 } 274 275 #[allow(dead_code)] 276 #[inline(always)] 277 fn set_have_async(&mut self) { 278 self.have_async = true; 279 } 280 } 281 282 impl DriverManager { 283 /// 尝试把驱动绑定到现有的设备上 284 /// 285 /// 这个函数会遍历驱动现有的全部设备,然后尝试把他们匹配。 286 /// 一旦有一个设备匹配成功,就会返回,并且设备的driver字段会被设置。 287 pub fn driver_attach(&self, driver: &Arc<dyn Driver>) -> Result<(), SystemError> { 288 let bus = driver 289 .bus() 290 .and_then(|bus| bus.upgrade()) 291 .ok_or(SystemError::EINVAL)?; 292 for dev in bus.subsystem().devices().iter() { 293 self.do_driver_attach(dev, driver); 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 #[inline(never)] 301 fn do_driver_attach(&self, device: &Arc<dyn Device>, driver: &Arc<dyn Driver>) -> bool { 302 let r = self.match_device(driver, device).unwrap_or(false); 303 if !r { 304 // 不匹配 305 return false; 306 } 307 308 if driver.allows_async_probing() { 309 unimplemented!( 310 "do_driver_attach: probe driver '{}' asynchronously", 311 driver.name() 312 ); 313 } 314 315 if self.probe_device(driver, device).is_err() { 316 return false; 317 } 318 319 return true; 320 } 321 322 #[inline(always)] 323 pub fn match_device( 324 &self, 325 driver: &Arc<dyn Driver>, 326 device: &Arc<dyn Device>, 327 ) -> Result<bool, SystemError> { 328 return driver 329 .bus() 330 .and_then(|bus| bus.upgrade()) 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().and_then(|bus| bus.upgrade()) { 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 error!( 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 error!( 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 error!( 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 error!( 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().and_then(|bus| bus.upgrade()) { 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 .and_then(|bus| bus.upgrade()) 516 .ok_or(SystemError::EINVAL)?; 517 let r = bus.probe(device); 518 if r == Err(SystemError::ENOSYS) { 519 error!( 520 "call_driver_probe: bus.probe() failed, dev: '{}', err: {:?}", 521 device.name(), 522 r 523 ); 524 return r; 525 } 526 527 if r.is_ok() { 528 return Ok(()); 529 } 530 531 let err = r.unwrap_err(); 532 match err { 533 SystemError::ENODEV | SystemError::ENXIO => { 534 debug!( 535 "driver'{}': probe of {} rejects match {:?}", 536 driver.name(), 537 device.name(), 538 err 539 ); 540 } 541 542 _ => { 543 warn!( 544 "driver'{}': probe of {} failed with error {:?}", 545 driver.name(), 546 device.name(), 547 err 548 ); 549 } 550 } 551 552 return Err(err); 553 } 554 555 /// 当设备被成功探测,进行了'设备->驱动'绑定后,调用这个函数,完成'驱动->设备'的绑定 556 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#393 557 fn driver_bound(&self, device: &Arc<dyn Device>) { 558 if self.driver_is_bound(device) { 559 warn!("driver_bound: device '{}' is already bound.", device.name()); 560 return; 561 } 562 563 let driver = device.driver().unwrap(); 564 driver.add_device(device.clone()); 565 566 if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) { 567 bus.subsystem().bus_notifier().call_chain( 568 BusNotifyEvent::BoundDriver, 569 Some(device), 570 None, 571 ); 572 } 573 574 // todo: 发送kobj bind的uevent 575 } 576 577 fn driver_is_bound(&self, device: &Arc<dyn Device>) -> bool { 578 if let Some(driver) = device.driver() { 579 if driver.find_device_by_name(&device.name()).is_some() { 580 return true; 581 } 582 } 583 584 return false; 585 } 586 } 587 588 /// 设备文件夹下的`dev`文件的属性 589 #[derive(Debug, Clone, Copy)] 590 pub struct DeviceAttrStateSynced; 591 592 impl Attribute for DeviceAttrStateSynced { 593 fn mode(&self) -> ModeType { 594 // 0o444 595 return ModeType::S_IRUGO; 596 } 597 598 fn name(&self) -> &str { 599 "state_synced" 600 } 601 602 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 603 let dev = kobj.cast::<dyn Device>().map_err(|kobj| { 604 error!( 605 "Intertrait casting not implemented for kobj: {}", 606 kobj.name() 607 ); 608 SystemError::ENOSYS 609 })?; 610 611 let val = dev.state_synced(); 612 let val = if val { 1 } else { 0 }; 613 return sysfs_emit_str(buf, format!("{}\n", val).as_str()); 614 } 615 616 fn support(&self) -> SysFSOpsSupport { 617 SysFSOpsSupport::ATTR_SHOW 618 } 619 } 620 621 #[derive(Debug)] 622 pub(super) struct DeviceAttrCoredump; 623 624 impl Attribute for DeviceAttrCoredump { 625 fn name(&self) -> &str { 626 "coredump" 627 } 628 629 fn mode(&self) -> ModeType { 630 SYSFS_ATTR_MODE_WO 631 } 632 633 fn support(&self) -> SysFSOpsSupport { 634 SysFSOpsSupport::ATTR_STORE 635 } 636 637 fn store(&self, kobj: Arc<dyn KObject>, buf: &[u8]) -> Result<usize, SystemError> { 638 let dev = kobj.cast::<dyn Device>().map_err(|kobj| { 639 error!( 640 "Intertrait casting not implemented for kobj: {}", 641 kobj.name() 642 ); 643 SystemError::ENOSYS 644 })?; 645 646 let drv = dev.driver().ok_or(SystemError::EINVAL)?; 647 drv.coredump(&dev)?; 648 649 return Ok(buf.len()); 650 } 651 } 652