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