106d5e247SLoGin use core::{intrinsics::unlikely, ops::BitAnd};
206d5e247SLoGin
306d5e247SLoGin use alloc::{
406d5e247SLoGin string::ToString,
506d5e247SLoGin sync::{Arc, Weak},
606d5e247SLoGin };
7*2eab6dd7S曾俊 use log::warn;
891e9d4abSLoGin use system_error::SystemError;
906d5e247SLoGin
1006d5e247SLoGin use crate::{
1106d5e247SLoGin driver::base::kobject::KObject,
1206d5e247SLoGin filesystem::{
1306d5e247SLoGin kernfs::{
1406d5e247SLoGin callback::{KernCallbackData, KernFSCallback, KernInodePrivateData},
1506d5e247SLoGin KernFSInode,
1606d5e247SLoGin },
1706d5e247SLoGin sysfs::{SysFSOps, SysFSOpsSupport},
1806d5e247SLoGin vfs::{syscall::ModeType, PollStatus},
1906d5e247SLoGin },
2006d5e247SLoGin };
2106d5e247SLoGin
227eda31b2SLoGin use super::{Attribute, BinAttribute, SysFS, SysFSKernPrivateData};
236b4e7a29SLoGin
246b4e7a29SLoGin #[derive(Debug)]
256b4e7a29SLoGin pub struct SysKernFilePriv {
266b4e7a29SLoGin attribute: Option<&'static dyn Attribute>,
277eda31b2SLoGin /// bin attribute和attribute二选一,只能有一个为Some
287eda31b2SLoGin bin_attribute: Option<Arc<dyn BinAttribute>>,
2906d5e247SLoGin /// 当前文件对应的kobject
3006d5e247SLoGin kobj: Weak<dyn KObject>,
316b4e7a29SLoGin }
326b4e7a29SLoGin
336b4e7a29SLoGin impl SysKernFilePriv {
new( kobj: &Arc<dyn KObject>, attribute: Option<&'static dyn Attribute>, bin_attribute: Option<Arc<dyn BinAttribute>>, ) -> Self347eda31b2SLoGin pub fn new(
357eda31b2SLoGin kobj: &Arc<dyn KObject>,
367eda31b2SLoGin attribute: Option<&'static dyn Attribute>,
377eda31b2SLoGin bin_attribute: Option<Arc<dyn BinAttribute>>,
387eda31b2SLoGin ) -> Self {
397eda31b2SLoGin if attribute.is_none() && bin_attribute.is_none() {
407eda31b2SLoGin panic!("attribute and bin_attribute can't be both None");
416b4e7a29SLoGin }
427eda31b2SLoGin if attribute.is_some() && bin_attribute.is_some() {
437eda31b2SLoGin panic!("attribute and bin_attribute can't be both Some");
447eda31b2SLoGin }
457eda31b2SLoGin
4606d5e247SLoGin let kobj = Arc::downgrade(kobj);
477eda31b2SLoGin return Self {
487eda31b2SLoGin kobj,
497eda31b2SLoGin attribute,
507eda31b2SLoGin bin_attribute,
517eda31b2SLoGin };
526b4e7a29SLoGin }
536b4e7a29SLoGin
5406d5e247SLoGin #[allow(dead_code)]
5506d5e247SLoGin #[inline]
attribute(&self) -> Option<&'static dyn Attribute>566b4e7a29SLoGin pub fn attribute(&self) -> Option<&'static dyn Attribute> {
576b4e7a29SLoGin self.attribute
586b4e7a29SLoGin }
5906d5e247SLoGin
callback_read(&self, buf: &mut [u8], offset: usize) -> Result<usize, SystemError>607eda31b2SLoGin pub fn callback_read(&self, buf: &mut [u8], offset: usize) -> Result<usize, SystemError> {
617eda31b2SLoGin if let Some(attribute) = self.attribute {
6206d5e247SLoGin // 当前文件所指向的kobject已经被释放
6306d5e247SLoGin let kobj = self.kobj.upgrade().expect("kobj is None");
647eda31b2SLoGin let len = attribute.show(kobj, buf)?;
657eda31b2SLoGin if offset > 0 {
667eda31b2SLoGin if len <= offset {
677eda31b2SLoGin return Ok(0);
687eda31b2SLoGin }
697eda31b2SLoGin let len = len - offset;
707eda31b2SLoGin buf.copy_within(offset..offset + len, 0);
717eda31b2SLoGin buf[len] = 0;
727eda31b2SLoGin }
737eda31b2SLoGin return Ok(len);
747eda31b2SLoGin } else if let Some(bin_attribute) = self.bin_attribute.as_ref() {
757eda31b2SLoGin // 当前文件所指向的kobject已经被释放
767eda31b2SLoGin let kobj = self.kobj.upgrade().expect("kobj is None");
777eda31b2SLoGin return bin_attribute.read(kobj, buf, offset);
787eda31b2SLoGin } else {
797eda31b2SLoGin panic!("attribute and bin_attribute can't be both None");
807eda31b2SLoGin }
8106d5e247SLoGin }
8206d5e247SLoGin
callback_write(&self, buf: &[u8], offset: usize) -> Result<usize, SystemError>837eda31b2SLoGin pub fn callback_write(&self, buf: &[u8], offset: usize) -> Result<usize, SystemError> {
847eda31b2SLoGin if let Some(attribute) = self.attribute {
8506d5e247SLoGin // 当前文件所指向的kobject已经被释放
8606d5e247SLoGin let kobj = self.kobj.upgrade().expect("kobj is None");
8706d5e247SLoGin return attribute.store(kobj, buf);
887eda31b2SLoGin } else if let Some(bin_attribute) = self.bin_attribute.as_ref() {
897eda31b2SLoGin // 当前文件所指向的kobject已经被释放
907eda31b2SLoGin let kobj = self.kobj.upgrade().expect("kobj is None");
917eda31b2SLoGin return bin_attribute.write(kobj, buf, offset);
927eda31b2SLoGin } else {
937eda31b2SLoGin panic!("attribute and bin_attribute can't be both None");
947eda31b2SLoGin }
9506d5e247SLoGin }
9606d5e247SLoGin }
9706d5e247SLoGin
9806d5e247SLoGin impl SysFS {
9906d5e247SLoGin /// 为指定的kobject创建一个属性文件
10006d5e247SLoGin ///
10106d5e247SLoGin /// ## 参数
10206d5e247SLoGin ///
10306d5e247SLoGin /// - `kobj` 要创建属性文件的kobject
10406d5e247SLoGin /// - `attr` 属性
create_file( &self, kobj: &Arc<dyn KObject>, attr: &'static dyn Attribute, ) -> Result<(), SystemError>10506d5e247SLoGin pub fn create_file(
10606d5e247SLoGin &self,
10706d5e247SLoGin kobj: &Arc<dyn KObject>,
10806d5e247SLoGin attr: &'static dyn Attribute,
10906d5e247SLoGin ) -> Result<(), SystemError> {
11006d5e247SLoGin let inode = kobj.inode().ok_or(SystemError::EINVAL)?;
11106d5e247SLoGin return self.add_file_with_mode(&inode, attr, attr.mode());
11206d5e247SLoGin }
11306d5e247SLoGin
114e7071df6SLoGin // https://code.dragonos.org.cn/xref/linux-6.1.9/fs/sysfs/file.c?fi=sysfs_add_file_mode_ns#271
add_file_with_mode( &self, parent: &Arc<KernFSInode>, attr: &'static dyn Attribute, mode: ModeType, ) -> Result<(), SystemError>11506d5e247SLoGin pub(super) fn add_file_with_mode(
11606d5e247SLoGin &self,
11706d5e247SLoGin parent: &Arc<KernFSInode>,
11806d5e247SLoGin attr: &'static dyn Attribute,
11906d5e247SLoGin mode: ModeType,
12006d5e247SLoGin ) -> Result<(), SystemError> {
12106d5e247SLoGin let x = parent.private_data_mut();
12206d5e247SLoGin let kobj: Arc<dyn KObject>;
12306d5e247SLoGin if let Some(KernInodePrivateData::SysFS(SysFSKernPrivateData::Dir(dt))) = x.as_ref() {
12406d5e247SLoGin kobj = dt.kobj().unwrap();
12506d5e247SLoGin } else {
12606d5e247SLoGin drop(x);
12706d5e247SLoGin let path = self.kernfs_path(parent);
12806d5e247SLoGin panic!("parent '{path}' is not a dir");
12906d5e247SLoGin }
13006d5e247SLoGin drop(x);
13106d5e247SLoGin
13206d5e247SLoGin let sysfs_ops: &dyn SysFSOps = kobj.kobj_type().unwrap().sysfs_ops().ok_or_else(|| {
133*2eab6dd7S曾俊 warn!("missing sysfs attribute operations for kobject: {kobj:?}");
13406d5e247SLoGin SystemError::EINVAL
13506d5e247SLoGin })?;
13606d5e247SLoGin
13706d5e247SLoGin // assume that all sysfs ops are preallocated.
13806d5e247SLoGin
13906d5e247SLoGin let sys_support = sysfs_ops.support(attr);
14006d5e247SLoGin
14106d5e247SLoGin let kern_callback: &'static dyn KernFSCallback;
142196b75dcSLoGin if sys_support.contains(SysFSOpsSupport::ATTR_SHOW)
143196b75dcSLoGin && sys_support.contains(SysFSOpsSupport::ATTR_STORE)
14406d5e247SLoGin {
14506d5e247SLoGin kern_callback = &PreallocKFOpsRW;
146196b75dcSLoGin } else if sys_support.contains(SysFSOpsSupport::ATTR_SHOW) {
14706d5e247SLoGin kern_callback = &PreallocKFOpsReadOnly;
148196b75dcSLoGin } else if sys_support.contains(SysFSOpsSupport::ATTR_STORE) {
14906d5e247SLoGin kern_callback = &PreallocKFOpsWriteOnly;
15006d5e247SLoGin } else {
15106d5e247SLoGin kern_callback = &PreallocKFOpsEmpty;
15206d5e247SLoGin }
15306d5e247SLoGin
1547eda31b2SLoGin let sys_priv = SysFSKernPrivateData::File(SysKernFilePriv::new(&kobj, Some(attr), None));
15506d5e247SLoGin let r = parent.add_file(
15606d5e247SLoGin attr.name().to_string(),
15706d5e247SLoGin mode.bitand(ModeType::from_bits_truncate(0o777)),
1587eda31b2SLoGin Some(4096),
15906d5e247SLoGin Some(KernInodePrivateData::SysFS(sys_priv)),
16006d5e247SLoGin Some(kern_callback),
16106d5e247SLoGin );
16206d5e247SLoGin
16306d5e247SLoGin if let Err(e) = r {
16406d5e247SLoGin if e == SystemError::EEXIST {
16506d5e247SLoGin self.warn_duplicate(parent, attr.name());
16606d5e247SLoGin }
16706d5e247SLoGin
16806d5e247SLoGin return Err(e);
16906d5e247SLoGin }
17006d5e247SLoGin return Ok(());
17106d5e247SLoGin }
17206d5e247SLoGin
17306d5e247SLoGin /// 在sysfs中删除某个kobject的属性文件
17406d5e247SLoGin ///
17506d5e247SLoGin /// 如果属性文件不存在,则发出一个警告
17606d5e247SLoGin ///
17706d5e247SLoGin /// ## 参数
17806d5e247SLoGin ///
17906d5e247SLoGin /// - `kobj` 要删除属性文件的kobject
18006d5e247SLoGin /// - `attr` 属性
remove_file(&self, kobj: &Arc<dyn KObject>, attr: &'static dyn Attribute)18106d5e247SLoGin pub fn remove_file(&self, kobj: &Arc<dyn KObject>, attr: &'static dyn Attribute) {
18206d5e247SLoGin let parent = kobj.inode();
18306d5e247SLoGin
18406d5e247SLoGin if let Some(parent) = parent {
18506d5e247SLoGin let r = parent.remove(attr.name());
18606d5e247SLoGin if unlikely(r.is_err()) {
187*2eab6dd7S曾俊 warn!(
18806d5e247SLoGin "failed to remove file '{}' from '{}'",
18906d5e247SLoGin attr.name(),
19006d5e247SLoGin kobj.name()
19106d5e247SLoGin );
19206d5e247SLoGin }
19306d5e247SLoGin }
19406d5e247SLoGin }
1957eda31b2SLoGin
1967eda31b2SLoGin /// 在sysfs中,为指定的kobject创建一个动态申请的bin属性文件
1977eda31b2SLoGin ///
1987eda31b2SLoGin /// ## 参数
1997eda31b2SLoGin ///
2007eda31b2SLoGin /// - `kobj` 要创建属性文件的kobject
2017eda31b2SLoGin /// - `attr` 属性
2027eda31b2SLoGin ///
203e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/sysfs/file.c#558
create_bin_file( &self, kobj: &Arc<dyn KObject>, attr: &Arc<dyn BinAttribute>, ) -> Result<(), SystemError>2047eda31b2SLoGin pub fn create_bin_file(
2057eda31b2SLoGin &self,
2067eda31b2SLoGin kobj: &Arc<dyn KObject>,
2077eda31b2SLoGin attr: &Arc<dyn BinAttribute>,
2087eda31b2SLoGin ) -> Result<(), SystemError> {
2097eda31b2SLoGin let inode = kobj.inode().ok_or(SystemError::EINVAL)?;
2107eda31b2SLoGin return self.add_bin_file_with_mode(&inode, attr, attr.mode());
2117eda31b2SLoGin }
2127eda31b2SLoGin
2137eda31b2SLoGin /// 在sysfs中删除某个kobject的bin属性文件
2147eda31b2SLoGin ///
2157eda31b2SLoGin /// 如果属性文件不存在,则发出一个警告
2167eda31b2SLoGin #[allow(dead_code)]
remove_bin_file(&self, kobj: &Arc<dyn KObject>, attr: &Arc<dyn BinAttribute>)2177eda31b2SLoGin pub fn remove_bin_file(&self, kobj: &Arc<dyn KObject>, attr: &Arc<dyn BinAttribute>) {
2187eda31b2SLoGin let parent = kobj.inode();
2197eda31b2SLoGin
2207eda31b2SLoGin if let Some(parent) = parent {
2217eda31b2SLoGin let r = parent.remove(attr.name());
2227eda31b2SLoGin if unlikely(r.is_err()) {
223*2eab6dd7S曾俊 warn!(
2247eda31b2SLoGin "failed to remove file '{}' from '{}'",
2257eda31b2SLoGin attr.name(),
2267eda31b2SLoGin kobj.name()
2277eda31b2SLoGin );
2287eda31b2SLoGin }
2297eda31b2SLoGin }
2307eda31b2SLoGin }
2317eda31b2SLoGin
232e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/sysfs/file.c#304
add_bin_file_with_mode( &self, parent: &Arc<KernFSInode>, attr: &Arc<dyn BinAttribute>, mode: ModeType, ) -> Result<(), SystemError>2337eda31b2SLoGin pub(super) fn add_bin_file_with_mode(
2347eda31b2SLoGin &self,
2357eda31b2SLoGin parent: &Arc<KernFSInode>,
2367eda31b2SLoGin attr: &Arc<dyn BinAttribute>,
2377eda31b2SLoGin mode: ModeType,
2387eda31b2SLoGin ) -> Result<(), SystemError> {
2397eda31b2SLoGin let x = parent.private_data_mut();
2407eda31b2SLoGin let kobj: Arc<dyn KObject>;
2417eda31b2SLoGin if let Some(KernInodePrivateData::SysFS(SysFSKernPrivateData::Dir(dt))) = x.as_ref() {
2427eda31b2SLoGin kobj = dt.kobj().unwrap();
2437eda31b2SLoGin } else {
2447eda31b2SLoGin drop(x);
2457eda31b2SLoGin let path = self.kernfs_path(parent);
2467eda31b2SLoGin panic!("parent '{path}' is not a dir");
2477eda31b2SLoGin }
2487eda31b2SLoGin drop(x);
2497eda31b2SLoGin
2507eda31b2SLoGin let kern_callback: &'static dyn KernFSCallback;
2517eda31b2SLoGin let bin_support = attr.support_battr();
2527eda31b2SLoGin
253196b75dcSLoGin if bin_support.contains(SysFSOpsSupport::BATTR_READ)
254196b75dcSLoGin && bin_support.contains(SysFSOpsSupport::BATTR_WRITE)
2557eda31b2SLoGin {
2567eda31b2SLoGin kern_callback = &PreallocKFOpsRW;
257196b75dcSLoGin } else if bin_support.contains(SysFSOpsSupport::BATTR_READ) {
2587eda31b2SLoGin kern_callback = &PreallocKFOpsReadOnly;
259196b75dcSLoGin } else if bin_support.contains(SysFSOpsSupport::BATTR_WRITE) {
2607eda31b2SLoGin kern_callback = &PreallocKFOpsWriteOnly;
2617eda31b2SLoGin } else {
2627eda31b2SLoGin kern_callback = &PreallocKFOpsEmpty;
2637eda31b2SLoGin }
2647eda31b2SLoGin
2657eda31b2SLoGin let sys_priv =
2667eda31b2SLoGin SysFSKernPrivateData::File(SysKernFilePriv::new(&kobj, None, Some(attr.clone())));
2677eda31b2SLoGin let r = parent.add_file(
2687eda31b2SLoGin attr.name().to_string(),
2697eda31b2SLoGin mode.bitand(ModeType::from_bits_truncate(0o777)),
2707eda31b2SLoGin Some(attr.size()),
2717eda31b2SLoGin Some(KernInodePrivateData::SysFS(sys_priv)),
2727eda31b2SLoGin Some(kern_callback),
2737eda31b2SLoGin );
2747eda31b2SLoGin
2757eda31b2SLoGin if let Err(e) = r {
2767eda31b2SLoGin if e == SystemError::EEXIST {
2777eda31b2SLoGin self.warn_duplicate(parent, attr.name());
2787eda31b2SLoGin }
2797eda31b2SLoGin
2807eda31b2SLoGin return Err(e);
2817eda31b2SLoGin }
2827eda31b2SLoGin return Ok(());
2837eda31b2SLoGin }
28406d5e247SLoGin }
28506d5e247SLoGin
28606d5e247SLoGin #[derive(Debug)]
28706d5e247SLoGin struct PreallocKFOpsRW;
28806d5e247SLoGin
28906d5e247SLoGin impl KernFSCallback for PreallocKFOpsRW {
open(&self, _data: KernCallbackData) -> Result<(), SystemError>29006d5e247SLoGin fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
29106d5e247SLoGin return Ok(());
29206d5e247SLoGin }
29306d5e247SLoGin
read( &self, data: KernCallbackData, buf: &mut [u8], offset: usize, ) -> Result<usize, SystemError>29406d5e247SLoGin fn read(
29506d5e247SLoGin &self,
29606d5e247SLoGin data: KernCallbackData,
29706d5e247SLoGin buf: &mut [u8],
29806d5e247SLoGin offset: usize,
29906d5e247SLoGin ) -> Result<usize, SystemError> {
30006d5e247SLoGin return data.callback_read(buf, offset);
30106d5e247SLoGin }
30206d5e247SLoGin
write( &self, data: KernCallbackData, buf: &[u8], offset: usize, ) -> Result<usize, SystemError>30306d5e247SLoGin fn write(
30406d5e247SLoGin &self,
30506d5e247SLoGin data: KernCallbackData,
30606d5e247SLoGin buf: &[u8],
30706d5e247SLoGin offset: usize,
30806d5e247SLoGin ) -> Result<usize, SystemError> {
30906d5e247SLoGin return data.callback_write(buf, offset);
31006d5e247SLoGin }
31106d5e247SLoGin
31206d5e247SLoGin #[inline]
poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError>31306d5e247SLoGin fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
31406d5e247SLoGin return Ok(PollStatus::READ | PollStatus::WRITE);
31506d5e247SLoGin }
31606d5e247SLoGin }
31706d5e247SLoGin
31806d5e247SLoGin #[derive(Debug)]
31906d5e247SLoGin struct PreallocKFOpsReadOnly;
32006d5e247SLoGin
32106d5e247SLoGin impl KernFSCallback for PreallocKFOpsReadOnly {
open(&self, _data: KernCallbackData) -> Result<(), SystemError>32206d5e247SLoGin fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
32306d5e247SLoGin return Ok(());
32406d5e247SLoGin }
32506d5e247SLoGin
read( &self, data: KernCallbackData, buf: &mut [u8], offset: usize, ) -> Result<usize, SystemError>32606d5e247SLoGin fn read(
32706d5e247SLoGin &self,
32806d5e247SLoGin data: KernCallbackData,
32906d5e247SLoGin buf: &mut [u8],
33006d5e247SLoGin offset: usize,
33106d5e247SLoGin ) -> Result<usize, SystemError> {
33206d5e247SLoGin return data.callback_read(buf, offset);
33306d5e247SLoGin }
33406d5e247SLoGin
write( &self, _data: KernCallbackData, _buf: &[u8], _offset: usize, ) -> Result<usize, SystemError>33506d5e247SLoGin fn write(
33606d5e247SLoGin &self,
33706d5e247SLoGin _data: KernCallbackData,
33806d5e247SLoGin _buf: &[u8],
33906d5e247SLoGin _offset: usize,
34006d5e247SLoGin ) -> Result<usize, SystemError> {
34106d5e247SLoGin return Err(SystemError::EPERM);
34206d5e247SLoGin }
34306d5e247SLoGin
34406d5e247SLoGin #[inline]
poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError>34506d5e247SLoGin fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
34606d5e247SLoGin return Ok(PollStatus::READ);
34706d5e247SLoGin }
34806d5e247SLoGin }
34906d5e247SLoGin
35006d5e247SLoGin #[derive(Debug)]
35106d5e247SLoGin struct PreallocKFOpsWriteOnly;
35206d5e247SLoGin
35306d5e247SLoGin impl KernFSCallback for PreallocKFOpsWriteOnly {
open(&self, _data: KernCallbackData) -> Result<(), SystemError>35406d5e247SLoGin fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
35506d5e247SLoGin return Ok(());
35606d5e247SLoGin }
35706d5e247SLoGin
read( &self, _data: KernCallbackData, _buf: &mut [u8], _offset: usize, ) -> Result<usize, SystemError>35806d5e247SLoGin fn read(
35906d5e247SLoGin &self,
36006d5e247SLoGin _data: KernCallbackData,
36106d5e247SLoGin _buf: &mut [u8],
36206d5e247SLoGin _offset: usize,
36306d5e247SLoGin ) -> Result<usize, SystemError> {
36406d5e247SLoGin return Err(SystemError::EPERM);
36506d5e247SLoGin }
36606d5e247SLoGin
write( &self, data: KernCallbackData, buf: &[u8], offset: usize, ) -> Result<usize, SystemError>36706d5e247SLoGin fn write(
36806d5e247SLoGin &self,
36906d5e247SLoGin data: KernCallbackData,
37006d5e247SLoGin buf: &[u8],
37106d5e247SLoGin offset: usize,
37206d5e247SLoGin ) -> Result<usize, SystemError> {
37306d5e247SLoGin return data.callback_write(buf, offset);
37406d5e247SLoGin }
37506d5e247SLoGin
37606d5e247SLoGin #[inline]
poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError>37706d5e247SLoGin fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
37806d5e247SLoGin return Ok(PollStatus::WRITE);
37906d5e247SLoGin }
38006d5e247SLoGin }
38106d5e247SLoGin
38206d5e247SLoGin #[derive(Debug)]
38306d5e247SLoGin struct PreallocKFOpsEmpty;
38406d5e247SLoGin
38506d5e247SLoGin impl KernFSCallback for PreallocKFOpsEmpty {
open(&self, _data: KernCallbackData) -> Result<(), SystemError>38606d5e247SLoGin fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
38706d5e247SLoGin return Ok(());
38806d5e247SLoGin }
38906d5e247SLoGin
read( &self, _data: KernCallbackData, _buf: &mut [u8], _offset: usize, ) -> Result<usize, SystemError>39006d5e247SLoGin fn read(
39106d5e247SLoGin &self,
39206d5e247SLoGin _data: KernCallbackData,
39306d5e247SLoGin _buf: &mut [u8],
39406d5e247SLoGin _offset: usize,
39506d5e247SLoGin ) -> Result<usize, SystemError> {
39606d5e247SLoGin return Err(SystemError::EPERM);
39706d5e247SLoGin }
39806d5e247SLoGin
write( &self, _data: KernCallbackData, _buf: &[u8], _offset: usize, ) -> Result<usize, SystemError>39906d5e247SLoGin fn write(
40006d5e247SLoGin &self,
40106d5e247SLoGin _data: KernCallbackData,
40206d5e247SLoGin _buf: &[u8],
40306d5e247SLoGin _offset: usize,
40406d5e247SLoGin ) -> Result<usize, SystemError> {
40506d5e247SLoGin return Err(SystemError::EPERM);
40606d5e247SLoGin }
40706d5e247SLoGin
40806d5e247SLoGin #[inline]
poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError>40906d5e247SLoGin fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
41006d5e247SLoGin return Ok(PollStatus::empty());
41106d5e247SLoGin }
41206d5e247SLoGin }
41306d5e247SLoGin
sysfs_emit_str(buf: &mut [u8], s: &str) -> Result<usize, SystemError>41406d5e247SLoGin pub fn sysfs_emit_str(buf: &mut [u8], s: &str) -> Result<usize, SystemError> {
415b5b571e0SLoGin let len = if buf.len() > s.len() {
416b5b571e0SLoGin s.len()
41706d5e247SLoGin } else {
418b5b571e0SLoGin buf.len() - 1
419b5b571e0SLoGin };
42006d5e247SLoGin buf[..len].copy_from_slice(&s.as_bytes()[..len]);
42106d5e247SLoGin buf[len] = b'\0';
42206d5e247SLoGin return Ok(len);
4236b4e7a29SLoGin }
424