16b4e7a29SLoGin use core::fmt::Debug;
26b4e7a29SLoGin
36b4e7a29SLoGin use self::{dir::SysKernDirPriv, file::SysKernFilePriv};
46b4e7a29SLoGin
506d5e247SLoGin use super::{
606d5e247SLoGin kernfs::{KernFS, KernFSInode},
706d5e247SLoGin vfs::{syscall::ModeType, FileSystem},
8dd9f1fc1STingHuang };
9dd9f1fc1STingHuang use crate::{
1006d5e247SLoGin driver::base::kobject::KObject,
1106d5e247SLoGin filesystem::vfs::ROOT_INODE,
1206d5e247SLoGin libs::{casting::DowncastArc, once::Once},
13dd9f1fc1STingHuang };
1406d5e247SLoGin use alloc::sync::Arc;
15*2eab6dd7S曾俊 use log::{info, warn};
1691e9d4abSLoGin use system_error::SystemError;
17dd9f1fc1STingHuang
1806d5e247SLoGin pub mod dir;
1906d5e247SLoGin pub mod file;
2006d5e247SLoGin pub mod group;
2106d5e247SLoGin pub mod symlink;
22dd9f1fc1STingHuang
2306d5e247SLoGin /// 全局的sysfs实例
24b5b571e0SLoGin static mut SYSFS_INSTANCE: Option<SysFS> = None;
25dd9f1fc1STingHuang
26dd9f1fc1STingHuang #[inline(always)]
sysfs_instance() -> &'static SysFS2706d5e247SLoGin pub fn sysfs_instance() -> &'static SysFS {
28dd9f1fc1STingHuang unsafe {
29b5b571e0SLoGin return SYSFS_INSTANCE.as_ref().unwrap();
30dd9f1fc1STingHuang }
31dd9f1fc1STingHuang }
32b087521eSChiichen
sysfs_init() -> Result<(), SystemError>33b087521eSChiichen pub fn sysfs_init() -> Result<(), SystemError> {
34b087521eSChiichen static INIT: Once = Once::new();
35b087521eSChiichen let mut result = None;
36b087521eSChiichen INIT.call_once(|| {
37*2eab6dd7S曾俊 info!("Initializing SysFS...");
3806d5e247SLoGin
39b087521eSChiichen // 创建 sysfs 实例
4006d5e247SLoGin // let sysfs: Arc<OldSysFS> = OldSysFS::new();
4106d5e247SLoGin let sysfs = SysFS::new();
4206d5e247SLoGin unsafe { SYSFS_INSTANCE = Some(sysfs) };
43b087521eSChiichen
44b087521eSChiichen // sysfs 挂载
451074eb34SSamuel Dai ROOT_INODE()
461074eb34SSamuel Dai .mkdir("sys", ModeType::from_bits_truncate(0o755))
471074eb34SSamuel Dai .expect("Unabled to find /sys")
4806d5e247SLoGin .mount(sysfs_instance().fs().clone())
491074eb34SSamuel Dai .expect("Failed to mount at /sys");
50*2eab6dd7S曾俊 info!("SysFS mounted.");
51b087521eSChiichen
52*2eab6dd7S曾俊 // debug!("sys_bus_init result: {:?}", SYS_BUS_INODE().list());
53b087521eSChiichen result = Some(Ok(()));
54b087521eSChiichen });
55b087521eSChiichen
56b087521eSChiichen return result.unwrap();
57b087521eSChiichen }
586b4e7a29SLoGin
596b4e7a29SLoGin /// SysFS在KernFS的inode中的私有信息
606b4e7a29SLoGin #[allow(dead_code)]
616b4e7a29SLoGin #[derive(Debug)]
626b4e7a29SLoGin pub enum SysFSKernPrivateData {
636b4e7a29SLoGin Dir(SysKernDirPriv),
646b4e7a29SLoGin File(SysKernFilePriv),
656b4e7a29SLoGin }
666b4e7a29SLoGin
6706d5e247SLoGin impl SysFSKernPrivateData {
6806d5e247SLoGin #[inline(always)]
callback_read(&self, buf: &mut [u8], offset: usize) -> Result<usize, SystemError>6906d5e247SLoGin pub fn callback_read(&self, buf: &mut [u8], offset: usize) -> Result<usize, SystemError> {
7006d5e247SLoGin match self {
7106d5e247SLoGin SysFSKernPrivateData::File(file) => {
727eda31b2SLoGin let len = file.callback_read(buf, offset)?;
737eda31b2SLoGin
7406d5e247SLoGin return Ok(len);
7506d5e247SLoGin }
7606d5e247SLoGin _ => {
771074eb34SSamuel Dai return Err(SystemError::ENOSYS);
7806d5e247SLoGin }
7906d5e247SLoGin }
8006d5e247SLoGin }
8106d5e247SLoGin
8206d5e247SLoGin #[inline(always)]
callback_write(&self, buf: &[u8], offset: usize) -> Result<usize, SystemError>837eda31b2SLoGin pub fn callback_write(&self, buf: &[u8], offset: usize) -> Result<usize, SystemError> {
8406d5e247SLoGin match self {
8506d5e247SLoGin SysFSKernPrivateData::File(file) => {
867eda31b2SLoGin return file.callback_write(buf, offset);
8706d5e247SLoGin }
8806d5e247SLoGin _ => {
891074eb34SSamuel Dai return Err(SystemError::ENOSYS);
9006d5e247SLoGin }
9106d5e247SLoGin }
9206d5e247SLoGin }
9306d5e247SLoGin }
9406d5e247SLoGin
956b4e7a29SLoGin /// sysfs文件目录的属性组
966b4e7a29SLoGin pub trait AttributeGroup: Debug + Send + Sync {
9706d5e247SLoGin /// 属性组的名称
9806d5e247SLoGin ///
9906d5e247SLoGin /// 如果属性组的名称为None,则所有的属性都会被添加到父目录下,而不是创建一个新的目录
name(&self) -> Option<&str>10006d5e247SLoGin fn name(&self) -> Option<&str>;
10106d5e247SLoGin /// 属性组的属性列表
attrs(&self) -> &[&'static dyn Attribute]1026b4e7a29SLoGin fn attrs(&self) -> &[&'static dyn Attribute];
10306d5e247SLoGin
10406d5e247SLoGin /// 属性在当前属性组内的权限(该方法可选)
10506d5e247SLoGin ///
10606d5e247SLoGin /// 如果返回None,则使用Attribute的mode()方法返回的权限
10706d5e247SLoGin ///
10806d5e247SLoGin /// 如果返回Some,则使用返回的权限。
10906d5e247SLoGin /// 如果要标识属性不可见,则返回Some(ModeType::empty())
is_visible( &self, _kobj: Arc<dyn KObject>, attr: &'static dyn Attribute, ) -> Option<ModeType>110e32effb1SLoGin fn is_visible(
111e32effb1SLoGin &self,
112e32effb1SLoGin _kobj: Arc<dyn KObject>,
113e32effb1SLoGin attr: &'static dyn Attribute,
114e32effb1SLoGin ) -> Option<ModeType> {
115e32effb1SLoGin return Some(attr.mode());
116e32effb1SLoGin }
1176b4e7a29SLoGin }
1186b4e7a29SLoGin
119196b75dcSLoGin /// sysfs只读属性文件的权限
120196b75dcSLoGin pub const SYSFS_ATTR_MODE_RO: ModeType = ModeType::from_bits_truncate(0o444);
121196b75dcSLoGin /// sysfs只写属性文件的权限
122196b75dcSLoGin pub const SYSFS_ATTR_MODE_WO: ModeType = ModeType::from_bits_truncate(0o200);
123196b75dcSLoGin /// sysfs读写属性文件的权限
124196b75dcSLoGin pub const SYSFS_ATTR_MODE_RW: ModeType = ModeType::from_bits_truncate(0o644);
125196b75dcSLoGin
1266b4e7a29SLoGin /// sysfs文件的属性
1276b4e7a29SLoGin pub trait Attribute: Debug + Send + Sync {
name(&self) -> &str1286b4e7a29SLoGin fn name(&self) -> &str;
mode(&self) -> ModeType1296b4e7a29SLoGin fn mode(&self) -> ModeType;
13006d5e247SLoGin
support(&self) -> SysFSOpsSupport13106d5e247SLoGin fn support(&self) -> SysFSOpsSupport;
13206d5e247SLoGin
show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError>13306d5e247SLoGin fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
1341074eb34SSamuel Dai return Err(SystemError::ENOSYS);
13506d5e247SLoGin }
13606d5e247SLoGin
store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError>13706d5e247SLoGin fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
1381074eb34SSamuel Dai return Err(SystemError::ENOSYS);
13906d5e247SLoGin }
14006d5e247SLoGin }
14106d5e247SLoGin
1427eda31b2SLoGin pub trait BinAttribute: Attribute {
support_battr(&self) -> SysFSOpsSupport1437eda31b2SLoGin fn support_battr(&self) -> SysFSOpsSupport;
1447eda31b2SLoGin
write( &self, _kobj: Arc<dyn KObject>, _buf: &[u8], _offset: usize, ) -> Result<usize, SystemError>1457eda31b2SLoGin fn write(
1467eda31b2SLoGin &self,
1477eda31b2SLoGin _kobj: Arc<dyn KObject>,
1487eda31b2SLoGin _buf: &[u8],
1497eda31b2SLoGin _offset: usize,
1507eda31b2SLoGin ) -> Result<usize, SystemError> {
1511074eb34SSamuel Dai return Err(SystemError::ENOSYS);
1527eda31b2SLoGin }
1537eda31b2SLoGin
read( &self, _kobj: Arc<dyn KObject>, _buf: &mut [u8], _offset: usize, ) -> Result<usize, SystemError>1547eda31b2SLoGin fn read(
1557eda31b2SLoGin &self,
1567eda31b2SLoGin _kobj: Arc<dyn KObject>,
1577eda31b2SLoGin _buf: &mut [u8],
1587eda31b2SLoGin _offset: usize,
1597eda31b2SLoGin ) -> Result<usize, SystemError> {
1601074eb34SSamuel Dai return Err(SystemError::ENOSYS);
1617eda31b2SLoGin }
1627eda31b2SLoGin
size(&self) -> usize1637eda31b2SLoGin fn size(&self) -> usize;
1647eda31b2SLoGin }
1657eda31b2SLoGin
16606d5e247SLoGin pub trait SysFSOps: Debug {
16706d5e247SLoGin /// 获取当前文件的支持的操作
support(&self, attr: &dyn Attribute) -> SysFSOpsSupport16806d5e247SLoGin fn support(&self, attr: &dyn Attribute) -> SysFSOpsSupport {
16906d5e247SLoGin return attr.support();
17006d5e247SLoGin }
17106d5e247SLoGin
support_battr(&self, attr: &Arc<dyn BinAttribute>) -> SysFSOpsSupport1727eda31b2SLoGin fn support_battr(&self, attr: &Arc<dyn BinAttribute>) -> SysFSOpsSupport {
1737eda31b2SLoGin return attr.support();
1747eda31b2SLoGin }
1757eda31b2SLoGin
show( &self, kobj: Arc<dyn KObject>, attr: &dyn Attribute, buf: &mut [u8], ) -> Result<usize, SystemError>17606d5e247SLoGin fn show(
17706d5e247SLoGin &self,
17806d5e247SLoGin kobj: Arc<dyn KObject>,
17906d5e247SLoGin attr: &dyn Attribute,
18006d5e247SLoGin buf: &mut [u8],
18106d5e247SLoGin ) -> Result<usize, SystemError>;
18206d5e247SLoGin
store( &self, kobj: Arc<dyn KObject>, attr: &dyn Attribute, buf: &[u8], ) -> Result<usize, SystemError>18306d5e247SLoGin fn store(
18406d5e247SLoGin &self,
18506d5e247SLoGin kobj: Arc<dyn KObject>,
18606d5e247SLoGin attr: &dyn Attribute,
18706d5e247SLoGin buf: &[u8],
18806d5e247SLoGin ) -> Result<usize, SystemError>;
18906d5e247SLoGin }
19006d5e247SLoGin
19106d5e247SLoGin bitflags! {
19206d5e247SLoGin pub struct SysFSOpsSupport: u8{
1937eda31b2SLoGin // === for attribute ===
194196b75dcSLoGin const ATTR_SHOW = 1 << 0;
195196b75dcSLoGin const ATTR_STORE = 1 << 1;
1967eda31b2SLoGin // === for bin attribute ===
197196b75dcSLoGin const BATTR_READ = 1 << 2;
198196b75dcSLoGin const BATTR_WRITE = 1 << 3;
19906d5e247SLoGin }
20006d5e247SLoGin }
20106d5e247SLoGin
20206d5e247SLoGin #[derive(Debug)]
20306d5e247SLoGin pub struct SysFS {
20406d5e247SLoGin root_inode: Arc<KernFSInode>,
20506d5e247SLoGin kernfs: Arc<KernFS>,
20606d5e247SLoGin }
20706d5e247SLoGin
20806d5e247SLoGin impl SysFS {
new() -> Self20906d5e247SLoGin pub fn new() -> Self {
21006d5e247SLoGin let kernfs: Arc<KernFS> = KernFS::new();
21106d5e247SLoGin
21206d5e247SLoGin let root_inode: Arc<KernFSInode> = kernfs.root_inode().downcast_arc().unwrap();
21306d5e247SLoGin
21406d5e247SLoGin let sysfs = SysFS { root_inode, kernfs };
21506d5e247SLoGin
21606d5e247SLoGin return sysfs;
21706d5e247SLoGin }
21806d5e247SLoGin
root_inode(&self) -> &Arc<KernFSInode>21906d5e247SLoGin pub fn root_inode(&self) -> &Arc<KernFSInode> {
22006d5e247SLoGin return &self.root_inode;
22106d5e247SLoGin }
22206d5e247SLoGin
fs(&self) -> &Arc<KernFS>22306d5e247SLoGin pub fn fs(&self) -> &Arc<KernFS> {
22406d5e247SLoGin return &self.kernfs;
22506d5e247SLoGin }
22606d5e247SLoGin
22706d5e247SLoGin /// 警告:重复的sysfs entry
warn_duplicate(&self, parent: &Arc<KernFSInode>, name: &str)22806d5e247SLoGin pub(self) fn warn_duplicate(&self, parent: &Arc<KernFSInode>, name: &str) {
22906d5e247SLoGin let path = self.kernfs_path(parent);
230*2eab6dd7S曾俊 warn!("duplicate sysfs entry: {path}/{name}");
23106d5e247SLoGin }
2326b4e7a29SLoGin }
233