增加serio总线和相关trait (#488)

* 新增serio总线和相关trait

* 补充SerioDeviceManager和SerioDriverManager
This commit is contained in:
R0ronoa 2024-01-17 23:57:49 +08:00 committed by GitHub
parent 6994f6b113
commit d8e29bffee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 326 additions and 0 deletions

View File

@ -1,3 +1,4 @@
use crate::driver::input::serio::serio_bus_init;
use system_error::SystemError; use system_error::SystemError;
use super::{ use super::{
@ -16,6 +17,7 @@ pub(super) fn driver_init() -> Result<(), SystemError> {
firmware_init()?; firmware_init()?;
hypervisor_init()?; hypervisor_init()?;
platform_bus_init()?; platform_bus_init()?;
serio_bus_init()?;
cpu_device_manager().init()?; cpu_device_manager().init()?;
// 至此,已完成设备驱动模型的初始化 // 至此,已完成设备驱动模型的初始化

View File

@ -0,0 +1,2 @@
pub mod ps2_dev;
pub mod serio;

View File

@ -0,0 +1 @@
pub mod ps2_device;

View File

@ -0,0 +1,4 @@
use crate::driver::{base::device::Device, input::serio::serio_device::SerioDevice};
// todo: https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/libps2.h#33
pub trait Ps2Device: Device + SerioDevice {}

View File

@ -0,0 +1,31 @@
use alloc::sync::Arc;
use system_error::SystemError;
use crate::driver::base::device::bus::{bus_register, Bus};
use self::subsys::SerioBus;
pub mod serio_device;
pub mod serio_driver;
pub mod subsys;
static mut SERIO_BUS: Option<Arc<SerioBus>> = None;
#[allow(dead_code)]
#[inline(always)]
pub fn serio_bus() -> Arc<SerioBus> {
unsafe { SERIO_BUS.clone().unwrap() }
}
/// # 函数的功能
///
/// 初始化serio bus
///
/// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/serio.c#1024
pub fn serio_bus_init() -> Result<(), SystemError> {
let serio_bus = SerioBus::new();
let r = bus_register(serio_bus.clone() as Arc<dyn Bus>);
unsafe { SERIO_BUS = Some(serio_bus) };
return r;
}

View File

@ -0,0 +1,70 @@
use alloc::sync::Arc;
use system_error::SystemError;
use crate::driver::base::device::{bus::Bus, Device};
use super::serio_bus;
/// 串行设备实现该trait的设备实例挂载在serio总线上同时应该实现Device trait
///
/// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/serio.h#20
pub trait SerioDevice: Device {
/// # 函数功能
///
/// Serio设备写入数据
///
/// ## 参数
///
/// - data 写入的数据
///
/// ## 返回值
///
/// 无
fn write(&self, device: &Arc<dyn SerioDevice>, data: u8) -> Result<(), SystemError>;
/// Serio设备连接驱动时调用
fn open(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
/// Serio设备断开驱动时调用
fn close(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
/// Serio设备初始化时调用
fn start(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
/// Serio设备销毁时调用
fn stop(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
}
#[allow(dead_code)]
#[inline(always)]
pub fn serio_device_manager() -> &'static SerioDeviceManager {
&SerioDeviceManager
}
pub struct SerioDeviceManager;
#[allow(dead_code)]
impl SerioDeviceManager {
/// # 函数功能
/// 注册Serio设备
///
/// ## 参数
/// - device 待注册的设备
///
/// ## 返回值
/// 无
pub fn register_port(&self, device: Arc<dyn SerioDevice>) -> Result<(), SystemError> {
self.init_port(device)
}
/// # 函数功能
/// 初始化Serio设备
///
/// ## 参数
/// - device 待初始化的Serio设备
///
/// ## 返回值
/// 无
///
/// todohttps://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/serio.c#494
pub fn init_port(&self, device: Arc<dyn SerioDevice>) -> Result<(), SystemError> {
device.set_bus(Some(Arc::downgrade(&(serio_bus() as Arc<dyn Bus>))));
Ok(())
}
}

View File

@ -0,0 +1,75 @@
use alloc::sync::Arc;
use system_error::SystemError;
use crate::driver::base::device::{
bus::Bus,
driver::{driver_manager, Driver},
};
use super::{serio_bus, serio_device::SerioDevice};
/// 实现该trait的设备驱动实例应挂载在serio总线上同时应该实现Driver trait
///
/// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/serio.h#67
pub trait SerioDriver: Driver {
// 写入时唤醒设备
fn write_wakeup(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
/// # 函数功能
/// 中断函数
///
/// ## 参数
/// - device: Serio设备
/// - data: 端口数据
/// - flag: 状态掩码
///
/// ## 返回值
/// 无
fn interrupt(
&self,
device: &Arc<dyn SerioDevice>,
data: u8,
flag: u8,
) -> Result<(), SystemError>;
/// Serio驱动连接设备
fn connect(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
/// 重新连接设备
fn reconnect(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
/// 快速重连设备
fn fast_reconnect(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
/// 驱动断开设备
fn disconnect(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
/// 清除设备状态
fn cleanup(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
}
///todo: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/serio.c#810
pub struct SerioDriverManager;
#[allow(dead_code)]
impl SerioDriverManager {
/// # 函数功能
/// 注册Serio驱动
///
/// ## 参数
/// - driver 待注册的Serio驱动
///
/// ## 返回值
/// 无
pub fn register(&self, driver: Arc<dyn SerioDriver>) -> Result<(), SystemError> {
driver.set_bus(Some(Arc::downgrade(&(serio_bus() as Arc<dyn Bus>))));
return driver_manager().register(driver as Arc<dyn Driver>);
}
/// # 函数功能
/// 卸载Serio驱动
///
/// ## 参数
/// - driver 待卸载的Serio驱动
///
/// ## 返回值
/// 无
#[allow(dead_code)]
pub fn unregister(&self, driver: &Arc<dyn SerioDriver>) {
driver_manager().unregister(&(driver.clone() as Arc<dyn Driver>));
}
}

View File

@ -0,0 +1,140 @@
use alloc::{
string::{String, ToString},
sync::{Arc, Weak},
};
use intertrait::cast::CastArc;
use system_error::SystemError;
use crate::{
driver::{
acpi::acpi_manager,
base::{
device::{bus::Bus, driver::Driver, Device},
kobject::KObject,
subsys::SubSysPrivate,
},
},
filesystem::{
sysfs::{Attribute, AttributeGroup},
vfs::syscall::ModeType,
},
};
use super::{serio_device::SerioDevice, serio_driver::SerioDriver};
#[derive(Debug)]
pub struct SerioBus {
private: SubSysPrivate,
}
impl SerioBus {
pub fn new() -> Arc<Self> {
let w: Weak<Self> = Weak::new();
let private = SubSysPrivate::new("serio".to_string(), Some(w), None, &[]);
let bus = Arc::new(Self { private });
bus.subsystem()
.set_bus(Some(Arc::downgrade(&(bus.clone() as Arc<dyn Bus>))));
return bus;
}
}
impl Bus for SerioBus {
fn name(&self) -> String {
return "serio".to_string();
}
fn dev_name(&self) -> String {
return self.name();
}
fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
return &[&SerioDeviceAttrGroup];
}
fn subsystem(&self) -> &SubSysPrivate {
return &self.private;
}
fn probe(&self, device: &Arc<dyn Device>) -> Result<(), SystemError> {
let drv = device.driver().ok_or(SystemError::EINVAL)?;
let pdrv = drv.cast::<dyn SerioDriver>().map_err(|_| {
kerror!(
"SerioBus::probe() failed: device.driver() is not a SerioDriver. Device: '{:?}'",
device.name()
);
SystemError::EINVAL
})?;
let pdev = device.clone().cast::<dyn SerioDevice>().map_err(|_| {
kerror!(
"SerioBus::probe() failed: device is not a SerioDevice. Device: '{:?}'",
device.name()
);
SystemError::EINVAL
})?;
return pdrv.connect(&pdev);
}
fn remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
todo!()
}
fn sync_state(&self, _device: &Arc<dyn Device>) {
todo!()
}
fn shutdown(&self, _device: &Arc<dyn Device>) {
todo!()
}
fn resume(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
todo!()
}
fn match_device(
&self,
device: &Arc<dyn Device>,
driver: &Arc<dyn Driver>,
) -> Result<bool, SystemError> {
// 尝试从 ACPI 中匹配
if let Ok(x) = acpi_manager().driver_match_device(driver, device) {
if x {
return Ok(true);
}
}
// 尝试从 ID table 中匹配
if let Some(drv_id_table) = driver.id_table() {
let pdev = device
.clone()
.cast::<dyn SerioDevice>()
.map_err(|_| SystemError::EINVAL)?;
if drv_id_table.name().eq(&pdev.name()) {
return Ok(true);
}
}
// 尝试根据设备名称匹配
return Ok(device.name().eq(&driver.name()));
}
}
#[derive(Debug)]
pub struct SerioDeviceAttrGroup;
impl AttributeGroup for SerioDeviceAttrGroup {
fn name(&self) -> Option<&str> {
None
}
/// todo: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/serio.c#473
fn attrs(&self) -> &[&'static dyn Attribute] {
return &[];
}
fn is_visible(&self, _kobj: Arc<dyn KObject>, _attr: &dyn Attribute) -> Option<ModeType> {
None
}
}

View File

@ -1,6 +1,7 @@
pub mod acpi; pub mod acpi;
pub mod base; pub mod base;
pub mod disk; pub mod disk;
pub mod input;
pub mod keyboard; pub mod keyboard;
pub mod net; pub mod net;
pub mod open_firmware; pub mod open_firmware;