xref: /DragonOS/kernel/src/driver/base/device/mod.rs (revision 1603395155fc166de0ac5f80369526e196526ed2)
1 use alloc::{
2     string::{String, ToString},
3     sync::{Arc, Weak},
4 };
5 use intertrait::cast::CastArc;
6 
7 use crate::{
8     driver::{
9         acpi::glue::acpi_device_notify,
10         base::map::{LockedDevsMap, LockedKObjMap},
11     },
12     filesystem::{
13         sysfs::{
14             file::sysfs_emit_str, sysfs_instance, Attribute, AttributeGroup, SysFSOps,
15             SysFSOpsSupport,
16         },
17         vfs::syscall::ModeType,
18     },
19     syscall::SystemError,
20 };
21 use core::fmt::Debug;
22 use core::intrinsics::unlikely;
23 
24 use self::{
25     bus::{bus_add_device, bus_probe_device, Bus},
26     driver::Driver,
27 };
28 
29 use super::{
30     kobject::{KObjType, KObject, KObjectManager, KObjectState},
31     kset::KSet,
32     swnode::software_node_notify,
33 };
34 
35 pub mod bus;
36 pub mod dd;
37 pub mod driver;
38 pub mod init;
39 
40 static mut DEVICE_MANAGER: Option<DeviceManager> = None;
41 
42 #[inline(always)]
43 pub fn device_manager() -> &'static DeviceManager {
44     unsafe { DEVICE_MANAGER.as_ref().unwrap() }
45 }
46 
47 lazy_static! {
48     // 全局字符设备号管理实例
49     pub static ref CHARDEVS: Arc<LockedDevsMap> = Arc::new(LockedDevsMap::default());
50 
51     // 全局块设备管理实例
52     pub static ref BLOCKDEVS: Arc<LockedDevsMap> = Arc::new(LockedDevsMap::default());
53 
54     // 全局设备管理实例
55     pub static ref DEVMAP: Arc<LockedKObjMap> = Arc::new(LockedKObjMap::default());
56 
57 }
58 
59 /// `/sys/devices` 的 kset 实例
60 static mut DEVICES_KSET_INSTANCE: Option<Arc<KSet>> = None;
61 /// `/sys/dev` 的 kset 实例
62 static mut DEV_KSET_INSTANCE: Option<Arc<KSet>> = None;
63 /// `/sys/dev/block` 的 kset 实例
64 static mut DEV_BLOCK_KSET_INSTANCE: Option<Arc<KSet>> = None;
65 /// `/sys/dev/char` 的 kset 实例
66 static mut DEV_CHAR_KSET_INSTANCE: Option<Arc<KSet>> = None;
67 
68 #[inline(always)]
69 pub(super) fn sys_devices_kset() -> Arc<KSet> {
70     unsafe { DEVICES_KSET_INSTANCE.as_ref().unwrap().clone() }
71 }
72 
73 #[inline(always)]
74 pub(super) fn sys_dev_kset() -> Arc<KSet> {
75     unsafe { DEV_KSET_INSTANCE.as_ref().unwrap().clone() }
76 }
77 
78 #[inline(always)]
79 #[allow(dead_code)]
80 pub(super) fn sys_dev_block_kset() -> Arc<KSet> {
81     unsafe { DEV_BLOCK_KSET_INSTANCE.as_ref().unwrap().clone() }
82 }
83 
84 #[inline(always)]
85 pub(self) fn sys_dev_char_kset() -> Arc<KSet> {
86     unsafe { DEV_CHAR_KSET_INSTANCE.as_ref().unwrap().clone() }
87 }
88 
89 /// 设备应该实现的操作
90 ///
91 /// ## 注意
92 ///
93 /// 由于设备驱动模型需要从Arc<dyn KObject>转换为Arc<dyn Device>,
94 /// 因此,所有的实现了Device trait的结构体,都应该在结构体上方标注`#[cast_to([sync] Device)]`,
95 ///
96 /// 否则在释放设备资源的时候,会由于无法转换为Arc<dyn Device>而导致资源泄露,并且release回调函数也不会被调用。
97 pub trait Device: KObject {
98     // TODO: 待实现 open, close
99 
100     /// @brief: 获取设备类型
101     /// @parameter: None
102     /// @return: 实现该trait的设备所属类型
103     fn dev_type(&self) -> DeviceType;
104 
105     /// @brief: 获取设备标识
106     /// @parameter: None
107     /// @return: 该设备唯一标识
108     fn id_table(&self) -> IdTable;
109 
110     /// 设备释放时的回调函数
111     fn release(&self) {
112         let name = self.name();
113         kwarn!(
114             "device {} does not have a release() function, it is broken and must be fixed.",
115             name
116         );
117     }
118 
119     /// 获取当前设备所属的总线
120     fn bus(&self) -> Option<Arc<dyn Bus>> {
121         return None;
122     }
123 
124     /// 设置当前设备所属的总线
125     ///
126     /// (一定要传入Arc,因为bus的subsysprivate里面存储的是Device的Weak指针)
127     fn set_bus(&self, bus: Option<Arc<dyn Bus>>);
128 
129     /// 返回已经与当前设备匹配好的驱动程序
130     fn driver(&self) -> Option<Arc<dyn Driver>>;
131 
132     fn set_driver(&self, driver: Option<Weak<dyn Driver>>);
133 
134     /// 当前设备是否已经挂掉了
135     fn is_dead(&self) -> bool;
136 
137     /// 当前设备是否处于可以被匹配的状态
138     ///
139     /// The device has matched with a driver at least once or it is in
140     /// a bus (like AMBA) which can't check for matching drivers until
141     /// other devices probe successfully.
142     fn can_match(&self) -> bool;
143 
144     fn set_can_match(&self, can_match: bool);
145 
146     /// The hardware state of this device has been synced to match
147     /// the software state of this device by calling the driver/bus
148     /// sync_state() callback.
149     fn state_synced(&self) -> bool;
150 }
151 
152 impl dyn Device {
153     #[inline(always)]
154     pub fn is_registered(&self) -> bool {
155         self.kobj_state().contains(KObjectState::IN_SYSFS)
156     }
157 }
158 
159 // 暂定是不可修改的,在初始化的时候就要确定。以后可能会包括例如硬件中断包含的信息
160 #[allow(dead_code)]
161 #[derive(Debug, Clone)]
162 pub struct DevicePrivateData {
163     id_table: IdTable,
164     state: DeviceState,
165 }
166 
167 #[allow(dead_code)]
168 impl DevicePrivateData {
169     pub fn new(id_table: IdTable, state: DeviceState) -> Self {
170         Self { id_table, state }
171     }
172 
173     pub fn id_table(&self) -> &IdTable {
174         &self.id_table
175     }
176 
177     pub fn state(&self) -> DeviceState {
178         self.state
179     }
180 
181     pub fn set_state(&mut self, state: DeviceState) {
182         self.state = state;
183     }
184 }
185 
186 int_like!(DeviceNumber, usize);
187 
188 impl Default for DeviceNumber {
189     fn default() -> Self {
190         DeviceNumber(0)
191     }
192 }
193 
194 impl From<usize> for DeviceNumber {
195     fn from(dev_t: usize) -> Self {
196         DeviceNumber(dev_t)
197     }
198 }
199 
200 impl Into<usize> for DeviceNumber {
201     fn into(self) -> usize {
202         self.0
203     }
204 }
205 
206 impl core::hash::Hash for DeviceNumber {
207     fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
208         self.0.hash(state);
209     }
210 }
211 
212 impl DeviceNumber {
213     /// @brief: 获取主设备号
214     /// @parameter: none
215     /// @return: 主设备号
216     pub fn major(&self) -> usize {
217         (self.0 >> 8) & 0xffffff
218     }
219 
220     /// @brief: 获取次设备号
221     /// @parameter: none
222     /// @return: 次设备号
223     pub fn minor(&self) -> usize {
224         self.0 & 0xff
225     }
226 
227     #[inline]
228     #[allow(dead_code)]
229     pub fn from_major_minor(major: usize, minor: usize) -> usize {
230         ((major & 0xffffff) << 8) | (minor & 0xff)
231     }
232 }
233 
234 /// @brief: 根据主次设备号创建设备号实例
235 /// @parameter: major: 主设备号
236 ///             minor: 次设备号
237 /// @return: 设备号实例
238 pub fn mkdev(major: usize, minor: usize) -> DeviceNumber {
239     DeviceNumber(((major & 0xfff) << 20) | (minor & 0xfffff))
240 }
241 
242 /// @brief: 设备类型
243 #[allow(dead_code)]
244 #[derive(Debug, Eq, PartialEq)]
245 pub enum DeviceType {
246     Bus,
247     Net,
248     Gpu,
249     Input,
250     Block,
251     Rtc,
252     Serial,
253     Intc,
254     PlatformDev,
255 }
256 
257 /// @brief: 设备标识符类型
258 #[derive(Debug, Clone, Hash, PartialOrd, PartialEq, Ord, Eq)]
259 pub struct IdTable(String, DeviceNumber);
260 
261 /// @brief: 设备标识符操作方法集
262 impl IdTable {
263     /// @brief: 创建一个新的设备标识符
264     /// @parameter name: 设备名
265     /// @parameter id: 设备id
266     /// @return: 设备标识符
267     pub fn new(name: String, id: DeviceNumber) -> IdTable {
268         Self(name, id)
269     }
270 
271     /// @brief: 将设备标识符转换成name
272     /// @parameter None
273     /// @return: 设备名
274     pub fn name(&self) -> String {
275         return format!("{}:{}", self.0, self.1 .0);
276     }
277 
278     pub fn device_number(&self) -> DeviceNumber {
279         return self.1;
280     }
281 }
282 
283 impl Default for IdTable {
284     fn default() -> Self {
285         IdTable("unknown".to_string(), DeviceNumber::new(0))
286     }
287 }
288 
289 // 以现在的模型,设备在加载到系统中就是已经初始化的状态了,因此可以考虑把这个删掉
290 /// @brief: 设备当前状态
291 #[derive(Debug, Clone, Copy, Eq, PartialEq)]
292 pub enum DeviceState {
293     NotInitialized = 0,
294     Initialized = 1,
295     UnDefined = 2,
296 }
297 
298 /// @brief: 设备错误类型
299 #[allow(dead_code)]
300 #[derive(Debug, Copy, Clone)]
301 pub enum DeviceError {
302     DriverExists,         // 设备已存在
303     DeviceExists,         // 驱动已存在
304     InitializeFailed,     // 初始化错误
305     NotInitialized,       // 未初始化的设备
306     NoDeviceForDriver,    // 没有合适的设备匹配驱动
307     NoDriverForDevice,    // 没有合适的驱动匹配设备
308     RegisterError,        // 注册失败
309     UnsupportedOperation, // 不支持的操作
310 }
311 
312 impl Into<SystemError> for DeviceError {
313     fn into(self) -> SystemError {
314         match self {
315             DeviceError::DriverExists => SystemError::EEXIST,
316             DeviceError::DeviceExists => SystemError::EEXIST,
317             DeviceError::InitializeFailed => SystemError::EIO,
318             DeviceError::NotInitialized => SystemError::ENODEV,
319             DeviceError::NoDeviceForDriver => SystemError::ENODEV,
320             DeviceError::NoDriverForDevice => SystemError::ENODEV,
321             DeviceError::RegisterError => SystemError::EIO,
322             DeviceError::UnsupportedOperation => SystemError::EIO,
323         }
324     }
325 }
326 
327 /// @brief: 将u32类型转换为设备状态类型
328 impl From<u32> for DeviceState {
329     fn from(state: u32) -> Self {
330         match state {
331             0 => DeviceState::NotInitialized,
332             1 => DeviceState::Initialized,
333             _ => todo!(),
334         }
335     }
336 }
337 
338 /// @brief: 将设备状态转换为u32类型
339 impl From<DeviceState> for u32 {
340     fn from(state: DeviceState) -> Self {
341         match state {
342             DeviceState::NotInitialized => 0,
343             DeviceState::Initialized => 1,
344             DeviceState::UnDefined => 2,
345         }
346     }
347 }
348 
349 #[derive(Debug)]
350 pub struct DeviceKObjType;
351 
352 impl KObjType for DeviceKObjType {
353     // https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#2307
354     fn release(&self, kobj: Arc<dyn KObject>) {
355         let dev = kobj.cast::<dyn Device>().unwrap();
356         /*
357          * Some platform devices are driven without driver attached
358          * and managed resources may have been acquired.  Make sure
359          * all resources are released.
360          *
361          * Drivers still can add resources into device after device
362          * is deleted but alive, so release devres here to avoid
363          * possible memory leak.
364          */
365 
366         // todo: 在引入devres之后再实现
367         // devres_release_all(kobj);
368         dev.release();
369     }
370 
371     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
372         None
373     }
374 
375     fn sysfs_ops(&self) -> Option<&dyn SysFSOps> {
376         Some(&DeviceSysFSOps)
377     }
378 }
379 
380 #[derive(Debug)]
381 pub(super) struct DeviceSysFSOps;
382 
383 impl SysFSOps for DeviceSysFSOps {
384     fn store(
385         &self,
386         kobj: Arc<dyn KObject>,
387         attr: &dyn Attribute,
388         buf: &[u8],
389     ) -> Result<usize, SystemError> {
390         return attr.store(kobj, buf);
391     }
392 
393     fn show(
394         &self,
395         kobj: Arc<dyn KObject>,
396         attr: &dyn Attribute,
397         buf: &mut [u8],
398     ) -> Result<usize, SystemError> {
399         return attr.show(kobj, buf);
400     }
401 }
402 
403 /// @brief Device管理器
404 #[derive(Debug)]
405 pub struct DeviceManager;
406 
407 impl DeviceManager {
408     /// @brief: 创建一个新的设备管理器
409     /// @parameter: None
410     /// @return: DeviceManager实体
411     #[inline]
412     const fn new() -> DeviceManager {
413         return Self;
414     }
415 
416     pub fn register(&self, device: Arc<dyn Device>) -> Result<(), SystemError> {
417         self.device_initialize(&device);
418         return self.add_device(device);
419     }
420 
421     /// device_initialize - init device structure.
422     pub fn device_initialize(&self, device: &Arc<dyn Device>) {
423         device.set_kset(Some(sys_devices_kset()));
424         device.set_kobj_type(Some(&DeviceKObjType));
425     }
426 
427     /// @brief: 添加设备
428     /// @parameter id_table: 总线标识符,用于唯一标识该总线
429     /// @parameter dev: 设备实例
430     /// @return: None
431     ///
432     /// https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#3398
433     ///
434     /// todo: 完善错误处理逻辑:如果添加失败,需要将之前添加的内容全部回滚
435     #[inline]
436     #[allow(dead_code)]
437     pub fn add_device(&self, device: Arc<dyn Device>) -> Result<(), SystemError> {
438         // todo: 引入class后,在这里处理与parent相关的逻辑
439 
440         KObjectManager::add_kobj(device.clone() as Arc<dyn KObject>, None).map_err(|e| {
441             kerror!("add device '{:?}' failed: {:?}", device.name(), e);
442             e
443         })?;
444 
445         self.device_platform_notify(&device);
446 
447         self.add_class_symlinks(&device)?;
448 
449         self.add_attrs(&device)?;
450 
451         bus_add_device(&device)?;
452 
453         if device.id_table().device_number().major() != 0 {
454             self.create_file(&device, &DeviceAttrDev)?;
455 
456             self.create_sys_dev_entry(&device)?;
457         }
458 
459         // todo: Notify clients of device addition.This call must come
460         //  after dpm_sysfs_add() and before kobject_uevent().
461         // 参考:https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#3491
462 
463         // todo: 发送uevent
464 
465         // probe drivers for a new device
466         bus_probe_device(&device);
467 
468         return Ok(());
469     }
470 
471     /// @brief: 卸载设备
472     /// @parameter id_table: 总线标识符,用于唯一标识该设备
473     /// @return: None
474     #[inline]
475     #[allow(dead_code)]
476     pub fn remove_device(&self, _id_table: &IdTable) {
477         todo!()
478     }
479 
480     /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#542
481     fn remove(&self, _dev: &Arc<dyn Device>) {
482         todo!("DeviceManager::remove")
483     }
484 
485     /// @brief: 获取设备
486     /// @parameter id_table: 设备标识符,用于唯一标识该设备
487     /// @return: 设备实例
488     #[inline]
489     #[allow(dead_code)]
490     pub fn find_device_by_idtable(&self, _id_table: &IdTable) -> Option<Arc<dyn Device>> {
491         todo!("find_device_by_idtable")
492     }
493 
494     fn device_platform_notify(&self, dev: &Arc<dyn Device>) {
495         acpi_device_notify(dev);
496         software_node_notify(dev);
497     }
498 
499     fn add_class_symlinks(&self, _dev: &Arc<dyn Device>) -> Result<(), SystemError> {
500         // todo: 引入class后,在这里处理与class相关的逻辑
501         // https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#3224
502 
503         return Ok(());
504     }
505 
506     /// 在sysfs中,为指定的设备创建属性文件
507     ///
508     /// ## 参数
509     ///
510     /// - `dev`: 设备
511     fn add_attrs(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> {
512         let kobj_type = dev.kobj_type();
513         if kobj_type.is_none() {
514             return Ok(());
515         }
516 
517         let kobj_type = kobj_type.unwrap();
518 
519         let attr_groups = kobj_type.attribute_groups();
520 
521         if attr_groups.is_none() {
522             return Ok(());
523         }
524 
525         self.add_groups(dev, attr_groups.unwrap())?;
526 
527         return Ok(());
528     }
529 
530     /// 在sysfs中,为指定的设备创建属性组,以及属性组中的属性文件
531     ///
532     /// ## 参数
533     ///
534     /// - `dev`: 设备
535     /// - `attr_groups`: 属性组
536     pub fn add_groups(
537         &self,
538         dev: &Arc<dyn Device>,
539         attr_groups: &'static [&dyn AttributeGroup],
540     ) -> Result<(), SystemError> {
541         let kobj = dev.clone() as Arc<dyn KObject>;
542         return sysfs_instance().create_groups(&kobj, attr_groups);
543     }
544 
545     /// 为设备在sysfs中创建属性文件
546     ///
547     /// ## 参数
548     ///
549     /// - `dev`: 设备
550     /// - `attr`: 属性
551     pub fn create_file(
552         &self,
553         dev: &Arc<dyn Device>,
554         attr: &'static dyn Attribute,
555     ) -> Result<(), SystemError> {
556         if unlikely(
557             attr.mode().contains(ModeType::S_IRUGO)
558                 && (!attr.support().contains(SysFSOpsSupport::SHOW)),
559         ) {
560             kwarn!(
561                 "Attribute '{}': read permission without 'show'",
562                 attr.name()
563             );
564         }
565         if unlikely(
566             attr.mode().contains(ModeType::S_IWUGO)
567                 && (!attr.support().contains(SysFSOpsSupport::STORE)),
568         ) {
569             kwarn!(
570                 "Attribute '{}': write permission without 'store'",
571                 attr.name()
572             );
573         }
574 
575         let kobj = dev.clone() as Arc<dyn KObject>;
576 
577         return sysfs_instance().create_file(&kobj, attr);
578     }
579 
580     /// 在/sys/dev下,或者设备所属的class下,为指定的设备创建链接
581     fn create_sys_dev_entry(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> {
582         let target_kobj = self.device_to_dev_kobj(dev);
583         let name = dev.id_table().name();
584         let current_kobj = dev.clone() as Arc<dyn KObject>;
585         return sysfs_instance().create_link(Some(&current_kobj), &target_kobj, name);
586     }
587 
588     /// Delete symlink for device in `/sys/dev` or `/sys/class/<class_name>`
589     #[allow(dead_code)]
590     fn remove_sys_dev_entry(&self, dev: &Arc<dyn Device>) {
591         let kobj = self.device_to_dev_kobj(dev);
592         let name = dev.id_table().name();
593         sysfs_instance().remove_link(&kobj, name);
594     }
595 
596     /// device_to_dev_kobj - select a /sys/dev/ directory for the device
597     ///
598     /// By default we select char/ for new entries.
599     ///
600     /// ## 参数
601     ///
602     /// - `dev`: 设备
603     fn device_to_dev_kobj(&self, _dev: &Arc<dyn Device>) -> Arc<dyn KObject> {
604         // todo: 处理class的逻辑
605         let kobj = sys_dev_char_kset().as_kobject();
606         return kobj;
607     }
608 
609     /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c?fi=device_links_force_bind#1226
610     pub fn device_links_force_bind(&self, _dev: &Arc<dyn Device>) {
611         todo!("device_links_force_bind")
612     }
613 
614     /// 把device对象的一些结构进行默认初始化
615     ///
616     /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c?fi=device_initialize#2976
617     pub fn device_default_initialize(&self, dev: &Arc<dyn Device>) {
618         dev.set_kset(Some(sys_devices_kset()));
619         return;
620     }
621 
622     /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c?r=&mo=29885&fi=1100#1100
623     pub fn device_driver_attach(
624         &self,
625         _driver: &Arc<dyn Driver>,
626         _dev: &Arc<dyn Device>,
627     ) -> Result<(), SystemError> {
628         todo!("device_driver_attach")
629     }
630 
631     /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c?r=&mo=35401&fi=1313#1313
632     pub fn device_driver_detach(&self, _dev: &Arc<dyn Device>) {
633         todo!("device_driver_detach")
634     }
635 }
636 
637 /// @brief: 设备注册
638 /// @parameter: name: 设备名
639 /// @return: 操作成功,返回(),操作失败,返回错误码
640 pub fn device_register<T: Device>(device: Arc<T>) -> Result<(), SystemError> {
641     return device_manager().register(device);
642 }
643 
644 /// @brief: 设备卸载
645 /// @parameter: name: 设备名
646 /// @return: 操作成功,返回(),操作失败,返回错误码
647 pub fn device_unregister<T: Device>(_device: Arc<T>) {
648     // DEVICE_MANAGER.add_device(device.id_table(), device.clone());
649     // match sys_device_unregister(&device.id_table().name()) {
650     //     Ok(_) => {
651     //         device.set_inode(None);
652     //         return Ok(());
653     //     }
654     //     Err(_) => Err(DeviceError::RegisterError),
655     // }
656     todo!("device_unregister")
657 }
658 
659 /// 设备文件夹下的`dev`文件的属性
660 #[derive(Debug, Clone, Copy)]
661 pub struct DeviceAttrDev;
662 
663 impl Attribute for DeviceAttrDev {
664     fn mode(&self) -> ModeType {
665         // 0o444
666         return ModeType::S_IRUGO;
667     }
668 
669     fn name(&self) -> &str {
670         "dev"
671     }
672 
673     fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
674         let dev = kobj.cast::<dyn Device>().map_err(|kobj| {
675             kerror!(
676                 "Intertrait casting not implemented for kobj: {}",
677                 kobj.name()
678             );
679             SystemError::EOPNOTSUPP_OR_ENOTSUP
680         })?;
681 
682         let device_number = dev.id_table().device_number();
683         let s = format!("{}:{}\n", device_number.major(), device_number.minor());
684 
685         return sysfs_emit_str(buf, &s);
686     }
687 
688     fn support(&self) -> SysFSOpsSupport {
689         SysFSOpsSupport::SHOW
690     }
691 }
692 
693 /// 设备匹配器
694 ///
695 /// 用于匹配设备是否符合某个条件
696 ///
697 /// ## 参数
698 ///
699 /// - `T` - 匹配器的数据类型
700 /// - `data` - 匹配器的数据
701 pub trait DeviceMatcher<T>: Debug {
702     fn match_device(&self, device: &Arc<dyn Device>, data: T) -> bool;
703 }
704 
705 /// 用于根据名称匹配设备的匹配器
706 #[derive(Debug)]
707 pub struct DeviceMatchName;
708 
709 impl DeviceMatcher<&str> for DeviceMatchName {
710     #[inline]
711     fn match_device(&self, device: &Arc<dyn Device>, data: &str) -> bool {
712         return device.name() == data;
713     }
714 }
715