xref: /DragonOS/kernel/src/driver/keyboard/ps2_keyboard.rs (revision 91e9d4ab55ef960f57a1b6287bc523ca4341f67a)
1 use core::{ffi::c_void, sync::atomic::AtomicI32};
2 
3 use alloc::sync::{Arc, Weak};
4 
5 use crate::{
6     driver::tty::tty_device::TTY_DEVICES,
7     filesystem::{
8         devfs::{devfs_register, DevFS, DeviceINode},
9         vfs::{
10             core::generate_inode_id, file::FileMode, syscall::ModeType, FileType, IndexNode,
11             Metadata,
12         },
13     },
14     include::bindings::bindings::vfs_file_operations_t,
15     libs::{keyboard_parser::TypeOneFSM, rwlock::RwLock, spinlock::SpinLock},
16     time::TimeSpec,
17 };
18 use system_error::SystemError;
19 #[derive(Debug)]
20 pub struct LockedPS2KeyBoardInode(RwLock<PS2KeyBoardInode>, AtomicI32); // self.1 用来记录有多少个文件打开了这个inode
21 
22 lazy_static! {
23     static ref PS2_KEYBOARD_FSM: SpinLock<TypeOneFSM> = {
24         let tty0 = TTY_DEVICES
25             .read()
26             .get("tty0")
27             .expect("Initializing PS2_KEYBOARD_FSM: Cannot found TTY0!")
28             .clone();
29         SpinLock::new(TypeOneFSM::new(tty0))
30     };
31 }
32 
33 #[derive(Debug)]
34 pub struct PS2KeyBoardInode {
35     /// uuid 暂时不知道有什么用(x
36     // uuid: Uuid,
37     /// 指向自身的弱引用
38     self_ref: Weak<LockedPS2KeyBoardInode>,
39     /// 指向inode所在的文件系统对象的指针
40     fs: Weak<DevFS>,
41     /// INode 元数据
42     metadata: Metadata,
43     /// 键盘操作函数
44     f_ops: vfs_file_operations_t,
45 }
46 
47 impl LockedPS2KeyBoardInode {
48     pub fn new(f_ops: &vfs_file_operations_t) -> Arc<Self> {
49         let inode = PS2KeyBoardInode {
50             // uuid: Uuid::new_v5(),
51             self_ref: Weak::default(),
52             fs: Weak::default(),
53             f_ops: f_ops.clone(), // 从引用复制一遍获取所有权
54             metadata: Metadata {
55                 dev_id: 1,
56                 inode_id: generate_inode_id(),
57                 size: 0,
58                 blk_size: 0,
59                 blocks: 0,
60                 atime: TimeSpec::default(),
61                 mtime: TimeSpec::default(),
62                 ctime: TimeSpec::default(),
63                 file_type: FileType::CharDevice, // 文件夹,block设备,char设备
64                 mode: ModeType::from_bits_truncate(0o666),
65                 nlinks: 1,
66                 uid: 0,
67                 gid: 0,
68                 raw_dev: 0, // 这里用来作为device number
69             },
70         };
71 
72         let result = Arc::new(LockedPS2KeyBoardInode(
73             RwLock::new(inode),
74             AtomicI32::new(0),
75         ));
76         result.0.write().self_ref = Arc::downgrade(&result);
77 
78         return result;
79     }
80 }
81 
82 impl DeviceINode for LockedPS2KeyBoardInode {
83     fn set_fs(&self, fs: Weak<DevFS>) {
84         self.0.write().fs = fs;
85     }
86 }
87 
88 #[no_mangle] // 不重命名
89 pub extern "C" fn ps2_keyboard_register(f_ops: &vfs_file_operations_t) {
90     devfs_register("ps2_keyboard", LockedPS2KeyBoardInode::new(f_ops))
91         .expect("Failed to register ps/2 keyboard");
92 }
93 
94 impl IndexNode for LockedPS2KeyBoardInode {
95     fn read_at(
96         &self,
97         _offset: usize,
98         len: usize,
99         buf: &mut [u8],
100         _data: &mut crate::filesystem::vfs::FilePrivateData,
101     ) -> Result<usize, SystemError> {
102         let guard = self.0.read();
103         let func = guard.f_ops.read.unwrap();
104         let r = unsafe {
105             func(
106                 0 as *mut c_void,
107                 &mut buf[0..len] as *mut [u8] as *mut i8,
108                 len as i64,
109                 0 as *mut i64,
110             )
111         };
112         return Ok(r as usize);
113     }
114 
115     fn write_at(
116         &self,
117         _offset: usize,
118         _len: usize,
119         _buf: &[u8],
120         _data: &mut crate::filesystem::vfs::FilePrivateData,
121     ) -> Result<usize, SystemError> {
122         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
123     }
124 
125     fn open(
126         &self,
127         _data: &mut crate::filesystem::vfs::FilePrivateData,
128         _mode: &FileMode,
129     ) -> Result<(), SystemError> {
130         let prev_ref_count = self.1.fetch_add(1, core::sync::atomic::Ordering::SeqCst);
131         if prev_ref_count == 0 {
132             // 第一次打开,需要初始化
133             let guard = self.0.write();
134             let func = guard.f_ops.open.unwrap();
135             let _ = unsafe { func(0 as *mut c_void, 0 as *mut c_void) };
136         }
137         return Ok(());
138     }
139 
140     fn close(
141         &self,
142         _data: &mut crate::filesystem::vfs::FilePrivateData,
143     ) -> Result<(), SystemError> {
144         let prev_ref_count = self.1.fetch_sub(1, core::sync::atomic::Ordering::SeqCst);
145         if prev_ref_count == 1 {
146             // 最后一次关闭,需要释放
147             let guard = self.0.write();
148             let func = guard.f_ops.close.unwrap();
149             let _ = unsafe { func(0 as *mut c_void, 0 as *mut c_void) };
150         }
151         return Ok(());
152     }
153 
154     fn metadata(&self) -> Result<Metadata, SystemError> {
155         return Ok(self.0.read().metadata.clone());
156     }
157 
158     fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> {
159         let mut inode = self.0.write();
160         inode.metadata.atime = metadata.atime;
161         inode.metadata.mtime = metadata.mtime;
162         inode.metadata.ctime = metadata.ctime;
163         inode.metadata.mode = metadata.mode;
164         inode.metadata.uid = metadata.uid;
165         inode.metadata.gid = metadata.gid;
166 
167         return Ok(());
168     }
169 
170     fn fs(&self) -> alloc::sync::Arc<dyn crate::filesystem::vfs::FileSystem> {
171         return self.0.read().fs.upgrade().unwrap();
172     }
173 
174     fn as_any_ref(&self) -> &dyn core::any::Any {
175         self
176     }
177 
178     fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> {
179         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
180     }
181 }
182 
183 #[allow(dead_code)]
184 #[no_mangle]
185 /// for test
186 pub extern "C" fn ps2_keyboard_parse_keycode(input: u8) {
187     PS2_KEYBOARD_FSM.lock().parse(input);
188 }
189