use alloc::{collections::BTreeMap, string::String, sync::Arc}; use crate::{ filesystem::{ sysfs::{ devices::{sys_device_register, sys_device_unregister}, SYS_DEVICES_INODE, }, vfs::IndexNode, }, libs::spinlock::SpinLock, syscall::SystemError, }; use core::{any::Any, fmt::Debug}; pub mod bus; pub mod driver; lazy_static! { pub static ref DEVICE_MANAGER: Arc = Arc::new(LockedDeviceManager::new()); } pub trait KObject: Any + Send + Sync + Debug {} /// @brief: 设备号实例 #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] pub struct DeviceNumber(usize); impl Default for DeviceNumber { fn default() -> Self { DeviceNumber(0) } } impl From for DeviceNumber { fn from(dev_t: usize) -> Self { DeviceNumber(dev_t) } } impl Into for DeviceNumber { fn into(self) -> usize { self.0 } } impl DeviceNumber { /// @brief: 设备号创建 /// @parameter: dev_t: 设备号 /// @return: 设备号实例 pub fn new(dev_t: usize) -> DeviceNumber { Self(dev_t) } /// @brief: 获取主设备号 /// @parameter: none /// @return: 主设备号 pub fn major(&self) -> usize { (self.0 >> 20) & 0xfff } /// @brief: 获取次设备号 /// @parameter: none /// @return: 次设备号 pub fn minor(&self) -> usize { self.0 & 0xfffff } } /// @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, } /// @brief: 设备标识符类型 #[derive(Debug, Clone, Hash, PartialOrd, PartialEq, Ord, Eq)] pub struct IdTable(&'static str, u32); /// @brief: 设备标识符操作方法集 impl IdTable { /// @brief: 创建一个新的设备标识符 /// @parameter name: 设备名 /// @parameter id: 设备id /// @return: 设备标识符 pub fn new(name: &'static str, id: u32) -> IdTable { Self(name, id) } /// @brief: 将设备标识符转换成name /// @parameter None /// @return: 设备名 pub fn to_name(&self) -> String { return format!("{}:{}", self.0, self.1); } } /// @brief: 设备当前状态 #[derive(Debug, Clone, Copy)] pub enum DeviceState { NotInitialized = 0, Initialized = 1, UnDefined = 2, } /// @brief: 设备错误类型 #[derive(Debug, Copy, Clone)] pub enum DeviceError { DriverExists, // 设备已存在 DeviceExists, // 驱动已存在 InitializeFailed, // 初始化错误 NoDeviceForDriver, // 没有合适的设备匹配驱动 NoDriverForDevice, // 没有合适的驱动匹配设备 RegisterError, // 注册失败 } impl Into for DeviceError { fn into(self) -> SystemError { match self { DeviceError::DriverExists => SystemError::EEXIST, DeviceError::DeviceExists => SystemError::EEXIST, DeviceError::InitializeFailed => SystemError::EIO, DeviceError::NoDeviceForDriver => SystemError::ENODEV, DeviceError::NoDriverForDevice => SystemError::ENODEV, DeviceError::RegisterError => SystemError::EIO, } } } /// @brief: 将u32类型转换为设备状态类型 impl From for DeviceState { fn from(state: u32) -> Self { match state { 0 => DeviceState::NotInitialized, 1 => DeviceState::Initialized, _ => todo!(), } } } /// @brief: 将设备状态转换为u32类型 impl From for u32 { fn from(state: DeviceState) -> Self { match state { DeviceState::NotInitialized => 0, DeviceState::Initialized => 1, DeviceState::UnDefined => 2, } } } /// @brief: 所有设备都应该实现该trait pub trait Device: KObject { /// @brief: 本函数用于实现动态转换 /// @parameter: None /// @return: any fn as_any_ref(&'static self) -> &'static dyn core::any::Any; /// @brief: 获取设备类型 /// @parameter: None /// @return: 实现该trait的设备所属类型 fn dev_type(&self) -> DeviceType; /// @brief: 获取设备标识 /// @parameter: None /// @return: 该设备唯一标识 fn id_table(&self) -> IdTable; /// @brief: 设置sysfs info /// @parameter: None /// @return: 该设备唯一标识 fn set_sys_info(&self, sys_info: Option>); /// @brief: 获取设备的sys information /// @parameter id_table: 设备标识符,用于唯一标识该设备 /// @return: 设备实例 fn sys_info(&self) -> Option>; } /// @brief Device管理器(锁) #[derive(Debug)] pub struct LockedDeviceManager(SpinLock); impl LockedDeviceManager { fn new() -> LockedDeviceManager { LockedDeviceManager(SpinLock::new(DeviceManager::new())) } /// @brief: 添加设备 /// @parameter id_table: 总线标识符,用于唯一标识该总线 /// @parameter dev: 设备实例 /// @return: None #[inline] #[allow(dead_code)] pub fn add_device(&self, id_table: IdTable, dev: Arc) { let mut device_manager = self.0.lock(); device_manager.devices.insert(id_table, dev); } /// @brief: 卸载设备 /// @parameter id_table: 总线标识符,用于唯一标识该设备 /// @return: None #[inline] #[allow(dead_code)] pub fn remove_device(&self, id_table: &IdTable) { let mut device_manager = self.0.lock(); device_manager.devices.remove(id_table); } /// @brief: 获取设备 /// @parameter id_table: 设备标识符,用于唯一标识该设备 /// @return: 设备实例 #[inline] #[allow(dead_code)] pub fn get_device(&self, id_table: &IdTable) -> Option> { let device_manager = self.0.lock(); device_manager.devices.get(id_table).cloned() } /// @brief: 获取设备管理器的sys information /// @parameter id_table: 设备标识符,用于唯一标识该设备 /// @return: 设备实例 #[inline] #[allow(dead_code)] fn sys_info(&self) -> Option> { return self.0.lock().sys_info.clone(); } } /// @brief Device管理器 #[derive(Debug, Clone)] pub struct DeviceManager { devices: BTreeMap>, // 所有设备 sys_info: Option>, // sys information } impl DeviceManager { /// @brief: 创建一个新的设备管理器 /// @parameter: None /// @return: DeviceManager实体 #[inline] fn new() -> DeviceManager { DeviceManager { devices: BTreeMap::new(), sys_info: Some(SYS_DEVICES_INODE()), } } } /// @brief: 设备注册 /// @parameter: name: 设备名 /// @return: 操作成功,返回(),操作失败,返回错误码 pub fn device_register(device: Arc) -> Result<(), DeviceError> { DEVICE_MANAGER.add_device(device.id_table(), device.clone()); match sys_device_register(&device.id_table().to_name()) { Ok(sys_info) => { device.set_sys_info(Some(sys_info)); return Ok(()); } Err(_) => Err(DeviceError::RegisterError), } } /// @brief: 设备卸载 /// @parameter: name: 设备名 /// @return: 操作成功,返回(),操作失败,返回错误码 pub fn device_unregister(device: Arc) -> Result<(), DeviceError> { DEVICE_MANAGER.add_device(device.id_table(), device.clone()); match sys_device_unregister(&device.id_table().to_name()) { Ok(_) => { device.set_sys_info(None); return Ok(()); } Err(_) => Err(DeviceError::RegisterError), } }