106d5e247SLoGin use core::intrinsics::unlikely; 206d5e247SLoGin 3*a03c4f9dSLoGin use alloc::{string::ToString, sync::Arc}; 4*a03c4f9dSLoGin use intertrait::cast::CastArc; 506d5e247SLoGin 6*a03c4f9dSLoGin use crate::{ 7*a03c4f9dSLoGin driver::base::kobject::KObject, 8*a03c4f9dSLoGin filesystem::{ 9*a03c4f9dSLoGin sysfs::{file::sysfs_emit_str, sysfs_instance, Attribute, SysFSOpsSupport}, 10*a03c4f9dSLoGin vfs::syscall::ModeType, 11*a03c4f9dSLoGin }, 12*a03c4f9dSLoGin libs::wait_queue::WaitQueue, 13*a03c4f9dSLoGin syscall::SystemError, 14*a03c4f9dSLoGin }; 1506d5e247SLoGin 16*a03c4f9dSLoGin use super::{ 17*a03c4f9dSLoGin bus::BusNotifyEvent, 18*a03c4f9dSLoGin device_manager, 19*a03c4f9dSLoGin driver::{driver_manager, Driver, DriverManager}, 20*a03c4f9dSLoGin Device, DeviceManager, 21*a03c4f9dSLoGin }; 22*a03c4f9dSLoGin 23*a03c4f9dSLoGin static PROBE_WAIT_QUEUE: WaitQueue = WaitQueue::INIT; 2406d5e247SLoGin 2506d5e247SLoGin impl DeviceManager { 2606d5e247SLoGin /// 尝试把一个设备与一个驱动匹配 2706d5e247SLoGin /// 2806d5e247SLoGin /// 当前函数会遍历整个bus的驱动列表,并且尝试把设备与每一个驱动进行匹配。 2906d5e247SLoGin /// 一旦有一个驱动匹配成功,就会返回。 3006d5e247SLoGin /// 3106d5e247SLoGin /// ## 参数 3206d5e247SLoGin /// 3306d5e247SLoGin /// - `dev`: 设备 3406d5e247SLoGin /// 3506d5e247SLoGin /// ## 返回 3606d5e247SLoGin /// 3706d5e247SLoGin /// - Ok(true): 匹配成功 3806d5e247SLoGin /// - Ok(false): 没有匹配成功 3906d5e247SLoGin /// - Err(SystemError::ENODEV): 设备还没被注册 4006d5e247SLoGin /// 4106d5e247SLoGin /// ## 参考 4206d5e247SLoGin /// 4306d5e247SLoGin /// https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#1049 4406d5e247SLoGin pub fn device_attach(&self, dev: &Arc<dyn Device>) -> Result<bool, SystemError> { 4506d5e247SLoGin return self.do_device_attach(dev, false); 4606d5e247SLoGin } 4706d5e247SLoGin 4806d5e247SLoGin pub fn device_initial_probe(&self, dev: &Arc<dyn Device>) -> Result<bool, SystemError> { 4906d5e247SLoGin return self.do_device_attach(dev, true); 5006d5e247SLoGin } 5106d5e247SLoGin 5206d5e247SLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#978 5306d5e247SLoGin fn do_device_attach( 5406d5e247SLoGin &self, 5506d5e247SLoGin dev: &Arc<dyn Device>, 5606d5e247SLoGin allow_async: bool, 5706d5e247SLoGin ) -> Result<bool, SystemError> { 5806d5e247SLoGin if unlikely(allow_async) { 59*a03c4f9dSLoGin // todo!("do_device_attach: allow_async") 60*a03c4f9dSLoGin kwarn!("do_device_attach: allow_async is true, but currently not supported"); 6106d5e247SLoGin } 6206d5e247SLoGin if dev.is_dead() { 6306d5e247SLoGin return Ok(false); 6406d5e247SLoGin } 6506d5e247SLoGin 6606d5e247SLoGin let mut do_async = false; 6706d5e247SLoGin let mut r = Ok(false); 6806d5e247SLoGin 6906d5e247SLoGin if dev.driver().is_some() { 7006d5e247SLoGin if self.device_is_bound(dev) { 7106d5e247SLoGin return Ok(true); 7206d5e247SLoGin } 7306d5e247SLoGin 7406d5e247SLoGin if self.device_bind_driver(dev).is_ok() { 7506d5e247SLoGin return Ok(true); 7606d5e247SLoGin } else { 7706d5e247SLoGin dev.set_driver(None); 7806d5e247SLoGin return Ok(false); 7906d5e247SLoGin } 8006d5e247SLoGin } else { 8106d5e247SLoGin let bus = dev.bus().ok_or(SystemError::EINVAL)?; 8206d5e247SLoGin let mut data = DeviceAttachData::new(dev.clone(), allow_async, false); 8306d5e247SLoGin let mut flag = true; 84*a03c4f9dSLoGin for driver in bus.subsystem().drivers().iter() { 8506d5e247SLoGin if let Some(driver) = driver.upgrade() { 8606d5e247SLoGin let r = self.do_device_attach_driver(&driver, &mut data); 8706d5e247SLoGin if unlikely(r.is_err()) { 8806d5e247SLoGin flag = false; 8906d5e247SLoGin break; 9006d5e247SLoGin } 9106d5e247SLoGin } 9206d5e247SLoGin } 9306d5e247SLoGin 9406d5e247SLoGin if flag { 9506d5e247SLoGin r = Ok(true); 9606d5e247SLoGin } 9706d5e247SLoGin 9806d5e247SLoGin if !flag && allow_async && data.have_async { 9906d5e247SLoGin // If we could not find appropriate driver 10006d5e247SLoGin // synchronously and we are allowed to do 10106d5e247SLoGin // async probes and there are drivers that 10206d5e247SLoGin // want to probe asynchronously, we'll 10306d5e247SLoGin // try them. 10406d5e247SLoGin 10506d5e247SLoGin do_async = true; 10606d5e247SLoGin kdebug!( 10706d5e247SLoGin "do_device_attach: try scheduling asynchronous probe for device: {}", 10806d5e247SLoGin dev.name() 10906d5e247SLoGin ); 11006d5e247SLoGin } 11106d5e247SLoGin } 11206d5e247SLoGin 11306d5e247SLoGin if do_async { 11406d5e247SLoGin todo!("do_device_attach: do_async") 11506d5e247SLoGin } 11606d5e247SLoGin return r; 11706d5e247SLoGin } 11806d5e247SLoGin 11906d5e247SLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#899 12006d5e247SLoGin fn do_device_attach_driver( 12106d5e247SLoGin &self, 12206d5e247SLoGin _driver: &Arc<dyn Driver>, 12306d5e247SLoGin _data: &mut DeviceAttachData, 12406d5e247SLoGin ) -> Result<(), SystemError> { 12506d5e247SLoGin todo!("do_device_attach_driver") 12606d5e247SLoGin } 12706d5e247SLoGin 12806d5e247SLoGin /// 检查设备是否绑定到驱动程序 12906d5e247SLoGin /// 13006d5e247SLoGin /// ## 参数 13106d5e247SLoGin /// 13206d5e247SLoGin /// - `dev`: 设备 13306d5e247SLoGin /// 13406d5e247SLoGin /// ## 返回 13506d5e247SLoGin /// 13606d5e247SLoGin /// 如果传递的设备已成功完成对驱动程序的探测,则返回true,否则返回false。 13706d5e247SLoGin pub fn device_is_bound(&self, dev: &Arc<dyn Device>) -> bool { 13806d5e247SLoGin if dev.driver().is_some() { 13906d5e247SLoGin return true; 14006d5e247SLoGin } else { 14106d5e247SLoGin return false; 14206d5e247SLoGin } 14306d5e247SLoGin } 14406d5e247SLoGin 14506d5e247SLoGin /// 把一个驱动绑定到设备上 14606d5e247SLoGin /// 14706d5e247SLoGin /// 允许手动绑定驱动到设备上。调用者需要设置好dev.driver(),保证其不为None 14806d5e247SLoGin /// 14906d5e247SLoGin /// ## 参数 15006d5e247SLoGin /// 15106d5e247SLoGin /// - `dev`: 设备 15206d5e247SLoGin /// 15306d5e247SLoGin /// ## 建议 15406d5e247SLoGin /// 15506d5e247SLoGin /// 使用device_manager().driver_attach()会更好 15606d5e247SLoGin /// 15706d5e247SLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#496 15806d5e247SLoGin pub fn device_bind_driver(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> { 15906d5e247SLoGin let r = driver_manager().driver_sysfs_add(dev); 16006d5e247SLoGin if let Err(e) = r { 16106d5e247SLoGin self.device_links_force_bind(dev); 162*a03c4f9dSLoGin driver_manager().driver_bound(dev); 16306d5e247SLoGin return Err(e); 16406d5e247SLoGin } else { 16506d5e247SLoGin if let Some(bus) = dev.bus() { 16606d5e247SLoGin bus.subsystem().bus_notifier().call_chain( 16706d5e247SLoGin BusNotifyEvent::DriverNotBound, 16806d5e247SLoGin Some(dev), 16906d5e247SLoGin None, 17006d5e247SLoGin ); 17106d5e247SLoGin } 17206d5e247SLoGin } 17306d5e247SLoGin return r; 17406d5e247SLoGin } 17506d5e247SLoGin 176*a03c4f9dSLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#528 177*a03c4f9dSLoGin fn unbind_cleanup(&self, dev: &Arc<dyn Device>) { 178*a03c4f9dSLoGin dev.set_driver(None); 179*a03c4f9dSLoGin // todo: 添加更多操作,清理数据 18006d5e247SLoGin } 18106d5e247SLoGin } 18206d5e247SLoGin 18306d5e247SLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#866 18406d5e247SLoGin #[derive(Debug)] 18506d5e247SLoGin #[allow(dead_code)] 18606d5e247SLoGin struct DeviceAttachData { 18706d5e247SLoGin dev: Arc<dyn Device>, 18806d5e247SLoGin 18906d5e247SLoGin /// Indicates whether we are considering asynchronous probing or 19006d5e247SLoGin /// not. Only initial binding after device or driver registration 19106d5e247SLoGin /// (including deferral processing) may be done asynchronously, the 19206d5e247SLoGin /// rest is always synchronous, as we expect it is being done by 19306d5e247SLoGin /// request from userspace. 19406d5e247SLoGin check_async: bool, 19506d5e247SLoGin 19606d5e247SLoGin /// Indicates if we are binding synchronous or asynchronous drivers. 19706d5e247SLoGin /// When asynchronous probing is enabled we'll execute 2 passes 19806d5e247SLoGin /// over drivers: first pass doing synchronous probing and second 19906d5e247SLoGin /// doing asynchronous probing (if synchronous did not succeed - 20006d5e247SLoGin /// most likely because there was no driver requiring synchronous 20106d5e247SLoGin /// probing - and we found asynchronous driver during first pass). 20206d5e247SLoGin /// The 2 passes are done because we can't shoot asynchronous 20306d5e247SLoGin /// probe for given device and driver from bus_for_each_drv() since 20406d5e247SLoGin /// driver pointer is not guaranteed to stay valid once 20506d5e247SLoGin /// bus_for_each_drv() iterates to the next driver on the bus. 20606d5e247SLoGin want_async: bool, 20706d5e247SLoGin 20806d5e247SLoGin /// We'll set have_async to 'true' if, while scanning for matching 20906d5e247SLoGin /// driver, we'll encounter one that requests asynchronous probing. 21006d5e247SLoGin have_async: bool, 21106d5e247SLoGin } 21206d5e247SLoGin 21306d5e247SLoGin impl DeviceAttachData { 21406d5e247SLoGin pub fn new(dev: Arc<dyn Device>, check_async: bool, want_async: bool) -> Self { 21506d5e247SLoGin Self { 21606d5e247SLoGin dev, 21706d5e247SLoGin check_async, 21806d5e247SLoGin want_async, 21906d5e247SLoGin have_async: false, 22006d5e247SLoGin } 22106d5e247SLoGin } 22206d5e247SLoGin 22306d5e247SLoGin #[allow(dead_code)] 22406d5e247SLoGin #[inline(always)] 22506d5e247SLoGin fn set_have_async(&mut self) { 22606d5e247SLoGin self.have_async = true; 22706d5e247SLoGin } 22806d5e247SLoGin } 229*a03c4f9dSLoGin 230*a03c4f9dSLoGin impl DriverManager { 231*a03c4f9dSLoGin /// 尝试把驱动绑定到现有的设备上 232*a03c4f9dSLoGin /// 233*a03c4f9dSLoGin /// 这个函数会遍历驱动现有的全部设备,然后尝试把他们匹配。 234*a03c4f9dSLoGin /// 一旦有一个设备匹配成功,就会返回,并且设备的driver字段会被设置。 235*a03c4f9dSLoGin pub fn driver_attach(&self, driver: &Arc<dyn Driver>) -> Result<(), SystemError> { 236*a03c4f9dSLoGin let bus = driver.bus().ok_or(SystemError::EINVAL)?; 237*a03c4f9dSLoGin for dev in bus.subsystem().devices().iter() { 238*a03c4f9dSLoGin if let Some(dev) = dev.upgrade() { 239*a03c4f9dSLoGin if self.do_driver_attach(&dev, &driver) { 240*a03c4f9dSLoGin // 匹配成功 241*a03c4f9dSLoGin return Ok(()); 242*a03c4f9dSLoGin } 243*a03c4f9dSLoGin } 244*a03c4f9dSLoGin } 245*a03c4f9dSLoGin 246*a03c4f9dSLoGin return Ok(()); 247*a03c4f9dSLoGin } 248*a03c4f9dSLoGin 249*a03c4f9dSLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#1134 250*a03c4f9dSLoGin fn do_driver_attach(&self, device: &Arc<dyn Device>, driver: &Arc<dyn Driver>) -> bool { 251*a03c4f9dSLoGin let r = self.match_device(driver, device).unwrap_or(false); 252*a03c4f9dSLoGin if r == false { 253*a03c4f9dSLoGin // 不匹配 254*a03c4f9dSLoGin return false; 255*a03c4f9dSLoGin } 256*a03c4f9dSLoGin 257*a03c4f9dSLoGin if driver.allows_async_probing() { 258*a03c4f9dSLoGin unimplemented!( 259*a03c4f9dSLoGin "do_driver_attach: probe driver '{}' asynchronously", 260*a03c4f9dSLoGin driver.name() 261*a03c4f9dSLoGin ); 262*a03c4f9dSLoGin } 263*a03c4f9dSLoGin 264*a03c4f9dSLoGin if self.probe_device(driver, device).is_err() { 265*a03c4f9dSLoGin return false; 266*a03c4f9dSLoGin } 267*a03c4f9dSLoGin 268*a03c4f9dSLoGin return true; 269*a03c4f9dSLoGin } 270*a03c4f9dSLoGin 271*a03c4f9dSLoGin #[inline(always)] 272*a03c4f9dSLoGin pub fn match_device( 273*a03c4f9dSLoGin &self, 274*a03c4f9dSLoGin driver: &Arc<dyn Driver>, 275*a03c4f9dSLoGin device: &Arc<dyn Device>, 276*a03c4f9dSLoGin ) -> Result<bool, SystemError> { 277*a03c4f9dSLoGin return driver.bus().unwrap().match_device(device, driver); 278*a03c4f9dSLoGin } 279*a03c4f9dSLoGin 280*a03c4f9dSLoGin /// 尝试把设备和驱动绑定在一起 281*a03c4f9dSLoGin /// 282*a03c4f9dSLoGin /// 283*a03c4f9dSLoGin /// ## 返回 284*a03c4f9dSLoGin /// 285*a03c4f9dSLoGin /// - Ok(): 绑定成功 286*a03c4f9dSLoGin /// - Err(ENODEV): 设备未注册 287*a03c4f9dSLoGin /// - Err(EBUSY): 设备已经绑定到驱动上 288*a03c4f9dSLoGin /// 289*a03c4f9dSLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#802 290*a03c4f9dSLoGin fn probe_device( 291*a03c4f9dSLoGin &self, 292*a03c4f9dSLoGin driver: &Arc<dyn Driver>, 293*a03c4f9dSLoGin device: &Arc<dyn Device>, 294*a03c4f9dSLoGin ) -> Result<(), SystemError> { 295*a03c4f9dSLoGin let r = self.do_probe_device(driver, device); 296*a03c4f9dSLoGin PROBE_WAIT_QUEUE.wakeup_all(None); 297*a03c4f9dSLoGin return r; 298*a03c4f9dSLoGin } 299*a03c4f9dSLoGin 300*a03c4f9dSLoGin fn do_probe_device( 301*a03c4f9dSLoGin &self, 302*a03c4f9dSLoGin driver: &Arc<dyn Driver>, 303*a03c4f9dSLoGin device: &Arc<dyn Device>, 304*a03c4f9dSLoGin ) -> Result<(), SystemError> { 305*a03c4f9dSLoGin if device.is_dead() || (!device.is_registered()) { 306*a03c4f9dSLoGin return Err(SystemError::ENODEV); 307*a03c4f9dSLoGin } 308*a03c4f9dSLoGin if device.driver().is_some() { 309*a03c4f9dSLoGin return Err(SystemError::EBUSY); 310*a03c4f9dSLoGin } 311*a03c4f9dSLoGin 312*a03c4f9dSLoGin device.set_can_match(true); 313*a03c4f9dSLoGin 314*a03c4f9dSLoGin self.really_probe(driver, device)?; 315*a03c4f9dSLoGin 316*a03c4f9dSLoGin return Ok(()); 317*a03c4f9dSLoGin } 318*a03c4f9dSLoGin 319*a03c4f9dSLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#584 320*a03c4f9dSLoGin fn really_probe( 321*a03c4f9dSLoGin &self, 322*a03c4f9dSLoGin driver: &Arc<dyn Driver>, 323*a03c4f9dSLoGin device: &Arc<dyn Device>, 324*a03c4f9dSLoGin ) -> Result<(), SystemError> { 325*a03c4f9dSLoGin let bind_failed = || { 326*a03c4f9dSLoGin device_manager().unbind_cleanup(device); 327*a03c4f9dSLoGin }; 328*a03c4f9dSLoGin 329*a03c4f9dSLoGin let sysfs_failed = || { 330*a03c4f9dSLoGin if let Some(bus) = device.bus() { 331*a03c4f9dSLoGin bus.subsystem().bus_notifier().call_chain( 332*a03c4f9dSLoGin BusNotifyEvent::DriverNotBound, 333*a03c4f9dSLoGin Some(device), 334*a03c4f9dSLoGin None, 335*a03c4f9dSLoGin ); 336*a03c4f9dSLoGin } 337*a03c4f9dSLoGin }; 338*a03c4f9dSLoGin 339*a03c4f9dSLoGin let probe_failed = || { 340*a03c4f9dSLoGin self.remove_from_sysfs(device); 341*a03c4f9dSLoGin }; 342*a03c4f9dSLoGin 343*a03c4f9dSLoGin let dev_groups_failed = || { 344*a03c4f9dSLoGin device_manager().remove(device); 345*a03c4f9dSLoGin }; 346*a03c4f9dSLoGin 347*a03c4f9dSLoGin device.set_driver(Some(Arc::downgrade(driver))); 348*a03c4f9dSLoGin 349*a03c4f9dSLoGin self.add_to_sysfs(device).map_err(|e| { 350*a03c4f9dSLoGin kerror!( 351*a03c4f9dSLoGin "really_probe: add_to_sysfs failed, dev: '{}', err: {:?}", 352*a03c4f9dSLoGin device.name(), 353*a03c4f9dSLoGin e 354*a03c4f9dSLoGin ); 355*a03c4f9dSLoGin sysfs_failed(); 356*a03c4f9dSLoGin bind_failed(); 357*a03c4f9dSLoGin e 358*a03c4f9dSLoGin })?; 359*a03c4f9dSLoGin 360*a03c4f9dSLoGin self.call_driver_probe(device, driver).map_err(|e| { 361*a03c4f9dSLoGin kerror!( 362*a03c4f9dSLoGin "really_probe: call_driver_probe failed, dev: '{}', err: {:?}", 363*a03c4f9dSLoGin device.name(), 364*a03c4f9dSLoGin e 365*a03c4f9dSLoGin ); 366*a03c4f9dSLoGin 367*a03c4f9dSLoGin probe_failed(); 368*a03c4f9dSLoGin sysfs_failed(); 369*a03c4f9dSLoGin bind_failed(); 370*a03c4f9dSLoGin e 371*a03c4f9dSLoGin })?; 372*a03c4f9dSLoGin 373*a03c4f9dSLoGin device_manager() 374*a03c4f9dSLoGin .add_groups(device, driver.dev_groups()) 375*a03c4f9dSLoGin .map_err(|e| { 376*a03c4f9dSLoGin kerror!( 377*a03c4f9dSLoGin "really_probe: add_groups failed, dev: '{}', err: {:?}", 378*a03c4f9dSLoGin device.name(), 379*a03c4f9dSLoGin e 380*a03c4f9dSLoGin ); 381*a03c4f9dSLoGin dev_groups_failed(); 382*a03c4f9dSLoGin probe_failed(); 383*a03c4f9dSLoGin sysfs_failed(); 384*a03c4f9dSLoGin bind_failed(); 385*a03c4f9dSLoGin e 386*a03c4f9dSLoGin })?; 387*a03c4f9dSLoGin 388*a03c4f9dSLoGin // 我们假设所有的设备都有sync_state这个属性。如果没有的话,也创建属性文件。 389*a03c4f9dSLoGin device_manager() 390*a03c4f9dSLoGin .create_file(device, &DeviceAttrStateSynced) 391*a03c4f9dSLoGin .map_err(|e| { 392*a03c4f9dSLoGin kerror!( 393*a03c4f9dSLoGin "really_probe: create_file failed, dev: '{}', err: {:?}", 394*a03c4f9dSLoGin device.name(), 395*a03c4f9dSLoGin e 396*a03c4f9dSLoGin ); 397*a03c4f9dSLoGin dev_groups_failed(); 398*a03c4f9dSLoGin probe_failed(); 399*a03c4f9dSLoGin sysfs_failed(); 400*a03c4f9dSLoGin bind_failed(); 401*a03c4f9dSLoGin e 402*a03c4f9dSLoGin })?; 403*a03c4f9dSLoGin 404*a03c4f9dSLoGin self.driver_bound(device); 405*a03c4f9dSLoGin 406*a03c4f9dSLoGin return Ok(()); 407*a03c4f9dSLoGin } 408*a03c4f9dSLoGin 409*a03c4f9dSLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#434 410*a03c4f9dSLoGin fn add_to_sysfs(&self, device: &Arc<dyn Device>) -> Result<(), SystemError> { 411*a03c4f9dSLoGin let driver = device.driver().ok_or(SystemError::EINVAL)?; 412*a03c4f9dSLoGin 413*a03c4f9dSLoGin if let Some(bus) = device.bus() { 414*a03c4f9dSLoGin bus.subsystem().bus_notifier().call_chain( 415*a03c4f9dSLoGin BusNotifyEvent::BindDriver, 416*a03c4f9dSLoGin Some(&device), 417*a03c4f9dSLoGin None, 418*a03c4f9dSLoGin ); 419*a03c4f9dSLoGin } 420*a03c4f9dSLoGin 421*a03c4f9dSLoGin let driver_kobj = driver.clone() as Arc<dyn KObject>; 422*a03c4f9dSLoGin let device_kobj = device.clone() as Arc<dyn KObject>; 423*a03c4f9dSLoGin 424*a03c4f9dSLoGin sysfs_instance().create_link(Some(&driver_kobj), &device_kobj, device.name())?; 425*a03c4f9dSLoGin 426*a03c4f9dSLoGin let fail_rm_dev_link = || { 427*a03c4f9dSLoGin sysfs_instance().remove_link(&driver_kobj, device.name()); 428*a03c4f9dSLoGin }; 429*a03c4f9dSLoGin 430*a03c4f9dSLoGin sysfs_instance() 431*a03c4f9dSLoGin .create_link(Some(&device_kobj), &driver_kobj, "driver".to_string()) 432*a03c4f9dSLoGin .map_err(|e| { 433*a03c4f9dSLoGin fail_rm_dev_link(); 434*a03c4f9dSLoGin e 435*a03c4f9dSLoGin })?; 436*a03c4f9dSLoGin 437*a03c4f9dSLoGin device_manager() 438*a03c4f9dSLoGin .create_file(device, &DeviceAttrCoredump) 439*a03c4f9dSLoGin .map_err(|e| { 440*a03c4f9dSLoGin sysfs_instance().remove_link(&device_kobj, "driver".to_string()); 441*a03c4f9dSLoGin fail_rm_dev_link(); 442*a03c4f9dSLoGin e 443*a03c4f9dSLoGin })?; 444*a03c4f9dSLoGin 445*a03c4f9dSLoGin return Ok(()); 446*a03c4f9dSLoGin } 447*a03c4f9dSLoGin 448*a03c4f9dSLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#469 449*a03c4f9dSLoGin fn remove_from_sysfs(&self, _device: &Arc<dyn Device>) { 450*a03c4f9dSLoGin todo!("remove_from_sysfs") 451*a03c4f9dSLoGin } 452*a03c4f9dSLoGin 453*a03c4f9dSLoGin fn call_driver_probe( 454*a03c4f9dSLoGin &self, 455*a03c4f9dSLoGin device: &Arc<dyn Device>, 456*a03c4f9dSLoGin driver: &Arc<dyn Driver>, 457*a03c4f9dSLoGin ) -> Result<(), SystemError> { 458*a03c4f9dSLoGin let bus = device.bus().ok_or(SystemError::EINVAL)?; 459*a03c4f9dSLoGin let r = bus.probe(device); 460*a03c4f9dSLoGin if r == Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) { 461*a03c4f9dSLoGin kerror!( 462*a03c4f9dSLoGin "call_driver_probe: bus.probe() failed, dev: '{}', err: {:?}", 463*a03c4f9dSLoGin device.name(), 464*a03c4f9dSLoGin r 465*a03c4f9dSLoGin ); 466*a03c4f9dSLoGin return r; 467*a03c4f9dSLoGin } 468*a03c4f9dSLoGin 469*a03c4f9dSLoGin if r.is_ok() { 470*a03c4f9dSLoGin return Ok(()); 471*a03c4f9dSLoGin } 472*a03c4f9dSLoGin 473*a03c4f9dSLoGin let err = r.unwrap_err(); 474*a03c4f9dSLoGin match err { 475*a03c4f9dSLoGin SystemError::ENODEV | SystemError::ENXIO => { 476*a03c4f9dSLoGin kdebug!( 477*a03c4f9dSLoGin "driver'{}': probe of {} rejects match {:?}", 478*a03c4f9dSLoGin driver.name(), 479*a03c4f9dSLoGin device.name(), 480*a03c4f9dSLoGin err 481*a03c4f9dSLoGin ); 482*a03c4f9dSLoGin } 483*a03c4f9dSLoGin 484*a03c4f9dSLoGin _ => { 485*a03c4f9dSLoGin kwarn!( 486*a03c4f9dSLoGin "driver'{}': probe of {} failed with error {:?}", 487*a03c4f9dSLoGin driver.name(), 488*a03c4f9dSLoGin device.name(), 489*a03c4f9dSLoGin err 490*a03c4f9dSLoGin ); 491*a03c4f9dSLoGin } 492*a03c4f9dSLoGin } 493*a03c4f9dSLoGin 494*a03c4f9dSLoGin return Err(err); 495*a03c4f9dSLoGin } 496*a03c4f9dSLoGin 497*a03c4f9dSLoGin /// 当设备被成功探测,进行了'设备->驱动'绑定后,调用这个函数,完成'驱动->设备'的绑定 498*a03c4f9dSLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#393 499*a03c4f9dSLoGin fn driver_bound(&self, device: &Arc<dyn Device>) { 500*a03c4f9dSLoGin if self.driver_is_bound(device) { 501*a03c4f9dSLoGin kwarn!("driver_bound: device '{}' is already bound.", device.name()); 502*a03c4f9dSLoGin return; 503*a03c4f9dSLoGin } 504*a03c4f9dSLoGin 505*a03c4f9dSLoGin let driver = device.driver().unwrap(); 506*a03c4f9dSLoGin driver.add_device(device.clone()); 507*a03c4f9dSLoGin 508*a03c4f9dSLoGin if let Some(bus) = device.bus() { 509*a03c4f9dSLoGin bus.subsystem().bus_notifier().call_chain( 510*a03c4f9dSLoGin BusNotifyEvent::BoundDriver, 511*a03c4f9dSLoGin Some(device), 512*a03c4f9dSLoGin None, 513*a03c4f9dSLoGin ); 514*a03c4f9dSLoGin } 515*a03c4f9dSLoGin 516*a03c4f9dSLoGin // todo: 发送kobj bind的uevent 517*a03c4f9dSLoGin } 518*a03c4f9dSLoGin 519*a03c4f9dSLoGin fn driver_is_bound(&self, device: &Arc<dyn Device>) -> bool { 520*a03c4f9dSLoGin if let Some(driver) = device.driver() { 521*a03c4f9dSLoGin if driver.find_device_by_name(&device.name()).is_some() { 522*a03c4f9dSLoGin return true; 523*a03c4f9dSLoGin } 524*a03c4f9dSLoGin } 525*a03c4f9dSLoGin 526*a03c4f9dSLoGin return false; 527*a03c4f9dSLoGin } 528*a03c4f9dSLoGin } 529*a03c4f9dSLoGin 530*a03c4f9dSLoGin /// 设备文件夹下的`dev`文件的属性 531*a03c4f9dSLoGin #[derive(Debug, Clone, Copy)] 532*a03c4f9dSLoGin pub struct DeviceAttrStateSynced; 533*a03c4f9dSLoGin 534*a03c4f9dSLoGin impl Attribute for DeviceAttrStateSynced { 535*a03c4f9dSLoGin fn mode(&self) -> ModeType { 536*a03c4f9dSLoGin // 0o444 537*a03c4f9dSLoGin return ModeType::S_IRUGO; 538*a03c4f9dSLoGin } 539*a03c4f9dSLoGin 540*a03c4f9dSLoGin fn name(&self) -> &str { 541*a03c4f9dSLoGin "state_synced" 542*a03c4f9dSLoGin } 543*a03c4f9dSLoGin 544*a03c4f9dSLoGin fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 545*a03c4f9dSLoGin let dev = kobj.cast::<dyn Device>().map_err(|kobj| { 546*a03c4f9dSLoGin kerror!( 547*a03c4f9dSLoGin "Intertrait casting not implemented for kobj: {}", 548*a03c4f9dSLoGin kobj.name() 549*a03c4f9dSLoGin ); 550*a03c4f9dSLoGin SystemError::EOPNOTSUPP_OR_ENOTSUP 551*a03c4f9dSLoGin })?; 552*a03c4f9dSLoGin 553*a03c4f9dSLoGin let val = dev.state_synced(); 554*a03c4f9dSLoGin let val = if val { 1 } else { 0 }; 555*a03c4f9dSLoGin return sysfs_emit_str(buf, format!("{}\n", val).as_str()); 556*a03c4f9dSLoGin } 557*a03c4f9dSLoGin 558*a03c4f9dSLoGin fn support(&self) -> SysFSOpsSupport { 559*a03c4f9dSLoGin SysFSOpsSupport::SHOW 560*a03c4f9dSLoGin } 561*a03c4f9dSLoGin } 562*a03c4f9dSLoGin 563*a03c4f9dSLoGin #[derive(Debug)] 564*a03c4f9dSLoGin struct DeviceAttrCoredump; 565*a03c4f9dSLoGin 566*a03c4f9dSLoGin impl Attribute for DeviceAttrCoredump { 567*a03c4f9dSLoGin fn name(&self) -> &str { 568*a03c4f9dSLoGin "coredump" 569*a03c4f9dSLoGin } 570*a03c4f9dSLoGin 571*a03c4f9dSLoGin fn mode(&self) -> ModeType { 572*a03c4f9dSLoGin ModeType::from_bits_truncate(0o200) 573*a03c4f9dSLoGin } 574*a03c4f9dSLoGin 575*a03c4f9dSLoGin fn support(&self) -> SysFSOpsSupport { 576*a03c4f9dSLoGin SysFSOpsSupport::STORE 577*a03c4f9dSLoGin } 578*a03c4f9dSLoGin 579*a03c4f9dSLoGin fn store(&self, kobj: Arc<dyn KObject>, buf: &[u8]) -> Result<usize, SystemError> { 580*a03c4f9dSLoGin let dev = kobj.cast::<dyn Device>().map_err(|kobj| { 581*a03c4f9dSLoGin kerror!( 582*a03c4f9dSLoGin "Intertrait casting not implemented for kobj: {}", 583*a03c4f9dSLoGin kobj.name() 584*a03c4f9dSLoGin ); 585*a03c4f9dSLoGin SystemError::EOPNOTSUPP_OR_ENOTSUP 586*a03c4f9dSLoGin })?; 587*a03c4f9dSLoGin 588*a03c4f9dSLoGin let drv = dev.driver().ok_or(SystemError::EINVAL)?; 589*a03c4f9dSLoGin drv.coredump(&dev)?; 590*a03c4f9dSLoGin 591*a03c4f9dSLoGin return Ok(buf.len()); 592*a03c4f9dSLoGin } 593*a03c4f9dSLoGin } 594