瀏覽代碼

添加i8042驱动 改正serio设备文件结构 (#538)

* 添加i8042驱动 改正serio设备文件结构
R0ronoa 1 年之前
父節點
當前提交
9993c0fc61

+ 10 - 7
kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs

@@ -6,7 +6,6 @@ use alloc::{
 };
 use kdepends::ringbuffer::{AllocRingBuffer, RingBuffer};
 use system_error::SystemError;
-use unified_init::macros::unified_init;
 
 use crate::{
     arch::{io::PortIOArch, CurrentIrqArch, CurrentPortIOArch},
@@ -20,7 +19,10 @@ use crate::{
             kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
             kset::KSet,
         },
-        input::serio::serio_device::{serio_device_manager, SerioDevice},
+        input::{
+            ps2_dev::ps2_device::Ps2Device,
+            serio::serio_device::{serio_device_manager, SerioDevice},
+        },
     },
     exception::InterruptArch,
     filesystem::{
@@ -31,7 +33,6 @@ use crate::{
             IndexNode, Metadata,
         },
     },
-    init::initcall::INITCALL_DEVICE,
     libs::{
         rwlock::{RwLockReadGuard, RwLockWriteGuard},
         spinlock::SpinLock,
@@ -316,7 +317,7 @@ impl Ps2MouseDevice {
                 //     guard.current_state.flags.bits,
                 //     guard.current_state.x,
                 //     guard.current_state.y
-                // )
+                // );
             }
             _ => unreachable!(),
         }
@@ -649,13 +650,15 @@ impl IndexNode for Ps2MouseDevice {
     }
 }
 
-#[unified_init(INITCALL_DEVICE)]
-fn rs_ps2_mouse_device_int() -> Result<(), SystemError> {
+impl Ps2Device for Ps2MouseDevice {}
+
+pub fn rs_ps2_mouse_device_init(parent: Arc<dyn KObject>) -> Result<(), SystemError> {
     kdebug!("ps2_mouse_device initializing...");
     let psmouse = Arc::new(Ps2MouseDevice::new());
 
     device_manager().device_default_initialize(&(psmouse.clone() as Arc<dyn Device>));
-    serio_device_manager().register_port(psmouse.clone())?;
+    psmouse.set_parent(Some(Arc::downgrade(&parent)));
+    serio_device_manager().register_port(psmouse.clone() as Arc<dyn SerioDevice>)?;
 
     devfs_register(&psmouse.name(), psmouse.clone()).map_err(|e| {
         kerror!(

+ 190 - 0
kernel/src/driver/input/serio/i8042/i8042_device.rs

@@ -0,0 +1,190 @@
+use alloc::{
+    string::{String, ToString},
+    sync::{Arc, Weak},
+};
+
+use crate::{
+    driver::base::{
+        class::Class,
+        device::{bus::Bus, driver::Driver, Device, DeviceState, DeviceType, IdTable},
+        kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
+        kset::KSet,
+        platform::{platform_device::PlatformDevice, CompatibleTable},
+    },
+    filesystem::kernfs::KernFSInode,
+    libs::{
+        rwlock::{RwLockReadGuard, RwLockWriteGuard},
+        spinlock::SpinLock,
+    },
+};
+
+#[derive(Debug)]
+#[cast_to([sync] Device)]
+#[cast_to([sync] PlatformDevice)]
+pub struct I8042PlatformDevice {
+    inner: SpinLock<InnerI8042PlatformDevice>,
+    kobj_state: LockedKObjectState,
+}
+
+impl I8042PlatformDevice {
+    pub const NAME: &'static str = "i8042";
+    pub fn new() -> Self {
+        return Self {
+            inner: SpinLock::new(InnerI8042PlatformDevice {
+                bus: None,
+                class: None,
+                driver: None,
+                kern_inode: None,
+                parent: None,
+                kset: None,
+                kobj_type: None,
+                device_state: DeviceState::NotInitialized,
+                pdev_id: 0,
+                pdev_id_auto: false,
+            }),
+            kobj_state: LockedKObjectState::new(None),
+        };
+    }
+}
+
+#[derive(Debug)]
+pub struct InnerI8042PlatformDevice {
+    bus: Option<Weak<dyn Bus>>,
+    class: Option<Arc<dyn Class>>,
+    driver: Option<Weak<dyn Driver>>,
+    kern_inode: Option<Arc<KernFSInode>>,
+    parent: Option<Weak<dyn KObject>>,
+    kset: Option<Arc<KSet>>,
+    kobj_type: Option<&'static dyn KObjType>,
+    device_state: DeviceState,
+    pdev_id: i32,
+    pdev_id_auto: bool,
+}
+
+impl Device for I8042PlatformDevice {
+    fn dev_type(&self) -> DeviceType {
+        DeviceType::Char
+    }
+
+    fn id_table(&self) -> IdTable {
+        IdTable::new(self.name(), None)
+    }
+
+    fn bus(&self) -> Option<Weak<dyn Bus>> {
+        self.inner.lock().bus.clone()
+    }
+
+    fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
+        self.inner.lock().bus = bus;
+    }
+
+    fn set_class(&self, class: Option<Arc<dyn Class>>) {
+        self.inner.lock().class = class;
+    }
+
+    fn driver(&self) -> Option<Arc<dyn Driver>> {
+        self.inner.lock().driver.clone()?.upgrade()
+    }
+
+    fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
+        self.inner.lock().driver = driver;
+    }
+
+    fn is_dead(&self) -> bool {
+        false
+    }
+
+    fn can_match(&self) -> bool {
+        true
+    }
+
+    fn set_can_match(&self, _can_match: bool) {}
+
+    fn state_synced(&self) -> bool {
+        true
+    }
+}
+
+impl KObject for I8042PlatformDevice {
+    fn as_any_ref(&self) -> &dyn core::any::Any {
+        self
+    }
+
+    fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
+        self.inner.lock().kern_inode = inode;
+    }
+
+    fn inode(&self) -> Option<Arc<KernFSInode>> {
+        self.inner.lock().kern_inode.clone()
+    }
+
+    fn parent(&self) -> Option<Weak<dyn KObject>> {
+        self.inner.lock().parent.clone()
+    }
+
+    fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
+        self.inner.lock().parent = parent;
+    }
+
+    fn kset(&self) -> Option<Arc<KSet>> {
+        self.inner.lock().kset.clone()
+    }
+
+    fn set_kset(&self, kset: Option<Arc<KSet>>) {
+        self.inner.lock().kset = kset;
+    }
+
+    fn kobj_type(&self) -> Option<&'static dyn KObjType> {
+        self.inner.lock().kobj_type
+    }
+
+    fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
+        self.inner.lock().kobj_type = ktype;
+    }
+
+    fn name(&self) -> String {
+        Self::NAME.to_string()
+    }
+
+    fn set_name(&self, _name: String) {
+        // do nothing
+    }
+
+    fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
+        self.kobj_state.read()
+    }
+
+    fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
+        self.kobj_state.write()
+    }
+
+    fn set_kobj_state(&self, state: KObjectState) {
+        *self.kobj_state.write() = state;
+    }
+}
+
+impl PlatformDevice for I8042PlatformDevice {
+    fn pdev_name(&self) -> &str {
+        Self::NAME
+    }
+
+    fn set_pdev_id(&self, id: i32) {
+        self.inner.lock().pdev_id = id;
+    }
+
+    fn set_pdev_id_auto(&self, id_auto: bool) {
+        self.inner.lock().pdev_id_auto = id_auto;
+    }
+
+    fn compatible_table(&self) -> CompatibleTable {
+        todo!()
+    }
+
+    fn is_initialized(&self) -> bool {
+        self.inner.lock().device_state == DeviceState::Initialized
+    }
+
+    fn set_state(&self, set_state: DeviceState) {
+        self.inner.lock().device_state = set_state;
+    }
+}

+ 190 - 0
kernel/src/driver/input/serio/i8042/i8042_driver.rs

@@ -0,0 +1,190 @@
+use alloc::{
+    string::{String, ToString},
+    sync::{Arc, Weak},
+    vec::Vec,
+};
+use system_error::SystemError;
+
+use crate::{
+    driver::base::{
+        device::{bus::Bus, driver::Driver, Device, IdTable},
+        kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
+        kset::KSet,
+        platform::{platform_device::PlatformDevice, platform_driver::PlatformDriver},
+    },
+    filesystem::kernfs::KernFSInode,
+    libs::{
+        rwlock::{RwLockReadGuard, RwLockWriteGuard},
+        spinlock::SpinLock,
+    },
+};
+
+use super::{i8042_device::I8042PlatformDevice, i8042_setup_aux};
+
+#[derive(Debug)]
+#[cast_to([sync] PlatformDriver)]
+pub struct I8042Driver {
+    inner: SpinLock<InnerI8042Driver>,
+    kobj_state: LockedKObjectState,
+}
+
+impl I8042Driver {
+    pub const NAME: &'static str = "i8042";
+    pub fn new() -> Arc<I8042Driver> {
+        let r = Arc::new(Self {
+            inner: SpinLock::new(InnerI8042Driver {
+                ktype: None,
+                kset: None,
+                parent: None,
+                kernfs_inode: None,
+                devices: Vec::new(),
+                bus: None,
+                self_ref: Weak::new(),
+            }),
+            kobj_state: LockedKObjectState::new(None),
+        });
+
+        r.inner.lock().self_ref = Arc::downgrade(&r);
+
+        return r;
+    }
+}
+
+#[derive(Debug)]
+pub struct InnerI8042Driver {
+    ktype: Option<&'static dyn KObjType>,
+    kset: Option<Arc<KSet>>,
+    parent: Option<Weak<dyn KObject>>,
+    kernfs_inode: Option<Arc<KernFSInode>>,
+    devices: Vec<Arc<dyn Device>>,
+    bus: Option<Weak<dyn Bus>>,
+
+    self_ref: Weak<I8042Driver>,
+}
+
+impl PlatformDriver for I8042Driver {
+    // TODO: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/i8042.c#1542
+    fn probe(&self, device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
+        let device = device
+            .clone()
+            .arc_any()
+            .downcast::<I8042PlatformDevice>()
+            .map_err(|_| SystemError::EINVAL)?;
+
+        device.set_driver(Some(self.inner.lock().self_ref.clone()));
+
+        i8042_setup_aux()?;
+        return Ok(());
+    }
+
+    // TODO: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/i8042.c#1587
+    fn remove(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
+        todo!()
+    }
+
+    // TODO: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/i8042.c#1322
+    fn shutdown(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
+        todo!()
+    }
+
+    fn suspend(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
+        // do nothing
+        return Ok(());
+    }
+
+    fn resume(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
+        // do nothing
+        return Ok(());
+    }
+}
+
+impl Driver for I8042Driver {
+    fn id_table(&self) -> Option<IdTable> {
+        Some(IdTable::new(I8042PlatformDevice::NAME.to_string(), None))
+    }
+
+    fn devices(&self) -> Vec<Arc<dyn Device>> {
+        self.inner.lock().devices.clone()
+    }
+
+    fn add_device(&self, device: Arc<dyn Device>) {
+        let mut guard = self.inner.lock();
+        // check if the device is already in the list
+        if guard.devices.iter().any(|dev| Arc::ptr_eq(dev, &device)) {
+            return;
+        }
+
+        guard.devices.push(device);
+    }
+
+    fn delete_device(&self, device: &Arc<dyn Device>) {
+        let mut guard = self.inner.lock();
+        guard.devices.retain(|dev| !Arc::ptr_eq(dev, device));
+    }
+
+    fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
+        self.inner.lock().bus = bus;
+    }
+
+    fn bus(&self) -> Option<Weak<dyn Bus>> {
+        self.inner.lock().bus.clone()
+    }
+}
+
+impl KObject for I8042Driver {
+    fn as_any_ref(&self) -> &dyn core::any::Any {
+        self
+    }
+
+    fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
+        self.inner.lock().kernfs_inode = inode;
+    }
+
+    fn inode(&self) -> Option<Arc<KernFSInode>> {
+        self.inner.lock().kernfs_inode.clone()
+    }
+
+    fn parent(&self) -> Option<Weak<dyn KObject>> {
+        self.inner.lock().parent.clone()
+    }
+
+    fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
+        self.inner.lock().parent = parent;
+    }
+
+    fn kset(&self) -> Option<Arc<KSet>> {
+        self.inner.lock().kset.clone()
+    }
+
+    fn set_kset(&self, kset: Option<Arc<KSet>>) {
+        self.inner.lock().kset = kset;
+    }
+
+    fn kobj_type(&self) -> Option<&'static dyn KObjType> {
+        self.inner.lock().ktype
+    }
+
+    fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
+        self.inner.lock().ktype = ktype;
+    }
+
+    fn name(&self) -> String {
+        Self::NAME.to_string()
+    }
+
+    fn set_name(&self, _name: String) {
+        // do nothing
+    }
+
+    fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
+        self.kobj_state.read()
+    }
+
+    fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
+        self.kobj_state.write()
+    }
+
+    fn set_kobj_state(&self, state: KObjectState) {
+        *self.kobj_state.write() = state;
+    }
+}

+ 185 - 0
kernel/src/driver/input/serio/i8042/i8042_ports.rs

@@ -0,0 +1,185 @@
+use alloc::{
+    string::{String, ToString},
+    sync::{Arc, Weak},
+};
+use system_error::SystemError;
+
+use crate::{
+    driver::{
+        base::{
+            class::Class,
+            device::{bus::Bus, driver::Driver, Device, DeviceType, IdTable},
+            kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
+            kset::KSet,
+        },
+        input::serio::serio_device::SerioDevice,
+    },
+    filesystem::kernfs::KernFSInode,
+    libs::{
+        rwlock::{RwLockReadGuard, RwLockWriteGuard},
+        spinlock::SpinLock,
+    },
+};
+
+use super::{i8042_start, i8042_stop};
+
+#[derive(Debug)]
+#[cast_to([sync] Device)]
+pub struct I8042AuxPort {
+    inner: SpinLock<InnerI8042AuxPort>,
+    kobj_state: LockedKObjectState,
+}
+
+#[derive(Debug)]
+pub struct InnerI8042AuxPort {
+    bus: Option<Weak<dyn Bus>>,
+    class: Option<Arc<dyn Class>>,
+    driver: Option<Weak<dyn Driver>>,
+    kern_inode: Option<Arc<KernFSInode>>,
+    parent: Option<Weak<dyn KObject>>,
+    kset: Option<Arc<KSet>>,
+    kobj_type: Option<&'static dyn KObjType>,
+}
+
+impl I8042AuxPort {
+    pub const NAME: &'static str = "serio1";
+    pub fn new() -> Self {
+        return Self {
+            inner: SpinLock::new(InnerI8042AuxPort {
+                bus: None,
+                class: None,
+                driver: None,
+                kern_inode: None,
+                parent: None,
+                kset: None,
+                kobj_type: None,
+            }),
+            kobj_state: LockedKObjectState::new(None),
+        };
+    }
+}
+
+impl Device for I8042AuxPort {
+    fn dev_type(&self) -> DeviceType {
+        DeviceType::Char
+    }
+
+    fn id_table(&self) -> IdTable {
+        IdTable::new(self.name(), None)
+    }
+
+    fn bus(&self) -> Option<Weak<dyn Bus>> {
+        self.inner.lock().bus.clone()
+    }
+
+    fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
+        self.inner.lock().bus = bus;
+    }
+
+    fn set_class(&self, class: Option<Arc<dyn Class>>) {
+        self.inner.lock().class = class;
+    }
+
+    fn driver(&self) -> Option<Arc<dyn Driver>> {
+        self.inner.lock().driver.clone()?.upgrade()
+    }
+
+    fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
+        self.inner.lock().driver = driver;
+    }
+
+    fn is_dead(&self) -> bool {
+        false
+    }
+
+    fn can_match(&self) -> bool {
+        true
+    }
+
+    fn set_can_match(&self, _can_match: bool) {}
+
+    fn state_synced(&self) -> bool {
+        true
+    }
+}
+
+impl KObject for I8042AuxPort {
+    fn as_any_ref(&self) -> &dyn core::any::Any {
+        self
+    }
+
+    fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
+        self.inner.lock().kern_inode = inode;
+    }
+
+    fn inode(&self) -> Option<Arc<KernFSInode>> {
+        self.inner.lock().kern_inode.clone()
+    }
+
+    fn parent(&self) -> Option<Weak<dyn KObject>> {
+        self.inner.lock().parent.clone()
+    }
+
+    fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
+        self.inner.lock().parent = parent;
+    }
+
+    fn kset(&self) -> Option<Arc<KSet>> {
+        self.inner.lock().kset.clone()
+    }
+
+    fn set_kset(&self, kset: Option<Arc<KSet>>) {
+        self.inner.lock().kset = kset;
+    }
+
+    fn kobj_type(&self) -> Option<&'static dyn KObjType> {
+        self.inner.lock().kobj_type
+    }
+
+    fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
+        self.inner.lock().kobj_type = ktype;
+    }
+
+    fn name(&self) -> String {
+        Self::NAME.to_string()
+    }
+
+    fn set_name(&self, _name: String) {
+        // do nothing
+    }
+
+    fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
+        self.kobj_state.read()
+    }
+
+    fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
+        self.kobj_state.write()
+    }
+
+    fn set_kobj_state(&self, state: KObjectState) {
+        *self.kobj_state.write() = state;
+    }
+}
+
+impl SerioDevice for I8042AuxPort {
+    // TODO: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/i8042.c#387
+    fn write(&self, _device: &Arc<dyn SerioDevice>, _data: u8) -> Result<(), SystemError> {
+        todo!()
+    }
+
+    fn open(&self, _device: &Arc<dyn SerioDevice>) -> Result<(), SystemError> {
+        Ok(())
+    }
+
+    fn close(&self, _device: &Arc<dyn SerioDevice>) -> Result<(), SystemError> {
+        Ok(())
+    }
+
+    fn start(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError> {
+        i8042_start(device)
+    }
+
+    fn stop(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError> {
+        i8042_stop(device)
+    }
+}

+ 75 - 0
kernel/src/driver/input/serio/i8042/mod.rs

@@ -0,0 +1,75 @@
+use alloc::sync::Arc;
+use system_error::SystemError;
+use unified_init::macros::unified_init;
+
+use crate::{
+    driver::{
+        base::{
+            device::{device_manager, Device},
+            kobject::KObject,
+            platform::{
+                platform_device::{platform_device_manager, PlatformDevice},
+                platform_driver::{platform_driver_manager, PlatformDriver},
+            },
+        },
+        input::ps2_mouse::ps_mouse_device::rs_ps2_mouse_device_init,
+    },
+    init::initcall::INITCALL_DEVICE,
+};
+
+use self::{
+    i8042_device::I8042PlatformDevice, i8042_driver::I8042Driver, i8042_ports::I8042AuxPort,
+};
+
+use super::serio_device::{serio_device_manager, SerioDevice};
+
+pub mod i8042_device;
+pub mod i8042_driver;
+pub mod i8042_ports;
+
+static mut I8042_PLATFORM_DEVICE: Option<Arc<I8042PlatformDevice>> = None;
+
+pub fn i8042_platform_device() -> Arc<I8042PlatformDevice> {
+    unsafe { I8042_PLATFORM_DEVICE.clone().unwrap() }
+}
+
+// TODO: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/i8042.c#1612
+#[unified_init(INITCALL_DEVICE)]
+pub fn i8042_init() -> Result<(), SystemError> {
+    kdebug!("i8042 initializing...");
+    let i8042_device = Arc::new(I8042PlatformDevice::new());
+    device_manager().device_default_initialize(&(i8042_device.clone() as Arc<dyn Device>));
+    platform_device_manager().device_add(i8042_device.clone() as Arc<dyn PlatformDevice>)?;
+    unsafe {
+        I8042_PLATFORM_DEVICE = Some(i8042_device);
+    }
+
+    let i8042_driver = I8042Driver::new();
+    platform_driver_manager().register(i8042_driver.clone() as Arc<dyn PlatformDriver>)?;
+    Ok(())
+}
+
+// TODO: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/i8042.c#441
+pub fn i8042_start(_serio: &Arc<dyn SerioDevice>) -> Result<(), SystemError> {
+    todo!()
+}
+
+// TODO: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/i8042.c#471
+pub fn i8042_stop(_serio: &Arc<dyn SerioDevice>) -> Result<(), SystemError> {
+    todo!()
+}
+
+/// # 函数的功能
+/// 创建i8042 Aux设备
+///
+/// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/i8042.c#i8042_setup_aux
+pub fn i8042_setup_aux() -> Result<(), SystemError> {
+    let aux_port = Arc::new(I8042AuxPort::new());
+    aux_port.set_parent(Some(Arc::downgrade(
+        &(i8042_platform_device() as Arc<dyn KObject>),
+    )));
+    serio_device_manager().register_port(aux_port.clone() as Arc<dyn SerioDevice>)?;
+
+    rs_ps2_mouse_device_init(aux_port.clone() as Arc<dyn KObject>)?;
+    Ok(())
+}

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

@@ -5,6 +5,7 @@ use crate::driver::base::device::bus::{bus_register, Bus};
 
 use self::subsys::SerioBus;
 
+pub mod i8042;
 pub mod serio_device;
 pub mod serio_driver;
 pub mod subsys;