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