xref: /DragonOS/kernel/src/driver/base/kobject.rs (revision 28fe4ad2a0b0d8b5abf1f0cb402b1c3204b42242)
106d5e247SLoGin use core::{any::Any, fmt::Debug, hash::Hash, ops::Deref};
206d5e247SLoGin 
306d5e247SLoGin use alloc::{
406d5e247SLoGin     string::String,
506d5e247SLoGin     sync::{Arc, Weak},
606d5e247SLoGin };
7da152319SLoGin use driver_base_macros::get_weak_or_clear;
806d5e247SLoGin use intertrait::CastFromSync;
92eab6dd7S曾俊 use log::{debug, error};
1006d5e247SLoGin 
1106d5e247SLoGin use crate::{
1206d5e247SLoGin     filesystem::{
1306d5e247SLoGin         kernfs::KernFSInode,
1406d5e247SLoGin         sysfs::{sysfs_instance, Attribute, AttributeGroup, SysFSOps, SysFSOpsSupport},
1506d5e247SLoGin     },
1606d5e247SLoGin     libs::{
1706d5e247SLoGin         casting::DowncastArc,
1806d5e247SLoGin         rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
1906d5e247SLoGin     },
2006d5e247SLoGin };
2106d5e247SLoGin 
2291e9d4abSLoGin use system_error::SystemError;
2391e9d4abSLoGin 
2406d5e247SLoGin use super::kset::KSet;
2506d5e247SLoGin 
2606d5e247SLoGin pub trait KObject: Any + Send + Sync + Debug + CastFromSync {
as_any_ref(&self) -> &dyn core::any::Any2706d5e247SLoGin     fn as_any_ref(&self) -> &dyn core::any::Any;
2806d5e247SLoGin 
2906d5e247SLoGin     /// 设置当前kobject对应的sysfs inode(类型为KernFSInode)
set_inode(&self, inode: Option<Arc<KernFSInode>>)3006d5e247SLoGin     fn set_inode(&self, inode: Option<Arc<KernFSInode>>);
3106d5e247SLoGin 
3206d5e247SLoGin     /// 获取当前kobject对应的sysfs inode(类型为KernFSInode)
inode(&self) -> Option<Arc<KernFSInode>>3306d5e247SLoGin     fn inode(&self) -> Option<Arc<KernFSInode>>;
3406d5e247SLoGin 
parent(&self) -> Option<Weak<dyn KObject>>3506d5e247SLoGin     fn parent(&self) -> Option<Weak<dyn KObject>>;
3606d5e247SLoGin 
3706d5e247SLoGin     /// 设置当前kobject的parent kobject(不一定与kset相同)
set_parent(&self, parent: Option<Weak<dyn KObject>>)3806d5e247SLoGin     fn set_parent(&self, parent: Option<Weak<dyn KObject>>);
3906d5e247SLoGin 
4006d5e247SLoGin     /// 当前kobject属于哪个kset
kset(&self) -> Option<Arc<KSet>>4106d5e247SLoGin     fn kset(&self) -> Option<Arc<KSet>>;
4206d5e247SLoGin 
4306d5e247SLoGin     /// 设置当前kobject所属的kset
set_kset(&self, kset: Option<Arc<KSet>>)4406d5e247SLoGin     fn set_kset(&self, kset: Option<Arc<KSet>>);
4506d5e247SLoGin 
kobj_type(&self) -> Option<&'static dyn KObjType>4606d5e247SLoGin     fn kobj_type(&self) -> Option<&'static dyn KObjType>;
4706d5e247SLoGin 
set_kobj_type(&self, ktype: Option<&'static dyn KObjType>)48a03c4f9dSLoGin     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>);
49a03c4f9dSLoGin 
name(&self) -> String5006d5e247SLoGin     fn name(&self) -> String;
5106d5e247SLoGin 
set_name(&self, name: String)5206d5e247SLoGin     fn set_name(&self, name: String);
5306d5e247SLoGin 
kobj_state(&self) -> RwLockReadGuard<KObjectState>5406d5e247SLoGin     fn kobj_state(&self) -> RwLockReadGuard<KObjectState>;
5506d5e247SLoGin 
kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>5606d5e247SLoGin     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>;
5706d5e247SLoGin 
set_kobj_state(&self, state: KObjectState)5806d5e247SLoGin     fn set_kobj_state(&self, state: KObjectState);
5906d5e247SLoGin }
6006d5e247SLoGin 
6106d5e247SLoGin impl dyn KObject {
6206d5e247SLoGin     /// 更新kobject的状态
update_kobj_state(&self, insert: Option<KObjectState>, remove: Option<KObjectState>)6306d5e247SLoGin     pub fn update_kobj_state(&self, insert: Option<KObjectState>, remove: Option<KObjectState>) {
6406d5e247SLoGin         let insert = insert.unwrap_or(KObjectState::empty());
6506d5e247SLoGin         let remove = remove.unwrap_or(KObjectState::empty());
6606d5e247SLoGin         let mut state = self.kobj_state_mut();
6706d5e247SLoGin         *state = (*state | insert) & !remove;
6806d5e247SLoGin     }
6906d5e247SLoGin }
7006d5e247SLoGin 
7106d5e247SLoGin impl DowncastArc for dyn KObject {
as_any_arc(self: Arc<Self>) -> Arc<dyn Any>7206d5e247SLoGin     fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any> {
7306d5e247SLoGin         self
7406d5e247SLoGin     }
7506d5e247SLoGin }
7606d5e247SLoGin 
77da152319SLoGin /// kobject的公共数据
78da152319SLoGin #[derive(Debug, Default)]
79da152319SLoGin pub struct KObjectCommonData {
80da152319SLoGin     pub kern_inode: Option<Arc<KernFSInode>>,
81da152319SLoGin     pub parent: Option<Weak<dyn KObject>>,
82da152319SLoGin     pub kset: Option<Arc<KSet>>,
83da152319SLoGin     pub kobj_type: Option<&'static dyn KObjType>,
84da152319SLoGin }
85da152319SLoGin 
86da152319SLoGin impl KObjectCommonData {
get_parent_or_clear_weak(&mut self) -> Option<Weak<dyn KObject>>87da152319SLoGin     pub fn get_parent_or_clear_weak(&mut self) -> Option<Weak<dyn KObject>> {
88da152319SLoGin         get_weak_or_clear!(self.parent)
89da152319SLoGin     }
90da152319SLoGin }
91da152319SLoGin 
92a03c4f9dSLoGin pub trait KObjType: Debug + Send + Sync {
9308a2ee40SLoGin     /// 当指定的kobject被释放时,设备驱动模型会调用此方法
release(&self, _kobj: Arc<dyn KObject>)9406d5e247SLoGin     fn release(&self, _kobj: Arc<dyn KObject>) {}
sysfs_ops(&self) -> Option<&dyn SysFSOps>9506d5e247SLoGin     fn sysfs_ops(&self) -> Option<&dyn SysFSOps>;
9606d5e247SLoGin 
attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]>9706d5e247SLoGin     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]>;
9806d5e247SLoGin }
9906d5e247SLoGin 
10006d5e247SLoGin bitflags! {
10106d5e247SLoGin     pub struct KObjectState: u32 {
10206d5e247SLoGin         const IN_SYSFS = 1 << 0;
10306d5e247SLoGin         const ADD_UEVENT_SENT = 1 << 1;
10406d5e247SLoGin         const REMOVE_UEVENT_SENT = 1 << 2;
10506d5e247SLoGin         const INITIALIZED = 1 << 3;
10606d5e247SLoGin     }
10706d5e247SLoGin 
10806d5e247SLoGin }
10906d5e247SLoGin 
11006d5e247SLoGin #[derive(Debug)]
11106d5e247SLoGin pub struct LockedKObjectState(RwLock<KObjectState>);
11206d5e247SLoGin 
11306d5e247SLoGin impl LockedKObjectState {
new(state: Option<KObjectState>) -> LockedKObjectState114a03c4f9dSLoGin     pub fn new(state: Option<KObjectState>) -> LockedKObjectState {
115a03c4f9dSLoGin         let state = state.unwrap_or(KObjectState::empty());
11606d5e247SLoGin         LockedKObjectState(RwLock::new(state))
11706d5e247SLoGin     }
11806d5e247SLoGin }
11906d5e247SLoGin 
12006d5e247SLoGin impl Deref for LockedKObjectState {
12106d5e247SLoGin     type Target = RwLock<KObjectState>;
12206d5e247SLoGin 
deref(&self) -> &Self::Target12306d5e247SLoGin     fn deref(&self) -> &Self::Target {
12406d5e247SLoGin         &self.0
12506d5e247SLoGin     }
12606d5e247SLoGin }
12706d5e247SLoGin 
128c566df45SLoGin impl Default for LockedKObjectState {
default() -> Self129c566df45SLoGin     fn default() -> Self {
130c566df45SLoGin         LockedKObjectState::new(None)
131c566df45SLoGin     }
13206d5e247SLoGin }
13306d5e247SLoGin 
13406d5e247SLoGin #[derive(Debug)]
13506d5e247SLoGin pub struct KObjectSysFSOps;
13606d5e247SLoGin 
13706d5e247SLoGin impl SysFSOps for KObjectSysFSOps {
support(&self, attr: &dyn Attribute) -> SysFSOpsSupport13806d5e247SLoGin     fn support(&self, attr: &dyn Attribute) -> SysFSOpsSupport {
13906d5e247SLoGin         return attr.support();
14006d5e247SLoGin     }
14106d5e247SLoGin 
show( &self, kobj: Arc<dyn KObject>, attr: &dyn Attribute, buf: &mut [u8], ) -> Result<usize, SystemError>14206d5e247SLoGin     fn show(
14306d5e247SLoGin         &self,
14406d5e247SLoGin         kobj: Arc<dyn KObject>,
14506d5e247SLoGin         attr: &dyn Attribute,
14606d5e247SLoGin         buf: &mut [u8],
14706d5e247SLoGin     ) -> Result<usize, SystemError> {
14806d5e247SLoGin         let r = attr.show(kobj, buf).map_err(|e| {
1491074eb34SSamuel Dai             if e == SystemError::ENOSYS {
15006d5e247SLoGin                 SystemError::EIO
15106d5e247SLoGin             } else {
15206d5e247SLoGin                 e
15306d5e247SLoGin             }
15406d5e247SLoGin         });
15506d5e247SLoGin 
15606d5e247SLoGin         return r;
15706d5e247SLoGin     }
15806d5e247SLoGin 
store( &self, kobj: Arc<dyn KObject>, attr: &dyn Attribute, buf: &[u8], ) -> Result<usize, SystemError>15906d5e247SLoGin     fn store(
16006d5e247SLoGin         &self,
16106d5e247SLoGin         kobj: Arc<dyn KObject>,
16206d5e247SLoGin         attr: &dyn Attribute,
16306d5e247SLoGin         buf: &[u8],
16406d5e247SLoGin     ) -> Result<usize, SystemError> {
16506d5e247SLoGin         let r = attr.store(kobj, buf).map_err(|e| {
1661074eb34SSamuel Dai             if e == SystemError::ENOSYS {
16706d5e247SLoGin                 SystemError::EIO
16806d5e247SLoGin             } else {
16906d5e247SLoGin                 e
17006d5e247SLoGin             }
17106d5e247SLoGin         });
17206d5e247SLoGin 
17306d5e247SLoGin         return r;
17406d5e247SLoGin     }
17506d5e247SLoGin }
17606d5e247SLoGin 
17706d5e247SLoGin #[derive(Debug)]
17806d5e247SLoGin pub struct KObjectManager;
17906d5e247SLoGin 
18006d5e247SLoGin impl KObjectManager {
init_and_add_kobj( kobj: Arc<dyn KObject>, join_kset: Option<Arc<KSet>>, kobj_type: Option<&'static dyn KObjType>, ) -> Result<(), SystemError>1817eda31b2SLoGin     pub fn init_and_add_kobj(
1827eda31b2SLoGin         kobj: Arc<dyn KObject>,
1837eda31b2SLoGin         join_kset: Option<Arc<KSet>>,
184*28fe4ad2S黄铭涛         kobj_type: Option<&'static dyn KObjType>,
1857eda31b2SLoGin     ) -> Result<(), SystemError> {
186*28fe4ad2S黄铭涛         Self::kobj_init(&kobj, kobj_type);
1877eda31b2SLoGin         Self::add_kobj(kobj, join_kset)
1887eda31b2SLoGin     }
1897eda31b2SLoGin 
kobj_init(kobj: &Arc<dyn KObject>, kobj_type: Option<&'static dyn KObjType>)190*28fe4ad2S黄铭涛     pub fn kobj_init(kobj: &Arc<dyn KObject>, kobj_type: Option<&'static dyn KObjType>) {
191*28fe4ad2S黄铭涛         kobj.set_kobj_type(kobj_type);
1927eda31b2SLoGin     }
1937eda31b2SLoGin 
add_kobj( kobj: Arc<dyn KObject>, join_kset: Option<Arc<KSet>>, ) -> Result<(), SystemError>19406d5e247SLoGin     pub fn add_kobj(
19506d5e247SLoGin         kobj: Arc<dyn KObject>,
19606d5e247SLoGin         join_kset: Option<Arc<KSet>>,
19706d5e247SLoGin     ) -> Result<(), SystemError> {
198b5b571e0SLoGin         if let Some(kset) = join_kset {
19906d5e247SLoGin             kset.join(&kobj);
20006d5e247SLoGin             // 如果kobject没有parent,那么就将这个kset作为parent
20106d5e247SLoGin             if kobj.parent().is_none() {
20206d5e247SLoGin                 kobj.set_parent(Some(Arc::downgrade(&(kset as Arc<dyn KObject>))));
20306d5e247SLoGin             }
20406d5e247SLoGin         }
20506d5e247SLoGin 
20606d5e247SLoGin         let r = Self::create_dir(kobj.clone());
20706d5e247SLoGin 
20806d5e247SLoGin         if let Err(e) = r {
209e7071df6SLoGin             // https://code.dragonos.org.cn/xref/linux-6.1.9/lib/kobject.c?r=&mo=10426&fi=394#224
21006d5e247SLoGin             if let Some(kset) = kobj.kset() {
21106d5e247SLoGin                 kset.leave(&kobj);
21206d5e247SLoGin             }
21306d5e247SLoGin             kobj.set_parent(None);
21406d5e247SLoGin             if e == SystemError::EEXIST {
2152eab6dd7S曾俊                 error!("KObjectManager::add_kobj() failed with error: {e:?}, kobj:{kobj:?}");
21606d5e247SLoGin             }
21706d5e247SLoGin 
21806d5e247SLoGin             return Err(e);
21906d5e247SLoGin         }
22006d5e247SLoGin 
22106d5e247SLoGin         kobj.update_kobj_state(Some(KObjectState::IN_SYSFS), None);
22206d5e247SLoGin         return Ok(());
22306d5e247SLoGin     }
22406d5e247SLoGin 
create_dir(kobj: Arc<dyn KObject>) -> Result<(), SystemError>22506d5e247SLoGin     fn create_dir(kobj: Arc<dyn KObject>) -> Result<(), SystemError> {
22606d5e247SLoGin         // create dir in sysfs
22706d5e247SLoGin         sysfs_instance().create_dir(kobj.clone())?;
22806d5e247SLoGin 
22906d5e247SLoGin         // create default attributes in sysfs
23006d5e247SLoGin         if let Some(ktype) = kobj.kobj_type() {
23106d5e247SLoGin             let groups = ktype.attribute_groups();
23206d5e247SLoGin             if let Some(groups) = groups {
23306d5e247SLoGin                 let r = sysfs_instance().create_groups(&kobj, groups);
23406d5e247SLoGin                 if let Err(e) = r {
23506d5e247SLoGin                     sysfs_instance().remove_dir(&kobj);
23606d5e247SLoGin                     return Err(e);
23706d5e247SLoGin                 }
23806d5e247SLoGin             }
23906d5e247SLoGin         }
24006d5e247SLoGin 
24106d5e247SLoGin         return Ok(());
24206d5e247SLoGin     }
24308a2ee40SLoGin 
24408a2ee40SLoGin     /// 从sysfs中移除kobject
remove_kobj(kobj: Arc<dyn KObject>)24508a2ee40SLoGin     pub fn remove_kobj(kobj: Arc<dyn KObject>) {
24608a2ee40SLoGin         let ktype = kobj.kobj_type();
24708a2ee40SLoGin         if let Some(ktype) = ktype {
24808a2ee40SLoGin             if let Some(groups) = ktype.attribute_groups() {
24908a2ee40SLoGin                 sysfs_instance().remove_groups(&kobj, groups);
25008a2ee40SLoGin             }
25108a2ee40SLoGin         }
25208a2ee40SLoGin 
25308a2ee40SLoGin         // todo: 发送uevent: KOBJ_REMOVE
25408a2ee40SLoGin 
25508a2ee40SLoGin         sysfs_instance().remove_dir(&kobj);
25608a2ee40SLoGin         kobj.update_kobj_state(None, Some(KObjectState::IN_SYSFS));
25708a2ee40SLoGin         let kset = kobj.kset();
25808a2ee40SLoGin         if let Some(kset) = kset {
25908a2ee40SLoGin             kset.leave(&kobj);
26008a2ee40SLoGin         }
26108a2ee40SLoGin         kobj.set_parent(None);
26208a2ee40SLoGin     }
26306d5e247SLoGin }
2647eda31b2SLoGin 
2657eda31b2SLoGin /// 动态创建的kobject对象的ktype
2667eda31b2SLoGin #[derive(Debug)]
2677eda31b2SLoGin pub struct DynamicKObjKType;
2687eda31b2SLoGin 
2697eda31b2SLoGin impl KObjType for DynamicKObjKType {
release(&self, kobj: Arc<dyn KObject>)2707eda31b2SLoGin     fn release(&self, kobj: Arc<dyn KObject>) {
2712eab6dd7S曾俊         debug!("DynamicKObjKType::release() kobj:{:?}", kobj.name());
2727eda31b2SLoGin     }
2737eda31b2SLoGin 
sysfs_ops(&self) -> Option<&dyn SysFSOps>2747eda31b2SLoGin     fn sysfs_ops(&self) -> Option<&dyn SysFSOps> {
2757eda31b2SLoGin         Some(&KObjectSysFSOps)
2767eda31b2SLoGin     }
2777eda31b2SLoGin 
attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]>2787eda31b2SLoGin     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
2797eda31b2SLoGin         None
2807eda31b2SLoGin     }
2817eda31b2SLoGin }
282