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