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 let dev = dev.upgrade(); 89 if let Some(dev) = dev { 90 if matcher.match_device(&dev, data) { 91 return Some(dev.clone()); 92 } 93 } 94 } 95 return None; 96 } 97 98 /// 根据名称匹配设备 99 /// 100 /// ## 参数 101 /// 102 /// - name 设备名称 103 #[allow(dead_code)] 104 pub fn find_device_by_name(&self, name: &str) -> Option<Arc<dyn Device>> { 105 return self.find_device(&DeviceMatchName, name); 106 } 107 } 108 109 #[inline(always)] 110 pub fn class_manager() -> &'static ClassManager { 111 return &ClassManager; 112 } 113 pub struct ClassManager; 114 115 impl ClassManager { 116 /// 注册一个设备类 117 /// 118 /// 该方法会将设备类注册到`/sys/class`目录下, 119 /// 并创建它的默认属性组对应的文件。 120 /// 121 /// ## 参数 122 /// 123 /// - `class` - 设备类 124 pub fn class_register(&self, class: &Arc<dyn Class>) -> Result<(), SystemError> { 125 let subsystem = class.subsystem(); 126 let subsys = subsystem.subsys(); 127 subsys.set_name(class.name().to_string()); 128 129 if class.dev_kobj().is_none() { 130 class.set_dev_kobj(sys_dev_char_kset() as Arc<dyn KObject>); 131 } 132 133 subsys.set_kobj_type(Some(&ClassKObjbectType)); 134 subsystem.set_class(Some(Arc::downgrade(class))); 135 136 subsys.register(Some(sys_class_kset()))?; 137 138 sysfs_instance().create_groups(&(subsys as Arc<dyn KObject>), class.class_groups())?; 139 140 return Ok(()); 141 } 142 143 /// 注销一个设备类 144 #[allow(dead_code)] 145 pub fn class_unregister(&self, class: &Arc<dyn Class>) { 146 let subsystem = class.subsystem(); 147 let subsys = subsystem.subsys(); 148 sysfs_instance().remove_groups(&(subsys.clone() as Arc<dyn KObject>), class.class_groups()); 149 subsys.unregister(); 150 } 151 } 152 153 #[derive(Debug)] 154 pub struct ClassKObjbectType; 155 156 impl KObjType for ClassKObjbectType { 157 fn sysfs_ops(&self) -> Option<&dyn SysFSOps> { 158 Some(&ClassSysFSOps) 159 } 160 161 fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { 162 None 163 } 164 } 165 166 #[derive(Debug)] 167 struct ClassSysFSOps; 168 169 impl SysFSOps for ClassSysFSOps { 170 fn show( 171 &self, 172 _kobj: Arc<dyn KObject>, 173 _attr: &dyn Attribute, 174 _buf: &mut [u8], 175 ) -> Result<usize, SystemError> { 176 todo!() 177 } 178 179 fn store( 180 &self, 181 _kobj: Arc<dyn KObject>, 182 _attr: &dyn Attribute, 183 _buf: &[u8], 184 ) -> Result<usize, SystemError> { 185 todo!() 186 } 187 } 188