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