--- /dev/null
+/**@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