123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907 |
- use alloc::{
- string::{String, ToString},
- sync::{Arc, Weak},
- };
- use intertrait::cast::CastArc;
- use crate::{
- driver::{
- acpi::glue::acpi_device_notify,
- base::map::{LockedDevsMap, LockedKObjMap},
- },
- filesystem::{
- sysfs::{
- file::sysfs_emit_str, sysfs_instance, Attribute, AttributeGroup, SysFSOps,
- SysFSOpsSupport,
- },
- vfs::syscall::ModeType,
- },
- syscall::SystemError,
- };
- use core::fmt::Debug;
- use core::intrinsics::unlikely;
- use self::{
- bus::{bus_add_device, bus_probe_device, Bus},
- driver::Driver,
- };
- use super::{
- class::Class,
- kobject::{KObjType, KObject, KObjectManager, KObjectState},
- kset::KSet,
- swnode::software_node_notify,
- };
- pub mod bus;
- pub mod dd;
- pub mod driver;
- pub mod init;
- static mut DEVICE_MANAGER: Option<DeviceManager> = None;
- #[inline(always)]
- pub fn device_manager() -> &'static DeviceManager {
- unsafe { DEVICE_MANAGER.as_ref().unwrap() }
- }
- lazy_static! {
- // 全局字符设备号管理实例
- pub static ref CHARDEVS: Arc<LockedDevsMap> = Arc::new(LockedDevsMap::default());
- // 全局块设备管理实例
- pub static ref BLOCKDEVS: Arc<LockedDevsMap> = Arc::new(LockedDevsMap::default());
- // 全局设备管理实例
- pub static ref DEVMAP: Arc<LockedKObjMap> = Arc::new(LockedKObjMap::default());
- }
- /// `/sys/devices` 的 kset 实例
- static mut DEVICES_KSET_INSTANCE: Option<Arc<KSet>> = None;
- /// `/sys/dev` 的 kset 实例
- static mut DEV_KSET_INSTANCE: Option<Arc<KSet>> = None;
- /// `/sys/dev/block` 的 kset 实例
- static mut DEV_BLOCK_KSET_INSTANCE: Option<Arc<KSet>> = None;
- /// `/sys/dev/char` 的 kset 实例
- static mut DEV_CHAR_KSET_INSTANCE: Option<Arc<KSet>> = None;
- /// `/sys/devices/virtual` 的 kset 实例
- static mut DEVICES_VIRTUAL_KSET_INSTANCE: Option<Arc<KSet>> = None;
- /// 获取`/sys/devices`的kset实例
- #[inline(always)]
- pub(super) fn sys_devices_kset() -> Arc<KSet> {
- unsafe { DEVICES_KSET_INSTANCE.as_ref().unwrap().clone() }
- }
- /// 获取`/sys/dev`的kset实例
- #[inline(always)]
- pub(super) fn sys_dev_kset() -> Arc<KSet> {
- unsafe { DEV_KSET_INSTANCE.as_ref().unwrap().clone() }
- }
- /// 获取`/sys/dev/block`的kset实例
- #[inline(always)]
- #[allow(dead_code)]
- pub fn sys_dev_block_kset() -> Arc<KSet> {
- unsafe { DEV_BLOCK_KSET_INSTANCE.as_ref().unwrap().clone() }
- }
- /// 获取`/sys/dev/char`的kset实例
- #[inline(always)]
- pub fn sys_dev_char_kset() -> Arc<KSet> {
- unsafe { DEV_CHAR_KSET_INSTANCE.as_ref().unwrap().clone() }
- }
- pub(self) unsafe fn set_sys_dev_block_kset(kset: Arc<KSet>) {
- DEV_BLOCK_KSET_INSTANCE = Some(kset);
- }
- pub(self) unsafe fn set_sys_dev_char_kset(kset: Arc<KSet>) {
- DEV_CHAR_KSET_INSTANCE = Some(kset);
- }
- /// 获取`/sys/devices/virtual`的kset实例
- pub fn sys_devices_virtual_kset() -> Arc<KSet> {
- unsafe { DEVICES_VIRTUAL_KSET_INSTANCE.as_ref().unwrap().clone() }
- }
- pub(self) unsafe fn set_sys_devices_virtual_kset(kset: Arc<KSet>) {
- DEVICES_VIRTUAL_KSET_INSTANCE = Some(kset);
- }
- /// 设备应该实现的操作
- ///
- /// ## 注意
- ///
- /// 由于设备驱动模型需要从Arc<dyn KObject>转换为Arc<dyn Device>,
- /// 因此,所有的实现了Device trait的结构体,都应该在结构体上方标注`#[cast_to([sync] Device)]`,
- ///
- /// 否则在释放设备资源的时候,会由于无法转换为Arc<dyn Device>而导致资源泄露,并且release回调函数也不会被调用。
- pub trait Device: KObject {
- // TODO: 待实现 open, close
- /// @brief: 获取设备类型
- /// @parameter: None
- /// @return: 实现该trait的设备所属类型
- fn dev_type(&self) -> DeviceType;
- /// @brief: 获取设备标识
- /// @parameter: None
- /// @return: 该设备唯一标识
- fn id_table(&self) -> IdTable;
- /// 设备释放时的回调函数
- fn release(&self) {
- let name = self.name();
- kwarn!(
- "device {} does not have a release() function, it is broken and must be fixed.",
- name
- );
- }
- /// 获取当前设备所属的总线
- fn bus(&self) -> Option<Arc<dyn Bus>> {
- return None;
- }
- /// 设置当前设备所属的总线
- ///
- /// (一定要传入Arc,因为bus的subsysprivate里面存储的是Device的Weak指针)
- fn set_bus(&self, bus: Option<Arc<dyn Bus>>);
- /// 获取当前设备所属的类
- fn class(&self) -> Option<Arc<dyn Class>> {
- return None;
- }
- /// 设置当前设备所属的类
- fn set_class(&self, class: Option<Arc<dyn Class>>);
- /// 返回已经与当前设备匹配好的驱动程序
- fn driver(&self) -> Option<Arc<dyn Driver>>;
- fn set_driver(&self, driver: Option<Weak<dyn Driver>>);
- /// 当前设备是否已经挂掉了
- fn is_dead(&self) -> bool;
- /// 当前设备是否处于可以被匹配的状态
- ///
- /// The device has matched with a driver at least once or it is in
- /// a bus (like AMBA) which can't check for matching drivers until
- /// other devices probe successfully.
- fn can_match(&self) -> bool;
- fn set_can_match(&self, can_match: bool);
- /// The hardware state of this device has been synced to match
- /// the software state of this device by calling the driver/bus
- /// sync_state() callback.
- fn state_synced(&self) -> bool;
- fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
- None
- }
- }
- impl dyn Device {
- #[inline(always)]
- pub fn is_registered(&self) -> bool {
- self.kobj_state().contains(KObjectState::IN_SYSFS)
- }
- }
- // 暂定是不可修改的,在初始化的时候就要确定。以后可能会包括例如硬件中断包含的信息
- #[allow(dead_code)]
- #[derive(Debug, Clone)]
- pub struct DevicePrivateData {
- id_table: IdTable,
- state: DeviceState,
- }
- #[allow(dead_code)]
- impl DevicePrivateData {
- pub fn new(id_table: IdTable, state: DeviceState) -> Self {
- Self { id_table, state }
- }
- pub fn id_table(&self) -> &IdTable {
- &self.id_table
- }
- pub fn state(&self) -> DeviceState {
- self.state
- }
- pub fn set_state(&mut self, state: DeviceState) {
- self.state = state;
- }
- }
- int_like!(DeviceNumber, usize);
- impl Default for DeviceNumber {
- fn default() -> Self {
- DeviceNumber(0)
- }
- }
- impl From<usize> for DeviceNumber {
- fn from(dev_t: usize) -> Self {
- DeviceNumber(dev_t)
- }
- }
- impl Into<usize> for DeviceNumber {
- fn into(self) -> usize {
- self.0
- }
- }
- impl core::hash::Hash for DeviceNumber {
- fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
- self.0.hash(state);
- }
- }
- impl DeviceNumber {
- /// @brief: 获取主设备号
- /// @parameter: none
- /// @return: 主设备号
- pub fn major(&self) -> usize {
- (self.0 >> 8) & 0xffffff
- }
- /// @brief: 获取次设备号
- /// @parameter: none
- /// @return: 次设备号
- pub fn minor(&self) -> usize {
- self.0 & 0xff
- }
- #[inline]
- #[allow(dead_code)]
- pub fn from_major_minor(major: usize, minor: usize) -> usize {
- ((major & 0xffffff) << 8) | (minor & 0xff)
- }
- }
- /// @brief: 根据主次设备号创建设备号实例
- /// @parameter: major: 主设备号
- /// minor: 次设备号
- /// @return: 设备号实例
- pub fn mkdev(major: usize, minor: usize) -> DeviceNumber {
- DeviceNumber(((major & 0xfff) << 20) | (minor & 0xfffff))
- }
- /// @brief: 设备类型
- #[allow(dead_code)]
- #[derive(Debug, Eq, PartialEq)]
- pub enum DeviceType {
- Bus,
- Net,
- Gpu,
- Input,
- Block,
- Rtc,
- Serial,
- Intc,
- PlatformDev,
- Char,
- }
- /// @brief: 设备标识符类型
- #[derive(Debug, Clone, Hash, PartialOrd, PartialEq, Ord, Eq)]
- pub struct IdTable {
- basename: String,
- id: Option<DeviceNumber>,
- }
- /// @brief: 设备标识符操作方法集
- impl IdTable {
- /// @brief: 创建一个新的设备标识符
- /// @parameter name: 设备名
- /// @parameter id: 设备id
- /// @return: 设备标识符
- pub fn new(basename: String, id: Option<DeviceNumber>) -> IdTable {
- return IdTable { basename, id };
- }
- /// @brief: 将设备标识符转换成name
- /// @parameter None
- /// @return: 设备名
- pub fn name(&self) -> String {
- if self.id.is_none() {
- return self.basename.clone();
- } else {
- return format!("{}:{}", self.basename, self.id.unwrap().data());
- }
- }
- pub fn device_number(&self) -> DeviceNumber {
- return self.id.unwrap_or(DeviceNumber::new(0));
- }
- }
- impl Default for IdTable {
- fn default() -> Self {
- IdTable::new("unknown".to_string(), None)
- }
- }
- // 以现在的模型,设备在加载到系统中就是已经初始化的状态了,因此可以考虑把这个删掉
- /// @brief: 设备当前状态
- #[derive(Debug, Clone, Copy, Eq, PartialEq)]
- pub enum DeviceState {
- NotInitialized = 0,
- Initialized = 1,
- UnDefined = 2,
- }
- /// @brief: 设备错误类型
- #[allow(dead_code)]
- #[derive(Debug, Copy, Clone)]
- pub enum DeviceError {
- DriverExists, // 设备已存在
- DeviceExists, // 驱动已存在
- InitializeFailed, // 初始化错误
- NotInitialized, // 未初始化的设备
- NoDeviceForDriver, // 没有合适的设备匹配驱动
- NoDriverForDevice, // 没有合适的驱动匹配设备
- RegisterError, // 注册失败
- UnsupportedOperation, // 不支持的操作
- }
- impl Into<SystemError> for DeviceError {
- fn into(self) -> SystemError {
- match self {
- DeviceError::DriverExists => SystemError::EEXIST,
- DeviceError::DeviceExists => SystemError::EEXIST,
- DeviceError::InitializeFailed => SystemError::EIO,
- DeviceError::NotInitialized => SystemError::ENODEV,
- DeviceError::NoDeviceForDriver => SystemError::ENODEV,
- DeviceError::NoDriverForDevice => SystemError::ENODEV,
- DeviceError::RegisterError => SystemError::EIO,
- DeviceError::UnsupportedOperation => SystemError::EIO,
- }
- }
- }
- /// @brief: 将u32类型转换为设备状态类型
- impl From<u32> for DeviceState {
- fn from(state: u32) -> Self {
- match state {
- 0 => DeviceState::NotInitialized,
- 1 => DeviceState::Initialized,
- _ => todo!(),
- }
- }
- }
- /// @brief: 将设备状态转换为u32类型
- impl From<DeviceState> for u32 {
- fn from(state: DeviceState) -> Self {
- match state {
- DeviceState::NotInitialized => 0,
- DeviceState::Initialized => 1,
- DeviceState::UnDefined => 2,
- }
- }
- }
- #[derive(Debug)]
- pub struct DeviceKObjType;
- impl KObjType for DeviceKObjType {
- // https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#2307
- fn release(&self, kobj: Arc<dyn KObject>) {
- let dev = kobj.cast::<dyn Device>().unwrap();
- /*
- * Some platform devices are driven without driver attached
- * and managed resources may have been acquired. Make sure
- * all resources are released.
- *
- * Drivers still can add resources into device after device
- * is deleted but alive, so release devres here to avoid
- * possible memory leak.
- */
- // todo: 在引入devres之后再实现
- // devres_release_all(kobj);
- dev.release();
- }
- fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
- None
- }
- fn sysfs_ops(&self) -> Option<&dyn SysFSOps> {
- Some(&DeviceSysFSOps)
- }
- }
- #[derive(Debug)]
- pub(super) struct DeviceSysFSOps;
- impl SysFSOps for DeviceSysFSOps {
- fn store(
- &self,
- kobj: Arc<dyn KObject>,
- attr: &dyn Attribute,
- buf: &[u8],
- ) -> Result<usize, SystemError> {
- return attr.store(kobj, buf);
- }
- fn show(
- &self,
- kobj: Arc<dyn KObject>,
- attr: &dyn Attribute,
- buf: &mut [u8],
- ) -> Result<usize, SystemError> {
- return attr.show(kobj, buf);
- }
- }
- /// @brief Device管理器
- #[derive(Debug)]
- pub struct DeviceManager;
- impl DeviceManager {
- /// @brief: 创建一个新的设备管理器
- /// @parameter: None
- /// @return: DeviceManager实体
- #[inline]
- const fn new() -> DeviceManager {
- return Self;
- }
- pub fn register(&self, device: Arc<dyn Device>) -> Result<(), SystemError> {
- self.device_initialize(&device);
- return self.add_device(device);
- }
- /// device_initialize - init device structure.
- pub fn device_initialize(&self, device: &Arc<dyn Device>) {
- device.set_kset(Some(sys_devices_kset()));
- device.set_kobj_type(Some(&DeviceKObjType));
- }
- /// @brief: 添加设备
- /// @parameter id_table: 总线标识符,用于唯一标识该总线
- /// @parameter dev: 设备实例
- /// @return: None
- ///
- /// https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#3398
- ///
- /// todo: 完善错误处理逻辑:如果添加失败,需要将之前添加的内容全部回滚
- #[inline]
- #[allow(dead_code)]
- pub fn add_device(&self, device: Arc<dyn Device>) -> Result<(), SystemError> {
- // 在这里处理与parent相关的逻辑
- let current_parent = device
- .parent()
- .map(|x| x.upgrade())
- .flatten()
- .map(|x| x.arc_any().cast::<dyn Device>().ok())
- .flatten();
- let actual_parent = self.get_device_parent(&device, current_parent)?;
- if let Some(actual_parent) = actual_parent {
- // kdebug!(
- // "device '{}' parent is '{}', strong_count: {}",
- // device.name().to_string(),
- // actual_parent.name(),
- // Arc::strong_count(&actual_parent)
- // );
- device.set_parent(Some(Arc::downgrade(&actual_parent)));
- }
- KObjectManager::add_kobj(device.clone() as Arc<dyn KObject>, None).map_err(|e| {
- kerror!("add device '{:?}' failed: {:?}", device.name(), e);
- e
- })?;
- self.device_platform_notify(&device);
- self.add_class_symlinks(&device)?;
- self.add_attrs(&device)?;
- bus_add_device(&device)?;
- if device.id_table().device_number().major() != 0 {
- self.create_file(&device, &DeviceAttrDev)?;
- self.create_sys_dev_entry(&device)?;
- }
- // 通知客户端有关设备添加的信息。此调用必须在 dpm_sysfs_add() 之后且在 kobject_uevent() 之前执行。
- if let Some(bus) = device.bus() {
- bus.subsystem().bus_notifier().call_chain(
- bus::BusNotifyEvent::AddDevice,
- Some(&device),
- None,
- );
- }
- // todo: 发送uevent: KOBJ_ADD
- // probe drivers for a new device
- bus_probe_device(&device);
- if let Some(class) = device.class() {
- class.subsystem().add_device_to_vec(&device)?;
- for class_interface in class.subsystem().interfaces() {
- class_interface.add_device(&device).ok();
- }
- }
- return Ok(());
- }
- /// 获取设备真实的parent kobject
- ///
- /// ## 参数
- ///
- /// - `device`: 设备
- /// - `current_parent`: 当前的parent kobject
- ///
- /// ## 返回值
- ///
- /// - `Ok(Some(kobj))`: 如果找到了真实的parent kobject,那么返回它
- /// - `Ok(None)`: 如果没有找到真实的parent kobject,那么返回None
- /// - `Err(e)`: 如果发生错误,那么返回错误
- fn get_device_parent(
- &self,
- device: &Arc<dyn Device>,
- current_parent: Option<Arc<dyn Device>>,
- ) -> Result<Option<Arc<dyn KObject>>, SystemError> {
- // kdebug!("get_device_parent() device:{:?}", device.name());
- if let Some(_) = device.class() {
- let parent_kobj: Arc<dyn KObject>;
- // kdebug!("current_parent:{:?}", current_parent);
- if current_parent.is_none() {
- parent_kobj = sys_devices_virtual_kset() as Arc<dyn KObject>;
- } else {
- let cp = current_parent.unwrap();
- if cp.class().is_some() {
- return Ok(Some(cp.clone() as Arc<dyn KObject>));
- } else {
- parent_kobj = cp.clone() as Arc<dyn KObject>;
- }
- }
- // 是否需要glue dir?
- return Ok(Some(parent_kobj));
- }
- // subsystems can specify a default root directory for their devices
- if current_parent.is_none() {
- if let Some(bus) = device.bus() {
- if let Some(root) = bus.root_device().map(|x| x.upgrade()).flatten() {
- return Ok(Some(root as Arc<dyn KObject>));
- }
- }
- }
- if current_parent.is_some() {
- return Ok(Some(current_parent.unwrap().clone() as Arc<dyn KObject>));
- }
- return Ok(None);
- }
- /// @brief: 卸载设备
- /// @parameter id_table: 总线标识符,用于唯一标识该设备
- /// @return: None
- #[inline]
- #[allow(dead_code)]
- pub fn remove_device(&self, _id_table: &IdTable) {
- todo!()
- }
- /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#542
- fn remove(&self, _dev: &Arc<dyn Device>) {
- todo!("DeviceManager::remove")
- }
- /// @brief: 获取设备
- /// @parameter id_table: 设备标识符,用于唯一标识该设备
- /// @return: 设备实例
- #[inline]
- #[allow(dead_code)]
- pub fn find_device_by_idtable(&self, _id_table: &IdTable) -> Option<Arc<dyn Device>> {
- todo!("find_device_by_idtable")
- }
- fn device_platform_notify(&self, dev: &Arc<dyn Device>) {
- acpi_device_notify(dev);
- software_node_notify(dev);
- }
- fn add_class_symlinks(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> {
- let class = dev.class();
- if class.is_none() {
- return Ok(());
- }
- // 定义错误处理函数,用于在添加符号链接失败时,移除已经添加的符号链接
- let err_remove_subsystem = |dev_kobj: &Arc<dyn KObject>| {
- sysfs_instance().remove_link(dev_kobj, "subsystem".to_string());
- };
- let class = class.unwrap();
- let dev_kobj = dev.clone() as Arc<dyn KObject>;
- let subsys_kobj = class.subsystem().subsys() as Arc<dyn KObject>;
- sysfs_instance().create_link(Some(&dev_kobj), &subsys_kobj, "subsystem".to_string())?;
- // todo: 这里需要处理class的parent逻辑, 添加device链接
- // https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/core.c#3245
- sysfs_instance()
- .create_link(Some(&subsys_kobj), &dev_kobj, dev.name())
- .map_err(|e| {
- err_remove_subsystem(&dev_kobj);
- e
- })?;
- return Ok(());
- }
- /// 在sysfs中,为指定的设备创建属性文件
- ///
- /// ## 参数
- ///
- /// - `dev`: 设备
- fn add_attrs(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> {
- // 定义错误处理函数,用于在添加属性文件失败时,移除已经添加的属性组
- let err_remove_class_groups = |dev: &Arc<dyn Device>| {
- if let Some(class) = dev.class() {
- let attr_groups = class.dev_groups();
- self.remove_groups(dev, attr_groups);
- }
- };
- let err_remove_kobj_type_groups = |dev: &Arc<dyn Device>| {
- if let Some(kobj_type) = dev.kobj_type() {
- let attr_groups = kobj_type.attribute_groups().unwrap_or(&[]);
- self.remove_groups(dev, attr_groups);
- }
- };
- // 真正开始添加属性文件
- // 添加设备类的属性文件
- if let Some(class) = dev.class() {
- let attr_groups = class.dev_groups();
- self.add_groups(dev, attr_groups)?;
- }
- // 添加kobj_type的属性文件
- if let Some(kobj_type) = dev.kobj_type() {
- self.add_groups(dev, kobj_type.attribute_groups().unwrap_or(&[]))
- .map_err(|e| {
- err_remove_class_groups(dev);
- e
- })?;
- }
- // 添加设备本身的属性文件
- self.add_groups(dev, dev.attribute_groups().unwrap_or(&[]))
- .map_err(|e| {
- err_remove_kobj_type_groups(dev);
- err_remove_class_groups(dev);
- e
- })?;
- return Ok(());
- }
- /// 在sysfs中,为指定的设备创建属性组,以及属性组中的属性文件
- ///
- /// ## 参数
- ///
- /// - `dev`: 设备
- /// - `attr_groups`: 属性组
- pub fn add_groups(
- &self,
- dev: &Arc<dyn Device>,
- attr_groups: &'static [&dyn AttributeGroup],
- ) -> Result<(), SystemError> {
- let kobj = dev.clone() as Arc<dyn KObject>;
- return sysfs_instance().create_groups(&kobj, attr_groups);
- }
- /// 在sysfs中,为指定的设备移除属性组,以及属性组中的属性文件
- ///
- /// ## 参数
- ///
- /// - `dev`: 设备
- /// - `attr_groups`: 要移除的属性组
- pub fn remove_groups(
- &self,
- dev: &Arc<dyn Device>,
- attr_groups: &'static [&dyn AttributeGroup],
- ) {
- let kobj = dev.clone() as Arc<dyn KObject>;
- sysfs_instance().remove_groups(&kobj, attr_groups);
- }
- /// 为设备在sysfs中创建属性文件
- ///
- /// ## 参数
- ///
- /// - `dev`: 设备
- /// - `attr`: 属性
- pub fn create_file(
- &self,
- dev: &Arc<dyn Device>,
- attr: &'static dyn Attribute,
- ) -> Result<(), SystemError> {
- if unlikely(
- attr.mode().contains(ModeType::S_IRUGO)
- && (!attr.support().contains(SysFSOpsSupport::SHOW)),
- ) {
- kwarn!(
- "Attribute '{}': read permission without 'show'",
- attr.name()
- );
- }
- if unlikely(
- attr.mode().contains(ModeType::S_IWUGO)
- && (!attr.support().contains(SysFSOpsSupport::STORE)),
- ) {
- kwarn!(
- "Attribute '{}': write permission without 'store'",
- attr.name()
- );
- }
- let kobj = dev.clone() as Arc<dyn KObject>;
- return sysfs_instance().create_file(&kobj, attr);
- }
- /// 在/sys/dev下,或者设备所属的class下,为指定的设备创建链接
- fn create_sys_dev_entry(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> {
- let target_kobj = self.device_to_dev_kobj(dev);
- let name = dev.id_table().name();
- let current_kobj = dev.clone() as Arc<dyn KObject>;
- return sysfs_instance().create_link(Some(¤t_kobj), &target_kobj, name);
- }
- /// Delete symlink for device in `/sys/dev` or `/sys/class/<class_name>`
- #[allow(dead_code)]
- fn remove_sys_dev_entry(&self, dev: &Arc<dyn Device>) {
- let kobj = self.device_to_dev_kobj(dev);
- let name = dev.id_table().name();
- sysfs_instance().remove_link(&kobj, name);
- }
- /// device_to_dev_kobj - select a /sys/dev/ directory for the device
- ///
- /// By default we select char/ for new entries.
- ///
- /// ## 参数
- ///
- /// - `dev`: 设备
- fn device_to_dev_kobj(&self, _dev: &Arc<dyn Device>) -> Arc<dyn KObject> {
- // todo: 处理class的逻辑
- let kobj = sys_dev_char_kset().as_kobject();
- return kobj;
- }
- /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c?fi=device_links_force_bind#1226
- pub fn device_links_force_bind(&self, _dev: &Arc<dyn Device>) {
- todo!("device_links_force_bind")
- }
- /// 把device对象的一些结构进行默认初始化
- ///
- /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c?fi=device_initialize#2976
- pub fn device_default_initialize(&self, dev: &Arc<dyn Device>) {
- dev.set_kset(Some(sys_devices_kset()));
- return;
- }
- /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c?r=&mo=29885&fi=1100#1100
- pub fn device_driver_attach(
- &self,
- _driver: &Arc<dyn Driver>,
- _dev: &Arc<dyn Device>,
- ) -> Result<(), SystemError> {
- todo!("device_driver_attach")
- }
- /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c?r=&mo=35401&fi=1313#1313
- pub fn device_driver_detach(&self, _dev: &Arc<dyn Device>) {
- todo!("device_driver_detach")
- }
- }
- /// @brief: 设备注册
- /// @parameter: name: 设备名
- /// @return: 操作成功,返回(),操作失败,返回错误码
- pub fn device_register<T: Device>(device: Arc<T>) -> Result<(), SystemError> {
- return device_manager().register(device);
- }
- /// @brief: 设备卸载
- /// @parameter: name: 设备名
- /// @return: 操作成功,返回(),操作失败,返回错误码
- pub fn device_unregister<T: Device>(_device: Arc<T>) {
- // DEVICE_MANAGER.add_device(device.id_table(), device.clone());
- // match sys_device_unregister(&device.id_table().name()) {
- // Ok(_) => {
- // device.set_inode(None);
- // return Ok(());
- // }
- // Err(_) => Err(DeviceError::RegisterError),
- // }
- todo!("device_unregister")
- }
- /// 设备文件夹下的`dev`文件的属性
- #[derive(Debug, Clone, Copy)]
- pub struct DeviceAttrDev;
- impl Attribute for DeviceAttrDev {
- fn mode(&self) -> ModeType {
- // 0o444
- return ModeType::S_IRUGO;
- }
- fn name(&self) -> &str {
- "dev"
- }
- fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
- let dev = kobj.cast::<dyn Device>().map_err(|kobj| {
- kerror!(
- "Intertrait casting not implemented for kobj: {}",
- kobj.name()
- );
- SystemError::EOPNOTSUPP_OR_ENOTSUP
- })?;
- let device_number = dev.id_table().device_number();
- let s = format!("{}:{}\n", device_number.major(), device_number.minor());
- return sysfs_emit_str(buf, &s);
- }
- fn support(&self) -> SysFSOpsSupport {
- SysFSOpsSupport::SHOW
- }
- }
- /// 设备匹配器
- ///
- /// 用于匹配设备是否符合某个条件
- ///
- /// ## 参数
- ///
- /// - `T` - 匹配器的数据类型
- /// - `data` - 匹配器的数据
- pub trait DeviceMatcher<T>: Debug {
- fn match_device(&self, device: &Arc<dyn Device>, data: T) -> bool;
- }
- /// 用于根据名称匹配设备的匹配器
- #[derive(Debug)]
- pub struct DeviceMatchName;
- impl DeviceMatcher<&str> for DeviceMatchName {
- #[inline]
- fn match_device(&self, device: &Arc<dyn Device>, data: &str) -> bool {
- return device.name() == data;
- }
- }
|