xref: /DragonOS/kernel/src/driver/input/ps2_mouse/ps_mouse_driver.rs (revision 59a6bcf6aee15a11a16431bdf875905c5ecf9157)
1 use alloc::{
2     string::ToString,
3     sync::{Arc, Weak},
4     vec::Vec,
5 };
6 use log::debug;
7 use system_error::SystemError;
8 use unified_init::macros::unified_init;
9 
10 use crate::{
11     arch::{io::PortIOArch, CurrentPortIOArch},
12     driver::{
13         base::{
14             device::{bus::Bus, driver::Driver, Device, DeviceId, IdTable},
15             kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
16             kset::KSet,
17         },
18         input::serio::{
19             serio_device::SerioDevice,
20             serio_driver::{serio_driver_manager, SerioDriver},
21         },
22     },
23     exception::{
24         irqdata::IrqHandlerData,
25         irqdesc::{IrqHandleFlags, IrqHandler, IrqReturn},
26         manage::irq_manager,
27         IrqNumber,
28     },
29     filesystem::kernfs::KernFSInode,
30     init::initcall::INITCALL_DEVICE,
31     libs::{
32         rwlock::{RwLockReadGuard, RwLockWriteGuard},
33         spinlock::SpinLock,
34     },
35 };
36 
37 use super::ps_mouse_device::{ps2_mouse_device, Ps2MouseDevice};
38 
39 const PS2_MOUSE_IRQ_NUM: IrqNumber = IrqNumber::new(0x2c);
40 
41 #[no_mangle]
42 unsafe extern "C" fn ps2_mouse_driver_interrupt() {}
43 
44 #[derive(Debug)]
45 struct Ps2MouseIrqHandler;
46 
47 impl IrqHandler for Ps2MouseIrqHandler {
48     fn handle(
49         &self,
50         _irq: IrqNumber,
51         _static_data: Option<&dyn IrqHandlerData>,
52         _dev_id: Option<Arc<dyn IrqHandlerData>>,
53     ) -> Result<IrqReturn, SystemError> {
54         if let Some(psmouse_device) = ps2_mouse_device() {
55             return Ok(ps2_mouse_driver()
56                 .interrupt(&(psmouse_device as Arc<dyn SerioDevice>), 0, 0)
57                 .map(|_| IrqReturn::Handled)
58                 .unwrap_or_else(|_| IrqReturn::NotHandled));
59         } else {
60             unsafe { CurrentPortIOArch::in8(0x60) };
61             return Ok(IrqReturn::NotHandled);
62         }
63     }
64 }
65 
66 static mut PS2_MOUSE_DRIVER: Option<Arc<Ps2MouseDriver>> = None;
67 
68 #[allow(dead_code)]
69 pub fn ps2_mouse_driver() -> Arc<Ps2MouseDriver> {
70     unsafe { PS2_MOUSE_DRIVER.clone().unwrap() }
71 }
72 
73 #[derive(Debug)]
74 #[cast_to([sync] Driver)]
75 #[cast_to([sync] SerioDriver)]
76 pub struct Ps2MouseDriver {
77     inner: SpinLock<InnerPs2MouseDriver>,
78     kobj_state: LockedKObjectState,
79 }
80 
81 impl Ps2MouseDriver {
82     pub const NAME: &'static str = "psmouse";
83     pub fn new() -> Arc<Self> {
84         let r = Arc::new(Ps2MouseDriver {
85             inner: SpinLock::new(InnerPs2MouseDriver {
86                 ktype: None,
87                 kset: None,
88                 parent: None,
89                 kernfs_inode: None,
90                 devices: Vec::new(),
91                 bus: None,
92                 self_ref: Weak::new(),
93             }),
94             kobj_state: LockedKObjectState::new(None),
95         });
96 
97         r.inner.lock().self_ref = Arc::downgrade(&r);
98         return r;
99     }
100 
101     #[allow(dead_code)]
102     pub fn process_packet(&self) {
103         let guard = self.inner.lock();
104         if guard.devices.is_empty() {
105             return;
106         }
107 
108         let device: Option<&Ps2MouseDevice> = guard.devices[0]
109             .as_any_ref()
110             .downcast_ref::<Ps2MouseDevice>();
111         let _ = device.unwrap().process_packet();
112     }
113 }
114 
115 #[derive(Debug)]
116 pub struct InnerPs2MouseDriver {
117     ktype: Option<&'static dyn KObjType>,
118     kset: Option<Arc<KSet>>,
119     parent: Option<Weak<dyn KObject>>,
120     kernfs_inode: Option<Arc<KernFSInode>>,
121     devices: Vec<Arc<dyn Device>>,
122     bus: Option<Weak<dyn Bus>>,
123     self_ref: Weak<Ps2MouseDriver>,
124 }
125 
126 impl Driver for Ps2MouseDriver {
127     fn id_table(&self) -> Option<IdTable> {
128         Some(IdTable::new("psmouse".to_string(), None))
129     }
130 
131     fn devices(&self) -> alloc::vec::Vec<Arc<dyn Device>> {
132         self.inner.lock().devices.clone()
133     }
134 
135     fn add_device(&self, device: Arc<dyn Device>) {
136         let mut guard = self.inner.lock();
137         // check if the device is already in the list
138         if guard.devices.iter().any(|dev| Arc::ptr_eq(dev, &device)) {
139             return;
140         }
141 
142         guard.devices.push(device);
143     }
144 
145     fn delete_device(&self, device: &Arc<dyn Device>) {
146         let mut guard = self.inner.lock();
147         guard.devices.retain(|dev| !Arc::ptr_eq(dev, device));
148     }
149 
150     fn set_bus(&self, bus: Option<alloc::sync::Weak<dyn Bus>>) {
151         self.inner.lock().bus = bus;
152     }
153 
154     fn bus(&self) -> Option<Weak<dyn Bus>> {
155         self.inner.lock().bus.clone()
156     }
157 }
158 
159 impl KObject for Ps2MouseDriver {
160     fn as_any_ref(&self) -> &dyn core::any::Any {
161         self
162     }
163 
164     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
165         self.inner.lock().kernfs_inode = inode;
166     }
167 
168     fn inode(&self) -> Option<Arc<KernFSInode>> {
169         self.inner.lock().kernfs_inode.clone()
170     }
171 
172     fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
173         self.inner.lock().parent.clone()
174     }
175 
176     fn set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>) {
177         self.inner.lock().parent = parent;
178     }
179 
180     fn kset(&self) -> Option<Arc<KSet>> {
181         self.inner.lock().kset.clone()
182     }
183 
184     fn set_kset(&self, kset: Option<Arc<KSet>>) {
185         self.inner.lock().kset = kset;
186     }
187 
188     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
189         self.inner.lock().ktype
190     }
191 
192     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
193         self.inner.lock().ktype = ktype;
194     }
195 
196     fn name(&self) -> alloc::string::String {
197         Self::NAME.to_string()
198     }
199 
200     fn set_name(&self, _name: alloc::string::String) {}
201 
202     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
203         self.kobj_state.read()
204     }
205 
206     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
207         self.kobj_state.write()
208     }
209 
210     fn set_kobj_state(&self, state: KObjectState) {
211         *self.kobj_state.write() = state;
212     }
213 }
214 
215 impl SerioDriver for Ps2MouseDriver {
216     fn write_wakeup(
217         &self,
218         _device: &Arc<dyn SerioDevice>,
219     ) -> Result<(), system_error::SystemError> {
220         todo!()
221     }
222 
223     fn interrupt(
224         &self,
225         device: &Arc<dyn SerioDevice>,
226         _char: u8,
227         _int: u8,
228     ) -> Result<(), system_error::SystemError> {
229         let device = device
230             .clone()
231             .arc_any()
232             .downcast::<Ps2MouseDevice>()
233             .map_err(|_| SystemError::EINVAL)?;
234         device.process_packet()?;
235         Ok(())
236     }
237 
238     fn connect(&self, device: &Arc<dyn SerioDevice>) -> Result<(), system_error::SystemError> {
239         let device = device
240             .clone()
241             .arc_any()
242             .downcast::<Ps2MouseDevice>()
243             .map_err(|_| SystemError::EINVAL)?;
244 
245         device.set_driver(Some(self.inner.lock_irqsave().self_ref.clone()));
246 
247         device.init()?;
248         irq_manager().request_irq(
249             PS2_MOUSE_IRQ_NUM,
250             "psmouse".to_string(),
251             &Ps2MouseIrqHandler,
252             IrqHandleFlags::IRQF_SHARED | IrqHandleFlags::IRQF_TRIGGER_RISING,
253             Some(DeviceId::new(Some(Self::NAME), None).unwrap()),
254         )?;
255         return Ok(());
256     }
257 
258     fn reconnect(&self, _device: &Arc<dyn SerioDevice>) -> Result<(), system_error::SystemError> {
259         todo!()
260     }
261 
262     fn fast_reconnect(
263         &self,
264         _device: &Arc<dyn SerioDevice>,
265     ) -> Result<(), system_error::SystemError> {
266         todo!()
267     }
268 
269     fn disconnect(&self, _device: &Arc<dyn SerioDevice>) -> Result<(), system_error::SystemError> {
270         todo!()
271     }
272 
273     fn cleanup(&self, _device: &Arc<dyn SerioDevice>) -> Result<(), system_error::SystemError> {
274         todo!()
275     }
276 }
277 
278 #[unified_init(INITCALL_DEVICE)]
279 fn ps2_mouse_driver_init() -> Result<(), SystemError> {
280     debug!("Ps2_mouse_drive initializing...");
281     let driver = Ps2MouseDriver::new();
282     serio_driver_manager().register(driver.clone())?;
283     unsafe { PS2_MOUSE_DRIVER = Some(driver) };
284     debug!("Ps2_mouse_drive initialized!");
285     return Ok(());
286 }
287