]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Bus/Isa/Ps2MouseSimulateTouchPadDxe/Ps2MouseAbsolutePointer.c
change "Ps2MouseSimulateTouchPad" to "Ps2MouseAbsolutePointer" for more clearing...
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / Ps2MouseSimulateTouchPadDxe / Ps2MouseAbsolutePointer.c
diff --git a/IntelFrameworkModulePkg/Bus/Isa/Ps2MouseSimulateTouchPadDxe/Ps2MouseAbsolutePointer.c b/IntelFrameworkModulePkg/Bus/Isa/Ps2MouseSimulateTouchPadDxe/Ps2MouseAbsolutePointer.c
new file mode 100644 (file)
index 0000000..930b49f
--- /dev/null
@@ -0,0 +1,799 @@
+/**@file\r
+  A faked PS/2 Touchpad driver. Routines that interacts with callers,\r
+  conforming to EFI driver model\r
+  \r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Ps2MouseAbsolutePointer.h"\r
+#include "CommPs2.h"\r
+\r
+//\r
+// DriverBinding Protocol Instance\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL gPS2MouseAbsolutePointerDriver = {\r
+  PS2MouseAbsolutePointerDriverSupported,\r
+  PS2MouseAbsolutePointerDriverStart,\r
+  PS2MouseAbsolutePointerDriverStop,\r
+  0x1,\r
+  NULL,\r
+  NULL\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PS2MouseAbsolutePointerDriverSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
+  IN EFI_HANDLE                     Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  ControllerDriver Protocol Method\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+// GC_TODO:    This - add argument and description to function comment\r
+// GC_TODO:    Controller - add argument and description to function comment\r
+// GC_TODO:    RemainingDevicePath - add argument and description to function comment\r
+{\r
+  EFI_STATUS                          Status;\r
+  EFI_ISA_IO_PROTOCOL                 *IsaIo;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  // Open the IO Abstraction(s) needed to perform the supported test\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiIsaIoProtocolGuid,\r
+                  (VOID **) &IsaIo,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Use the ISA I/O Protocol to see if Controller is the Mouse controller\r
+  //\r
+  switch (IsaIo->ResourceList->Device.HID) {\r
+  case EISA_PNP_ID (0xF03):\r
+  //\r
+  // Microsoft PS/2 style mouse\r
+  //\r
+  case EISA_PNP_ID (0xF13):\r
+    //\r
+    // PS/2 Port for PS/2-style Mice\r
+    //\r
+    break;\r
+\r
+  case EISA_PNP_ID (0x303):\r
+    //\r
+    // IBM Enhanced (101/102-key, PS/2 mouse support)\r
+    //\r
+    if (IsaIo->ResourceList->Device.UID == 1) {\r
+      break;\r
+    }\r
+\r
+  default:\r
+    Status = EFI_UNSUPPORTED;\r
+    break;\r
+  }\r
+  //\r
+  // Close the I/O Abstraction(s) used to perform the supported test\r
+  //\r
+  gBS->CloseProtocol (\r
+         Controller,\r
+         &gEfiIsaIoProtocolGuid,\r
+         This->DriverBindingHandle,\r
+         Controller\r
+         );\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PS2MouseAbsolutePointerDriverStart (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
+  IN EFI_HANDLE                     Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    Start protocol interfaces for the mouse device handles.\r
+\r
+Arguments:\r
+    This                               - Protocol instance pointer.\r
+    Controller                      - Handle of device to bind driver to.\r
+    RemainingDevicePath  - Not used.\r
+\r
+Returns:\r
+    EFI_SUCCESS             - This driver is added to DeviceHandle.\r
+    other                               - Errors occurred.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                          Status;\r
+  EFI_STATUS                          EmptyStatus;\r
+  EFI_ISA_IO_PROTOCOL                 *IsaIo;\r
+  PS2_MOUSE_ABSOLUTE_POINTER_DEV     *MouseAbsolutePointerDev;\r
+  UINT8                               Data;\r
+  EFI_TPL                             OldTpl;\r
+  EFI_STATUS_CODE_VALUE               StatusCode;\r
+  EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;\r
+\r
+  StatusCode  = 0;\r
+  MouseAbsolutePointerDev    = NULL;\r
+  IsaIo       = NULL;\r
+\r
+  //\r
+  // Open the device path protocol\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **) &ParentDevicePath,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Report that the keyboard is being enabled\r
+  //\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE,\r
+    ParentDevicePath\r
+    );\r
+\r
+  //\r
+  // Get the ISA I/O Protocol on Controller's handle\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiIsaIoProtocolGuid,\r
+                  (VOID **) &IsaIo,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->CloseProtocol (\r
+           Controller,\r
+           &gEfiDevicePathProtocolGuid,\r
+           This->DriverBindingHandle,\r
+           Controller\r
+           );\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Raise TPL to avoid keyboard operation impact\r
+  //\r
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+  //\r
+  // Allocate private data\r
+  //\r
+  MouseAbsolutePointerDev = AllocateZeroPool (sizeof (PS2_MOUSE_ABSOLUTE_POINTER_DEV));\r
+  if (MouseAbsolutePointerDev == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ErrorExit;\r
+  }\r
+  //\r
+  // Setup the device instance\r
+  //\r
+  MouseAbsolutePointerDev->Signature       = PS2_MOUSE_ABSOLUTE_POINTER_DEV_SIGNATURE;\r
+  MouseAbsolutePointerDev->Handle          = Controller;\r
+  MouseAbsolutePointerDev->SampleRate      = SSR_20;\r
+  MouseAbsolutePointerDev->Resolution      = CMR4;\r
+  MouseAbsolutePointerDev->Scaling         = SF1;\r
+  MouseAbsolutePointerDev->DataPackageSize = 3;\r
+  MouseAbsolutePointerDev->IsaIo           = IsaIo;\r
+  MouseAbsolutePointerDev->DevicePath      = ParentDevicePath;\r
+\r
+  //\r
+  // Resolution = 4 counts/mm\r
+  //\r
+  MouseAbsolutePointerDev->Mode.AbsoluteMaxX               = 1024;\r
+  MouseAbsolutePointerDev->Mode.AbsoluteMinX               = 0;\r
+  MouseAbsolutePointerDev->Mode.AbsoluteMaxY               = 798;\r
+  MouseAbsolutePointerDev->Mode.AbsoluteMinY               = 0;\r
+  MouseAbsolutePointerDev->Mode.AbsoluteMaxZ               = 0;\r
+  MouseAbsolutePointerDev->Mode.AbsoluteMinZ               = 0;\r
+  MouseAbsolutePointerDev->Mode.Attributes                 = 0x03;\r
+\r
+  MouseAbsolutePointerDev->AbsolutePointerProtocol.Reset     = MouseAbsolutePointerReset;\r
+  MouseAbsolutePointerDev->AbsolutePointerProtocol.GetState  = MouseAbsolutePointerGetState;\r
+  MouseAbsolutePointerDev->AbsolutePointerProtocol.Mode      = &(MouseAbsolutePointerDev->Mode);\r
+\r
+  //\r
+  // Initialize keyboard controller if necessary\r
+  //\r
+  IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);\r
+  if ((Data & KBC_SYSF) != KBC_SYSF) {\r
+    Status = KbcSelfTest (IsaIo);\r
+    if (EFI_ERROR (Status)) {\r
+      StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_CONTROLLER_ERROR;\r
+      goto ErrorExit;\r
+    }\r
+  }\r
+\r
+  KbcEnableAux (IsaIo);\r
+\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT,\r
+    ParentDevicePath\r
+    );\r
+\r
+  //\r
+  // Reset the mouse\r
+  //\r
+  Status = MouseAbsolutePointerDev->AbsolutePointerProtocol.Reset (&MouseAbsolutePointerDev->AbsolutePointerProtocol, TRUE);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // mouse not connected\r
+    //\r
+    Status      = EFI_SUCCESS;\r
+    StatusCode  = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED;\r
+    goto ErrorExit;\r
+  }\r
+  //\r
+  // Setup the WaitForKey event\r
+  //\r
+  Status = gBS->CreateEvent (\r
+                  EVT_NOTIFY_WAIT,\r
+                  TPL_NOTIFY,\r
+                  MouseAbsolutePointerWaitForInput,\r
+                  MouseAbsolutePointerDev,\r
+                  &((MouseAbsolutePointerDev->AbsolutePointerProtocol).WaitForInput)\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ErrorExit;\r
+  }\r
+  //\r
+  // Setup a periodic timer, used to poll mouse state\r
+  //\r
+  Status = gBS->CreateEvent (\r
+                  EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
+                  TPL_NOTIFY,\r
+                  PollMouseAbsolutePointer,\r
+                  MouseAbsolutePointerDev,\r
+                  &MouseAbsolutePointerDev->TimerEvent\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ErrorExit;\r
+  }\r
+  //\r
+  // Start timer to poll mouse (100 samples per second)\r
+  //\r
+  Status = gBS->SetTimer (MouseAbsolutePointerDev->TimerEvent, TimerPeriodic, 100000);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ErrorExit;\r
+  }\r
+\r
+  MouseAbsolutePointerDev->ControllerNameTable = NULL;\r
+  AddUnicodeString2 (\r
+    "eng",\r
+    gPs2MouseAbsolutePointerComponentName.SupportedLanguages,\r
+    &MouseAbsolutePointerDev->ControllerNameTable,\r
+    L"Faked PS/2 Touchpad Device",\r
+    TRUE\r
+    );\r
+  AddUnicodeString2 (\r
+    "en",\r
+    gPs2MouseAbsolutePointerComponentName2.SupportedLanguages,\r
+    &MouseAbsolutePointerDev->ControllerNameTable,\r
+    L"Faked PS/2 Touchpad Device",\r
+    FALSE\r
+    );\r
+\r
+\r
+  //\r
+  // Install protocol interfaces for the mouse device.\r
+  //\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &Controller,\r
+                  &gEfiAbsolutePointerProtocolGuid,\r
+                  &MouseAbsolutePointerDev->AbsolutePointerProtocol,\r
+                  NULL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto ErrorExit;\r
+  }\r
+\r
+  gBS->RestoreTPL (OldTpl);\r
+\r
+  return Status;\r
+\r
+ErrorExit:\r
+\r
+  KbcDisableAux (IsaIo);\r
+\r
+  if (StatusCode != 0) {\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      StatusCode,\r
+      ParentDevicePath\r
+      );\r
+  }\r
+\r
+  if ((MouseAbsolutePointerDev != NULL) && (MouseAbsolutePointerDev->AbsolutePointerProtocol.WaitForInput != NULL)) {\r
+    gBS->CloseEvent (MouseAbsolutePointerDev->AbsolutePointerProtocol.WaitForInput);\r
+  }\r
+\r
+  if ((MouseAbsolutePointerDev != NULL) && (MouseAbsolutePointerDev->TimerEvent != NULL)) {\r
+    gBS->CloseEvent (MouseAbsolutePointerDev->TimerEvent);\r
+  }\r
+\r
+  if ((MouseAbsolutePointerDev != NULL) && (MouseAbsolutePointerDev->ControllerNameTable != NULL)) {\r
+    FreeUnicodeStringTable (MouseAbsolutePointerDev->ControllerNameTable);\r
+  }\r
+  //\r
+  // Since there will be no timer handler for mouse input any more,\r
+  // exhaust input data just in case there is still mouse data left\r
+  //\r
+  EmptyStatus = EFI_SUCCESS;\r
+  while (!EFI_ERROR (EmptyStatus)) {\r
+    EmptyStatus = In8042Data (IsaIo, &Data);\r
+  }\r
+\r
+  if (MouseAbsolutePointerDev != NULL) {\r
+    gBS->FreePool (MouseAbsolutePointerDev);\r
+  }\r
+\r
+  gBS->CloseProtocol (\r
+         Controller,\r
+         &gEfiDevicePathProtocolGuid,\r
+         This->DriverBindingHandle,\r
+         Controller\r
+         );\r
+\r
+  gBS->CloseProtocol (\r
+         Controller,\r
+         &gEfiIsaIoProtocolGuid,\r
+         This->DriverBindingHandle,\r
+         Controller\r
+         );\r
+\r
+  gBS->RestoreTPL (OldTpl);\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PS2MouseAbsolutePointerDriverStop (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
+  IN EFI_HANDLE                     Controller,\r
+  IN UINTN                          NumberOfChildren,\r
+  IN EFI_HANDLE                     *ChildHandleBuffer\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+\r
+  Arguments:\r
+\r
+  Returns:\r
+\r
+--*/\r
+// GC_TODO:    This - add argument and description to function comment\r
+// GC_TODO:    Controller - add argument and description to function comment\r
+// GC_TODO:    NumberOfChildren - add argument and description to function comment\r
+// GC_TODO:    ChildHandleBuffer - add argument and description to function comment\r
+// GC_TODO:    EFI_SUCCESS - add return value to function comment\r
+// GC_TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  EFI_STATUS                            Status;\r
+  EFI_ABSOLUTE_POINTER_PROTOCOL         *AbsolutePointerProtocol;\r
+  PS2_MOUSE_ABSOLUTE_POINTER_DEV       *MouseAbsolutePointerDev;\r
+  UINT8                                 Data;\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiAbsolutePointerProtocolGuid,\r
+                  (VOID **) &AbsolutePointerProtocol,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  MouseAbsolutePointerDev = PS2_MOUSE_ABSOLUTE_POINTER_DEV_FROM_THIS (AbsolutePointerProtocol);\r
+\r
+  //\r
+  // Report that the keyboard is being disabled\r
+  //\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE,\r
+    MouseAbsolutePointerDev->DevicePath\r
+    );\r
+\r
+  Status = gBS->UninstallProtocolInterface (\r
+                  Controller,\r
+                  &gEfiAbsolutePointerProtocolGuid,\r
+                  &MouseAbsolutePointerDev->AbsolutePointerProtocol\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Disable mouse on keyboard controller\r
+  //\r
+  KbcDisableAux (MouseAbsolutePointerDev->IsaIo);\r
+\r
+  //\r
+  // Cancel mouse data polling timer, close timer event\r
+  //\r
+  gBS->SetTimer (MouseAbsolutePointerDev->TimerEvent, TimerCancel, 0);\r
+  gBS->CloseEvent (MouseAbsolutePointerDev->TimerEvent);\r
+\r
+  //\r
+  // Since there will be no timer handler for mouse input any more,\r
+  // exhaust input data just in case there is still mouse data left\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  while (!EFI_ERROR (Status)) {\r
+    Status = In8042Data (MouseAbsolutePointerDev->IsaIo, &Data);\r
+  }\r
+\r
+  gBS->CloseEvent (MouseAbsolutePointerDev->AbsolutePointerProtocol.WaitForInput);\r
+  FreeUnicodeStringTable (MouseAbsolutePointerDev->ControllerNameTable);\r
+  gBS->FreePool (MouseAbsolutePointerDev);\r
+\r
+  gBS->CloseProtocol (\r
+         Controller,\r
+         &gEfiDevicePathProtocolGuid,\r
+         This->DriverBindingHandle,\r
+         Controller\r
+         );\r
+\r
+  gBS->CloseProtocol (\r
+         Controller,\r
+         &gEfiIsaIoProtocolGuid,\r
+         This->DriverBindingHandle,\r
+         Controller\r
+         );\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MouseAbsolutePointerReset (\r
+  IN EFI_ABSOLUTE_POINTER_PROTOCOL    *This,\r
+  IN BOOLEAN                          ExtendedVerification\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Reset the Mouse and do BAT test for it, if ExtendedVerification isTRUE and there is a mouse device connectted to system\r
+\r
+Arguments:\r
+\r
+  This                 - Pointer of simple pointer Protocol.\r
+  ExtendedVerification - Whether configure mouse parameters. True: do; FALSE: skip.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS         - The command byte is written successfully.\r
+ EFI_DEVICE_ERROR    - Errors occurred during reseting keyboard.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                       Status;\r
+  PS2_MOUSE_ABSOLUTE_POINTER_DEV  *MouseAbsolutePointerDev;\r
+  EFI_TPL                          OldTpl;\r
+  BOOLEAN                          KeyboardEnable;\r
+  UINT8                            Data;\r
+\r
+  MouseAbsolutePointerDev = PS2_MOUSE_ABSOLUTE_POINTER_DEV_FROM_THIS (This);\r
+\r
+  //\r
+  // Report reset progress code\r
+  //\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET,\r
+    MouseAbsolutePointerDev->DevicePath\r
+    );\r
+\r
+  KeyboardEnable = FALSE;\r
+\r
+  //\r
+  // Raise TPL to avoid keyboard operation impact\r
+  //\r
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+  ZeroMem (&MouseAbsolutePointerDev->State, sizeof (EFI_ABSOLUTE_POINTER_STATE));\r
+  MouseAbsolutePointerDev->StateChanged = FALSE;\r
+\r
+  //\r
+  // Exhaust input data\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  while (!EFI_ERROR (Status)) {\r
+    Status = In8042Data (MouseAbsolutePointerDev->IsaIo, &Data);\r
+  }\r
+\r
+  CheckKbStatus (MouseAbsolutePointerDev->IsaIo, &KeyboardEnable);\r
+\r
+  KbcDisableKb (MouseAbsolutePointerDev->IsaIo);\r
+\r
+  MouseAbsolutePointerDev->IsaIo->Io.Read (MouseAbsolutePointerDev->IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);\r
+\r
+  //\r
+  // if there's data block on KBC data port, read it out\r
+  //\r
+  if ((Data & KBC_OUTB) == KBC_OUTB) {\r
+    MouseAbsolutePointerDev->IsaIo->Io.Read (MouseAbsolutePointerDev->IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Data);\r
+  }\r
+\r
+  Status = EFI_SUCCESS;\r
+  //\r
+  // The PS2 mouse driver reset behavior is always successfully return no matter wheater or not there is mouse connected to system.\r
+  // This behavior is needed by performance speed. The following mouse command only succeessfully finish when mouse device is\r
+  // connected to system, so if PS2 mouse device not connect to system or user not ask for, we skip the mouse configuration and enabling\r
+  //\r
+  if (ExtendedVerification && CheckMouseAbsolutePointerConnect (MouseAbsolutePointerDev)) {\r
+    //\r
+    // Send mouse reset command and set mouse default configure\r
+    //\r
+    Status = PS2MouseReset (MouseAbsolutePointerDev->IsaIo);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Exit;\r
+    }\r
+\r
+    Status = PS2MouseSetSampleRate (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->SampleRate);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Exit;\r
+    }\r
+\r
+    Status = PS2MouseSetResolution (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->Resolution);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Exit;\r
+    }\r
+\r
+    Status = PS2MouseSetScaling (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->Scaling);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Exit;\r
+    }\r
+\r
+    Status = PS2MouseEnable (MouseAbsolutePointerDev->IsaIo);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Exit;\r
+    }\r
+  }\r
+Exit:\r
+  gBS->RestoreTPL (OldTpl);\r
+\r
+  if (KeyboardEnable) {\r
+    KbcEnableKb (MouseAbsolutePointerDev->IsaIo);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+BOOLEAN\r
+CheckMouseAbsolutePointerConnect (\r
+  IN  PS2_MOUSE_ABSOLUTE_POINTER_DEV     *MouseAbsolutePointerDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check whether there is Ps/2 mouse device in system\r
+\r
+Arguments:\r
+\r
+  PS2_MOUSE_DEV - Mouse Private Data Structure\r
+\r
+Returns:\r
+\r
+  TRUE                - Keyboard in System.\r
+  FALSE               - Keyboard not in System.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS     Status;\r
+\r
+  Status = PS2MouseEnable (MouseAbsolutePointerDev->IsaIo);\r
+  if (!EFI_ERROR (Status)) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MouseAbsolutePointerGetState (\r
+  IN EFI_ABSOLUTE_POINTER_PROTOCOL     *This,\r
+  IN OUT EFI_ABSOLUTE_POINTER_STATE    *State\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  This  - GC_TODO: add argument description\r
+  State - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER - GC_TODO: Add description for return value\r
+  EFI_NOT_READY - GC_TODO: Add description for return value\r
+  EFI_SUCCESS - GC_TODO: Add description for return value\r
+\r
+--*/\r
+{\r
+  PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;\r
+  EFI_TPL       OldTpl;\r
+\r
+  MouseAbsolutePointerDev = PS2_MOUSE_ABSOLUTE_POINTER_DEV_FROM_THIS (This);\r
+\r
+  if (State == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (!MouseAbsolutePointerDev->StateChanged) {\r
+    return EFI_NOT_READY;\r
+  }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+  CopyMem (State, &(MouseAbsolutePointerDev->State), sizeof (EFI_ABSOLUTE_POINTER_STATE));\r
+\r
+  //\r
+  // clear mouse state\r
+  //\r
+  MouseAbsolutePointerDev->State.CurrentX = 0;\r
+  MouseAbsolutePointerDev->State.CurrentY = 0;\r
+  MouseAbsolutePointerDev->State.CurrentZ = 0;\r
+  MouseAbsolutePointerDev->State.ActiveButtons = 0x0;\r
+  MouseAbsolutePointerDev->StateChanged            = FALSE;\r
+  gBS->RestoreTPL (OldTpl);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+MouseAbsolutePointerWaitForInput (\r
+  IN  EFI_EVENT               Event,\r
+  IN  VOID                    *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Event notification function for SIMPLE_POINTER.WaitForInput event\r
+  Signal the event if there is input from mouse\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+// GC_TODO:    Event - add argument and description to function comment\r
+// GC_TODO:    Context - add argument and description to function comment\r
+{\r
+  PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;\r
+\r
+  MouseAbsolutePointerDev = (PS2_MOUSE_ABSOLUTE_POINTER_DEV *) Context;\r
+\r
+  //\r
+  // Someone is waiting on the mouse event, if there's\r
+  // input from mouse, signal the event\r
+  //\r
+  if (MouseAbsolutePointerDev->StateChanged) {\r
+    gBS->SignalEvent (Event);\r
+  }\r
+\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+PollMouseAbsolutePointer(\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Event notification function for TimerEvent event\r
+  If mouse device is connected to system, try to get the mouse packet data\r
+\r
+Arguments:\r
+\r
+  Event      -  TimerEvent in PS2_MOUSE_DEV\r
+  Context  -  Pointer to PS2_MOUSE_DEV structure\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;\r
+\r
+  MouseAbsolutePointerDev = (PS2_MOUSE_ABSOLUTE_POINTER_DEV *) Context;\r
+\r
+  //\r
+  // Polling mouse packet data\r
+  //\r
+  PS2MouseGetPacket (MouseAbsolutePointerDev);\r
+}\r
+\r
+/**\r
+  The user Entry Point for module Ps2MouseAbsolutePointer. The user code starts with this function.\r
+\r
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  \r
+  @param[in] SystemTable    A pointer to the EFI System Table.\r
+  \r
+  @retval EFI_SUCCESS       The entry point is executed successfully.\r
+  @retval other             Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializePs2MouseAbsolutePointer(\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+\r
+  //\r
+  // Install driver model protocol(s).\r
+  //\r
+  Status = EfiLibInstallDriverBindingComponentName2 (\r
+             ImageHandle,\r
+             SystemTable,\r
+             &gPS2MouseAbsolutePointerDriver,\r
+             ImageHandle,\r
+             &gPs2MouseAbsolutePointerComponentName,\r
+             &gPs2MouseAbsolutePointerComponentName2\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+  return Status;\r
+}\r