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 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()?;
|
||||||
|
|
||||||
// 至此,已完成设备驱动模型的初始化
|
// 至此,已完成设备驱动模型的初始化
|
||||||
|
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 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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user