1 use alloc::{string::ToString, sync::Arc}; 2 3 use core::fmt::Debug; 4 5 use super::{ 6 device::{sys_dev_char_kset, Device, DeviceMatchName, DeviceMatcher}, 7 kobject::{KObjType, KObject}, 8 kset::KSet, 9 subsys::SubSysPrivate, 10 }; 11 use crate::filesystem::sysfs::{sysfs_instance, Attribute, AttributeGroup, SysFSOps}; 12 use system_error::SystemError; 13 14 /// `/sys/class`的kset 15 static mut CLASS_KSET_INSTANCE: Option<Arc<KSet>> = None; 16 17 #[inline(always)] 18 #[allow(dead_code)] 19 pub fn sys_class_kset() -> Arc<KSet> { 20 unsafe { CLASS_KSET_INSTANCE.clone().unwrap() } 21 } 22 23 /// 初始化`/sys/class`的kset 24 pub(super) fn classes_init() -> Result<(), SystemError> { 25 let class_kset = KSet::new("class".to_string()); 26 class_kset 27 .register(None) 28 .expect("register class kset failed"); 29 unsafe { 30 CLASS_KSET_INSTANCE = Some(class_kset); 31 } 32 33 return Ok(()); 34 } 35 36 /// 设备分类 37 /// 38 /// 类是对设备的高级视图,它抽象了低级实现细节。 39 /// 40 /// 比如,驱动程序可能看到一个SCSI硬盘或一个ATA硬盘,但在类的这个级别,它们都只是硬盘。 41 /// 类允许用户空间根据设备的功能而不是它们如何连接或工作来操作设备。 42 /// 43 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/device/class.h#54 44 pub trait Class: Debug + Send + Sync { 45 /// 获取类的名称 46 fn name(&self) -> &'static str; 47 48 /// 属于该类的设备的基本属性。 49 fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] { 50 return &[]; 51 } 52 53 /// 当前类的基本属性。 54 fn class_groups(&self) -> &'static [&'static dyn AttributeGroup] { 55 return &[]; 56 } 57 58 /// 表示此类的kobject,并将它链接到层次结构中。 59 /// 60 /// 当前class的所有设备,将会挂载到的`/sys/dev/`内的某个目录下。 61 fn dev_kobj(&self) -> Option<Arc<dyn KObject>>; 62 63 fn set_dev_kobj(&self, kobj: Arc<dyn KObject>); 64 65 /// subsystem应当拥有的数据 66 fn subsystem(&self) -> &SubSysPrivate; 67 68 /// Called to release this class 69 fn class_release(&self) {} 70 } 71 72 impl dyn Class { 73 /// 在class内,根据条件寻找一个特定的设备 74 /// 75 /// ## 参数 76 /// 77 /// - `matcher` - 匹配器 78 /// - `data` - 传给匹配器的数据 79 #[allow(dead_code)] 80 pub fn find_device<T: Copy>( 81 &self, 82 matcher: &dyn DeviceMatcher<T>, 83 data: T, 84 ) -> Option<Arc<dyn Device>> { 85 let subsys = self.subsystem(); 86 let guard = subsys.devices(); 87 for dev in guard.iter() { 88 if matcher.match_device(dev, data) { 89 return Some(dev.clone()); 90 } 91 } 92 return None; 93 } 94 95 /// 根据名称匹配设备 96 /// 97 /// ## 参数 98 /// 99 /// - name 设备名称 100 #[allow(dead_code)] 101 pub fn find_device_by_name(&self, name: &str) -> Option<Arc<dyn Device>> { 102 return self.find_device(&DeviceMatchName, name); 103 } 104 } 105 106 #[inline(always)] 107 pub fn class_manager() -> &'static ClassManager { 108 return &ClassManager; 109 } 110 pub struct ClassManager; 111 112 impl ClassManager { 113 /// 注册一个设备类 114 /// 115 /// 该方法会将设备类注册到`/sys/class`目录下, 116 /// 并创建它的默认属性组对应的文件。 117 /// 118 /// ## 参数 119 /// 120 /// - `class` - 设备类 121 pub fn class_register(&self, class: &Arc<dyn Class>) -> Result<(), SystemError> { 122 let subsystem = class.subsystem(); 123 let subsys = subsystem.subsys(); 124 subsys.set_name(class.name().to_string()); 125 126 if class.dev_kobj().is_none() { 127 class.set_dev_kobj(sys_dev_char_kset() as Arc<dyn KObject>); 128 } 129 130 subsys.set_kobj_type(Some(&ClassKObjbectType)); 131 subsystem.set_class(Some(Arc::downgrade(class))); 132 133 subsys.register(Some(sys_class_kset()))?; 134 135 sysfs_instance().create_groups(&(subsys as Arc<dyn KObject>), class.class_groups())?; 136 137 return Ok(()); 138 } 139 140 /// 注销一个设备类 141 #[allow(dead_code)] 142 pub fn class_unregister(&self, class: &Arc<dyn Class>) { 143 let subsystem = class.subsystem(); 144 let subsys = subsystem.subsys(); 145 sysfs_instance().remove_groups(&(subsys.clone() as Arc<dyn KObject>), class.class_groups()); 146 subsys.unregister(); 147 } 148 } 149 150 #[derive(Debug)] 151 pub struct ClassKObjbectType; 152 153 impl KObjType for ClassKObjbectType { 154 fn sysfs_ops(&self) -> Option<&dyn SysFSOps> { 155 Some(&ClassSysFSOps) 156 } 157 158 fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { 159 None 160 } 161 } 162 163 #[derive(Debug)] 164 struct ClassSysFSOps; 165 166 impl SysFSOps for ClassSysFSOps { 167 fn show( 168 &self, 169 _kobj: Arc<dyn KObject>, 170 _attr: &dyn Attribute, 171 _buf: &mut [u8], 172 ) -> Result<usize, SystemError> { 173 todo!() 174 } 175 176 fn store( 177 &self, 178 _kobj: Arc<dyn KObject>, 179 _attr: &dyn Attribute, 180 _buf: &[u8], 181 ) -> Result<usize, SystemError> { 182 todo!() 183 } 184 } 185