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