xref: /DragonOS/kernel/src/driver/base/device/dd.rs (revision bd70d2d1f490aabd570a5301b858bd5eb04149fa)
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