1 use core::{any::Any, fmt::Debug, hash::Hash, ops::Deref}; 2 3 use alloc::{ 4 string::String, 5 sync::{Arc, Weak}, 6 }; 7 use driver_base_macros::get_weak_or_clear; 8 use intertrait::CastFromSync; 9 use log::{debug, error}; 10 11 use crate::{ 12 filesystem::{ 13 kernfs::KernFSInode, 14 sysfs::{sysfs_instance, Attribute, AttributeGroup, SysFSOps, SysFSOpsSupport}, 15 }, 16 libs::{ 17 casting::DowncastArc, 18 rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}, 19 }, 20 }; 21 22 use system_error::SystemError; 23 24 use super::kset::KSet; 25 26 pub trait KObject: Any + Send + Sync + Debug + CastFromSync { as_any_ref(&self) -> &dyn core::any::Any27 fn as_any_ref(&self) -> &dyn core::any::Any; 28 29 /// 设置当前kobject对应的sysfs inode(类型为KernFSInode) set_inode(&self, inode: Option<Arc<KernFSInode>>)30 fn set_inode(&self, inode: Option<Arc<KernFSInode>>); 31 32 /// 获取当前kobject对应的sysfs inode(类型为KernFSInode) inode(&self) -> Option<Arc<KernFSInode>>33 fn inode(&self) -> Option<Arc<KernFSInode>>; 34 parent(&self) -> Option<Weak<dyn KObject>>35 fn parent(&self) -> Option<Weak<dyn KObject>>; 36 37 /// 设置当前kobject的parent kobject(不一定与kset相同) set_parent(&self, parent: Option<Weak<dyn KObject>>)38 fn set_parent(&self, parent: Option<Weak<dyn KObject>>); 39 40 /// 当前kobject属于哪个kset kset(&self) -> Option<Arc<KSet>>41 fn kset(&self) -> Option<Arc<KSet>>; 42 43 /// 设置当前kobject所属的kset set_kset(&self, kset: Option<Arc<KSet>>)44 fn set_kset(&self, kset: Option<Arc<KSet>>); 45 kobj_type(&self) -> Option<&'static dyn KObjType>46 fn kobj_type(&self) -> Option<&'static dyn KObjType>; 47 set_kobj_type(&self, ktype: Option<&'static dyn KObjType>)48 fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>); 49 name(&self) -> String50 fn name(&self) -> String; 51 set_name(&self, name: String)52 fn set_name(&self, name: String); 53 kobj_state(&self) -> RwLockReadGuard<KObjectState>54 fn kobj_state(&self) -> RwLockReadGuard<KObjectState>; 55 kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>56 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>; 57 set_kobj_state(&self, state: KObjectState)58 fn set_kobj_state(&self, state: KObjectState); 59 } 60 61 impl dyn KObject { 62 /// 更新kobject的状态 update_kobj_state(&self, insert: Option<KObjectState>, remove: Option<KObjectState>)63 pub fn update_kobj_state(&self, insert: Option<KObjectState>, remove: Option<KObjectState>) { 64 let insert = insert.unwrap_or(KObjectState::empty()); 65 let remove = remove.unwrap_or(KObjectState::empty()); 66 let mut state = self.kobj_state_mut(); 67 *state = (*state | insert) & !remove; 68 } 69 } 70 71 impl DowncastArc for dyn KObject { as_any_arc(self: Arc<Self>) -> Arc<dyn Any>72 fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any> { 73 self 74 } 75 } 76 77 /// kobject的公共数据 78 #[derive(Debug, Default)] 79 pub struct KObjectCommonData { 80 pub kern_inode: Option<Arc<KernFSInode>>, 81 pub parent: Option<Weak<dyn KObject>>, 82 pub kset: Option<Arc<KSet>>, 83 pub kobj_type: Option<&'static dyn KObjType>, 84 } 85 86 impl KObjectCommonData { get_parent_or_clear_weak(&mut self) -> Option<Weak<dyn KObject>>87 pub fn get_parent_or_clear_weak(&mut self) -> Option<Weak<dyn KObject>> { 88 get_weak_or_clear!(self.parent) 89 } 90 } 91 92 pub trait KObjType: Debug + Send + Sync { 93 /// 当指定的kobject被释放时,设备驱动模型会调用此方法 release(&self, _kobj: Arc<dyn KObject>)94 fn release(&self, _kobj: Arc<dyn KObject>) {} sysfs_ops(&self) -> Option<&dyn SysFSOps>95 fn sysfs_ops(&self) -> Option<&dyn SysFSOps>; 96 attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]>97 fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]>; 98 } 99 100 bitflags! { 101 pub struct KObjectState: u32 { 102 const IN_SYSFS = 1 << 0; 103 const ADD_UEVENT_SENT = 1 << 1; 104 const REMOVE_UEVENT_SENT = 1 << 2; 105 const INITIALIZED = 1 << 3; 106 } 107 108 } 109 110 #[derive(Debug)] 111 pub struct LockedKObjectState(RwLock<KObjectState>); 112 113 impl LockedKObjectState { new(state: Option<KObjectState>) -> LockedKObjectState114 pub fn new(state: Option<KObjectState>) -> LockedKObjectState { 115 let state = state.unwrap_or(KObjectState::empty()); 116 LockedKObjectState(RwLock::new(state)) 117 } 118 } 119 120 impl Deref for LockedKObjectState { 121 type Target = RwLock<KObjectState>; 122 deref(&self) -> &Self::Target123 fn deref(&self) -> &Self::Target { 124 &self.0 125 } 126 } 127 128 impl Default for LockedKObjectState { default() -> Self129 fn default() -> Self { 130 LockedKObjectState::new(None) 131 } 132 } 133 134 #[derive(Debug)] 135 pub struct KObjectSysFSOps; 136 137 impl SysFSOps for KObjectSysFSOps { support(&self, attr: &dyn Attribute) -> SysFSOpsSupport138 fn support(&self, attr: &dyn Attribute) -> SysFSOpsSupport { 139 return attr.support(); 140 } 141 show( &self, kobj: Arc<dyn KObject>, attr: &dyn Attribute, buf: &mut [u8], ) -> Result<usize, SystemError>142 fn show( 143 &self, 144 kobj: Arc<dyn KObject>, 145 attr: &dyn Attribute, 146 buf: &mut [u8], 147 ) -> Result<usize, SystemError> { 148 let r = attr.show(kobj, buf).map_err(|e| { 149 if e == SystemError::ENOSYS { 150 SystemError::EIO 151 } else { 152 e 153 } 154 }); 155 156 return r; 157 } 158 store( &self, kobj: Arc<dyn KObject>, attr: &dyn Attribute, buf: &[u8], ) -> Result<usize, SystemError>159 fn store( 160 &self, 161 kobj: Arc<dyn KObject>, 162 attr: &dyn Attribute, 163 buf: &[u8], 164 ) -> Result<usize, SystemError> { 165 let r = attr.store(kobj, buf).map_err(|e| { 166 if e == SystemError::ENOSYS { 167 SystemError::EIO 168 } else { 169 e 170 } 171 }); 172 173 return r; 174 } 175 } 176 177 #[derive(Debug)] 178 pub struct KObjectManager; 179 180 impl KObjectManager { init_and_add_kobj( kobj: Arc<dyn KObject>, join_kset: Option<Arc<KSet>>, kobj_type: Option<&'static dyn KObjType>, ) -> Result<(), SystemError>181 pub fn init_and_add_kobj( 182 kobj: Arc<dyn KObject>, 183 join_kset: Option<Arc<KSet>>, 184 kobj_type: Option<&'static dyn KObjType>, 185 ) -> Result<(), SystemError> { 186 Self::kobj_init(&kobj, kobj_type); 187 Self::add_kobj(kobj, join_kset) 188 } 189 kobj_init(kobj: &Arc<dyn KObject>, kobj_type: Option<&'static dyn KObjType>)190 pub fn kobj_init(kobj: &Arc<dyn KObject>, kobj_type: Option<&'static dyn KObjType>) { 191 kobj.set_kobj_type(kobj_type); 192 } 193 add_kobj( kobj: Arc<dyn KObject>, join_kset: Option<Arc<KSet>>, ) -> Result<(), SystemError>194 pub fn add_kobj( 195 kobj: Arc<dyn KObject>, 196 join_kset: Option<Arc<KSet>>, 197 ) -> Result<(), SystemError> { 198 if let Some(kset) = join_kset { 199 kset.join(&kobj); 200 // 如果kobject没有parent,那么就将这个kset作为parent 201 if kobj.parent().is_none() { 202 kobj.set_parent(Some(Arc::downgrade(&(kset as Arc<dyn KObject>)))); 203 } 204 } 205 206 let r = Self::create_dir(kobj.clone()); 207 208 if let Err(e) = r { 209 // https://code.dragonos.org.cn/xref/linux-6.1.9/lib/kobject.c?r=&mo=10426&fi=394#224 210 if let Some(kset) = kobj.kset() { 211 kset.leave(&kobj); 212 } 213 kobj.set_parent(None); 214 if e == SystemError::EEXIST { 215 error!("KObjectManager::add_kobj() failed with error: {e:?}, kobj:{kobj:?}"); 216 } 217 218 return Err(e); 219 } 220 221 kobj.update_kobj_state(Some(KObjectState::IN_SYSFS), None); 222 return Ok(()); 223 } 224 create_dir(kobj: Arc<dyn KObject>) -> Result<(), SystemError>225 fn create_dir(kobj: Arc<dyn KObject>) -> Result<(), SystemError> { 226 // create dir in sysfs 227 sysfs_instance().create_dir(kobj.clone())?; 228 229 // create default attributes in sysfs 230 if let Some(ktype) = kobj.kobj_type() { 231 let groups = ktype.attribute_groups(); 232 if let Some(groups) = groups { 233 let r = sysfs_instance().create_groups(&kobj, groups); 234 if let Err(e) = r { 235 sysfs_instance().remove_dir(&kobj); 236 return Err(e); 237 } 238 } 239 } 240 241 return Ok(()); 242 } 243 244 /// 从sysfs中移除kobject remove_kobj(kobj: Arc<dyn KObject>)245 pub fn remove_kobj(kobj: Arc<dyn KObject>) { 246 let ktype = kobj.kobj_type(); 247 if let Some(ktype) = ktype { 248 if let Some(groups) = ktype.attribute_groups() { 249 sysfs_instance().remove_groups(&kobj, groups); 250 } 251 } 252 253 // todo: 发送uevent: KOBJ_REMOVE 254 255 sysfs_instance().remove_dir(&kobj); 256 kobj.update_kobj_state(None, Some(KObjectState::IN_SYSFS)); 257 let kset = kobj.kset(); 258 if let Some(kset) = kset { 259 kset.leave(&kobj); 260 } 261 kobj.set_parent(None); 262 } 263 } 264 265 /// 动态创建的kobject对象的ktype 266 #[derive(Debug)] 267 pub struct DynamicKObjKType; 268 269 impl KObjType for DynamicKObjKType { release(&self, kobj: Arc<dyn KObject>)270 fn release(&self, kobj: Arc<dyn KObject>) { 271 debug!("DynamicKObjKType::release() kobj:{:?}", kobj.name()); 272 } 273 sysfs_ops(&self) -> Option<&dyn SysFSOps>274 fn sysfs_ops(&self) -> Option<&dyn SysFSOps> { 275 Some(&KObjectSysFSOps) 276 } 277 attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]>278 fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { 279 None 280 } 281 } 282