xref: /DragonOS/kernel/src/driver/base/kobject.rs (revision 06d5e247267cb65b84a80f219853ccd0f384b16e)
1*06d5e247SLoGin use core::{any::Any, fmt::Debug, hash::Hash, ops::Deref};
2*06d5e247SLoGin 
3*06d5e247SLoGin use alloc::{
4*06d5e247SLoGin     string::String,
5*06d5e247SLoGin     sync::{Arc, Weak},
6*06d5e247SLoGin };
7*06d5e247SLoGin use intertrait::CastFromSync;
8*06d5e247SLoGin 
9*06d5e247SLoGin use crate::{
10*06d5e247SLoGin     filesystem::{
11*06d5e247SLoGin         kernfs::KernFSInode,
12*06d5e247SLoGin         sysfs::{sysfs_instance, Attribute, AttributeGroup, SysFSOps, SysFSOpsSupport},
13*06d5e247SLoGin     },
14*06d5e247SLoGin     kerror,
15*06d5e247SLoGin     libs::{
16*06d5e247SLoGin         casting::DowncastArc,
17*06d5e247SLoGin         rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
18*06d5e247SLoGin     },
19*06d5e247SLoGin     syscall::SystemError,
20*06d5e247SLoGin };
21*06d5e247SLoGin 
22*06d5e247SLoGin use super::kset::KSet;
23*06d5e247SLoGin 
24*06d5e247SLoGin pub trait KObject: Any + Send + Sync + Debug + CastFromSync {
25*06d5e247SLoGin     fn as_any_ref(&self) -> &dyn core::any::Any;
26*06d5e247SLoGin 
27*06d5e247SLoGin     /// 设置当前kobject对应的sysfs inode(类型为KernFSInode)
28*06d5e247SLoGin     fn set_inode(&self, inode: Option<Arc<KernFSInode>>);
29*06d5e247SLoGin 
30*06d5e247SLoGin     /// 获取当前kobject对应的sysfs inode(类型为KernFSInode)
31*06d5e247SLoGin     fn inode(&self) -> Option<Arc<KernFSInode>>;
32*06d5e247SLoGin 
33*06d5e247SLoGin     fn parent(&self) -> Option<Weak<dyn KObject>>;
34*06d5e247SLoGin 
35*06d5e247SLoGin     /// 设置当前kobject的parent kobject(不一定与kset相同)
36*06d5e247SLoGin     fn set_parent(&self, parent: Option<Weak<dyn KObject>>);
37*06d5e247SLoGin 
38*06d5e247SLoGin     /// 当前kobject属于哪个kset
39*06d5e247SLoGin     fn kset(&self) -> Option<Arc<KSet>>;
40*06d5e247SLoGin 
41*06d5e247SLoGin     /// 设置当前kobject所属的kset
42*06d5e247SLoGin     fn set_kset(&self, kset: Option<Arc<KSet>>);
43*06d5e247SLoGin 
44*06d5e247SLoGin     fn kobj_type(&self) -> Option<&'static dyn KObjType>;
45*06d5e247SLoGin 
46*06d5e247SLoGin     fn name(&self) -> String;
47*06d5e247SLoGin 
48*06d5e247SLoGin     fn set_name(&self, name: String);
49*06d5e247SLoGin 
50*06d5e247SLoGin     fn kobj_state(&self) -> RwLockReadGuard<KObjectState>;
51*06d5e247SLoGin 
52*06d5e247SLoGin     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>;
53*06d5e247SLoGin 
54*06d5e247SLoGin     fn set_kobj_state(&self, state: KObjectState);
55*06d5e247SLoGin }
56*06d5e247SLoGin 
57*06d5e247SLoGin impl dyn KObject {
58*06d5e247SLoGin     /// 更新kobject的状态
59*06d5e247SLoGin     pub fn update_kobj_state(&self, insert: Option<KObjectState>, remove: Option<KObjectState>) {
60*06d5e247SLoGin         let insert = insert.unwrap_or(KObjectState::empty());
61*06d5e247SLoGin         let remove = remove.unwrap_or(KObjectState::empty());
62*06d5e247SLoGin         let mut state = self.kobj_state_mut();
63*06d5e247SLoGin         *state = (*state | insert) & !remove;
64*06d5e247SLoGin     }
65*06d5e247SLoGin }
66*06d5e247SLoGin 
67*06d5e247SLoGin impl DowncastArc for dyn KObject {
68*06d5e247SLoGin     fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any> {
69*06d5e247SLoGin         self
70*06d5e247SLoGin     }
71*06d5e247SLoGin }
72*06d5e247SLoGin 
73*06d5e247SLoGin pub trait KObjType: Debug {
74*06d5e247SLoGin     fn release(&self, _kobj: Arc<dyn KObject>) {}
75*06d5e247SLoGin     fn sysfs_ops(&self) -> Option<&dyn SysFSOps>;
76*06d5e247SLoGin 
77*06d5e247SLoGin     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]>;
78*06d5e247SLoGin }
79*06d5e247SLoGin 
80*06d5e247SLoGin bitflags! {
81*06d5e247SLoGin     pub struct KObjectState: u32 {
82*06d5e247SLoGin         const IN_SYSFS = 1 << 0;
83*06d5e247SLoGin         const ADD_UEVENT_SENT = 1 << 1;
84*06d5e247SLoGin         const REMOVE_UEVENT_SENT = 1 << 2;
85*06d5e247SLoGin         const INITIALIZED = 1 << 3;
86*06d5e247SLoGin     }
87*06d5e247SLoGin 
88*06d5e247SLoGin }
89*06d5e247SLoGin 
90*06d5e247SLoGin #[derive(Debug)]
91*06d5e247SLoGin pub struct LockedKObjectState(RwLock<KObjectState>);
92*06d5e247SLoGin 
93*06d5e247SLoGin impl LockedKObjectState {
94*06d5e247SLoGin     pub const fn new(state: KObjectState) -> LockedKObjectState {
95*06d5e247SLoGin         LockedKObjectState(RwLock::new(state))
96*06d5e247SLoGin     }
97*06d5e247SLoGin }
98*06d5e247SLoGin 
99*06d5e247SLoGin impl Deref for LockedKObjectState {
100*06d5e247SLoGin     type Target = RwLock<KObjectState>;
101*06d5e247SLoGin 
102*06d5e247SLoGin     fn deref(&self) -> &Self::Target {
103*06d5e247SLoGin         &self.0
104*06d5e247SLoGin     }
105*06d5e247SLoGin }
106*06d5e247SLoGin 
107*06d5e247SLoGin pub trait KObjectAttribute: Attribute {
108*06d5e247SLoGin     fn support(&self) -> SysFSOpsSupport;
109*06d5e247SLoGin 
110*06d5e247SLoGin     fn show(&self, kobj: &dyn KObject, buf: &mut [u8]) -> Result<usize, SystemError>;
111*06d5e247SLoGin     fn store(&self, kobj: &dyn KObject, buf: &[u8]) -> Result<usize, SystemError>;
112*06d5e247SLoGin }
113*06d5e247SLoGin 
114*06d5e247SLoGin #[derive(Debug)]
115*06d5e247SLoGin pub struct KObjectSysFSOps;
116*06d5e247SLoGin 
117*06d5e247SLoGin impl SysFSOps for KObjectSysFSOps {
118*06d5e247SLoGin     fn support(&self, attr: &dyn Attribute) -> SysFSOpsSupport {
119*06d5e247SLoGin         return attr.support();
120*06d5e247SLoGin     }
121*06d5e247SLoGin 
122*06d5e247SLoGin     fn show(
123*06d5e247SLoGin         &self,
124*06d5e247SLoGin         kobj: Arc<dyn KObject>,
125*06d5e247SLoGin         attr: &dyn Attribute,
126*06d5e247SLoGin         buf: &mut [u8],
127*06d5e247SLoGin     ) -> Result<usize, SystemError> {
128*06d5e247SLoGin         let r = attr.show(kobj, buf).map_err(|e| {
129*06d5e247SLoGin             if e == SystemError::EOPNOTSUPP_OR_ENOTSUP {
130*06d5e247SLoGin                 SystemError::EIO
131*06d5e247SLoGin             } else {
132*06d5e247SLoGin                 e
133*06d5e247SLoGin             }
134*06d5e247SLoGin         });
135*06d5e247SLoGin 
136*06d5e247SLoGin         return r;
137*06d5e247SLoGin     }
138*06d5e247SLoGin 
139*06d5e247SLoGin     fn store(
140*06d5e247SLoGin         &self,
141*06d5e247SLoGin         kobj: Arc<dyn KObject>,
142*06d5e247SLoGin         attr: &dyn Attribute,
143*06d5e247SLoGin         buf: &[u8],
144*06d5e247SLoGin     ) -> Result<usize, SystemError> {
145*06d5e247SLoGin         let r = attr.store(kobj, buf).map_err(|e| {
146*06d5e247SLoGin             if e == SystemError::EOPNOTSUPP_OR_ENOTSUP {
147*06d5e247SLoGin                 SystemError::EIO
148*06d5e247SLoGin             } else {
149*06d5e247SLoGin                 e
150*06d5e247SLoGin             }
151*06d5e247SLoGin         });
152*06d5e247SLoGin 
153*06d5e247SLoGin         return r;
154*06d5e247SLoGin     }
155*06d5e247SLoGin }
156*06d5e247SLoGin 
157*06d5e247SLoGin #[derive(Debug)]
158*06d5e247SLoGin pub struct KObjectManager;
159*06d5e247SLoGin 
160*06d5e247SLoGin impl KObjectManager {
161*06d5e247SLoGin     pub fn add_kobj(
162*06d5e247SLoGin         kobj: Arc<dyn KObject>,
163*06d5e247SLoGin         join_kset: Option<Arc<KSet>>,
164*06d5e247SLoGin     ) -> Result<(), SystemError> {
165*06d5e247SLoGin         if join_kset.is_some() {
166*06d5e247SLoGin             let kset = join_kset.unwrap();
167*06d5e247SLoGin             kset.join(&kobj);
168*06d5e247SLoGin             // 如果kobject没有parent,那么就将这个kset作为parent
169*06d5e247SLoGin             if kobj.parent().is_none() {
170*06d5e247SLoGin                 kobj.set_parent(Some(Arc::downgrade(&(kset as Arc<dyn KObject>))));
171*06d5e247SLoGin             }
172*06d5e247SLoGin         }
173*06d5e247SLoGin 
174*06d5e247SLoGin         let r = Self::create_dir(kobj.clone());
175*06d5e247SLoGin 
176*06d5e247SLoGin         if let Err(e) = r {
177*06d5e247SLoGin             // https://opengrok.ringotek.cn/xref/linux-6.1.9/lib/kobject.c?r=&mo=10426&fi=394#224
178*06d5e247SLoGin             if let Some(kset) = kobj.kset() {
179*06d5e247SLoGin                 kset.leave(&kobj);
180*06d5e247SLoGin             }
181*06d5e247SLoGin             kobj.set_parent(None);
182*06d5e247SLoGin             if e == SystemError::EEXIST {
183*06d5e247SLoGin                 kerror!("KObjectManager::add_kobj() failed with error: {e:?}, kobj:{kobj:?}");
184*06d5e247SLoGin             }
185*06d5e247SLoGin 
186*06d5e247SLoGin             return Err(e);
187*06d5e247SLoGin         }
188*06d5e247SLoGin 
189*06d5e247SLoGin         kobj.update_kobj_state(Some(KObjectState::IN_SYSFS), None);
190*06d5e247SLoGin         return Ok(());
191*06d5e247SLoGin     }
192*06d5e247SLoGin 
193*06d5e247SLoGin     fn create_dir(kobj: Arc<dyn KObject>) -> Result<(), SystemError> {
194*06d5e247SLoGin         // create dir in sysfs
195*06d5e247SLoGin         sysfs_instance().create_dir(kobj.clone())?;
196*06d5e247SLoGin 
197*06d5e247SLoGin         // create default attributes in sysfs
198*06d5e247SLoGin         if let Some(ktype) = kobj.kobj_type() {
199*06d5e247SLoGin             let groups = ktype.attribute_groups();
200*06d5e247SLoGin             if let Some(groups) = groups {
201*06d5e247SLoGin                 let r = sysfs_instance().create_groups(&kobj, groups);
202*06d5e247SLoGin                 if let Err(e) = r {
203*06d5e247SLoGin                     sysfs_instance().remove_dir(&kobj);
204*06d5e247SLoGin                     return Err(e);
205*06d5e247SLoGin                 }
206*06d5e247SLoGin             }
207*06d5e247SLoGin         }
208*06d5e247SLoGin 
209*06d5e247SLoGin         return Ok(());
210*06d5e247SLoGin     }
211*06d5e247SLoGin }
212