mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 19:36:47 +00:00
增加serio总线和相关trait (#488)
* 新增serio总线和相关trait * 补充SerioDeviceManager和SerioDriverManager
This commit is contained in:
parent
6994f6b113
commit
d8e29bffee
@ -1,3 +1,4 @@
|
||||
use crate::driver::input::serio::serio_bus_init;
|
||||
use system_error::SystemError;
|
||||
|
||||
use super::{
|
||||
@ -16,6 +17,7 @@ pub(super) fn driver_init() -> Result<(), SystemError> {
|
||||
firmware_init()?;
|
||||
hypervisor_init()?;
|
||||
platform_bus_init()?;
|
||||
serio_bus_init()?;
|
||||
cpu_device_manager().init()?;
|
||||
|
||||
// 至此,已完成设备驱动模型的初始化
|
||||
|
2
kernel/src/driver/input/mod.rs
Normal file
2
kernel/src/driver/input/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod ps2_dev;
|
||||
pub mod serio;
|
1
kernel/src/driver/input/ps2_dev/mod.rs
Normal file
1
kernel/src/driver/input/ps2_dev/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod ps2_device;
|
4
kernel/src/driver/input/ps2_dev/ps2_device.rs
Normal file
4
kernel/src/driver/input/ps2_dev/ps2_device.rs
Normal 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 {}
|
31
kernel/src/driver/input/serio/mod.rs
Normal file
31
kernel/src/driver/input/serio/mod.rs
Normal 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;
|
||||
}
|
70
kernel/src/driver/input/serio/serio_device.rs
Normal file
70
kernel/src/driver/input/serio/serio_device.rs
Normal 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设备
|
||||
///
|
||||
/// ## 返回值
|
||||
/// 无
|
||||
///
|
||||
/// todo:https://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(())
|
||||
}
|
||||
}
|
75
kernel/src/driver/input/serio/serio_driver.rs
Normal file
75
kernel/src/driver/input/serio/serio_driver.rs
Normal 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>));
|
||||
}
|
||||
}
|
140
kernel/src/driver/input/serio/subsys.rs
Normal file
140
kernel/src/driver/input/serio/subsys.rs
Normal 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
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
pub mod acpi;
|
||||
pub mod base;
|
||||
pub mod disk;
|
||||
pub mod input;
|
||||
pub mod keyboard;
|
||||
pub mod net;
|
||||
pub mod open_firmware;
|
||||
|
Loading…
x
Reference in New Issue
Block a user