--- /dev/null
+/** @file\r
+ PS/2 Mouse driver. Routines that interacts with callers,\r
+ conforming to EFI driver model.\r
+\r
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
+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 "Ps2Mouse.h"\r
+#include "CommPs2.h"\r
+\r
+///\r
+/// DriverBinding Protocol Instance\r
+///\r
+EFI_DRIVER_BINDING_PROTOCOL gPS2MouseDriver = {\r
+ PS2MouseDriverSupported,\r
+ PS2MouseDriverStart,\r
+ PS2MouseDriverStop,\r
+ 0xa,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
+/**\r
+ Test to see if this driver supports ControllerHandle. Any ControllerHandle\r
+ than contains a IsaIo protocol can be supported.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ControllerHandle Handle of device to test\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCESS This driver supports this device\r
+ @retval EFI_ALREADY_STARTED This driver is already running on this device\r
+ @retval other This driver does not support this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PS2MouseDriverSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_SIO_PROTOCOL *Sio;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ ACPI_HID_DEVICE_PATH *Acpi;\r
+\r
+ //\r
+ // Check whether the controller is keyboard.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &DevicePath,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ do {\r
+ Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath;\r
+ DevicePath = NextDevicePathNode (DevicePath);\r
+ } while (!IsDevicePathEnd (DevicePath));\r
+\r
+ if (DevicePathType (Acpi) != ACPI_DEVICE_PATH ||\r
+ (DevicePathSubType (Acpi) != ACPI_DP && DevicePathSubType (Acpi) != ACPI_EXTENDED_DP)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ switch (Acpi->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 (Acpi->UID == 1) {\r
+ break;\r
+ }\r
+\r
+ default:\r
+ return EFI_UNSUPPORTED;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Open the IO Abstraction(s) needed to perform the supported test\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiSioProtocolGuid,\r
+ (VOID **) &Sio,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Close the I/O Abstraction(s) used to perform the supported test\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiSioProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Start this driver on ControllerHandle by opening a Sio protocol, creating\r
+ PS2_MOUSE_DEV device and install gEfiSimplePointerProtocolGuid finally.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ControllerHandle Handle of device to bind driver to\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCESS This driver is added to ControllerHandle\r
+ @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle\r
+ @retval other This driver does not support this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PS2MouseDriverStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STATUS EmptyStatus;\r
+ EFI_SIO_PROTOCOL *Sio;\r
+ PS2_MOUSE_DEV *MouseDev;\r
+ UINT8 Data;\r
+ EFI_TPL OldTpl;\r
+ EFI_STATUS_CODE_VALUE StatusCode;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+\r
+ StatusCode = 0;\r
+\r
+ //\r
+ // Open the device path protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &DevicePath,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\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
+ DevicePath\r
+ );\r
+\r
+ //\r
+ // Get the ISA I/O Protocol on Controller's handle\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiSioProtocolGuid,\r
+ (VOID **) &Sio,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\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
+ MouseDev = AllocateZeroPool (sizeof (PS2_MOUSE_DEV));\r
+ if (MouseDev == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ErrorExit;\r
+ }\r
+ //\r
+ // Setup the device instance\r
+ //\r
+ MouseDev->Signature = PS2_MOUSE_DEV_SIGNATURE;\r
+ MouseDev->Handle = Controller;\r
+ MouseDev->SampleRate = SampleRate20;\r
+ MouseDev->Resolution = MouseResolution4;\r
+ MouseDev->Scaling = Scaling1;\r
+ MouseDev->DataPackageSize = 3;\r
+ MouseDev->DevicePath = DevicePath;\r
+\r
+ //\r
+ // Resolution = 4 counts/mm\r
+ //\r
+ MouseDev->Mode.ResolutionX = 4;\r
+ MouseDev->Mode.ResolutionY = 4;\r
+ MouseDev->Mode.LeftButton = TRUE;\r
+ MouseDev->Mode.RightButton = TRUE;\r
+\r
+ MouseDev->SimplePointerProtocol.Reset = MouseReset;\r
+ MouseDev->SimplePointerProtocol.GetState = MouseGetState;\r
+ MouseDev->SimplePointerProtocol.Mode = &(MouseDev->Mode);\r
+\r
+ //\r
+ // Initialize keyboard controller if necessary\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_PERIPHERAL_MOUSE | EFI_P_MOUSE_PC_SELF_TEST,\r
+ DevicePath\r
+ );\r
+\r
+ Data = IoRead8 (KBC_CMD_STS_PORT);\r
+ //\r
+ // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS.\r
+ //\r
+ if ((Data & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) {\r
+ //\r
+ // If nobody decodes KBC I/O port, it will read back as 0xFF.\r
+ // Check the Time-Out and Parity bit to see if it has an active KBC in system\r
+ //\r
+ Status = EFI_DEVICE_ERROR;\r
+ StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED;\r
+ goto ErrorExit;\r
+ }\r
+\r
+ if ((Data & KBC_SYSF) != KBC_SYSF) {\r
+ Status = KbcSelfTest ();\r
+ if (EFI_ERROR (Status)) {\r
+ StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_CONTROLLER_ERROR;\r
+ goto ErrorExit;\r
+ }\r
+ }\r
+\r
+ KbcEnableAux ();\r
+\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT,\r
+ DevicePath\r
+ );\r
+\r
+ //\r
+ // Reset the mouse\r
+ //\r
+ Status = MouseDev->SimplePointerProtocol.Reset (\r
+ &MouseDev->SimplePointerProtocol,\r
+ FeaturePcdGet (PcdPs2MouseExtendedVerification)\r
+ );\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
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_PERIPHERAL_MOUSE | EFI_P_PC_DETECTED,\r
+ DevicePath\r
+ );\r
+\r
+ //\r
+ // Setup the WaitForKey event\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_WAIT,\r
+ TPL_NOTIFY,\r
+ MouseWaitForInput,\r
+ MouseDev,\r
+ &((MouseDev->SimplePointerProtocol).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
+ PollMouse,\r
+ MouseDev,\r
+ &MouseDev->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 (MouseDev->TimerEvent, TimerPeriodic, 100000);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ErrorExit;\r
+ }\r
+\r
+ MouseDev->ControllerNameTable = NULL;\r
+ AddUnicodeString2 (\r
+ "eng",\r
+ gPs2MouseComponentName.SupportedLanguages,\r
+ &MouseDev->ControllerNameTable,\r
+ L"PS/2 Mouse Device",\r
+ TRUE\r
+ );\r
+ AddUnicodeString2 (\r
+ "en",\r
+ gPs2MouseComponentName2.SupportedLanguages,\r
+ &MouseDev->ControllerNameTable,\r
+ L"PS/2 Mouse Device",\r
+ FALSE\r
+ );\r
+\r
+\r
+ //\r
+ // Install protocol interfaces for the mouse device.\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &Controller,\r
+ &gEfiSimplePointerProtocolGuid,\r
+ &MouseDev->SimplePointerProtocol,\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
+ if (Status != EFI_DEVICE_ERROR) {\r
+ KbcDisableAux ();\r
+ }\r
+\r
+ if (StatusCode != 0) {\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+ StatusCode,\r
+ DevicePath\r
+ );\r
+ }\r
+\r
+ if ((MouseDev != NULL) && (MouseDev->SimplePointerProtocol.WaitForInput != NULL)) {\r
+ gBS->CloseEvent (MouseDev->SimplePointerProtocol.WaitForInput);\r
+ }\r
+\r
+ if ((MouseDev != NULL) && (MouseDev->TimerEvent != NULL)) {\r
+ gBS->CloseEvent (MouseDev->TimerEvent);\r
+ }\r
+\r
+ if ((MouseDev != NULL) && (MouseDev->ControllerNameTable != NULL)) {\r
+ FreeUnicodeStringTable (MouseDev->ControllerNameTable);\r
+ }\r
+\r
+ if (Status != EFI_DEVICE_ERROR) {\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 (&Data);\r
+ }\r
+ }\r
+\r
+ if (MouseDev != NULL) {\r
+ FreePool (MouseDev);\r
+ }\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiSioProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Stop this driver on ControllerHandle. Support stoping any child handles\r
+ created by this driver.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ControllerHandle Handle of device to stop driver on\r
+ @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
+ children is zero stop the entire bus driver.\r
+ @param ChildHandleBuffer List of Child Handles to Stop.\r
+\r
+ @retval EFI_SUCCESS This driver is removed ControllerHandle\r
+ @retval other This driver was not removed from this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PS2MouseDriverStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_SIMPLE_POINTER_PROTOCOL *SimplePointerProtocol;\r
+ PS2_MOUSE_DEV *MouseDev;\r
+ UINT8 Data;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiSimplePointerProtocolGuid,\r
+ (VOID **) &SimplePointerProtocol,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ MouseDev = PS2_MOUSE_DEV_FROM_THIS (SimplePointerProtocol);\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
+ MouseDev->DevicePath\r
+ );\r
+\r
+ Status = gBS->UninstallProtocolInterface (\r
+ Controller,\r
+ &gEfiSimplePointerProtocolGuid,\r
+ &MouseDev->SimplePointerProtocol\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Cancel mouse data polling timer, close timer event\r
+ //\r
+ gBS->SetTimer (MouseDev->TimerEvent, TimerCancel, 0);\r
+ gBS->CloseEvent (MouseDev->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 (&Data);\r
+ }\r
+\r
+ gBS->CloseEvent (MouseDev->SimplePointerProtocol.WaitForInput);\r
+ FreeUnicodeStringTable (MouseDev->ControllerNameTable);\r
+ FreePool (MouseDev);\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiSioProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Reset the Mouse and do BAT test for it, if ExtendedVerification is TRUE and\r
+ there is a mouse device connectted to system.\r
+\r
+ @param This - Pointer of simple pointer Protocol.\r
+ @param ExtendedVerification - Whether configure mouse parameters. True: do; FALSE: skip.\r
+\r
+\r
+ @retval EFI_SUCCESS - The command byte is written successfully.\r
+ @retval EFI_DEVICE_ERROR - Errors occurred during reseting keyboard.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MouseReset (\r
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ PS2_MOUSE_DEV *MouseDev;\r
+ EFI_TPL OldTpl;\r
+ BOOLEAN KeyboardEnable;\r
+ UINT8 Data;\r
+\r
+ MouseDev = PS2_MOUSE_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
+ MouseDev->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 (&MouseDev->State, sizeof (EFI_SIMPLE_POINTER_STATE));\r
+ MouseDev->StateChanged = FALSE;\r
+\r
+ //\r
+ // Exhaust input data\r
+ //\r
+ Status = EFI_SUCCESS;\r
+ while (!EFI_ERROR (Status)) {\r
+ Status = In8042Data (&Data);\r
+ }\r
+\r
+ CheckKbStatus (&KeyboardEnable);\r
+\r
+ KbcDisableKb ();\r
+\r
+ //\r
+ // if there's data block on KBC data port, read it out\r
+ //\r
+ if ((IoRead8 (KBC_CMD_STS_PORT) & KBC_OUTB) == KBC_OUTB) {\r
+ IoRead8 (KBC_DATA_PORT);\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 && CheckMouseConnect (MouseDev)) {\r
+ //\r
+ // Send mouse reset command and set mouse default configure\r
+ //\r
+ Status = PS2MouseReset ();\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Exit;\r
+ }\r
+\r
+ Status = PS2MouseSetSampleRate (MouseDev->SampleRate);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Exit;\r
+ }\r
+\r
+ Status = PS2MouseSetResolution (MouseDev->Resolution);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Exit;\r
+ }\r
+\r
+ Status = PS2MouseSetScaling (MouseDev->Scaling);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Exit;\r
+ }\r
+\r
+ Status = PS2MouseEnable ();\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 ();\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Check whether there is Ps/2 mouse device in system\r
+\r
+ @param MouseDev - Mouse Private Data Structure\r
+\r
+ @retval TRUE - Keyboard in System.\r
+ @retval FALSE - Keyboard not in System.\r
+\r
+**/\r
+BOOLEAN\r
+CheckMouseConnect (\r
+ IN PS2_MOUSE_DEV *MouseDev\r
+ )\r
+\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = PS2MouseEnable ();\r
+ if (!EFI_ERROR (Status)) {\r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Get and Clear mouse status.\r
+\r
+ @param This - Pointer of simple pointer Protocol.\r
+ @param State - Output buffer holding status.\r
+\r
+ @retval EFI_INVALID_PARAMETER Output buffer is invalid.\r
+ @retval EFI_NOT_READY Mouse is not changed status yet.\r
+ @retval EFI_SUCCESS Mouse status is changed and get successful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MouseGetState (\r
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,\r
+ IN OUT EFI_SIMPLE_POINTER_STATE *State\r
+ )\r
+{\r
+ PS2_MOUSE_DEV *MouseDev;\r
+ EFI_TPL OldTpl;\r
+\r
+ MouseDev = PS2_MOUSE_DEV_FROM_THIS (This);\r
+\r
+ if (State == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (!MouseDev->StateChanged) {\r
+ return EFI_NOT_READY;\r
+ }\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+ CopyMem (State, &(MouseDev->State), sizeof (EFI_SIMPLE_POINTER_STATE));\r
+\r
+ //\r
+ // clear mouse state\r
+ //\r
+ MouseDev->State.RelativeMovementX = 0;\r
+ MouseDev->State.RelativeMovementY = 0;\r
+ MouseDev->State.RelativeMovementZ = 0;\r
+ MouseDev->StateChanged = FALSE;\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+\r
+ Event notification function for SIMPLE_POINTER.WaitForInput event.\r
+ Signal the event if there is input from mouse.\r
+\r
+ @param Event event object\r
+ @param Context event context\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+MouseWaitForInput (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ PS2_MOUSE_DEV *MouseDev;\r
+\r
+ MouseDev = (PS2_MOUSE_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 (MouseDev->StateChanged) {\r
+ gBS->SignalEvent (Event);\r
+ }\r
+\r
+}\r
+\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
+ @param Event - TimerEvent in PS2_MOUSE_DEV\r
+ @param Context - Pointer to PS2_MOUSE_DEV structure\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+PollMouse (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+\r
+{\r
+ PS2_MOUSE_DEV *MouseDev;\r
+\r
+ MouseDev = (PS2_MOUSE_DEV *) Context;\r
+\r
+ //\r
+ // Polling mouse packet data\r
+ //\r
+ PS2MouseGetPacket (MouseDev);\r
+}\r
+\r
+/**\r
+ The user Entry Point for module Ps2Mouse. 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
+InitializePs2Mouse(\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
+ &gPS2MouseDriver,\r
+ ImageHandle,\r
+ &gPs2MouseComponentName,\r
+ &gPs2MouseComponentName2\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+ return Status;\r
+}\r
+\r