1 /** @file
2   PS/2 Mouse driver. Routines that interacts with callers,
3   conforming to EFI driver model.
4 
5 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7 
8 **/
9 
10 #include "Ps2Mouse.h"
11 #include "CommPs2.h"
12 
13 ///
14 /// DriverBinding Protocol Instance
15 ///
16 EFI_DRIVER_BINDING_PROTOCOL gPS2MouseDriver = {
17   PS2MouseDriverSupported,
18   PS2MouseDriverStart,
19   PS2MouseDriverStop,
20   0xa,
21   NULL,
22   NULL
23 };
24 
25 /**
26   Test to see if this driver supports ControllerHandle. Any ControllerHandle
27   than contains a IsaIo protocol can be supported.
28 
29   @param  This                Protocol instance pointer.
30   @param  ControllerHandle    Handle of device to test
31   @param  RemainingDevicePath Optional parameter use to pick a specific child
32                               device to start.
33 
34   @retval EFI_SUCCESS         This driver supports this device
35   @retval EFI_ALREADY_STARTED This driver is already running on this device
36   @retval other               This driver does not support this device
37 
38 **/
39 EFI_STATUS
40 EFIAPI
PS2MouseDriverSupported(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)41 PS2MouseDriverSupported (
42   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
43   IN EFI_HANDLE                     Controller,
44   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
45   )
46 {
47   EFI_STATUS                        Status;
48   EFI_SIO_PROTOCOL                  *Sio;
49   EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
50   ACPI_HID_DEVICE_PATH              *Acpi;
51 
52   //
53   // Check whether the controller is keyboard.
54   //
55   Status = gBS->OpenProtocol (
56                   Controller,
57                   &gEfiDevicePathProtocolGuid,
58                   (VOID **) &DevicePath,
59                   This->DriverBindingHandle,
60                   Controller,
61                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
62                   );
63   if (EFI_ERROR (Status)) {
64     return Status;
65   }
66 
67   do {
68     Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath;
69     DevicePath = NextDevicePathNode (DevicePath);
70   } while (!IsDevicePathEnd (DevicePath));
71 
72   if (DevicePathType (Acpi) != ACPI_DEVICE_PATH ||
73       (DevicePathSubType (Acpi) != ACPI_DP && DevicePathSubType (Acpi) != ACPI_EXTENDED_DP)) {
74     return EFI_UNSUPPORTED;
75   }
76 
77   switch (Acpi->HID) {
78   case EISA_PNP_ID (0xF03):
79     //
80     // Microsoft PS/2 style mouse
81     //
82   case EISA_PNP_ID (0xF13):
83     //
84     // PS/2 Port for PS/2-style Mice
85     //
86     break;
87 
88   case EISA_PNP_ID (0x303):
89     //
90     // IBM Enhanced (101/102-key, PS/2 mouse support)
91     //
92     if (Acpi->UID == 1) {
93       break;
94     }
95 
96   default:
97     return EFI_UNSUPPORTED;
98     break;
99   }
100 
101   //
102   // Open the IO Abstraction(s) needed to perform the supported test
103   //
104   Status = gBS->OpenProtocol (
105                   Controller,
106                   &gEfiSioProtocolGuid,
107                   (VOID **) &Sio,
108                   This->DriverBindingHandle,
109                   Controller,
110                   EFI_OPEN_PROTOCOL_BY_DRIVER
111                   );
112   if (EFI_ERROR (Status)) {
113     return Status;
114   }
115 
116   //
117   // Close the I/O Abstraction(s) used to perform the supported test
118   //
119   gBS->CloseProtocol (
120          Controller,
121          &gEfiSioProtocolGuid,
122          This->DriverBindingHandle,
123          Controller
124          );
125 
126   return Status;
127 }
128 
129 /**
130   Start this driver on ControllerHandle by opening a Sio protocol, creating
131   PS2_MOUSE_DEV device and install gEfiSimplePointerProtocolGuid finally.
132 
133   @param  This                 Protocol instance pointer.
134   @param  ControllerHandle     Handle of device to bind driver to
135   @param  RemainingDevicePath  Optional parameter use to pick a specific child
136                                device to start.
137 
138   @retval EFI_SUCCESS          This driver is added to ControllerHandle
139   @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
140   @retval other                This driver does not support this device
141 
142 **/
143 EFI_STATUS
144 EFIAPI
PS2MouseDriverStart(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)145 PS2MouseDriverStart (
146   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
147   IN EFI_HANDLE                     Controller,
148   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
149   )
150 {
151   EFI_STATUS                          Status;
152   EFI_STATUS                          EmptyStatus;
153   EFI_SIO_PROTOCOL                    *Sio;
154   PS2_MOUSE_DEV                       *MouseDev;
155   UINT8                               Data;
156   EFI_TPL                             OldTpl;
157   EFI_STATUS_CODE_VALUE               StatusCode;
158   EFI_DEVICE_PATH_PROTOCOL            *DevicePath;
159 
160   StatusCode  = 0;
161 
162   //
163   // Open the device path protocol
164   //
165   Status = gBS->OpenProtocol (
166                   Controller,
167                   &gEfiDevicePathProtocolGuid,
168                   (VOID **) &DevicePath,
169                   This->DriverBindingHandle,
170                   Controller,
171                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
172                   );
173   if (EFI_ERROR (Status)) {
174     return Status;
175   }
176   //
177   // Report that the keyboard is being enabled
178   //
179   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
180     EFI_PROGRESS_CODE,
181     EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE,
182     DevicePath
183     );
184 
185   //
186   // Get the ISA I/O Protocol on Controller's handle
187   //
188   Status = gBS->OpenProtocol (
189                   Controller,
190                   &gEfiSioProtocolGuid,
191                   (VOID **) &Sio,
192                   This->DriverBindingHandle,
193                   Controller,
194                   EFI_OPEN_PROTOCOL_BY_DRIVER
195                   );
196   if (EFI_ERROR (Status)) {
197     return Status;
198   }
199   //
200   // Raise TPL to avoid keyboard operation impact
201   //
202   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
203 
204   //
205   // Allocate private data
206   //
207   MouseDev = AllocateZeroPool (sizeof (PS2_MOUSE_DEV));
208   if (MouseDev == NULL) {
209     Status = EFI_OUT_OF_RESOURCES;
210     goto ErrorExit;
211   }
212   //
213   // Setup the device instance
214   //
215   MouseDev->Signature       = PS2_MOUSE_DEV_SIGNATURE;
216   MouseDev->Handle          = Controller;
217   MouseDev->SampleRate      = SampleRate20;
218   MouseDev->Resolution      = MouseResolution4;
219   MouseDev->Scaling         = Scaling1;
220   MouseDev->DataPackageSize = 3;
221   MouseDev->DevicePath      = DevicePath;
222 
223   //
224   // Resolution = 4 counts/mm
225   //
226   MouseDev->Mode.ResolutionX                = 4;
227   MouseDev->Mode.ResolutionY                = 4;
228   MouseDev->Mode.LeftButton                 = TRUE;
229   MouseDev->Mode.RightButton                = TRUE;
230 
231   MouseDev->SimplePointerProtocol.Reset     = MouseReset;
232   MouseDev->SimplePointerProtocol.GetState  = MouseGetState;
233   MouseDev->SimplePointerProtocol.Mode      = &(MouseDev->Mode);
234 
235   //
236   // Initialize keyboard controller if necessary
237   //
238   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
239     EFI_PROGRESS_CODE,
240     EFI_PERIPHERAL_MOUSE | EFI_P_MOUSE_PC_SELF_TEST,
241     DevicePath
242     );
243 
244   Data = IoRead8 (KBC_CMD_STS_PORT);
245   //
246   // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS.
247   //
248   if ((Data & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) {
249     //
250     // If nobody decodes KBC I/O port, it will read back as 0xFF.
251     // Check the Time-Out and Parity bit to see if it has an active KBC in system
252     //
253     Status     = EFI_DEVICE_ERROR;
254     StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED;
255     goto ErrorExit;
256   }
257 
258   if ((Data & KBC_SYSF) != KBC_SYSF) {
259     Status = KbcSelfTest ();
260     if (EFI_ERROR (Status)) {
261       StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_CONTROLLER_ERROR;
262       goto ErrorExit;
263     }
264   }
265 
266   KbcEnableAux ();
267 
268   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
269     EFI_PROGRESS_CODE,
270     EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT,
271     DevicePath
272     );
273 
274   //
275   // Reset the mouse
276   //
277   Status = MouseDev->SimplePointerProtocol.Reset (
278                      &MouseDev->SimplePointerProtocol,
279                      FeaturePcdGet (PcdPs2MouseExtendedVerification)
280                      );
281   if (EFI_ERROR (Status)) {
282     //
283     // mouse not connected
284     //
285     Status      = EFI_SUCCESS;
286     StatusCode  = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED;
287     goto ErrorExit;
288   }
289 
290   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
291     EFI_PROGRESS_CODE,
292     EFI_PERIPHERAL_MOUSE | EFI_P_PC_DETECTED,
293     DevicePath
294     );
295 
296   //
297   // Setup the WaitForKey event
298   //
299   Status = gBS->CreateEvent (
300                   EVT_NOTIFY_WAIT,
301                   TPL_NOTIFY,
302                   MouseWaitForInput,
303                   MouseDev,
304                   &((MouseDev->SimplePointerProtocol).WaitForInput)
305                   );
306   if (EFI_ERROR (Status)) {
307     Status = EFI_OUT_OF_RESOURCES;
308     goto ErrorExit;
309   }
310   //
311   // Setup a periodic timer, used to poll mouse state
312   //
313   Status = gBS->CreateEvent (
314                   EVT_TIMER | EVT_NOTIFY_SIGNAL,
315                   TPL_NOTIFY,
316                   PollMouse,
317                   MouseDev,
318                   &MouseDev->TimerEvent
319                   );
320   if (EFI_ERROR (Status)) {
321     Status = EFI_OUT_OF_RESOURCES;
322     goto ErrorExit;
323   }
324   //
325   // Start timer to poll mouse (100 samples per second)
326   //
327   Status = gBS->SetTimer (MouseDev->TimerEvent, TimerPeriodic, 100000);
328   if (EFI_ERROR (Status)) {
329     Status = EFI_OUT_OF_RESOURCES;
330     goto ErrorExit;
331   }
332 
333   MouseDev->ControllerNameTable = NULL;
334   AddUnicodeString2 (
335     "eng",
336     gPs2MouseComponentName.SupportedLanguages,
337     &MouseDev->ControllerNameTable,
338     L"PS/2 Mouse Device",
339     TRUE
340     );
341   AddUnicodeString2 (
342     "en",
343     gPs2MouseComponentName2.SupportedLanguages,
344     &MouseDev->ControllerNameTable,
345     L"PS/2 Mouse Device",
346     FALSE
347     );
348 
349 
350   //
351   // Install protocol interfaces for the mouse device.
352   //
353   Status = gBS->InstallMultipleProtocolInterfaces (
354                   &Controller,
355                   &gEfiSimplePointerProtocolGuid,
356                   &MouseDev->SimplePointerProtocol,
357                   NULL
358                   );
359   if (EFI_ERROR (Status)) {
360     goto ErrorExit;
361   }
362 
363   gBS->RestoreTPL (OldTpl);
364 
365   return Status;
366 
367 ErrorExit:
368 
369   if (Status != EFI_DEVICE_ERROR) {
370     KbcDisableAux ();
371   }
372 
373   if (StatusCode != 0) {
374     REPORT_STATUS_CODE_WITH_DEVICE_PATH (
375       EFI_ERROR_CODE | EFI_ERROR_MINOR,
376       StatusCode,
377       DevicePath
378       );
379   }
380 
381   if ((MouseDev != NULL) && (MouseDev->SimplePointerProtocol.WaitForInput != NULL)) {
382     gBS->CloseEvent (MouseDev->SimplePointerProtocol.WaitForInput);
383   }
384 
385   if ((MouseDev != NULL) && (MouseDev->TimerEvent != NULL)) {
386     gBS->CloseEvent (MouseDev->TimerEvent);
387   }
388 
389   if ((MouseDev != NULL) && (MouseDev->ControllerNameTable != NULL)) {
390     FreeUnicodeStringTable (MouseDev->ControllerNameTable);
391   }
392 
393   if (Status != EFI_DEVICE_ERROR) {
394     //
395     // Since there will be no timer handler for mouse input any more,
396     // exhaust input data just in case there is still mouse data left
397     //
398     EmptyStatus = EFI_SUCCESS;
399     while (!EFI_ERROR (EmptyStatus)) {
400       EmptyStatus = In8042Data (&Data);
401     }
402   }
403 
404   if (MouseDev != NULL) {
405     FreePool (MouseDev);
406   }
407 
408   gBS->CloseProtocol (
409          Controller,
410          &gEfiDevicePathProtocolGuid,
411          This->DriverBindingHandle,
412          Controller
413          );
414 
415   gBS->CloseProtocol (
416          Controller,
417          &gEfiSioProtocolGuid,
418          This->DriverBindingHandle,
419          Controller
420          );
421 
422   gBS->RestoreTPL (OldTpl);
423 
424   return Status;
425 }
426 
427 /**
428   Stop this driver on ControllerHandle. Support stopping any child handles
429   created by this driver.
430 
431   @param  This              Protocol instance pointer.
432   @param  ControllerHandle  Handle of device to stop driver on
433   @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
434                             children is zero stop the entire bus driver.
435   @param  ChildHandleBuffer List of Child Handles to Stop.
436 
437   @retval EFI_SUCCESS       This driver is removed ControllerHandle
438   @retval other             This driver was not removed from this device
439 
440 **/
441 EFI_STATUS
442 EFIAPI
PS2MouseDriverStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer)443 PS2MouseDriverStop (
444   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
445   IN EFI_HANDLE                     Controller,
446   IN UINTN                          NumberOfChildren,
447   IN EFI_HANDLE                     *ChildHandleBuffer
448   )
449 {
450   EFI_STATUS                  Status;
451   EFI_SIMPLE_POINTER_PROTOCOL *SimplePointerProtocol;
452   PS2_MOUSE_DEV               *MouseDev;
453   UINT8                       Data;
454 
455   Status = gBS->OpenProtocol (
456                   Controller,
457                   &gEfiSimplePointerProtocolGuid,
458                   (VOID **) &SimplePointerProtocol,
459                   This->DriverBindingHandle,
460                   Controller,
461                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
462                   );
463   if (EFI_ERROR (Status)) {
464     return EFI_SUCCESS;
465   }
466 
467   MouseDev = PS2_MOUSE_DEV_FROM_THIS (SimplePointerProtocol);
468 
469   //
470   // Report that the keyboard is being disabled
471   //
472   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
473     EFI_PROGRESS_CODE,
474     EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE,
475     MouseDev->DevicePath
476     );
477 
478   Status = gBS->UninstallProtocolInterface (
479                   Controller,
480                   &gEfiSimplePointerProtocolGuid,
481                   &MouseDev->SimplePointerProtocol
482                   );
483   if (EFI_ERROR (Status)) {
484     return Status;
485   }
486 
487   //
488   // Cancel mouse data polling timer, close timer event
489   //
490   gBS->SetTimer (MouseDev->TimerEvent, TimerCancel, 0);
491   gBS->CloseEvent (MouseDev->TimerEvent);
492 
493   //
494   // Since there will be no timer handler for mouse input any more,
495   // exhaust input data just in case there is still mouse data left
496   //
497   Status = EFI_SUCCESS;
498   while (!EFI_ERROR (Status)) {
499     Status = In8042Data (&Data);
500   }
501 
502   gBS->CloseEvent (MouseDev->SimplePointerProtocol.WaitForInput);
503   FreeUnicodeStringTable (MouseDev->ControllerNameTable);
504   FreePool (MouseDev);
505 
506   gBS->CloseProtocol (
507          Controller,
508          &gEfiDevicePathProtocolGuid,
509          This->DriverBindingHandle,
510          Controller
511          );
512 
513   gBS->CloseProtocol (
514          Controller,
515          &gEfiSioProtocolGuid,
516          This->DriverBindingHandle,
517          Controller
518          );
519 
520   return EFI_SUCCESS;
521 }
522 
523 /**
524   Reset the Mouse and do BAT test for it, if ExtendedVerification is TRUE and
525   there is a mouse device connected to system.
526 
527   @param This                 - Pointer of simple pointer Protocol.
528   @param ExtendedVerification - Whether configure mouse parameters. True: do; FALSE: skip.
529 
530 
531   @retval EFI_SUCCESS         - The command byte is written successfully.
532   @retval EFI_DEVICE_ERROR    - Errors occurred during resetting keyboard.
533 
534 **/
535 EFI_STATUS
536 EFIAPI
MouseReset(IN EFI_SIMPLE_POINTER_PROTOCOL * This,IN BOOLEAN ExtendedVerification)537 MouseReset (
538   IN EFI_SIMPLE_POINTER_PROTOCOL    *This,
539   IN BOOLEAN                        ExtendedVerification
540   )
541 {
542   EFI_STATUS    Status;
543   PS2_MOUSE_DEV *MouseDev;
544   EFI_TPL       OldTpl;
545   BOOLEAN       KeyboardEnable;
546   UINT8         Data;
547 
548   MouseDev = PS2_MOUSE_DEV_FROM_THIS (This);
549 
550   //
551   // Report reset progress code
552   //
553   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
554     EFI_PROGRESS_CODE,
555     EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET,
556     MouseDev->DevicePath
557     );
558 
559   KeyboardEnable = FALSE;
560 
561   //
562   // Raise TPL to avoid keyboard operation impact
563   //
564   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
565 
566   ZeroMem (&MouseDev->State, sizeof (EFI_SIMPLE_POINTER_STATE));
567   MouseDev->StateChanged = FALSE;
568 
569   //
570   // Exhaust input data
571   //
572   Status = EFI_SUCCESS;
573   while (!EFI_ERROR (Status)) {
574     Status = In8042Data (&Data);
575   }
576 
577   CheckKbStatus (&KeyboardEnable);
578 
579   KbcDisableKb ();
580 
581   //
582   // if there's data block on KBC data port, read it out
583   //
584   if ((IoRead8 (KBC_CMD_STS_PORT) & KBC_OUTB) == KBC_OUTB) {
585     IoRead8 (KBC_DATA_PORT);
586   }
587 
588   Status = EFI_SUCCESS;
589   //
590   // The PS2 mouse driver reset behavior is always successfully return no matter whether or not there is mouse connected to system.
591   // This behavior is needed by performance speed. The following mouse command only successfully finish when mouse device is
592   // connected to system, so if PS2 mouse device not connect to system or user not ask for, we skip the mouse configuration and enabling
593   //
594   if (ExtendedVerification && CheckMouseConnect (MouseDev)) {
595     //
596     // Send mouse reset command and set mouse default configure
597     //
598     Status = PS2MouseReset ();
599     if (EFI_ERROR (Status)) {
600       Status = EFI_DEVICE_ERROR;
601       goto Exit;
602     }
603 
604     Status = PS2MouseSetSampleRate (MouseDev->SampleRate);
605     if (EFI_ERROR (Status)) {
606       Status = EFI_DEVICE_ERROR;
607       goto Exit;
608     }
609 
610     Status = PS2MouseSetResolution (MouseDev->Resolution);
611     if (EFI_ERROR (Status)) {
612       Status = EFI_DEVICE_ERROR;
613       goto Exit;
614     }
615 
616     Status = PS2MouseSetScaling (MouseDev->Scaling);
617     if (EFI_ERROR (Status)) {
618       Status = EFI_DEVICE_ERROR;
619       goto Exit;
620     }
621 
622     Status = PS2MouseEnable ();
623     if (EFI_ERROR (Status)) {
624       Status = EFI_DEVICE_ERROR;
625       goto Exit;
626     }
627   }
628 Exit:
629   gBS->RestoreTPL (OldTpl);
630 
631   if (KeyboardEnable) {
632     KbcEnableKb ();
633   }
634 
635   return Status;
636 }
637 
638 /**
639   Check whether there is Ps/2 mouse device in system
640 
641   @param MouseDev   - Mouse Private Data Structure
642 
643   @retval TRUE      - Keyboard in System.
644   @retval FALSE     - Keyboard not in System.
645 
646 **/
647 BOOLEAN
CheckMouseConnect(IN PS2_MOUSE_DEV * MouseDev)648 CheckMouseConnect (
649   IN  PS2_MOUSE_DEV     *MouseDev
650   )
651 
652 {
653   EFI_STATUS     Status;
654 
655   Status = PS2MouseEnable ();
656   if (!EFI_ERROR (Status)) {
657     return TRUE;
658   }
659 
660   return FALSE;
661 }
662 
663 /**
664   Get and Clear mouse status.
665 
666   @param This                 - Pointer of simple pointer Protocol.
667   @param State                - Output buffer holding status.
668 
669   @retval EFI_INVALID_PARAMETER Output buffer is invalid.
670   @retval EFI_NOT_READY         Mouse is not changed status yet.
671   @retval EFI_SUCCESS           Mouse status is changed and get successful.
672 **/
673 EFI_STATUS
674 EFIAPI
MouseGetState(IN EFI_SIMPLE_POINTER_PROTOCOL * This,IN OUT EFI_SIMPLE_POINTER_STATE * State)675 MouseGetState (
676   IN EFI_SIMPLE_POINTER_PROTOCOL    *This,
677   IN OUT EFI_SIMPLE_POINTER_STATE   *State
678   )
679 {
680   PS2_MOUSE_DEV *MouseDev;
681   EFI_TPL       OldTpl;
682 
683   MouseDev = PS2_MOUSE_DEV_FROM_THIS (This);
684 
685   if (State == NULL) {
686     return EFI_INVALID_PARAMETER;
687   }
688 
689   if (!MouseDev->StateChanged) {
690     return EFI_NOT_READY;
691   }
692 
693   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
694   CopyMem (State, &(MouseDev->State), sizeof (EFI_SIMPLE_POINTER_STATE));
695 
696   //
697   // clear mouse state
698   //
699   MouseDev->State.RelativeMovementX = 0;
700   MouseDev->State.RelativeMovementY = 0;
701   MouseDev->State.RelativeMovementZ = 0;
702   MouseDev->StateChanged            = FALSE;
703   gBS->RestoreTPL (OldTpl);
704 
705   return EFI_SUCCESS;
706 }
707 
708 /**
709 
710   Event notification function for SIMPLE_POINTER.WaitForInput event.
711   Signal the event if there is input from mouse.
712 
713   @param Event    event object
714   @param Context  event context
715 
716 **/
717 VOID
718 EFIAPI
MouseWaitForInput(IN EFI_EVENT Event,IN VOID * Context)719 MouseWaitForInput (
720   IN  EFI_EVENT               Event,
721   IN  VOID                    *Context
722   )
723 {
724   PS2_MOUSE_DEV *MouseDev;
725 
726   MouseDev = (PS2_MOUSE_DEV *) Context;
727 
728   //
729   // Someone is waiting on the mouse event, if there's
730   // input from mouse, signal the event
731   //
732   if (MouseDev->StateChanged) {
733     gBS->SignalEvent (Event);
734   }
735 
736 }
737 
738 /**
739   Event notification function for TimerEvent event.
740   If mouse device is connected to system, try to get the mouse packet data.
741 
742   @param Event      -  TimerEvent in PS2_MOUSE_DEV
743   @param Context    -  Pointer to PS2_MOUSE_DEV structure
744 
745 **/
746 VOID
747 EFIAPI
PollMouse(IN EFI_EVENT Event,IN VOID * Context)748 PollMouse (
749   IN EFI_EVENT  Event,
750   IN VOID       *Context
751   )
752 
753 {
754   PS2_MOUSE_DEV *MouseDev;
755 
756   MouseDev = (PS2_MOUSE_DEV *) Context;
757 
758   //
759   // Polling mouse packet data
760   //
761   PS2MouseGetPacket (MouseDev);
762 }
763 
764 /**
765   The user Entry Point for module Ps2Mouse. The user code starts with this function.
766 
767   @param[in] ImageHandle    The firmware allocated handle for the EFI image.
768   @param[in] SystemTable    A pointer to the EFI System Table.
769 
770   @retval EFI_SUCCESS       The entry point is executed successfully.
771   @retval other             Some error occurs when executing this entry point.
772 
773 **/
774 EFI_STATUS
775 EFIAPI
InitializePs2Mouse(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)776 InitializePs2Mouse(
777   IN EFI_HANDLE           ImageHandle,
778   IN EFI_SYSTEM_TABLE     *SystemTable
779   )
780 {
781   EFI_STATUS              Status;
782 
783   //
784   // Install driver model protocol(s).
785   //
786   Status = EfiLibInstallDriverBindingComponentName2 (
787              ImageHandle,
788              SystemTable,
789              &gPS2MouseDriver,
790              ImageHandle,
791              &gPs2MouseComponentName,
792              &gPs2MouseComponentName2
793              );
794   ASSERT_EFI_ERROR (Status);
795 
796 
797   return Status;
798 }
799 
800