Skip to content

Commit d8e29bf

Browse files
authored
增加serio总线和相关trait (#488)
* 新增serio总线和相关trait * 补充SerioDeviceManager和SerioDriverManager
1 parent 6994f6b commit d8e29bf

File tree

9 files changed

+326
-0
lines changed

9 files changed

+326
-0
lines changed

kernel/src/driver/base/init.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::driver::input::serio::serio_bus_init;
12
use system_error::SystemError;
23

34
use super::{
@@ -16,6 +17,7 @@ pub(super) fn driver_init() -> Result<(), SystemError> {
1617
firmware_init()?;
1718
hypervisor_init()?;
1819
platform_bus_init()?;
20+
serio_bus_init()?;
1921
cpu_device_manager().init()?;
2022

2123
// 至此,已完成设备驱动模型的初始化

kernel/src/driver/input/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod ps2_dev;
2+
pub mod serio;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod ps2_device;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
use crate::driver::{base::device::Device, input::serio::serio_device::SerioDevice};
2+
3+
// todo: https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/libps2.h#33
4+
pub trait Ps2Device: Device + SerioDevice {}

kernel/src/driver/input/serio/mod.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use alloc::sync::Arc;
2+
use system_error::SystemError;
3+
4+
use crate::driver::base::device::bus::{bus_register, Bus};
5+
6+
use self::subsys::SerioBus;
7+
8+
pub mod serio_device;
9+
pub mod serio_driver;
10+
pub mod subsys;
11+
12+
static mut SERIO_BUS: Option<Arc<SerioBus>> = None;
13+
14+
#[allow(dead_code)]
15+
#[inline(always)]
16+
pub fn serio_bus() -> Arc<SerioBus> {
17+
unsafe { SERIO_BUS.clone().unwrap() }
18+
}
19+
20+
/// # 函数的功能
21+
///
22+
/// 初始化serio bus
23+
///
24+
/// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/serio.c#1024
25+
pub fn serio_bus_init() -> Result<(), SystemError> {
26+
let serio_bus = SerioBus::new();
27+
let r = bus_register(serio_bus.clone() as Arc<dyn Bus>);
28+
unsafe { SERIO_BUS = Some(serio_bus) };
29+
30+
return r;
31+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
use alloc::sync::Arc;
2+
use system_error::SystemError;
3+
4+
use crate::driver::base::device::{bus::Bus, Device};
5+
6+
use super::serio_bus;
7+
8+
/// 串行设备,实现该trait的设备实例挂载在serio总线上,同时应该实现Device trait
9+
///
10+
/// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/serio.h#20
11+
pub trait SerioDevice: Device {
12+
/// # 函数功能
13+
///
14+
/// Serio设备写入数据
15+
///
16+
/// ## 参数
17+
///
18+
/// - data 写入的数据
19+
///
20+
/// ## 返回值
21+
///
22+
/// 无
23+
fn write(&self, device: &Arc<dyn SerioDevice>, data: u8) -> Result<(), SystemError>;
24+
/// Serio设备连接驱动时调用
25+
fn open(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
26+
/// Serio设备断开驱动时调用
27+
fn close(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
28+
/// Serio设备初始化时调用
29+
fn start(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
30+
/// Serio设备销毁时调用
31+
fn stop(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
32+
}
33+
34+
#[allow(dead_code)]
35+
#[inline(always)]
36+
pub fn serio_device_manager() -> &'static SerioDeviceManager {
37+
&SerioDeviceManager
38+
}
39+
40+
pub struct SerioDeviceManager;
41+
42+
#[allow(dead_code)]
43+
impl SerioDeviceManager {
44+
/// # 函数功能
45+
/// 注册Serio设备
46+
///
47+
/// ## 参数
48+
/// - device 待注册的设备
49+
///
50+
/// ## 返回值
51+
/// 无
52+
pub fn register_port(&self, device: Arc<dyn SerioDevice>) -> Result<(), SystemError> {
53+
self.init_port(device)
54+
}
55+
56+
/// # 函数功能
57+
/// 初始化Serio设备
58+
///
59+
/// ## 参数
60+
/// - device 待初始化的Serio设备
61+
///
62+
/// ## 返回值
63+
/// 无
64+
///
65+
/// todo:https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/serio.c#494
66+
pub fn init_port(&self, device: Arc<dyn SerioDevice>) -> Result<(), SystemError> {
67+
device.set_bus(Some(Arc::downgrade(&(serio_bus() as Arc<dyn Bus>))));
68+
Ok(())
69+
}
70+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use alloc::sync::Arc;
2+
use system_error::SystemError;
3+
4+
use crate::driver::base::device::{
5+
bus::Bus,
6+
driver::{driver_manager, Driver},
7+
};
8+
9+
use super::{serio_bus, serio_device::SerioDevice};
10+
11+
/// 实现该trait的设备驱动实例应挂载在serio总线上,同时应该实现Driver trait
12+
///
13+
/// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/serio.h#67
14+
pub trait SerioDriver: Driver {
15+
// 写入时唤醒设备
16+
fn write_wakeup(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
17+
/// # 函数功能
18+
/// 中断函数
19+
///
20+
/// ## 参数
21+
/// - device: Serio设备
22+
/// - data: 端口数据
23+
/// - flag: 状态掩码
24+
///
25+
/// ## 返回值
26+
/// 无
27+
fn interrupt(
28+
&self,
29+
device: &Arc<dyn SerioDevice>,
30+
data: u8,
31+
flag: u8,
32+
) -> Result<(), SystemError>;
33+
/// Serio驱动连接设备
34+
fn connect(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
35+
/// 重新连接设备
36+
fn reconnect(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
37+
/// 快速重连设备
38+
fn fast_reconnect(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
39+
/// 驱动断开设备
40+
fn disconnect(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
41+
/// 清除设备状态
42+
fn cleanup(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError>;
43+
}
44+
45+
///todo: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/serio.c#810
46+
pub struct SerioDriverManager;
47+
48+
#[allow(dead_code)]
49+
impl SerioDriverManager {
50+
/// # 函数功能
51+
/// 注册Serio驱动
52+
///
53+
/// ## 参数
54+
/// - driver 待注册的Serio驱动
55+
///
56+
/// ## 返回值
57+
/// 无
58+
pub fn register(&self, driver: Arc<dyn SerioDriver>) -> Result<(), SystemError> {
59+
driver.set_bus(Some(Arc::downgrade(&(serio_bus() as Arc<dyn Bus>))));
60+
return driver_manager().register(driver as Arc<dyn Driver>);
61+
}
62+
63+
/// # 函数功能
64+
/// 卸载Serio驱动
65+
///
66+
/// ## 参数
67+
/// - driver 待卸载的Serio驱动
68+
///
69+
/// ## 返回值
70+
/// 无
71+
#[allow(dead_code)]
72+
pub fn unregister(&self, driver: &Arc<dyn SerioDriver>) {
73+
driver_manager().unregister(&(driver.clone() as Arc<dyn Driver>));
74+
}
75+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
use alloc::{
2+
string::{String, ToString},
3+
sync::{Arc, Weak},
4+
};
5+
use intertrait::cast::CastArc;
6+
use system_error::SystemError;
7+
8+
use crate::{
9+
driver::{
10+
acpi::acpi_manager,
11+
base::{
12+
device::{bus::Bus, driver::Driver, Device},
13+
kobject::KObject,
14+
subsys::SubSysPrivate,
15+
},
16+
},
17+
filesystem::{
18+
sysfs::{Attribute, AttributeGroup},
19+
vfs::syscall::ModeType,
20+
},
21+
};
22+
23+
use super::{serio_device::SerioDevice, serio_driver::SerioDriver};
24+
25+
#[derive(Debug)]
26+
pub struct SerioBus {
27+
private: SubSysPrivate,
28+
}
29+
30+
impl SerioBus {
31+
pub fn new() -> Arc<Self> {
32+
let w: Weak<Self> = Weak::new();
33+
let private = SubSysPrivate::new("serio".to_string(), Some(w), None, &[]);
34+
let bus = Arc::new(Self { private });
35+
bus.subsystem()
36+
.set_bus(Some(Arc::downgrade(&(bus.clone() as Arc<dyn Bus>))));
37+
38+
return bus;
39+
}
40+
}
41+
42+
impl Bus for SerioBus {
43+
fn name(&self) -> String {
44+
return "serio".to_string();
45+
}
46+
47+
fn dev_name(&self) -> String {
48+
return self.name();
49+
}
50+
51+
fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
52+
return &[&SerioDeviceAttrGroup];
53+
}
54+
55+
fn subsystem(&self) -> &SubSysPrivate {
56+
return &self.private;
57+
}
58+
59+
fn probe(&self, device: &Arc<dyn Device>) -> Result<(), SystemError> {
60+
let drv = device.driver().ok_or(SystemError::EINVAL)?;
61+
let pdrv = drv.cast::<dyn SerioDriver>().map_err(|_| {
62+
kerror!(
63+
"SerioBus::probe() failed: device.driver() is not a SerioDriver. Device: '{:?}'",
64+
device.name()
65+
);
66+
SystemError::EINVAL
67+
})?;
68+
69+
let pdev = device.clone().cast::<dyn SerioDevice>().map_err(|_| {
70+
kerror!(
71+
"SerioBus::probe() failed: device is not a SerioDevice. Device: '{:?}'",
72+
device.name()
73+
);
74+
SystemError::EINVAL
75+
})?;
76+
77+
return pdrv.connect(&pdev);
78+
}
79+
80+
fn remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
81+
todo!()
82+
}
83+
84+
fn sync_state(&self, _device: &Arc<dyn Device>) {
85+
todo!()
86+
}
87+
88+
fn shutdown(&self, _device: &Arc<dyn Device>) {
89+
todo!()
90+
}
91+
92+
fn resume(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
93+
todo!()
94+
}
95+
96+
fn match_device(
97+
&self,
98+
device: &Arc<dyn Device>,
99+
driver: &Arc<dyn Driver>,
100+
) -> Result<bool, SystemError> {
101+
// 尝试从 ACPI 中匹配
102+
if let Ok(x) = acpi_manager().driver_match_device(driver, device) {
103+
if x {
104+
return Ok(true);
105+
}
106+
}
107+
108+
// 尝试从 ID table 中匹配
109+
if let Some(drv_id_table) = driver.id_table() {
110+
let pdev = device
111+
.clone()
112+
.cast::<dyn SerioDevice>()
113+
.map_err(|_| SystemError::EINVAL)?;
114+
if drv_id_table.name().eq(&pdev.name()) {
115+
return Ok(true);
116+
}
117+
}
118+
119+
// 尝试根据设备名称匹配
120+
return Ok(device.name().eq(&driver.name()));
121+
}
122+
}
123+
124+
#[derive(Debug)]
125+
pub struct SerioDeviceAttrGroup;
126+
127+
impl AttributeGroup for SerioDeviceAttrGroup {
128+
fn name(&self) -> Option<&str> {
129+
None
130+
}
131+
132+
/// todo: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/serio.c#473
133+
fn attrs(&self) -> &[&'static dyn Attribute] {
134+
return &[];
135+
}
136+
137+
fn is_visible(&self, _kobj: Arc<dyn KObject>, _attr: &dyn Attribute) -> Option<ModeType> {
138+
None
139+
}
140+
}

kernel/src/driver/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pub mod acpi;
22
pub mod base;
33
pub mod disk;
4+
pub mod input;
45
pub mod keyboard;
56
pub mod net;
67
pub mod open_firmware;

0 commit comments

Comments
 (0)