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