Browse Source

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

* 新增serio总线和相关trait

* 补充SerioDeviceManager和SerioDriverManager
R0ronoa 1 year ago
parent
commit
d8e29bffee

+ 2 - 0
kernel/src/driver/base/init.rs

@@ -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 - 0
kernel/src/driver/input/mod.rs

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

+ 1 - 0
kernel/src/driver/input/ps2_dev/mod.rs

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

+ 4 - 0
kernel/src/driver/input/ps2_dev/ps2_device.rs

@@ -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 - 0
kernel/src/driver/input/serio/mod.rs

@@ -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 - 0
kernel/src/driver/input/serio/serio_device.rs

@@ -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 - 0
kernel/src/driver/input/serio/serio_driver.rs

@@ -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 - 0
kernel/src/driver/input/serio/subsys.rs

@@ -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 - 0
kernel/src/driver/mod.rs

@@ -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;