1*06d5e247SLoGin use core::intrinsics::unlikely; 2*06d5e247SLoGin 3*06d5e247SLoGin use alloc::sync::Arc; 4*06d5e247SLoGin 5*06d5e247SLoGin use crate::{driver::Driver, syscall::SystemError}; 6*06d5e247SLoGin 7*06d5e247SLoGin use super::{bus::BusNotifyEvent, driver::driver_manager, Device, DeviceManager}; 8*06d5e247SLoGin 9*06d5e247SLoGin impl DeviceManager { 10*06d5e247SLoGin /// 尝试把一个设备与一个驱动匹配 11*06d5e247SLoGin /// 12*06d5e247SLoGin /// 当前函数会遍历整个bus的驱动列表,并且尝试把设备与每一个驱动进行匹配。 13*06d5e247SLoGin /// 一旦有一个驱动匹配成功,就会返回。 14*06d5e247SLoGin /// 15*06d5e247SLoGin /// ## 参数 16*06d5e247SLoGin /// 17*06d5e247SLoGin /// - `dev`: 设备 18*06d5e247SLoGin /// 19*06d5e247SLoGin /// ## 返回 20*06d5e247SLoGin /// 21*06d5e247SLoGin /// - Ok(true): 匹配成功 22*06d5e247SLoGin /// - Ok(false): 没有匹配成功 23*06d5e247SLoGin /// - Err(SystemError::ENODEV): 设备还没被注册 24*06d5e247SLoGin /// 25*06d5e247SLoGin /// ## 参考 26*06d5e247SLoGin /// 27*06d5e247SLoGin /// https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#1049 28*06d5e247SLoGin pub fn device_attach(&self, dev: &Arc<dyn Device>) -> Result<bool, SystemError> { 29*06d5e247SLoGin return self.do_device_attach(dev, false); 30*06d5e247SLoGin } 31*06d5e247SLoGin 32*06d5e247SLoGin pub fn device_initial_probe(&self, dev: &Arc<dyn Device>) -> Result<bool, SystemError> { 33*06d5e247SLoGin return self.do_device_attach(dev, true); 34*06d5e247SLoGin } 35*06d5e247SLoGin 36*06d5e247SLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#978 37*06d5e247SLoGin fn do_device_attach( 38*06d5e247SLoGin &self, 39*06d5e247SLoGin dev: &Arc<dyn Device>, 40*06d5e247SLoGin allow_async: bool, 41*06d5e247SLoGin ) -> Result<bool, SystemError> { 42*06d5e247SLoGin if unlikely(allow_async) { 43*06d5e247SLoGin todo!("do_device_attach: allow_async") 44*06d5e247SLoGin } 45*06d5e247SLoGin if dev.is_dead() { 46*06d5e247SLoGin return Ok(false); 47*06d5e247SLoGin } 48*06d5e247SLoGin 49*06d5e247SLoGin let mut do_async = false; 50*06d5e247SLoGin let mut r = Ok(false); 51*06d5e247SLoGin 52*06d5e247SLoGin if dev.driver().is_some() { 53*06d5e247SLoGin if self.device_is_bound(dev) { 54*06d5e247SLoGin return Ok(true); 55*06d5e247SLoGin } 56*06d5e247SLoGin 57*06d5e247SLoGin if self.device_bind_driver(dev).is_ok() { 58*06d5e247SLoGin return Ok(true); 59*06d5e247SLoGin } else { 60*06d5e247SLoGin dev.set_driver(None); 61*06d5e247SLoGin return Ok(false); 62*06d5e247SLoGin } 63*06d5e247SLoGin } else { 64*06d5e247SLoGin let bus = dev.bus().ok_or(SystemError::EINVAL)?; 65*06d5e247SLoGin let mut data = DeviceAttachData::new(dev.clone(), allow_async, false); 66*06d5e247SLoGin let mut flag = true; 67*06d5e247SLoGin for driver in bus.subsystem().drivers().read().iter() { 68*06d5e247SLoGin if let Some(driver) = driver.upgrade() { 69*06d5e247SLoGin let r = self.do_device_attach_driver(&driver, &mut data); 70*06d5e247SLoGin if unlikely(r.is_err()) { 71*06d5e247SLoGin flag = false; 72*06d5e247SLoGin break; 73*06d5e247SLoGin } 74*06d5e247SLoGin } 75*06d5e247SLoGin } 76*06d5e247SLoGin 77*06d5e247SLoGin if flag { 78*06d5e247SLoGin r = Ok(true); 79*06d5e247SLoGin } 80*06d5e247SLoGin 81*06d5e247SLoGin if !flag && allow_async && data.have_async { 82*06d5e247SLoGin // If we could not find appropriate driver 83*06d5e247SLoGin // synchronously and we are allowed to do 84*06d5e247SLoGin // async probes and there are drivers that 85*06d5e247SLoGin // want to probe asynchronously, we'll 86*06d5e247SLoGin // try them. 87*06d5e247SLoGin 88*06d5e247SLoGin do_async = true; 89*06d5e247SLoGin kdebug!( 90*06d5e247SLoGin "do_device_attach: try scheduling asynchronous probe for device: {}", 91*06d5e247SLoGin dev.name() 92*06d5e247SLoGin ); 93*06d5e247SLoGin } 94*06d5e247SLoGin } 95*06d5e247SLoGin 96*06d5e247SLoGin if do_async { 97*06d5e247SLoGin todo!("do_device_attach: do_async") 98*06d5e247SLoGin } 99*06d5e247SLoGin return r; 100*06d5e247SLoGin } 101*06d5e247SLoGin 102*06d5e247SLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#899 103*06d5e247SLoGin fn do_device_attach_driver( 104*06d5e247SLoGin &self, 105*06d5e247SLoGin _driver: &Arc<dyn Driver>, 106*06d5e247SLoGin _data: &mut DeviceAttachData, 107*06d5e247SLoGin ) -> Result<(), SystemError> { 108*06d5e247SLoGin todo!("do_device_attach_driver") 109*06d5e247SLoGin } 110*06d5e247SLoGin 111*06d5e247SLoGin /// 检查设备是否绑定到驱动程序 112*06d5e247SLoGin /// 113*06d5e247SLoGin /// ## 参数 114*06d5e247SLoGin /// 115*06d5e247SLoGin /// - `dev`: 设备 116*06d5e247SLoGin /// 117*06d5e247SLoGin /// ## 返回 118*06d5e247SLoGin /// 119*06d5e247SLoGin /// 如果传递的设备已成功完成对驱动程序的探测,则返回true,否则返回false。 120*06d5e247SLoGin pub fn device_is_bound(&self, dev: &Arc<dyn Device>) -> bool { 121*06d5e247SLoGin if dev.driver().is_some() { 122*06d5e247SLoGin return true; 123*06d5e247SLoGin } else { 124*06d5e247SLoGin return false; 125*06d5e247SLoGin } 126*06d5e247SLoGin } 127*06d5e247SLoGin 128*06d5e247SLoGin /// 把一个驱动绑定到设备上 129*06d5e247SLoGin /// 130*06d5e247SLoGin /// 允许手动绑定驱动到设备上。调用者需要设置好dev.driver(),保证其不为None 131*06d5e247SLoGin /// 132*06d5e247SLoGin /// ## 参数 133*06d5e247SLoGin /// 134*06d5e247SLoGin /// - `dev`: 设备 135*06d5e247SLoGin /// 136*06d5e247SLoGin /// ## 建议 137*06d5e247SLoGin /// 138*06d5e247SLoGin /// 使用device_manager().driver_attach()会更好 139*06d5e247SLoGin /// 140*06d5e247SLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#496 141*06d5e247SLoGin pub fn device_bind_driver(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> { 142*06d5e247SLoGin let r = driver_manager().driver_sysfs_add(dev); 143*06d5e247SLoGin if let Err(e) = r { 144*06d5e247SLoGin self.device_links_force_bind(dev); 145*06d5e247SLoGin self.driver_bound(dev); 146*06d5e247SLoGin return Err(e); 147*06d5e247SLoGin } else { 148*06d5e247SLoGin if let Some(bus) = dev.bus() { 149*06d5e247SLoGin bus.subsystem().bus_notifier().call_chain( 150*06d5e247SLoGin BusNotifyEvent::DriverNotBound, 151*06d5e247SLoGin Some(dev), 152*06d5e247SLoGin None, 153*06d5e247SLoGin ); 154*06d5e247SLoGin } 155*06d5e247SLoGin } 156*06d5e247SLoGin return r; 157*06d5e247SLoGin } 158*06d5e247SLoGin 159*06d5e247SLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#393 160*06d5e247SLoGin fn driver_bound(&self, _dev: &Arc<dyn Device>) { 161*06d5e247SLoGin todo!("driver_bound") 162*06d5e247SLoGin } 163*06d5e247SLoGin } 164*06d5e247SLoGin 165*06d5e247SLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#866 166*06d5e247SLoGin #[derive(Debug)] 167*06d5e247SLoGin #[allow(dead_code)] 168*06d5e247SLoGin struct DeviceAttachData { 169*06d5e247SLoGin dev: Arc<dyn Device>, 170*06d5e247SLoGin 171*06d5e247SLoGin /// Indicates whether we are considering asynchronous probing or 172*06d5e247SLoGin /// not. Only initial binding after device or driver registration 173*06d5e247SLoGin /// (including deferral processing) may be done asynchronously, the 174*06d5e247SLoGin /// rest is always synchronous, as we expect it is being done by 175*06d5e247SLoGin /// request from userspace. 176*06d5e247SLoGin check_async: bool, 177*06d5e247SLoGin 178*06d5e247SLoGin /// Indicates if we are binding synchronous or asynchronous drivers. 179*06d5e247SLoGin /// When asynchronous probing is enabled we'll execute 2 passes 180*06d5e247SLoGin /// over drivers: first pass doing synchronous probing and second 181*06d5e247SLoGin /// doing asynchronous probing (if synchronous did not succeed - 182*06d5e247SLoGin /// most likely because there was no driver requiring synchronous 183*06d5e247SLoGin /// probing - and we found asynchronous driver during first pass). 184*06d5e247SLoGin /// The 2 passes are done because we can't shoot asynchronous 185*06d5e247SLoGin /// probe for given device and driver from bus_for_each_drv() since 186*06d5e247SLoGin /// driver pointer is not guaranteed to stay valid once 187*06d5e247SLoGin /// bus_for_each_drv() iterates to the next driver on the bus. 188*06d5e247SLoGin want_async: bool, 189*06d5e247SLoGin 190*06d5e247SLoGin /// We'll set have_async to 'true' if, while scanning for matching 191*06d5e247SLoGin /// driver, we'll encounter one that requests asynchronous probing. 192*06d5e247SLoGin have_async: bool, 193*06d5e247SLoGin } 194*06d5e247SLoGin 195*06d5e247SLoGin impl DeviceAttachData { 196*06d5e247SLoGin pub fn new(dev: Arc<dyn Device>, check_async: bool, want_async: bool) -> Self { 197*06d5e247SLoGin Self { 198*06d5e247SLoGin dev, 199*06d5e247SLoGin check_async, 200*06d5e247SLoGin want_async, 201*06d5e247SLoGin have_async: false, 202*06d5e247SLoGin } 203*06d5e247SLoGin } 204*06d5e247SLoGin 205*06d5e247SLoGin #[allow(dead_code)] 206*06d5e247SLoGin #[inline(always)] 207*06d5e247SLoGin fn set_have_async(&mut self) { 208*06d5e247SLoGin self.have_async = true; 209*06d5e247SLoGin } 210*06d5e247SLoGin } 211