xref: /DragonOS/kernel/src/driver/base/kobject.rs (revision 1074eb34e784aa2adfc5b9e0d89fa4b7e6ea03ef)
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;
906d5e247SLoGin 
1006d5e247SLoGin use crate::{
1106d5e247SLoGin     filesystem::{
1206d5e247SLoGin         kernfs::KernFSInode,
1306d5e247SLoGin         sysfs::{sysfs_instance, Attribute, AttributeGroup, SysFSOps, SysFSOpsSupport},
1406d5e247SLoGin     },
1506d5e247SLoGin     kerror,
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 {
2706d5e247SLoGin     fn as_any_ref(&self) -> &dyn core::any::Any;
2806d5e247SLoGin 
2906d5e247SLoGin     /// 设置当前kobject对应的sysfs inode(类型为KernFSInode)
3006d5e247SLoGin     fn set_inode(&self, inode: Option<Arc<KernFSInode>>);
3106d5e247SLoGin 
3206d5e247SLoGin     /// 获取当前kobject对应的sysfs inode(类型为KernFSInode)
3306d5e247SLoGin     fn inode(&self) -> Option<Arc<KernFSInode>>;
3406d5e247SLoGin 
3506d5e247SLoGin     fn parent(&self) -> Option<Weak<dyn KObject>>;
3606d5e247SLoGin 
3706d5e247SLoGin     /// 设置当前kobject的parent kobject(不一定与kset相同)
3806d5e247SLoGin     fn set_parent(&self, parent: Option<Weak<dyn KObject>>);
3906d5e247SLoGin 
4006d5e247SLoGin     /// 当前kobject属于哪个kset
4106d5e247SLoGin     fn kset(&self) -> Option<Arc<KSet>>;
4206d5e247SLoGin 
4306d5e247SLoGin     /// 设置当前kobject所属的kset
4406d5e247SLoGin     fn set_kset(&self, kset: Option<Arc<KSet>>);
4506d5e247SLoGin 
4606d5e247SLoGin     fn kobj_type(&self) -> Option<&'static dyn KObjType>;
4706d5e247SLoGin 
48a03c4f9dSLoGin     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>);
49a03c4f9dSLoGin 
5006d5e247SLoGin     fn name(&self) -> String;
5106d5e247SLoGin 
5206d5e247SLoGin     fn set_name(&self, name: String);
5306d5e247SLoGin 
5406d5e247SLoGin     fn kobj_state(&self) -> RwLockReadGuard<KObjectState>;
5506d5e247SLoGin 
5606d5e247SLoGin     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>;
5706d5e247SLoGin 
5806d5e247SLoGin     fn set_kobj_state(&self, state: KObjectState);
5906d5e247SLoGin }
6006d5e247SLoGin 
6106d5e247SLoGin impl dyn KObject {
6206d5e247SLoGin     /// 更新kobject的状态
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 {
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 {
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被释放时,设备驱动模型会调用此方法
9406d5e247SLoGin     fn release(&self, _kobj: Arc<dyn KObject>) {}
9506d5e247SLoGin     fn sysfs_ops(&self) -> Option<&dyn SysFSOps>;
9606d5e247SLoGin 
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 {
114a03c4f9dSLoGin     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 
12306d5e247SLoGin     fn deref(&self) -> &Self::Target {
12406d5e247SLoGin         &self.0
12506d5e247SLoGin     }
12606d5e247SLoGin }
12706d5e247SLoGin 
128c566df45SLoGin impl Default for LockedKObjectState {
129c566df45SLoGin     fn default() -> Self {
130c566df45SLoGin         LockedKObjectState::new(None)
131c566df45SLoGin     }
13206d5e247SLoGin }
13306d5e247SLoGin 
13406d5e247SLoGin #[derive(Debug)]
13506d5e247SLoGin pub struct KObjectSysFSOps;
13606d5e247SLoGin 
13706d5e247SLoGin impl SysFSOps for KObjectSysFSOps {
13806d5e247SLoGin     fn support(&self, attr: &dyn Attribute) -> SysFSOpsSupport {
13906d5e247SLoGin         return attr.support();
14006d5e247SLoGin     }
14106d5e247SLoGin 
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| {
149*1074eb34SSamuel Dai             if e == SystemError::ENOSYS {
15006d5e247SLoGin                 SystemError::EIO
15106d5e247SLoGin             } else {
15206d5e247SLoGin                 e
15306d5e247SLoGin             }
15406d5e247SLoGin         });
15506d5e247SLoGin 
15606d5e247SLoGin         return r;
15706d5e247SLoGin     }
15806d5e247SLoGin 
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| {
166*1074eb34SSamuel 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 {
1817eda31b2SLoGin     #[allow(dead_code)]
1827eda31b2SLoGin     pub fn init_and_add_kobj(
1837eda31b2SLoGin         kobj: Arc<dyn KObject>,
1847eda31b2SLoGin         join_kset: Option<Arc<KSet>>,
1857eda31b2SLoGin     ) -> Result<(), SystemError> {
1867eda31b2SLoGin         Self::kobj_init(&kobj);
1877eda31b2SLoGin         Self::add_kobj(kobj, join_kset)
1887eda31b2SLoGin     }
1897eda31b2SLoGin 
1907eda31b2SLoGin     #[allow(dead_code)]
1917eda31b2SLoGin     pub fn kobj_init(kobj: &Arc<dyn KObject>) {
1927eda31b2SLoGin         kobj.set_kobj_type(Some(&DynamicKObjKType));
1937eda31b2SLoGin     }
1947eda31b2SLoGin 
19506d5e247SLoGin     pub fn add_kobj(
19606d5e247SLoGin         kobj: Arc<dyn KObject>,
19706d5e247SLoGin         join_kset: Option<Arc<KSet>>,
19806d5e247SLoGin     ) -> Result<(), SystemError> {
199b5b571e0SLoGin         if let Some(kset) = join_kset {
20006d5e247SLoGin             kset.join(&kobj);
20106d5e247SLoGin             // 如果kobject没有parent,那么就将这个kset作为parent
20206d5e247SLoGin             if kobj.parent().is_none() {
20306d5e247SLoGin                 kobj.set_parent(Some(Arc::downgrade(&(kset as Arc<dyn KObject>))));
20406d5e247SLoGin             }
20506d5e247SLoGin         }
20606d5e247SLoGin 
20706d5e247SLoGin         let r = Self::create_dir(kobj.clone());
20806d5e247SLoGin 
20906d5e247SLoGin         if let Err(e) = r {
210e7071df6SLoGin             // https://code.dragonos.org.cn/xref/linux-6.1.9/lib/kobject.c?r=&mo=10426&fi=394#224
21106d5e247SLoGin             if let Some(kset) = kobj.kset() {
21206d5e247SLoGin                 kset.leave(&kobj);
21306d5e247SLoGin             }
21406d5e247SLoGin             kobj.set_parent(None);
21506d5e247SLoGin             if e == SystemError::EEXIST {
21606d5e247SLoGin                 kerror!("KObjectManager::add_kobj() failed with error: {e:?}, kobj:{kobj:?}");
21706d5e247SLoGin             }
21806d5e247SLoGin 
21906d5e247SLoGin             return Err(e);
22006d5e247SLoGin         }
22106d5e247SLoGin 
22206d5e247SLoGin         kobj.update_kobj_state(Some(KObjectState::IN_SYSFS), None);
22306d5e247SLoGin         return Ok(());
22406d5e247SLoGin     }
22506d5e247SLoGin 
22606d5e247SLoGin     fn create_dir(kobj: Arc<dyn KObject>) -> Result<(), SystemError> {
22706d5e247SLoGin         // create dir in sysfs
22806d5e247SLoGin         sysfs_instance().create_dir(kobj.clone())?;
22906d5e247SLoGin 
23006d5e247SLoGin         // create default attributes in sysfs
23106d5e247SLoGin         if let Some(ktype) = kobj.kobj_type() {
23206d5e247SLoGin             let groups = ktype.attribute_groups();
23306d5e247SLoGin             if let Some(groups) = groups {
23406d5e247SLoGin                 let r = sysfs_instance().create_groups(&kobj, groups);
23506d5e247SLoGin                 if let Err(e) = r {
23606d5e247SLoGin                     sysfs_instance().remove_dir(&kobj);
23706d5e247SLoGin                     return Err(e);
23806d5e247SLoGin                 }
23906d5e247SLoGin             }
24006d5e247SLoGin         }
24106d5e247SLoGin 
24206d5e247SLoGin         return Ok(());
24306d5e247SLoGin     }
24408a2ee40SLoGin 
24508a2ee40SLoGin     /// 从sysfs中移除kobject
24608a2ee40SLoGin     pub fn remove_kobj(kobj: Arc<dyn KObject>) {
24708a2ee40SLoGin         let ktype = kobj.kobj_type();
24808a2ee40SLoGin         if let Some(ktype) = ktype {
24908a2ee40SLoGin             if let Some(groups) = ktype.attribute_groups() {
25008a2ee40SLoGin                 sysfs_instance().remove_groups(&kobj, groups);
25108a2ee40SLoGin             }
25208a2ee40SLoGin         }
25308a2ee40SLoGin 
25408a2ee40SLoGin         // todo: 发送uevent: KOBJ_REMOVE
25508a2ee40SLoGin 
25608a2ee40SLoGin         sysfs_instance().remove_dir(&kobj);
25708a2ee40SLoGin         kobj.update_kobj_state(None, Some(KObjectState::IN_SYSFS));
25808a2ee40SLoGin         let kset = kobj.kset();
25908a2ee40SLoGin         if let Some(kset) = kset {
26008a2ee40SLoGin             kset.leave(&kobj);
26108a2ee40SLoGin         }
26208a2ee40SLoGin         kobj.set_parent(None);
26308a2ee40SLoGin     }
26406d5e247SLoGin }
2657eda31b2SLoGin 
2667eda31b2SLoGin /// 动态创建的kobject对象的ktype
2677eda31b2SLoGin #[derive(Debug)]
2687eda31b2SLoGin pub struct DynamicKObjKType;
2697eda31b2SLoGin 
2707eda31b2SLoGin impl KObjType for DynamicKObjKType {
2717eda31b2SLoGin     fn release(&self, kobj: Arc<dyn KObject>) {
2727eda31b2SLoGin         kdebug!("DynamicKObjKType::release() kobj:{:?}", kobj.name());
2737eda31b2SLoGin     }
2747eda31b2SLoGin 
2757eda31b2SLoGin     fn sysfs_ops(&self) -> Option<&dyn SysFSOps> {
2767eda31b2SLoGin         Some(&KObjectSysFSOps)
2777eda31b2SLoGin     }
2787eda31b2SLoGin 
2797eda31b2SLoGin     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
2807eda31b2SLoGin         None
2817eda31b2SLoGin     }
2827eda31b2SLoGin }
283