xref: /DragonOS/kernel/src/driver/base/device/dd.rs (revision e32effb1507773d32c216d9e77b963786e275c06)
1 use core::intrinsics::unlikely;
2 
3 use alloc::{string::ToString, sync::Arc};
4 use intertrait::cast::CastArc;
5 
6 use crate::{
7     driver::base::kobject::KObject,
8     filesystem::{
9         sysfs::{
10             file::sysfs_emit_str, sysfs_instance, Attribute, SysFSOpsSupport, SYSFS_ATTR_MODE_WO,
11         },
12         vfs::syscall::ModeType,
13     },
14     libs::wait_queue::WaitQueue,
15 };
16 use system_error::SystemError;
17 
18 use super::{
19     bus::BusNotifyEvent,
20     device_manager,
21     driver::{driver_manager, Driver, DriverManager},
22     Device, DeviceManager,
23 };
24 
25 static PROBE_WAIT_QUEUE: WaitQueue = WaitQueue::default();
26 
27 impl DeviceManager {
28     /// 尝试把一个设备与一个驱动匹配
29     ///
30     /// 当前函数会遍历整个bus的驱动列表,并且尝试把设备与每一个驱动进行匹配。
31     /// 一旦有一个驱动匹配成功,就会返回。
32     ///
33     /// ## 参数
34     ///
35     /// - `dev`: 设备
36     ///
37     /// ## 返回
38     ///
39     /// - Ok(true): 匹配成功
40     /// - Ok(false): 没有匹配成功
41     /// - Err(SystemError::ENODEV): 设备还没被注册
42     ///
43     /// ## 参考
44     ///
45     /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#1049
46     pub fn device_attach(&self, dev: &Arc<dyn Device>) -> Result<bool, SystemError> {
47         return self.do_device_attach(dev, false);
48     }
49 
50     pub fn device_initial_probe(&self, dev: &Arc<dyn Device>) -> Result<bool, SystemError> {
51         return self.do_device_attach(dev, true);
52     }
53 
54     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#978
55     fn do_device_attach(
56         &self,
57         dev: &Arc<dyn Device>,
58         allow_async: bool,
59     ) -> Result<bool, SystemError> {
60         if unlikely(allow_async) {
61             // todo!("do_device_attach: allow_async")
62             kwarn!("do_device_attach: allow_async is true, but currently not supported");
63         }
64         if dev.is_dead() {
65             return Ok(false);
66         }
67 
68         kwarn!("do_device_attach: dev: '{}'", dev.name());
69 
70         let mut do_async = false;
71         let mut r = Ok(false);
72 
73         if dev.driver().is_some() {
74             if self.device_is_bound(dev) {
75                 return Ok(true);
76             }
77 
78             if self.device_bind_driver(dev).is_ok() {
79                 return Ok(true);
80             } else {
81                 dev.set_driver(None);
82                 return Ok(false);
83             }
84         } else {
85             let bus = dev
86                 .bus()
87                 .and_then(|bus| bus.upgrade())
88                 .ok_or(SystemError::EINVAL)?;
89             let mut data = DeviceAttachData::new(dev.clone(), allow_async, false);
90             let mut flag = false;
91             for driver in bus.subsystem().drivers().iter() {
92                 let r = self.do_device_attach_driver(driver, &mut data);
93                 if unlikely(r.is_err()) {
94                     flag = false;
95                     break;
96                 } else if r.unwrap() {
97                     flag = true;
98                     break;
99                 }
100             }
101 
102             if flag {
103                 r = Ok(true);
104             }
105 
106             if !flag && allow_async && data.have_async {
107                 // If we could not find appropriate driver
108                 // synchronously and we are allowed to do
109                 // async probes and there are drivers that
110                 // want to probe asynchronously, we'll
111                 // try them.
112 
113                 do_async = true;
114                 kdebug!(
115                     "do_device_attach: try scheduling asynchronous probe for device: {}",
116                     dev.name()
117                 );
118             }
119         }
120 
121         if do_async {
122             todo!("do_device_attach: do_async")
123         }
124         return r;
125     }
126 
127     /// 匹配设备和驱动
128     ///
129     /// ## 参数
130     ///
131     /// - `driver`: 驱动
132     /// - `data`: 匹配数据
133     ///
134     /// ## 返回
135     ///
136     /// - Ok(true): 匹配成功
137     /// - Ok(false): 没有匹配成功
138     /// - Err(SystemError): 匹配过程中出现意外错误,没有匹配成功
139     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#899
140     fn do_device_attach_driver(
141         &self,
142         driver: &Arc<dyn Driver>,
143         data: &mut DeviceAttachData,
144     ) -> Result<bool, SystemError> {
145         if let Some(bus) = driver.bus().and_then(|bus| bus.upgrade()) {
146             let r = bus.match_device(&data.dev, driver);
147 
148             if let Err(e) = r {
149                 // 如果不是ENOSYS,则总线出错
150                 if e != SystemError::ENOSYS {
151                     kdebug!(
152                         "do_device_attach_driver: bus.match_device() failed, dev: '{}', err: {:?}",
153                         data.dev.name(),
154                         e
155                     );
156                     return Err(e);
157                 }
158             } else if !r.unwrap() {
159                 return Ok(false);
160             }
161         }
162 
163         let async_allowed = driver.allows_async_probing();
164         if data.check_async && async_allowed != data.want_async {
165             return Ok(false);
166         }
167 
168         return driver_manager()
169             .probe_device(driver, &data.dev)
170             .map(|_| true);
171     }
172 
173     /// 检查设备是否绑定到驱动程序
174     ///
175     /// ## 参数
176     ///
177     /// - `dev`: 设备
178     ///
179     /// ## 返回
180     ///
181     /// 如果传递的设备已成功完成对驱动程序的探测,则返回true,否则返回false。
182     pub fn device_is_bound(&self, dev: &Arc<dyn Device>) -> bool {
183         return driver_manager().driver_is_bound(dev);
184     }
185 
186     /// 把一个驱动绑定到设备上
187     ///
188     /// 允许手动绑定驱动到设备上。调用者需要设置好dev.driver(),保证其不为None
189     ///
190     /// ## 参数
191     ///
192     /// - `dev`: 设备
193     ///
194     /// ## 建议
195     ///
196     /// 使用device_manager().driver_attach()会更好
197     ///
198     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#496
199     pub fn device_bind_driver(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> {
200         let r = driver_manager().driver_sysfs_add(dev);
201         if let Err(e) = r {
202             kerror!(
203                 "device_bind_driver: driver_sysfs_add failed, dev: '{}', err: {:?}",
204                 dev.name(),
205                 e
206             );
207             self.device_links_force_bind(dev);
208             driver_manager().driver_bound(dev);
209             return Err(e);
210         } else if let Some(bus) = dev.bus().and_then(|bus| bus.upgrade()) {
211             bus.subsystem().bus_notifier().call_chain(
212                 BusNotifyEvent::DriverNotBound,
213                 Some(dev),
214                 None,
215             );
216         }
217         return r;
218     }
219 
220     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#528
221     fn unbind_cleanup(&self, dev: &Arc<dyn Device>) {
222         dev.set_driver(None);
223         // todo: 添加更多操作,清理数据
224     }
225 }
226 
227 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#866
228 #[derive(Debug)]
229 #[allow(dead_code)]
230 struct DeviceAttachData {
231     dev: Arc<dyn Device>,
232 
233     ///  Indicates whether we are considering asynchronous probing or
234     ///  not. Only initial binding after device or driver registration
235     ///  (including deferral processing) may be done asynchronously, the
236     ///  rest is always synchronous, as we expect it is being done by
237     ///  request from userspace.
238     check_async: bool,
239 
240     /// Indicates if we are binding synchronous or asynchronous drivers.
241     /// When asynchronous probing is enabled we'll execute 2 passes
242     /// over drivers: first pass doing synchronous probing and second
243     /// doing asynchronous probing (if synchronous did not succeed -
244     /// most likely because there was no driver requiring synchronous
245     /// probing - and we found asynchronous driver during first pass).
246     /// The 2 passes are done because we can't shoot asynchronous
247     /// probe for given device and driver from bus_for_each_drv() since
248     /// driver pointer is not guaranteed to stay valid once
249     /// bus_for_each_drv() iterates to the next driver on the bus.
250     want_async: bool,
251 
252     /// We'll set have_async to 'true' if, while scanning for matching
253     /// driver, we'll encounter one that requests asynchronous probing.
254     have_async: bool,
255 }
256 
257 impl DeviceAttachData {
258     pub fn new(dev: Arc<dyn Device>, check_async: bool, want_async: bool) -> Self {
259         Self {
260             dev,
261             check_async,
262             want_async,
263             have_async: false,
264         }
265     }
266 
267     #[allow(dead_code)]
268     #[inline(always)]
269     fn set_have_async(&mut self) {
270         self.have_async = true;
271     }
272 }
273 
274 impl DriverManager {
275     /// 尝试把驱动绑定到现有的设备上
276     ///
277     /// 这个函数会遍历驱动现有的全部设备,然后尝试把他们匹配。
278     /// 一旦有一个设备匹配成功,就会返回,并且设备的driver字段会被设置。
279     pub fn driver_attach(&self, driver: &Arc<dyn Driver>) -> Result<(), SystemError> {
280         let bus = driver
281             .bus()
282             .and_then(|bus| bus.upgrade())
283             .ok_or(SystemError::EINVAL)?;
284         for dev in bus.subsystem().devices().iter() {
285             self.do_driver_attach(dev, driver);
286         }
287 
288         return Ok(());
289     }
290 
291     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#1134
292     #[inline(never)]
293     fn do_driver_attach(&self, device: &Arc<dyn Device>, driver: &Arc<dyn Driver>) -> bool {
294         let r = self.match_device(driver, device).unwrap_or(false);
295         if !r {
296             // 不匹配
297             return false;
298         }
299 
300         if driver.allows_async_probing() {
301             unimplemented!(
302                 "do_driver_attach: probe driver '{}' asynchronously",
303                 driver.name()
304             );
305         }
306 
307         if self.probe_device(driver, device).is_err() {
308             return false;
309         }
310 
311         return true;
312     }
313 
314     #[inline(always)]
315     pub fn match_device(
316         &self,
317         driver: &Arc<dyn Driver>,
318         device: &Arc<dyn Device>,
319     ) -> Result<bool, SystemError> {
320         return driver
321             .bus()
322             .and_then(|bus| bus.upgrade())
323             .unwrap()
324             .match_device(device, driver);
325     }
326 
327     /// 尝试把设备和驱动绑定在一起
328     ///
329     ///
330     /// ## 返回
331     ///
332     /// - Ok(): 绑定成功
333     /// - Err(ENODEV): 设备未注册
334     /// - Err(EBUSY): 设备已经绑定到驱动上
335     ///
336     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#802
337     fn probe_device(
338         &self,
339         driver: &Arc<dyn Driver>,
340         device: &Arc<dyn Device>,
341     ) -> Result<(), SystemError> {
342         let r = self.do_probe_device(driver, device);
343         PROBE_WAIT_QUEUE.wakeup_all(None);
344         return r;
345     }
346 
347     fn do_probe_device(
348         &self,
349         driver: &Arc<dyn Driver>,
350         device: &Arc<dyn Device>,
351     ) -> Result<(), SystemError> {
352         if device.is_dead() || (!device.is_registered()) {
353             return Err(SystemError::ENODEV);
354         }
355         if device.driver().is_some() {
356             return Err(SystemError::EBUSY);
357         }
358 
359         device.set_can_match(true);
360 
361         self.really_probe(driver, device)?;
362 
363         return Ok(());
364     }
365 
366     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#584
367     fn really_probe(
368         &self,
369         driver: &Arc<dyn Driver>,
370         device: &Arc<dyn Device>,
371     ) -> Result<(), SystemError> {
372         let bind_failed = || {
373             device_manager().unbind_cleanup(device);
374         };
375 
376         let sysfs_failed = || {
377             if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) {
378                 bus.subsystem().bus_notifier().call_chain(
379                     BusNotifyEvent::DriverNotBound,
380                     Some(device),
381                     None,
382                 );
383             }
384         };
385 
386         let probe_failed = || {
387             self.remove_from_sysfs(device);
388         };
389 
390         let dev_groups_failed = || {
391             device_manager().remove(device);
392         };
393 
394         device.set_driver(Some(Arc::downgrade(driver)));
395 
396         self.add_to_sysfs(device).map_err(|e| {
397             kerror!(
398                 "really_probe: add_to_sysfs failed, dev: '{}', err: {:?}",
399                 device.name(),
400                 e
401             );
402             sysfs_failed();
403             bind_failed();
404             e
405         })?;
406 
407         self.call_driver_probe(device, driver).map_err(|e| {
408             kerror!(
409                 "really_probe: call_driver_probe failed, dev: '{}', err: {:?}",
410                 device.name(),
411                 e
412             );
413 
414             probe_failed();
415             sysfs_failed();
416             bind_failed();
417             e
418         })?;
419 
420         device_manager()
421             .add_groups(device, driver.dev_groups())
422             .map_err(|e| {
423                 kerror!(
424                     "really_probe: add_groups failed, dev: '{}', err: {:?}",
425                     device.name(),
426                     e
427                 );
428                 dev_groups_failed();
429                 probe_failed();
430                 sysfs_failed();
431                 bind_failed();
432                 e
433             })?;
434 
435         // 我们假设所有的设备都有 sync_state 这个属性。如果没有的话,也创建属性文件。
436         device_manager()
437             .create_file(device, &DeviceAttrStateSynced)
438             .map_err(|e| {
439                 kerror!(
440                     "really_probe: create_file failed, dev: '{}', err: {:?}",
441                     device.name(),
442                     e
443                 );
444                 dev_groups_failed();
445                 probe_failed();
446                 sysfs_failed();
447                 bind_failed();
448                 e
449             })?;
450 
451         self.driver_bound(device);
452 
453         return Ok(());
454     }
455 
456     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#434
457     fn add_to_sysfs(&self, device: &Arc<dyn Device>) -> Result<(), SystemError> {
458         let driver = device.driver().ok_or(SystemError::EINVAL)?;
459 
460         if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) {
461             bus.subsystem().bus_notifier().call_chain(
462                 BusNotifyEvent::BindDriver,
463                 Some(device),
464                 None,
465             );
466         }
467 
468         let driver_kobj = driver.clone() as Arc<dyn KObject>;
469         let device_kobj = device.clone() as Arc<dyn KObject>;
470 
471         sysfs_instance().create_link(Some(&driver_kobj), &device_kobj, device.name())?;
472 
473         let fail_rm_dev_link = || {
474             sysfs_instance().remove_link(&driver_kobj, device.name());
475         };
476 
477         sysfs_instance()
478             .create_link(Some(&device_kobj), &driver_kobj, "driver".to_string())
479             .map_err(|e| {
480                 fail_rm_dev_link();
481                 e
482             })?;
483 
484         device_manager()
485             .create_file(device, &DeviceAttrCoredump)
486             .map_err(|e| {
487                 sysfs_instance().remove_link(&device_kobj, "driver".to_string());
488                 fail_rm_dev_link();
489                 e
490             })?;
491 
492         return Ok(());
493     }
494 
495     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#469
496     fn remove_from_sysfs(&self, _device: &Arc<dyn Device>) {
497         todo!("remove_from_sysfs")
498     }
499 
500     fn call_driver_probe(
501         &self,
502         device: &Arc<dyn Device>,
503         driver: &Arc<dyn Driver>,
504     ) -> Result<(), SystemError> {
505         let bus = device
506             .bus()
507             .and_then(|bus| bus.upgrade())
508             .ok_or(SystemError::EINVAL)?;
509         let r = bus.probe(device);
510         if r == Err(SystemError::ENOSYS) {
511             kerror!(
512                 "call_driver_probe: bus.probe() failed, dev: '{}', err: {:?}",
513                 device.name(),
514                 r
515             );
516             return r;
517         }
518 
519         if r.is_ok() {
520             return Ok(());
521         }
522 
523         let err = r.unwrap_err();
524         match err {
525             SystemError::ENODEV | SystemError::ENXIO => {
526                 kdebug!(
527                     "driver'{}': probe of {} rejects match {:?}",
528                     driver.name(),
529                     device.name(),
530                     err
531                 );
532             }
533 
534             _ => {
535                 kwarn!(
536                     "driver'{}': probe of {} failed with error {:?}",
537                     driver.name(),
538                     device.name(),
539                     err
540                 );
541             }
542         }
543 
544         return Err(err);
545     }
546 
547     /// 当设备被成功探测,进行了'设备->驱动'绑定后,调用这个函数,完成'驱动->设备'的绑定
548     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#393
549     fn driver_bound(&self, device: &Arc<dyn Device>) {
550         if self.driver_is_bound(device) {
551             kwarn!("driver_bound: device '{}' is already bound.", device.name());
552             return;
553         }
554 
555         let driver = device.driver().unwrap();
556         driver.add_device(device.clone());
557 
558         if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) {
559             bus.subsystem().bus_notifier().call_chain(
560                 BusNotifyEvent::BoundDriver,
561                 Some(device),
562                 None,
563             );
564         }
565 
566         // todo: 发送kobj bind的uevent
567     }
568 
569     fn driver_is_bound(&self, device: &Arc<dyn Device>) -> bool {
570         if let Some(driver) = device.driver() {
571             if driver.find_device_by_name(&device.name()).is_some() {
572                 return true;
573             }
574         }
575 
576         return false;
577     }
578 }
579 
580 /// 设备文件夹下的`dev`文件的属性
581 #[derive(Debug, Clone, Copy)]
582 pub struct DeviceAttrStateSynced;
583 
584 impl Attribute for DeviceAttrStateSynced {
585     fn mode(&self) -> ModeType {
586         // 0o444
587         return ModeType::S_IRUGO;
588     }
589 
590     fn name(&self) -> &str {
591         "state_synced"
592     }
593 
594     fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
595         let dev = kobj.cast::<dyn Device>().map_err(|kobj| {
596             kerror!(
597                 "Intertrait casting not implemented for kobj: {}",
598                 kobj.name()
599             );
600             SystemError::ENOSYS
601         })?;
602 
603         let val = dev.state_synced();
604         let val = if val { 1 } else { 0 };
605         return sysfs_emit_str(buf, format!("{}\n", val).as_str());
606     }
607 
608     fn support(&self) -> SysFSOpsSupport {
609         SysFSOpsSupport::ATTR_SHOW
610     }
611 }
612 
613 #[derive(Debug)]
614 pub(super) struct DeviceAttrCoredump;
615 
616 impl Attribute for DeviceAttrCoredump {
617     fn name(&self) -> &str {
618         "coredump"
619     }
620 
621     fn mode(&self) -> ModeType {
622         SYSFS_ATTR_MODE_WO
623     }
624 
625     fn support(&self) -> SysFSOpsSupport {
626         SysFSOpsSupport::ATTR_STORE
627     }
628 
629     fn store(&self, kobj: Arc<dyn KObject>, buf: &[u8]) -> Result<usize, SystemError> {
630         let dev = kobj.cast::<dyn Device>().map_err(|kobj| {
631             kerror!(
632                 "Intertrait casting not implemented for kobj: {}",
633                 kobj.name()
634             );
635             SystemError::ENOSYS
636         })?;
637 
638         let drv = dev.driver().ok_or(SystemError::EINVAL)?;
639         drv.coredump(&dev)?;
640 
641         return Ok(buf.len());
642     }
643 }
644