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