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 112c566df45SLoGin impl Default for LockedKObjectState { 113c566df45SLoGin fn default() -> Self { 114c566df45SLoGin LockedKObjectState::new(None) 115c566df45SLoGin } 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 { 195*e7071df6SLoGin // https://code.dragonos.org.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