106d5e247SLoGin use core::intrinsics::unlikely; 206d5e247SLoGin 3a03c4f9dSLoGin use alloc::{string::ToString, sync::Arc}; 4a03c4f9dSLoGin use intertrait::cast::CastArc; 52eab6dd7S曾俊 use log::{debug, error, warn}; 606d5e247SLoGin 7a03c4f9dSLoGin use crate::{ 8a03c4f9dSLoGin driver::base::kobject::KObject, 9a03c4f9dSLoGin filesystem::{ 10196b75dcSLoGin sysfs::{ 11196b75dcSLoGin file::sysfs_emit_str, sysfs_instance, Attribute, SysFSOpsSupport, SYSFS_ATTR_MODE_WO, 12196b75dcSLoGin }, 13a03c4f9dSLoGin vfs::syscall::ModeType, 14a03c4f9dSLoGin }, 15a03c4f9dSLoGin libs::wait_queue::WaitQueue, 16a03c4f9dSLoGin }; 1791e9d4abSLoGin use system_error::SystemError; 1806d5e247SLoGin 19a03c4f9dSLoGin use super::{ 20a03c4f9dSLoGin bus::BusNotifyEvent, 21a03c4f9dSLoGin device_manager, 22a03c4f9dSLoGin driver::{driver_manager, Driver, DriverManager}, 23a03c4f9dSLoGin Device, DeviceManager, 24a03c4f9dSLoGin }; 25a03c4f9dSLoGin 26b5b571e0SLoGin static PROBE_WAIT_QUEUE: WaitQueue = WaitQueue::default(); 2706d5e247SLoGin 2806d5e247SLoGin impl DeviceManager { 2906d5e247SLoGin /// 尝试把一个设备与一个驱动匹配 3006d5e247SLoGin /// 3106d5e247SLoGin /// 当前函数会遍历整个bus的驱动列表,并且尝试把设备与每一个驱动进行匹配。 3206d5e247SLoGin /// 一旦有一个驱动匹配成功,就会返回。 3306d5e247SLoGin /// 3406d5e247SLoGin /// ## 参数 3506d5e247SLoGin /// 3606d5e247SLoGin /// - `dev`: 设备 3706d5e247SLoGin /// 3806d5e247SLoGin /// ## 返回 3906d5e247SLoGin /// 4006d5e247SLoGin /// - Ok(true): 匹配成功 4106d5e247SLoGin /// - Ok(false): 没有匹配成功 4206d5e247SLoGin /// - Err(SystemError::ENODEV): 设备还没被注册 4306d5e247SLoGin /// 4406d5e247SLoGin /// ## 参考 4506d5e247SLoGin /// 46e7071df6SLoGin /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#1049 device_attach(&self, dev: &Arc<dyn Device>) -> Result<bool, SystemError>4706d5e247SLoGin pub fn device_attach(&self, dev: &Arc<dyn Device>) -> Result<bool, SystemError> { 4806d5e247SLoGin return self.do_device_attach(dev, false); 4906d5e247SLoGin } 5006d5e247SLoGin device_initial_probe(&self, dev: &Arc<dyn Device>) -> Result<bool, SystemError>5106d5e247SLoGin pub fn device_initial_probe(&self, dev: &Arc<dyn Device>) -> Result<bool, SystemError> { 5206d5e247SLoGin return self.do_device_attach(dev, true); 5306d5e247SLoGin } 5406d5e247SLoGin 55e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#978 do_device_attach( &self, dev: &Arc<dyn Device>, allow_async: bool, ) -> Result<bool, SystemError>5606d5e247SLoGin fn do_device_attach( 5706d5e247SLoGin &self, 5806d5e247SLoGin dev: &Arc<dyn Device>, 5906d5e247SLoGin allow_async: bool, 6006d5e247SLoGin ) -> Result<bool, SystemError> { 6106d5e247SLoGin if unlikely(allow_async) { 62a03c4f9dSLoGin // todo!("do_device_attach: allow_async") 632eab6dd7S曾俊 warn!("do_device_attach: allow_async is true, but currently not supported"); 6406d5e247SLoGin } 6506d5e247SLoGin if dev.is_dead() { 6606d5e247SLoGin return Ok(false); 6706d5e247SLoGin } 6806d5e247SLoGin 692eab6dd7S曾俊 warn!("do_device_attach: dev: '{}'", dev.name()); 70c566df45SLoGin 7106d5e247SLoGin let mut do_async = false; 7206d5e247SLoGin let mut r = Ok(false); 7306d5e247SLoGin 7406d5e247SLoGin if dev.driver().is_some() { 7506d5e247SLoGin if self.device_is_bound(dev) { 762eab6dd7S曾俊 debug!( 77731bc2b3SLoGin "do_device_attach: device '{}' is already bound.", 78731bc2b3SLoGin dev.name() 79731bc2b3SLoGin ); 8006d5e247SLoGin return Ok(true); 8106d5e247SLoGin } 8206d5e247SLoGin 8306d5e247SLoGin if self.device_bind_driver(dev).is_ok() { 8406d5e247SLoGin return Ok(true); 8506d5e247SLoGin } else { 8606d5e247SLoGin dev.set_driver(None); 8706d5e247SLoGin return Ok(false); 8806d5e247SLoGin } 8906d5e247SLoGin } else { 902eab6dd7S曾俊 debug!("do_device_attach: device '{}' is not bound.", dev.name()); 91c566df45SLoGin let bus = dev 92c566df45SLoGin .bus() 93b5b571e0SLoGin .and_then(|bus| bus.upgrade()) 94c566df45SLoGin .ok_or(SystemError::EINVAL)?; 9506d5e247SLoGin let mut data = DeviceAttachData::new(dev.clone(), allow_async, false); 96c566df45SLoGin let mut flag = false; 97a03c4f9dSLoGin for driver in bus.subsystem().drivers().iter() { 98b5b571e0SLoGin let r = self.do_device_attach_driver(driver, &mut data); 9906d5e247SLoGin if unlikely(r.is_err()) { 10006d5e247SLoGin flag = false; 10106d5e247SLoGin break; 102b5b571e0SLoGin } else if r.unwrap() { 103c566df45SLoGin flag = true; 104c566df45SLoGin break; 10506d5e247SLoGin } 10606d5e247SLoGin } 10706d5e247SLoGin 10806d5e247SLoGin if flag { 10906d5e247SLoGin r = Ok(true); 11006d5e247SLoGin } 11106d5e247SLoGin 11206d5e247SLoGin if !flag && allow_async && data.have_async { 11306d5e247SLoGin // If we could not find appropriate driver 11406d5e247SLoGin // synchronously and we are allowed to do 11506d5e247SLoGin // async probes and there are drivers that 11606d5e247SLoGin // want to probe asynchronously, we'll 11706d5e247SLoGin // try them. 11806d5e247SLoGin 11906d5e247SLoGin do_async = true; 1202eab6dd7S曾俊 debug!( 12106d5e247SLoGin "do_device_attach: try scheduling asynchronous probe for device: {}", 12206d5e247SLoGin dev.name() 12306d5e247SLoGin ); 12406d5e247SLoGin } 12506d5e247SLoGin } 12606d5e247SLoGin 12706d5e247SLoGin if do_async { 12806d5e247SLoGin todo!("do_device_attach: do_async") 12906d5e247SLoGin } 13006d5e247SLoGin return r; 13106d5e247SLoGin } 13206d5e247SLoGin 133c566df45SLoGin /// 匹配设备和驱动 134c566df45SLoGin /// 135c566df45SLoGin /// ## 参数 136c566df45SLoGin /// 137c566df45SLoGin /// - `driver`: 驱动 138c566df45SLoGin /// - `data`: 匹配数据 139c566df45SLoGin /// 140c566df45SLoGin /// ## 返回 141c566df45SLoGin /// 142c566df45SLoGin /// - Ok(true): 匹配成功 143c566df45SLoGin /// - Ok(false): 没有匹配成功 144c566df45SLoGin /// - Err(SystemError): 匹配过程中出现意外错误,没有匹配成功 145*bd70d2d1SLoGin /// 146e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#899 do_device_attach_driver( &self, driver: &Arc<dyn Driver>, data: &mut DeviceAttachData, ) -> Result<bool, SystemError>14706d5e247SLoGin fn do_device_attach_driver( 14806d5e247SLoGin &self, 149c566df45SLoGin driver: &Arc<dyn Driver>, 150c566df45SLoGin data: &mut DeviceAttachData, 151c566df45SLoGin ) -> Result<bool, SystemError> { 152b5b571e0SLoGin if let Some(bus) = driver.bus().and_then(|bus| bus.upgrade()) { 153c566df45SLoGin let r = bus.match_device(&data.dev, driver); 154c566df45SLoGin 155c566df45SLoGin if let Err(e) = r { 156c566df45SLoGin // 如果不是ENOSYS,则总线出错 157c566df45SLoGin if e != SystemError::ENOSYS { 1582eab6dd7S曾俊 debug!( 159c566df45SLoGin "do_device_attach_driver: bus.match_device() failed, dev: '{}', err: {:?}", 160c566df45SLoGin data.dev.name(), 161c566df45SLoGin e 162c566df45SLoGin ); 163c566df45SLoGin return Err(e); 164c566df45SLoGin } 165b5b571e0SLoGin } else if !r.unwrap() { 166c566df45SLoGin return Ok(false); 167c566df45SLoGin } 168c566df45SLoGin } 169c566df45SLoGin 170c566df45SLoGin let async_allowed = driver.allows_async_probing(); 171c566df45SLoGin if data.check_async && async_allowed != data.want_async { 172c566df45SLoGin return Ok(false); 173c566df45SLoGin } 174c566df45SLoGin 175c566df45SLoGin return driver_manager() 176c566df45SLoGin .probe_device(driver, &data.dev) 177c566df45SLoGin .map(|_| true); 17806d5e247SLoGin } 17906d5e247SLoGin 18006d5e247SLoGin /// 检查设备是否绑定到驱动程序 18106d5e247SLoGin /// 18206d5e247SLoGin /// ## 参数 18306d5e247SLoGin /// 18406d5e247SLoGin /// - `dev`: 设备 18506d5e247SLoGin /// 18606d5e247SLoGin /// ## 返回 18706d5e247SLoGin /// 18806d5e247SLoGin /// 如果传递的设备已成功完成对驱动程序的探测,则返回true,否则返回false。 device_is_bound(&self, dev: &Arc<dyn Device>) -> bool18906d5e247SLoGin pub fn device_is_bound(&self, dev: &Arc<dyn Device>) -> bool { 190e32effb1SLoGin return driver_manager().driver_is_bound(dev); 19106d5e247SLoGin } 19206d5e247SLoGin 19306d5e247SLoGin /// 把一个驱动绑定到设备上 19406d5e247SLoGin /// 19506d5e247SLoGin /// 允许手动绑定驱动到设备上。调用者需要设置好dev.driver(),保证其不为None 19606d5e247SLoGin /// 19706d5e247SLoGin /// ## 参数 19806d5e247SLoGin /// 19906d5e247SLoGin /// - `dev`: 设备 20006d5e247SLoGin /// 20106d5e247SLoGin /// ## 建议 20206d5e247SLoGin /// 20306d5e247SLoGin /// 使用device_manager().driver_attach()会更好 20406d5e247SLoGin /// 205e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#496 device_bind_driver(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError>20606d5e247SLoGin pub fn device_bind_driver(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> { 20706d5e247SLoGin let r = driver_manager().driver_sysfs_add(dev); 208731bc2b3SLoGin if r.is_ok() { 20906d5e247SLoGin self.device_links_force_bind(dev); 210a03c4f9dSLoGin driver_manager().driver_bound(dev); 211b5b571e0SLoGin } else if let Some(bus) = dev.bus().and_then(|bus| bus.upgrade()) { 21206d5e247SLoGin bus.subsystem().bus_notifier().call_chain( 21306d5e247SLoGin BusNotifyEvent::DriverNotBound, 21406d5e247SLoGin Some(dev), 21506d5e247SLoGin None, 21606d5e247SLoGin ); 21706d5e247SLoGin } 218731bc2b3SLoGin 219731bc2b3SLoGin if let Err(e) = r.as_ref() { 2202eab6dd7S曾俊 error!( 221731bc2b3SLoGin "device_bind_driver: driver_sysfs_add failed, dev: '{}', err: {:?}", 222731bc2b3SLoGin dev.name(), 223731bc2b3SLoGin e 224731bc2b3SLoGin ); 225731bc2b3SLoGin } 22606d5e247SLoGin return r; 22706d5e247SLoGin } 22806d5e247SLoGin 229e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#528 unbind_cleanup(&self, dev: &Arc<dyn Device>)230a03c4f9dSLoGin fn unbind_cleanup(&self, dev: &Arc<dyn Device>) { 231a03c4f9dSLoGin dev.set_driver(None); 232a03c4f9dSLoGin // todo: 添加更多操作,清理数据 23306d5e247SLoGin } 23406d5e247SLoGin } 23506d5e247SLoGin 236e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#866 23706d5e247SLoGin #[derive(Debug)] 23806d5e247SLoGin #[allow(dead_code)] 23906d5e247SLoGin struct DeviceAttachData { 24006d5e247SLoGin dev: Arc<dyn Device>, 24106d5e247SLoGin 24206d5e247SLoGin /// Indicates whether we are considering asynchronous probing or 24306d5e247SLoGin /// not. Only initial binding after device or driver registration 24406d5e247SLoGin /// (including deferral processing) may be done asynchronously, the 24506d5e247SLoGin /// rest is always synchronous, as we expect it is being done by 24606d5e247SLoGin /// request from userspace. 24706d5e247SLoGin check_async: bool, 24806d5e247SLoGin 24906d5e247SLoGin /// Indicates if we are binding synchronous or asynchronous drivers. 25006d5e247SLoGin /// When asynchronous probing is enabled we'll execute 2 passes 25106d5e247SLoGin /// over drivers: first pass doing synchronous probing and second 25206d5e247SLoGin /// doing asynchronous probing (if synchronous did not succeed - 25306d5e247SLoGin /// most likely because there was no driver requiring synchronous 25406d5e247SLoGin /// probing - and we found asynchronous driver during first pass). 25506d5e247SLoGin /// The 2 passes are done because we can't shoot asynchronous 25606d5e247SLoGin /// probe for given device and driver from bus_for_each_drv() since 25706d5e247SLoGin /// driver pointer is not guaranteed to stay valid once 25806d5e247SLoGin /// bus_for_each_drv() iterates to the next driver on the bus. 25906d5e247SLoGin want_async: bool, 26006d5e247SLoGin 26106d5e247SLoGin /// We'll set have_async to 'true' if, while scanning for matching 26206d5e247SLoGin /// driver, we'll encounter one that requests asynchronous probing. 26306d5e247SLoGin have_async: bool, 26406d5e247SLoGin } 26506d5e247SLoGin 26606d5e247SLoGin impl DeviceAttachData { new(dev: Arc<dyn Device>, check_async: bool, want_async: bool) -> Self26706d5e247SLoGin pub fn new(dev: Arc<dyn Device>, check_async: bool, want_async: bool) -> Self { 26806d5e247SLoGin Self { 26906d5e247SLoGin dev, 27006d5e247SLoGin check_async, 27106d5e247SLoGin want_async, 27206d5e247SLoGin have_async: false, 27306d5e247SLoGin } 27406d5e247SLoGin } 27506d5e247SLoGin 27606d5e247SLoGin #[allow(dead_code)] 27706d5e247SLoGin #[inline(always)] set_have_async(&mut self)27806d5e247SLoGin fn set_have_async(&mut self) { 27906d5e247SLoGin self.have_async = true; 28006d5e247SLoGin } 28106d5e247SLoGin } 282a03c4f9dSLoGin 283a03c4f9dSLoGin impl DriverManager { 284a03c4f9dSLoGin /// 尝试把驱动绑定到现有的设备上 285a03c4f9dSLoGin /// 286a03c4f9dSLoGin /// 这个函数会遍历驱动现有的全部设备,然后尝试把他们匹配。 287a03c4f9dSLoGin /// 一旦有一个设备匹配成功,就会返回,并且设备的driver字段会被设置。 driver_attach(&self, driver: &Arc<dyn Driver>) -> Result<(), SystemError>288a03c4f9dSLoGin pub fn driver_attach(&self, driver: &Arc<dyn Driver>) -> Result<(), SystemError> { 289c566df45SLoGin let bus = driver 290c566df45SLoGin .bus() 291b5b571e0SLoGin .and_then(|bus| bus.upgrade()) 292c566df45SLoGin .ok_or(SystemError::EINVAL)?; 293a03c4f9dSLoGin for dev in bus.subsystem().devices().iter() { 294da152319SLoGin self.do_driver_attach(dev, driver); 295a03c4f9dSLoGin } 296a03c4f9dSLoGin 297a03c4f9dSLoGin return Ok(()); 298a03c4f9dSLoGin } 299a03c4f9dSLoGin 300e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#1134 301da152319SLoGin #[inline(never)] do_driver_attach(&self, device: &Arc<dyn Device>, driver: &Arc<dyn Driver>) -> bool302a03c4f9dSLoGin fn do_driver_attach(&self, device: &Arc<dyn Device>, driver: &Arc<dyn Driver>) -> bool { 303a03c4f9dSLoGin let r = self.match_device(driver, device).unwrap_or(false); 304b5b571e0SLoGin if !r { 305a03c4f9dSLoGin // 不匹配 306a03c4f9dSLoGin return false; 307a03c4f9dSLoGin } 308a03c4f9dSLoGin 309a03c4f9dSLoGin if driver.allows_async_probing() { 310a03c4f9dSLoGin unimplemented!( 311a03c4f9dSLoGin "do_driver_attach: probe driver '{}' asynchronously", 312a03c4f9dSLoGin driver.name() 313a03c4f9dSLoGin ); 314a03c4f9dSLoGin } 315a03c4f9dSLoGin 316a03c4f9dSLoGin if self.probe_device(driver, device).is_err() { 317a03c4f9dSLoGin return false; 318a03c4f9dSLoGin } 319a03c4f9dSLoGin 320a03c4f9dSLoGin return true; 321a03c4f9dSLoGin } 322a03c4f9dSLoGin 323a03c4f9dSLoGin #[inline(always)] match_device( &self, driver: &Arc<dyn Driver>, device: &Arc<dyn Device>, ) -> Result<bool, SystemError>324a03c4f9dSLoGin pub fn match_device( 325a03c4f9dSLoGin &self, 326a03c4f9dSLoGin driver: &Arc<dyn Driver>, 327a03c4f9dSLoGin device: &Arc<dyn Device>, 328a03c4f9dSLoGin ) -> Result<bool, SystemError> { 329c566df45SLoGin return driver 330c566df45SLoGin .bus() 331b5b571e0SLoGin .and_then(|bus| bus.upgrade()) 332c566df45SLoGin .unwrap() 333c566df45SLoGin .match_device(device, driver); 334a03c4f9dSLoGin } 335a03c4f9dSLoGin 336a03c4f9dSLoGin /// 尝试把设备和驱动绑定在一起 337a03c4f9dSLoGin /// 338a03c4f9dSLoGin /// 339a03c4f9dSLoGin /// ## 返回 340a03c4f9dSLoGin /// 341a03c4f9dSLoGin /// - Ok(): 绑定成功 342a03c4f9dSLoGin /// - Err(ENODEV): 设备未注册 343a03c4f9dSLoGin /// - Err(EBUSY): 设备已经绑定到驱动上 344a03c4f9dSLoGin /// 345e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#802 probe_device( &self, driver: &Arc<dyn Driver>, device: &Arc<dyn Device>, ) -> Result<(), SystemError>346a03c4f9dSLoGin fn probe_device( 347a03c4f9dSLoGin &self, 348a03c4f9dSLoGin driver: &Arc<dyn Driver>, 349a03c4f9dSLoGin device: &Arc<dyn Device>, 350a03c4f9dSLoGin ) -> Result<(), SystemError> { 351a03c4f9dSLoGin let r = self.do_probe_device(driver, device); 352a03c4f9dSLoGin PROBE_WAIT_QUEUE.wakeup_all(None); 353a03c4f9dSLoGin return r; 354a03c4f9dSLoGin } 355a03c4f9dSLoGin do_probe_device( &self, driver: &Arc<dyn Driver>, device: &Arc<dyn Device>, ) -> Result<(), SystemError>356a03c4f9dSLoGin fn do_probe_device( 357a03c4f9dSLoGin &self, 358a03c4f9dSLoGin driver: &Arc<dyn Driver>, 359a03c4f9dSLoGin device: &Arc<dyn Device>, 360a03c4f9dSLoGin ) -> Result<(), SystemError> { 361a03c4f9dSLoGin if device.is_dead() || (!device.is_registered()) { 362a03c4f9dSLoGin return Err(SystemError::ENODEV); 363a03c4f9dSLoGin } 364a03c4f9dSLoGin if device.driver().is_some() { 365a03c4f9dSLoGin return Err(SystemError::EBUSY); 366a03c4f9dSLoGin } 367a03c4f9dSLoGin 368a03c4f9dSLoGin device.set_can_match(true); 369a03c4f9dSLoGin 370a03c4f9dSLoGin self.really_probe(driver, device)?; 371a03c4f9dSLoGin 372a03c4f9dSLoGin return Ok(()); 373a03c4f9dSLoGin } 374a03c4f9dSLoGin 375e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#584 really_probe( &self, driver: &Arc<dyn Driver>, device: &Arc<dyn Device>, ) -> Result<(), SystemError>376a03c4f9dSLoGin fn really_probe( 377a03c4f9dSLoGin &self, 378a03c4f9dSLoGin driver: &Arc<dyn Driver>, 379a03c4f9dSLoGin device: &Arc<dyn Device>, 380a03c4f9dSLoGin ) -> Result<(), SystemError> { 381a03c4f9dSLoGin let bind_failed = || { 382a03c4f9dSLoGin device_manager().unbind_cleanup(device); 383a03c4f9dSLoGin }; 384a03c4f9dSLoGin 385a03c4f9dSLoGin let sysfs_failed = || { 386b5b571e0SLoGin if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) { 387a03c4f9dSLoGin bus.subsystem().bus_notifier().call_chain( 388a03c4f9dSLoGin BusNotifyEvent::DriverNotBound, 389a03c4f9dSLoGin Some(device), 390a03c4f9dSLoGin None, 391a03c4f9dSLoGin ); 392a03c4f9dSLoGin } 393a03c4f9dSLoGin }; 394a03c4f9dSLoGin 395a03c4f9dSLoGin let probe_failed = || { 396a03c4f9dSLoGin self.remove_from_sysfs(device); 397a03c4f9dSLoGin }; 398a03c4f9dSLoGin 399a03c4f9dSLoGin let dev_groups_failed = || { 400a03c4f9dSLoGin device_manager().remove(device); 401a03c4f9dSLoGin }; 402a03c4f9dSLoGin 403a03c4f9dSLoGin device.set_driver(Some(Arc::downgrade(driver))); 404a03c4f9dSLoGin 405a03c4f9dSLoGin self.add_to_sysfs(device).map_err(|e| { 4062eab6dd7S曾俊 error!( 407a03c4f9dSLoGin "really_probe: add_to_sysfs failed, dev: '{}', err: {:?}", 408a03c4f9dSLoGin device.name(), 409a03c4f9dSLoGin e 410a03c4f9dSLoGin ); 411a03c4f9dSLoGin sysfs_failed(); 412a03c4f9dSLoGin bind_failed(); 413a03c4f9dSLoGin e 414a03c4f9dSLoGin })?; 415a03c4f9dSLoGin 416a03c4f9dSLoGin self.call_driver_probe(device, driver).map_err(|e| { 4172eab6dd7S曾俊 error!( 418a03c4f9dSLoGin "really_probe: call_driver_probe failed, dev: '{}', err: {:?}", 419a03c4f9dSLoGin device.name(), 420a03c4f9dSLoGin e 421a03c4f9dSLoGin ); 422a03c4f9dSLoGin 423a03c4f9dSLoGin probe_failed(); 424a03c4f9dSLoGin sysfs_failed(); 425a03c4f9dSLoGin bind_failed(); 426a03c4f9dSLoGin e 427a03c4f9dSLoGin })?; 428a03c4f9dSLoGin 429a03c4f9dSLoGin device_manager() 430a03c4f9dSLoGin .add_groups(device, driver.dev_groups()) 431a03c4f9dSLoGin .map_err(|e| { 4322eab6dd7S曾俊 error!( 433a03c4f9dSLoGin "really_probe: add_groups failed, dev: '{}', err: {:?}", 434a03c4f9dSLoGin device.name(), 435a03c4f9dSLoGin e 436a03c4f9dSLoGin ); 437a03c4f9dSLoGin dev_groups_failed(); 438a03c4f9dSLoGin probe_failed(); 439a03c4f9dSLoGin sysfs_failed(); 440a03c4f9dSLoGin bind_failed(); 441a03c4f9dSLoGin e 442a03c4f9dSLoGin })?; 443a03c4f9dSLoGin 444a03c4f9dSLoGin // 我们假设所有的设备都有 sync_state 这个属性。如果没有的话,也创建属性文件。 445a03c4f9dSLoGin device_manager() 446a03c4f9dSLoGin .create_file(device, &DeviceAttrStateSynced) 447a03c4f9dSLoGin .map_err(|e| { 4482eab6dd7S曾俊 error!( 449a03c4f9dSLoGin "really_probe: create_file failed, dev: '{}', err: {:?}", 450a03c4f9dSLoGin device.name(), 451a03c4f9dSLoGin e 452a03c4f9dSLoGin ); 453a03c4f9dSLoGin dev_groups_failed(); 454a03c4f9dSLoGin probe_failed(); 455a03c4f9dSLoGin sysfs_failed(); 456a03c4f9dSLoGin bind_failed(); 457a03c4f9dSLoGin e 458a03c4f9dSLoGin })?; 459a03c4f9dSLoGin 460a03c4f9dSLoGin self.driver_bound(device); 461a03c4f9dSLoGin 462a03c4f9dSLoGin return Ok(()); 463a03c4f9dSLoGin } 464a03c4f9dSLoGin 465e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#434 add_to_sysfs(&self, device: &Arc<dyn Device>) -> Result<(), SystemError>466a03c4f9dSLoGin fn add_to_sysfs(&self, device: &Arc<dyn Device>) -> Result<(), SystemError> { 467a03c4f9dSLoGin let driver = device.driver().ok_or(SystemError::EINVAL)?; 468a03c4f9dSLoGin 469b5b571e0SLoGin if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) { 470a03c4f9dSLoGin bus.subsystem().bus_notifier().call_chain( 471a03c4f9dSLoGin BusNotifyEvent::BindDriver, 472b5b571e0SLoGin Some(device), 473a03c4f9dSLoGin None, 474a03c4f9dSLoGin ); 475a03c4f9dSLoGin } 476a03c4f9dSLoGin 477a03c4f9dSLoGin let driver_kobj = driver.clone() as Arc<dyn KObject>; 478a03c4f9dSLoGin let device_kobj = device.clone() as Arc<dyn KObject>; 479a03c4f9dSLoGin 480a03c4f9dSLoGin sysfs_instance().create_link(Some(&driver_kobj), &device_kobj, device.name())?; 481a03c4f9dSLoGin 482a03c4f9dSLoGin let fail_rm_dev_link = || { 483a03c4f9dSLoGin sysfs_instance().remove_link(&driver_kobj, device.name()); 484a03c4f9dSLoGin }; 485a03c4f9dSLoGin 486a03c4f9dSLoGin sysfs_instance() 487a03c4f9dSLoGin .create_link(Some(&device_kobj), &driver_kobj, "driver".to_string()) 488*bd70d2d1SLoGin .inspect_err(|_e| { 489a03c4f9dSLoGin fail_rm_dev_link(); 490a03c4f9dSLoGin })?; 491a03c4f9dSLoGin 492a03c4f9dSLoGin device_manager() 493a03c4f9dSLoGin .create_file(device, &DeviceAttrCoredump) 494*bd70d2d1SLoGin .inspect_err(|_e| { 495a03c4f9dSLoGin sysfs_instance().remove_link(&device_kobj, "driver".to_string()); 496a03c4f9dSLoGin fail_rm_dev_link(); 497a03c4f9dSLoGin })?; 498a03c4f9dSLoGin 499a03c4f9dSLoGin return Ok(()); 500a03c4f9dSLoGin } 501a03c4f9dSLoGin 502e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#469 remove_from_sysfs(&self, _device: &Arc<dyn Device>)503a03c4f9dSLoGin fn remove_from_sysfs(&self, _device: &Arc<dyn Device>) { 504a03c4f9dSLoGin todo!("remove_from_sysfs") 505a03c4f9dSLoGin } 506a03c4f9dSLoGin call_driver_probe( &self, device: &Arc<dyn Device>, driver: &Arc<dyn Driver>, ) -> Result<(), SystemError>507a03c4f9dSLoGin fn call_driver_probe( 508a03c4f9dSLoGin &self, 509a03c4f9dSLoGin device: &Arc<dyn Device>, 510a03c4f9dSLoGin driver: &Arc<dyn Driver>, 511a03c4f9dSLoGin ) -> Result<(), SystemError> { 512c566df45SLoGin let bus = device 513c566df45SLoGin .bus() 514b5b571e0SLoGin .and_then(|bus| bus.upgrade()) 515c566df45SLoGin .ok_or(SystemError::EINVAL)?; 516a03c4f9dSLoGin let r = bus.probe(device); 5171074eb34SSamuel Dai if r == Err(SystemError::ENOSYS) { 5182eab6dd7S曾俊 error!( 519a03c4f9dSLoGin "call_driver_probe: bus.probe() failed, dev: '{}', err: {:?}", 520a03c4f9dSLoGin device.name(), 521a03c4f9dSLoGin r 522a03c4f9dSLoGin ); 523a03c4f9dSLoGin return r; 524a03c4f9dSLoGin } 525a03c4f9dSLoGin 526a03c4f9dSLoGin if r.is_ok() { 527a03c4f9dSLoGin return Ok(()); 528a03c4f9dSLoGin } 529a03c4f9dSLoGin 530a03c4f9dSLoGin let err = r.unwrap_err(); 531a03c4f9dSLoGin match err { 532a03c4f9dSLoGin SystemError::ENODEV | SystemError::ENXIO => { 5332eab6dd7S曾俊 debug!( 534a03c4f9dSLoGin "driver'{}': probe of {} rejects match {:?}", 535a03c4f9dSLoGin driver.name(), 536a03c4f9dSLoGin device.name(), 537a03c4f9dSLoGin err 538a03c4f9dSLoGin ); 539a03c4f9dSLoGin } 540a03c4f9dSLoGin 541a03c4f9dSLoGin _ => { 5422eab6dd7S曾俊 warn!( 543a03c4f9dSLoGin "driver'{}': probe of {} failed with error {:?}", 544a03c4f9dSLoGin driver.name(), 545a03c4f9dSLoGin device.name(), 546a03c4f9dSLoGin err 547a03c4f9dSLoGin ); 548a03c4f9dSLoGin } 549a03c4f9dSLoGin } 550a03c4f9dSLoGin 551a03c4f9dSLoGin return Err(err); 552a03c4f9dSLoGin } 553a03c4f9dSLoGin 554a03c4f9dSLoGin /// 当设备被成功探测,进行了'设备->驱动'绑定后,调用这个函数,完成'驱动->设备'的绑定 555e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#393 driver_bound(&self, device: &Arc<dyn Device>)556a03c4f9dSLoGin fn driver_bound(&self, device: &Arc<dyn Device>) { 557a03c4f9dSLoGin if self.driver_is_bound(device) { 5582eab6dd7S曾俊 warn!("driver_bound: device '{}' is already bound.", device.name()); 559a03c4f9dSLoGin return; 560a03c4f9dSLoGin } 561a03c4f9dSLoGin 562a03c4f9dSLoGin let driver = device.driver().unwrap(); 563a03c4f9dSLoGin driver.add_device(device.clone()); 564a03c4f9dSLoGin 565b5b571e0SLoGin if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) { 566a03c4f9dSLoGin bus.subsystem().bus_notifier().call_chain( 567a03c4f9dSLoGin BusNotifyEvent::BoundDriver, 568a03c4f9dSLoGin Some(device), 569a03c4f9dSLoGin None, 570a03c4f9dSLoGin ); 571a03c4f9dSLoGin } 572a03c4f9dSLoGin 573a03c4f9dSLoGin // todo: 发送kobj bind的uevent 574a03c4f9dSLoGin } 575a03c4f9dSLoGin driver_is_bound(&self, device: &Arc<dyn Device>) -> bool576a03c4f9dSLoGin fn driver_is_bound(&self, device: &Arc<dyn Device>) -> bool { 577a03c4f9dSLoGin if let Some(driver) = device.driver() { 578a03c4f9dSLoGin if driver.find_device_by_name(&device.name()).is_some() { 579a03c4f9dSLoGin return true; 580a03c4f9dSLoGin } 581a03c4f9dSLoGin } 582a03c4f9dSLoGin 583a03c4f9dSLoGin return false; 584a03c4f9dSLoGin } 585a03c4f9dSLoGin } 586a03c4f9dSLoGin 587a03c4f9dSLoGin /// 设备文件夹下的`dev`文件的属性 588a03c4f9dSLoGin #[derive(Debug, Clone, Copy)] 589a03c4f9dSLoGin pub struct DeviceAttrStateSynced; 590a03c4f9dSLoGin 591a03c4f9dSLoGin impl Attribute for DeviceAttrStateSynced { mode(&self) -> ModeType592a03c4f9dSLoGin fn mode(&self) -> ModeType { 593a03c4f9dSLoGin // 0o444 594a03c4f9dSLoGin return ModeType::S_IRUGO; 595a03c4f9dSLoGin } 596a03c4f9dSLoGin name(&self) -> &str597a03c4f9dSLoGin fn name(&self) -> &str { 598a03c4f9dSLoGin "state_synced" 599a03c4f9dSLoGin } 600a03c4f9dSLoGin show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>601a03c4f9dSLoGin fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 602a03c4f9dSLoGin let dev = kobj.cast::<dyn Device>().map_err(|kobj| { 6032eab6dd7S曾俊 error!( 604a03c4f9dSLoGin "Intertrait casting not implemented for kobj: {}", 605a03c4f9dSLoGin kobj.name() 606a03c4f9dSLoGin ); 6071074eb34SSamuel Dai SystemError::ENOSYS 608a03c4f9dSLoGin })?; 609a03c4f9dSLoGin 610a03c4f9dSLoGin let val = dev.state_synced(); 611a03c4f9dSLoGin let val = if val { 1 } else { 0 }; 612a03c4f9dSLoGin return sysfs_emit_str(buf, format!("{}\n", val).as_str()); 613a03c4f9dSLoGin } 614a03c4f9dSLoGin support(&self) -> SysFSOpsSupport615a03c4f9dSLoGin fn support(&self) -> SysFSOpsSupport { 616196b75dcSLoGin SysFSOpsSupport::ATTR_SHOW 617a03c4f9dSLoGin } 618a03c4f9dSLoGin } 619a03c4f9dSLoGin 620a03c4f9dSLoGin #[derive(Debug)] 621e32effb1SLoGin pub(super) struct DeviceAttrCoredump; 622a03c4f9dSLoGin 623a03c4f9dSLoGin impl Attribute for DeviceAttrCoredump { name(&self) -> &str624a03c4f9dSLoGin fn name(&self) -> &str { 625a03c4f9dSLoGin "coredump" 626a03c4f9dSLoGin } 627a03c4f9dSLoGin mode(&self) -> ModeType628a03c4f9dSLoGin fn mode(&self) -> ModeType { 629196b75dcSLoGin SYSFS_ATTR_MODE_WO 630a03c4f9dSLoGin } 631a03c4f9dSLoGin support(&self) -> SysFSOpsSupport632a03c4f9dSLoGin fn support(&self) -> SysFSOpsSupport { 633196b75dcSLoGin SysFSOpsSupport::ATTR_STORE 634a03c4f9dSLoGin } 635a03c4f9dSLoGin store(&self, kobj: Arc<dyn KObject>, buf: &[u8]) -> Result<usize, SystemError>636a03c4f9dSLoGin fn store(&self, kobj: Arc<dyn KObject>, buf: &[u8]) -> Result<usize, SystemError> { 637a03c4f9dSLoGin let dev = kobj.cast::<dyn Device>().map_err(|kobj| { 6382eab6dd7S曾俊 error!( 639a03c4f9dSLoGin "Intertrait casting not implemented for kobj: {}", 640a03c4f9dSLoGin kobj.name() 641a03c4f9dSLoGin ); 6421074eb34SSamuel Dai SystemError::ENOSYS 643a03c4f9dSLoGin })?; 644a03c4f9dSLoGin 645a03c4f9dSLoGin let drv = dev.driver().ok_or(SystemError::EINVAL)?; 646a03c4f9dSLoGin drv.coredump(&dev)?; 647a03c4f9dSLoGin 648a03c4f9dSLoGin return Ok(buf.len()); 649a03c4f9dSLoGin } 650a03c4f9dSLoGin } 651