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 10 use crate::{ 11 filesystem::{ 12 kernfs::KernFSInode, 13 sysfs::{sysfs_instance, Attribute, AttributeGroup, SysFSOps, SysFSOpsSupport}, 14 }, 15 kerror, 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 { 27 fn as_any_ref(&self) -> &dyn core::any::Any; 28 29 /// 设置当前kobject对应的sysfs inode(类型为KernFSInode) 30 fn set_inode(&self, inode: Option<Arc<KernFSInode>>); 31 32 /// 获取当前kobject对应的sysfs inode(类型为KernFSInode) 33 fn inode(&self) -> Option<Arc<KernFSInode>>; 34 35 fn parent(&self) -> Option<Weak<dyn KObject>>; 36 37 /// 设置当前kobject的parent kobject(不一定与kset相同) 38 fn set_parent(&self, parent: Option<Weak<dyn KObject>>); 39 40 /// 当前kobject属于哪个kset 41 fn kset(&self) -> Option<Arc<KSet>>; 42 43 /// 设置当前kobject所属的kset 44 fn set_kset(&self, kset: Option<Arc<KSet>>); 45 46 fn kobj_type(&self) -> Option<&'static dyn KObjType>; 47 48 fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>); 49 50 fn name(&self) -> String; 51 52 fn set_name(&self, name: String); 53 54 fn kobj_state(&self) -> RwLockReadGuard<KObjectState>; 55 56 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>; 57 58 fn set_kobj_state(&self, state: KObjectState); 59 } 60 61 impl dyn KObject { 62 /// 更新kobject的状态 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 { 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 { 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被释放时,设备驱动模型会调用此方法 94 fn release(&self, _kobj: Arc<dyn KObject>) {} 95 fn sysfs_ops(&self) -> Option<&dyn SysFSOps>; 96 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 { 114 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 123 fn deref(&self) -> &Self::Target { 124 &self.0 125 } 126 } 127 128 impl Default for LockedKObjectState { 129 fn default() -> Self { 130 LockedKObjectState::new(None) 131 } 132 } 133 134 #[derive(Debug)] 135 pub struct KObjectSysFSOps; 136 137 impl SysFSOps for KObjectSysFSOps { 138 fn support(&self, attr: &dyn Attribute) -> SysFSOpsSupport { 139 return attr.support(); 140 } 141 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 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 { 181 #[allow(dead_code)] 182 pub fn init_and_add_kobj( 183 kobj: Arc<dyn KObject>, 184 join_kset: Option<Arc<KSet>>, 185 ) -> Result<(), SystemError> { 186 Self::kobj_init(&kobj); 187 Self::add_kobj(kobj, join_kset) 188 } 189 190 #[allow(dead_code)] 191 pub fn kobj_init(kobj: &Arc<dyn KObject>) { 192 kobj.set_kobj_type(Some(&DynamicKObjKType)); 193 } 194 195 pub fn add_kobj( 196 kobj: Arc<dyn KObject>, 197 join_kset: Option<Arc<KSet>>, 198 ) -> Result<(), SystemError> { 199 if let Some(kset) = join_kset { 200 kset.join(&kobj); 201 // 如果kobject没有parent,那么就将这个kset作为parent 202 if kobj.parent().is_none() { 203 kobj.set_parent(Some(Arc::downgrade(&(kset as Arc<dyn KObject>)))); 204 } 205 } 206 207 let r = Self::create_dir(kobj.clone()); 208 209 if let Err(e) = r { 210 // https://code.dragonos.org.cn/xref/linux-6.1.9/lib/kobject.c?r=&mo=10426&fi=394#224 211 if let Some(kset) = kobj.kset() { 212 kset.leave(&kobj); 213 } 214 kobj.set_parent(None); 215 if e == SystemError::EEXIST { 216 kerror!("KObjectManager::add_kobj() failed with error: {e:?}, kobj:{kobj:?}"); 217 } 218 219 return Err(e); 220 } 221 222 kobj.update_kobj_state(Some(KObjectState::IN_SYSFS), None); 223 return Ok(()); 224 } 225 226 fn create_dir(kobj: Arc<dyn KObject>) -> Result<(), SystemError> { 227 // create dir in sysfs 228 sysfs_instance().create_dir(kobj.clone())?; 229 230 // create default attributes in sysfs 231 if let Some(ktype) = kobj.kobj_type() { 232 let groups = ktype.attribute_groups(); 233 if let Some(groups) = groups { 234 let r = sysfs_instance().create_groups(&kobj, groups); 235 if let Err(e) = r { 236 sysfs_instance().remove_dir(&kobj); 237 return Err(e); 238 } 239 } 240 } 241 242 return Ok(()); 243 } 244 245 /// 从sysfs中移除kobject 246 pub fn remove_kobj(kobj: Arc<dyn KObject>) { 247 let ktype = kobj.kobj_type(); 248 if let Some(ktype) = ktype { 249 if let Some(groups) = ktype.attribute_groups() { 250 sysfs_instance().remove_groups(&kobj, groups); 251 } 252 } 253 254 // todo: 发送uevent: KOBJ_REMOVE 255 256 sysfs_instance().remove_dir(&kobj); 257 kobj.update_kobj_state(None, Some(KObjectState::IN_SYSFS)); 258 let kset = kobj.kset(); 259 if let Some(kset) = kset { 260 kset.leave(&kobj); 261 } 262 kobj.set_parent(None); 263 } 264 } 265 266 /// 动态创建的kobject对象的ktype 267 #[derive(Debug)] 268 pub struct DynamicKObjKType; 269 270 impl KObjType for DynamicKObjKType { 271 fn release(&self, kobj: Arc<dyn KObject>) { 272 kdebug!("DynamicKObjKType::release() kobj:{:?}", kobj.name()); 273 } 274 275 fn sysfs_ops(&self) -> Option<&dyn SysFSOps> { 276 Some(&KObjectSysFSOps) 277 } 278 279 fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { 280 None 281 } 282 } 283