xref: /DragonOS/kernel/src/driver/base/kobject.rs (revision c566df451ce6dbf2af684333e68b39fdfff86498)
106d5e247SLoGin use core::{any::Any, fmt::Debug, hash::Hash, ops::Deref};
206d5e247SLoGin 
306d5e247SLoGin use alloc::{
406d5e247SLoGin     string::String,
506d5e247SLoGin     sync::{Arc, Weak},
606d5e247SLoGin };
706d5e247SLoGin use intertrait::CastFromSync;
806d5e247SLoGin 
906d5e247SLoGin use crate::{
1006d5e247SLoGin     filesystem::{
1106d5e247SLoGin         kernfs::KernFSInode,
1206d5e247SLoGin         sysfs::{sysfs_instance, Attribute, AttributeGroup, SysFSOps, SysFSOpsSupport},
1306d5e247SLoGin     },
1406d5e247SLoGin     kerror,
1506d5e247SLoGin     libs::{
1606d5e247SLoGin         casting::DowncastArc,
1706d5e247SLoGin         rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
1806d5e247SLoGin     },
1906d5e247SLoGin };
2006d5e247SLoGin 
2191e9d4abSLoGin use system_error::SystemError;
2291e9d4abSLoGin 
2306d5e247SLoGin use super::kset::KSet;
2406d5e247SLoGin 
2506d5e247SLoGin pub trait KObject: Any + Send + Sync + Debug + CastFromSync {
2606d5e247SLoGin     fn as_any_ref(&self) -> &dyn core::any::Any;
2706d5e247SLoGin 
2806d5e247SLoGin     /// 设置当前kobject对应的sysfs inode(类型为KernFSInode)
2906d5e247SLoGin     fn set_inode(&self, inode: Option<Arc<KernFSInode>>);
3006d5e247SLoGin 
3106d5e247SLoGin     /// 获取当前kobject对应的sysfs inode(类型为KernFSInode)
3206d5e247SLoGin     fn inode(&self) -> Option<Arc<KernFSInode>>;
3306d5e247SLoGin 
3406d5e247SLoGin     fn parent(&self) -> Option<Weak<dyn KObject>>;
3506d5e247SLoGin 
3606d5e247SLoGin     /// 设置当前kobject的parent kobject(不一定与kset相同)
3706d5e247SLoGin     fn set_parent(&self, parent: Option<Weak<dyn KObject>>);
3806d5e247SLoGin 
3906d5e247SLoGin     /// 当前kobject属于哪个kset
4006d5e247SLoGin     fn kset(&self) -> Option<Arc<KSet>>;
4106d5e247SLoGin 
4206d5e247SLoGin     /// 设置当前kobject所属的kset
4306d5e247SLoGin     fn set_kset(&self, kset: Option<Arc<KSet>>);
4406d5e247SLoGin 
4506d5e247SLoGin     fn kobj_type(&self) -> Option<&'static dyn KObjType>;
4606d5e247SLoGin 
47a03c4f9dSLoGin     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>);
48a03c4f9dSLoGin 
4906d5e247SLoGin     fn name(&self) -> String;
5006d5e247SLoGin 
5106d5e247SLoGin     fn set_name(&self, name: String);
5206d5e247SLoGin 
5306d5e247SLoGin     fn kobj_state(&self) -> RwLockReadGuard<KObjectState>;
5406d5e247SLoGin 
5506d5e247SLoGin     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>;
5606d5e247SLoGin 
5706d5e247SLoGin     fn set_kobj_state(&self, state: KObjectState);
5806d5e247SLoGin }
5906d5e247SLoGin 
6006d5e247SLoGin impl dyn KObject {
6106d5e247SLoGin     /// 更新kobject的状态
6206d5e247SLoGin     pub fn update_kobj_state(&self, insert: Option<KObjectState>, remove: Option<KObjectState>) {
6306d5e247SLoGin         let insert = insert.unwrap_or(KObjectState::empty());
6406d5e247SLoGin         let remove = remove.unwrap_or(KObjectState::empty());
6506d5e247SLoGin         let mut state = self.kobj_state_mut();
6606d5e247SLoGin         *state = (*state | insert) & !remove;
6706d5e247SLoGin     }
6806d5e247SLoGin }
6906d5e247SLoGin 
7006d5e247SLoGin impl DowncastArc for dyn KObject {
7106d5e247SLoGin     fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any> {
7206d5e247SLoGin         self
7306d5e247SLoGin     }
7406d5e247SLoGin }
7506d5e247SLoGin 
76a03c4f9dSLoGin pub trait KObjType: Debug + Send + Sync {
7708a2ee40SLoGin     /// 当指定的kobject被释放时,设备驱动模型会调用此方法
7806d5e247SLoGin     fn release(&self, _kobj: Arc<dyn KObject>) {}
7906d5e247SLoGin     fn sysfs_ops(&self) -> Option<&dyn SysFSOps>;
8006d5e247SLoGin 
8106d5e247SLoGin     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]>;
8206d5e247SLoGin }
8306d5e247SLoGin 
8406d5e247SLoGin bitflags! {
8506d5e247SLoGin     pub struct KObjectState: u32 {
8606d5e247SLoGin         const IN_SYSFS = 1 << 0;
8706d5e247SLoGin         const ADD_UEVENT_SENT = 1 << 1;
8806d5e247SLoGin         const REMOVE_UEVENT_SENT = 1 << 2;
8906d5e247SLoGin         const INITIALIZED = 1 << 3;
9006d5e247SLoGin     }
9106d5e247SLoGin 
9206d5e247SLoGin }
9306d5e247SLoGin 
9406d5e247SLoGin #[derive(Debug)]
9506d5e247SLoGin pub struct LockedKObjectState(RwLock<KObjectState>);
9606d5e247SLoGin 
9706d5e247SLoGin impl LockedKObjectState {
98a03c4f9dSLoGin     pub fn new(state: Option<KObjectState>) -> LockedKObjectState {
99a03c4f9dSLoGin         let state = state.unwrap_or(KObjectState::empty());
10006d5e247SLoGin         LockedKObjectState(RwLock::new(state))
10106d5e247SLoGin     }
10206d5e247SLoGin }
10306d5e247SLoGin 
10406d5e247SLoGin impl Deref for LockedKObjectState {
10506d5e247SLoGin     type Target = RwLock<KObjectState>;
10606d5e247SLoGin 
10706d5e247SLoGin     fn deref(&self) -> &Self::Target {
10806d5e247SLoGin         &self.0
10906d5e247SLoGin     }
11006d5e247SLoGin }
11106d5e247SLoGin 
112*c566df45SLoGin impl Default for LockedKObjectState {
113*c566df45SLoGin     fn default() -> Self {
114*c566df45SLoGin         LockedKObjectState::new(None)
115*c566df45SLoGin     }
11606d5e247SLoGin }
11706d5e247SLoGin 
11806d5e247SLoGin #[derive(Debug)]
11906d5e247SLoGin pub struct KObjectSysFSOps;
12006d5e247SLoGin 
12106d5e247SLoGin impl SysFSOps for KObjectSysFSOps {
12206d5e247SLoGin     fn support(&self, attr: &dyn Attribute) -> SysFSOpsSupport {
12306d5e247SLoGin         return attr.support();
12406d5e247SLoGin     }
12506d5e247SLoGin 
12606d5e247SLoGin     fn show(
12706d5e247SLoGin         &self,
12806d5e247SLoGin         kobj: Arc<dyn KObject>,
12906d5e247SLoGin         attr: &dyn Attribute,
13006d5e247SLoGin         buf: &mut [u8],
13106d5e247SLoGin     ) -> Result<usize, SystemError> {
13206d5e247SLoGin         let r = attr.show(kobj, buf).map_err(|e| {
13306d5e247SLoGin             if e == SystemError::EOPNOTSUPP_OR_ENOTSUP {
13406d5e247SLoGin                 SystemError::EIO
13506d5e247SLoGin             } else {
13606d5e247SLoGin                 e
13706d5e247SLoGin             }
13806d5e247SLoGin         });
13906d5e247SLoGin 
14006d5e247SLoGin         return r;
14106d5e247SLoGin     }
14206d5e247SLoGin 
14306d5e247SLoGin     fn store(
14406d5e247SLoGin         &self,
14506d5e247SLoGin         kobj: Arc<dyn KObject>,
14606d5e247SLoGin         attr: &dyn Attribute,
14706d5e247SLoGin         buf: &[u8],
14806d5e247SLoGin     ) -> Result<usize, SystemError> {
14906d5e247SLoGin         let r = attr.store(kobj, buf).map_err(|e| {
15006d5e247SLoGin             if e == SystemError::EOPNOTSUPP_OR_ENOTSUP {
15106d5e247SLoGin                 SystemError::EIO
15206d5e247SLoGin             } else {
15306d5e247SLoGin                 e
15406d5e247SLoGin             }
15506d5e247SLoGin         });
15606d5e247SLoGin 
15706d5e247SLoGin         return r;
15806d5e247SLoGin     }
15906d5e247SLoGin }
16006d5e247SLoGin 
16106d5e247SLoGin #[derive(Debug)]
16206d5e247SLoGin pub struct KObjectManager;
16306d5e247SLoGin 
16406d5e247SLoGin impl KObjectManager {
1657eda31b2SLoGin     #[allow(dead_code)]
1667eda31b2SLoGin     pub fn init_and_add_kobj(
1677eda31b2SLoGin         kobj: Arc<dyn KObject>,
1687eda31b2SLoGin         join_kset: Option<Arc<KSet>>,
1697eda31b2SLoGin     ) -> Result<(), SystemError> {
1707eda31b2SLoGin         Self::kobj_init(&kobj);
1717eda31b2SLoGin         Self::add_kobj(kobj, join_kset)
1727eda31b2SLoGin     }
1737eda31b2SLoGin 
1747eda31b2SLoGin     #[allow(dead_code)]
1757eda31b2SLoGin     pub fn kobj_init(kobj: &Arc<dyn KObject>) {
1767eda31b2SLoGin         kobj.set_kobj_type(Some(&DynamicKObjKType));
1777eda31b2SLoGin     }
1787eda31b2SLoGin 
17906d5e247SLoGin     pub fn add_kobj(
18006d5e247SLoGin         kobj: Arc<dyn KObject>,
18106d5e247SLoGin         join_kset: Option<Arc<KSet>>,
18206d5e247SLoGin     ) -> Result<(), SystemError> {
18306d5e247SLoGin         if join_kset.is_some() {
18406d5e247SLoGin             let kset = join_kset.unwrap();
18506d5e247SLoGin             kset.join(&kobj);
18606d5e247SLoGin             // 如果kobject没有parent,那么就将这个kset作为parent
18706d5e247SLoGin             if kobj.parent().is_none() {
18806d5e247SLoGin                 kobj.set_parent(Some(Arc::downgrade(&(kset as Arc<dyn KObject>))));
18906d5e247SLoGin             }
19006d5e247SLoGin         }
19106d5e247SLoGin 
19206d5e247SLoGin         let r = Self::create_dir(kobj.clone());
19306d5e247SLoGin 
19406d5e247SLoGin         if let Err(e) = r {
19506d5e247SLoGin             // https://opengrok.ringotek.cn/xref/linux-6.1.9/lib/kobject.c?r=&mo=10426&fi=394#224
19606d5e247SLoGin             if let Some(kset) = kobj.kset() {
19706d5e247SLoGin                 kset.leave(&kobj);
19806d5e247SLoGin             }
19906d5e247SLoGin             kobj.set_parent(None);
20006d5e247SLoGin             if e == SystemError::EEXIST {
20106d5e247SLoGin                 kerror!("KObjectManager::add_kobj() failed with error: {e:?}, kobj:{kobj:?}");
20206d5e247SLoGin             }
20306d5e247SLoGin 
20406d5e247SLoGin             return Err(e);
20506d5e247SLoGin         }
20606d5e247SLoGin 
20706d5e247SLoGin         kobj.update_kobj_state(Some(KObjectState::IN_SYSFS), None);
20806d5e247SLoGin         return Ok(());
20906d5e247SLoGin     }
21006d5e247SLoGin 
21106d5e247SLoGin     fn create_dir(kobj: Arc<dyn KObject>) -> Result<(), SystemError> {
21206d5e247SLoGin         // create dir in sysfs
21306d5e247SLoGin         sysfs_instance().create_dir(kobj.clone())?;
21406d5e247SLoGin 
21506d5e247SLoGin         // create default attributes in sysfs
21606d5e247SLoGin         if let Some(ktype) = kobj.kobj_type() {
21706d5e247SLoGin             let groups = ktype.attribute_groups();
21806d5e247SLoGin             if let Some(groups) = groups {
21906d5e247SLoGin                 let r = sysfs_instance().create_groups(&kobj, groups);
22006d5e247SLoGin                 if let Err(e) = r {
22106d5e247SLoGin                     sysfs_instance().remove_dir(&kobj);
22206d5e247SLoGin                     return Err(e);
22306d5e247SLoGin                 }
22406d5e247SLoGin             }
22506d5e247SLoGin         }
22606d5e247SLoGin 
22706d5e247SLoGin         return Ok(());
22806d5e247SLoGin     }
22908a2ee40SLoGin 
23008a2ee40SLoGin     /// 从sysfs中移除kobject
23108a2ee40SLoGin     pub fn remove_kobj(kobj: Arc<dyn KObject>) {
23208a2ee40SLoGin         let ktype = kobj.kobj_type();
23308a2ee40SLoGin         if let Some(ktype) = ktype {
23408a2ee40SLoGin             if let Some(groups) = ktype.attribute_groups() {
23508a2ee40SLoGin                 sysfs_instance().remove_groups(&kobj, groups);
23608a2ee40SLoGin             }
23708a2ee40SLoGin         }
23808a2ee40SLoGin 
23908a2ee40SLoGin         // todo: 发送uevent: KOBJ_REMOVE
24008a2ee40SLoGin 
24108a2ee40SLoGin         sysfs_instance().remove_dir(&kobj);
24208a2ee40SLoGin         kobj.update_kobj_state(None, Some(KObjectState::IN_SYSFS));
24308a2ee40SLoGin         let kset = kobj.kset();
24408a2ee40SLoGin         if let Some(kset) = kset {
24508a2ee40SLoGin             kset.leave(&kobj);
24608a2ee40SLoGin         }
24708a2ee40SLoGin         kobj.set_parent(None);
24808a2ee40SLoGin     }
24906d5e247SLoGin }
2507eda31b2SLoGin 
2517eda31b2SLoGin /// 动态创建的kobject对象的ktype
2527eda31b2SLoGin #[derive(Debug)]
2537eda31b2SLoGin pub struct DynamicKObjKType;
2547eda31b2SLoGin 
2557eda31b2SLoGin impl KObjType for DynamicKObjKType {
2567eda31b2SLoGin     fn release(&self, kobj: Arc<dyn KObject>) {
2577eda31b2SLoGin         kdebug!("DynamicKObjKType::release() kobj:{:?}", kobj.name());
2587eda31b2SLoGin     }
2597eda31b2SLoGin 
2607eda31b2SLoGin     fn sysfs_ops(&self) -> Option<&dyn SysFSOps> {
2617eda31b2SLoGin         Some(&KObjectSysFSOps)
2627eda31b2SLoGin     }
2637eda31b2SLoGin 
2647eda31b2SLoGin     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
2657eda31b2SLoGin         None
2667eda31b2SLoGin     }
2677eda31b2SLoGin }
268