REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the MdeModulePkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			676 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			676 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
| 
 | |
|   PS/2 Keyboard driver. Routines that interacts with callers,
 | |
|   conforming to EFI driver model
 | |
| 
 | |
| Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
 | |
| SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "Ps2Keyboard.h"
 | |
| 
 | |
| //
 | |
| // Function prototypes
 | |
| //
 | |
| 
 | |
| /**
 | |
|   Test controller is a keyboard Controller.
 | |
| 
 | |
|   @param This                 Pointer of EFI_DRIVER_BINDING_PROTOCOL
 | |
|   @param Controller           driver's controller
 | |
|   @param RemainingDevicePath  children device path
 | |
| 
 | |
|   @retval EFI_UNSUPPORTED controller is not floppy disk
 | |
|   @retval EFI_SUCCESS     controller is floppy disk
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| KbdControllerDriverSupported (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN EFI_HANDLE                   Controller,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
 | |
|   );
 | |
| 
 | |
| /**
 | |
|   Create KEYBOARD_CONSOLE_IN_DEV instance on controller.
 | |
| 
 | |
|   @param This         Pointer of EFI_DRIVER_BINDING_PROTOCOL
 | |
|   @param Controller   driver controller handle
 | |
|   @param RemainingDevicePath Children's device path
 | |
| 
 | |
|   @retval whether success to create floppy control instance.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| KbdControllerDriverStart (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN EFI_HANDLE                   Controller,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
 | |
|   );
 | |
| 
 | |
| /**
 | |
|   Stop this driver on ControllerHandle. Support stopping any child handles
 | |
|   created by this driver.
 | |
| 
 | |
|   @param  This              Protocol instance pointer.
 | |
|   @param  ControllerHandle  Handle of device to stop driver on
 | |
|   @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
 | |
|                             children is zero stop the entire bus driver.
 | |
|   @param  ChildHandleBuffer List of Child Handles to Stop.
 | |
| 
 | |
|   @retval EFI_SUCCESS       This driver is removed ControllerHandle
 | |
|   @retval other             This driver was not removed from this device
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| KbdControllerDriverStop (
 | |
|   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN  EFI_HANDLE                   Controller,
 | |
|   IN  UINTN                        NumberOfChildren,
 | |
|   IN  EFI_HANDLE                   *ChildHandleBuffer
 | |
|   );
 | |
| 
 | |
| /**
 | |
|   Free the waiting key notify list.
 | |
| 
 | |
|   @param ListHead  Pointer to list head
 | |
| 
 | |
|   @retval EFI_INVALID_PARAMETER  ListHead is NULL
 | |
|   @retval EFI_SUCCESS            Success to free NotifyList
 | |
| **/
 | |
| EFI_STATUS
 | |
| KbdFreeNotifyList (
 | |
|   IN OUT LIST_ENTRY  *ListHead
 | |
|   );
 | |
| 
 | |
| //
 | |
| // DriverBinding Protocol Instance
 | |
| //
 | |
| EFI_DRIVER_BINDING_PROTOCOL  gKeyboardControllerDriver = {
 | |
|   KbdControllerDriverSupported,
 | |
|   KbdControllerDriverStart,
 | |
|   KbdControllerDriverStop,
 | |
|   0xa,
 | |
|   NULL,
 | |
|   NULL
 | |
| };
 | |
| 
 | |
| /**
 | |
|   Test controller is a keyboard Controller.
 | |
| 
 | |
|   @param This                 Pointer of EFI_DRIVER_BINDING_PROTOCOL
 | |
|   @param Controller           driver's controller
 | |
|   @param RemainingDevicePath  children device path
 | |
| 
 | |
|   @retval EFI_UNSUPPORTED controller is not floppy disk
 | |
|   @retval EFI_SUCCESS     controller is floppy disk
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| KbdControllerDriverSupported (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN EFI_HANDLE                   Controller,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                Status;
 | |
|   EFI_SIO_PROTOCOL          *Sio;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
 | |
|   ACPI_HID_DEVICE_PATH      *Acpi;
 | |
| 
 | |
|   //
 | |
|   // Check whether the controller is keyboard.
 | |
|   //
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   Controller,
 | |
|                   &gEfiDevicePathProtocolGuid,
 | |
|                   (VOID **)&DevicePath,
 | |
|                   This->DriverBindingHandle,
 | |
|                   Controller,
 | |
|                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   do {
 | |
|     Acpi       = (ACPI_HID_DEVICE_PATH *)DevicePath;
 | |
|     DevicePath = NextDevicePathNode (DevicePath);
 | |
|   } while (!IsDevicePathEnd (DevicePath));
 | |
| 
 | |
|   if ((DevicePathType (Acpi) != ACPI_DEVICE_PATH) ||
 | |
|       ((DevicePathSubType (Acpi) != ACPI_DP) && (DevicePathSubType (Acpi) != ACPI_EXTENDED_DP)))
 | |
|   {
 | |
|     return EFI_UNSUPPORTED;
 | |
|   }
 | |
| 
 | |
|   if ((Acpi->HID != EISA_PNP_ID (0x303)) || (Acpi->UID != 0)) {
 | |
|     return EFI_UNSUPPORTED;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Open the IO Abstraction(s) needed to perform the supported test
 | |
|   //
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   Controller,
 | |
|                   &gEfiSioProtocolGuid,
 | |
|                   (VOID **)&Sio,
 | |
|                   This->DriverBindingHandle,
 | |
|                   Controller,
 | |
|                   EFI_OPEN_PROTOCOL_BY_DRIVER
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Close the I/O Abstraction(s) used to perform the supported test
 | |
|   //
 | |
|   gBS->CloseProtocol (
 | |
|          Controller,
 | |
|          &gEfiSioProtocolGuid,
 | |
|          This->DriverBindingHandle,
 | |
|          Controller
 | |
|          );
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Create KEYBOARD_CONSOLE_IN_DEV instance on controller.
 | |
| 
 | |
|   @param This         Pointer of EFI_DRIVER_BINDING_PROTOCOL
 | |
|   @param Controller   driver controller handle
 | |
|   @param RemainingDevicePath Children's device path
 | |
| 
 | |
|   @retval whether success to create floppy control instance.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| KbdControllerDriverStart (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN EFI_HANDLE                   Controller,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                Status;
 | |
|   EFI_STATUS                Status1;
 | |
|   EFI_SIO_PROTOCOL          *Sio;
 | |
|   KEYBOARD_CONSOLE_IN_DEV   *ConsoleIn;
 | |
|   UINT8                     Data;
 | |
|   EFI_STATUS_CODE_VALUE     StatusCode;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
 | |
| 
 | |
|   StatusCode = 0;
 | |
| 
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   Controller,
 | |
|                   &gEfiDevicePathProtocolGuid,
 | |
|                   (VOID **)&DevicePath,
 | |
|                   This->DriverBindingHandle,
 | |
|                   Controller,
 | |
|                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Report that the keyboard is being enabled
 | |
|   //
 | |
|   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
 | |
|     EFI_PROGRESS_CODE,
 | |
|     EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE,
 | |
|     DevicePath
 | |
|     );
 | |
| 
 | |
|   //
 | |
|   // Get the ISA I/O Protocol on Controller's handle
 | |
|   //
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   Controller,
 | |
|                   &gEfiSioProtocolGuid,
 | |
|                   (VOID **)&Sio,
 | |
|                   This->DriverBindingHandle,
 | |
|                   Controller,
 | |
|                   EFI_OPEN_PROTOCOL_BY_DRIVER
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Allocate private data
 | |
|   //
 | |
|   ConsoleIn = AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_DEV));
 | |
|   if (ConsoleIn == NULL) {
 | |
|     Status     = EFI_OUT_OF_RESOURCES;
 | |
|     StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
 | |
|     goto ErrorExit;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Setup the device instance
 | |
|   //
 | |
|   ConsoleIn->Signature              = KEYBOARD_CONSOLE_IN_DEV_SIGNATURE;
 | |
|   ConsoleIn->Handle                 = Controller;
 | |
|   (ConsoleIn->ConIn).Reset          = KeyboardEfiReset;
 | |
|   (ConsoleIn->ConIn).ReadKeyStroke  = KeyboardReadKeyStroke;
 | |
|   ConsoleIn->DataRegisterAddress    = KEYBOARD_8042_DATA_REGISTER;
 | |
|   ConsoleIn->StatusRegisterAddress  = KEYBOARD_8042_STATUS_REGISTER;
 | |
|   ConsoleIn->CommandRegisterAddress = KEYBOARD_8042_COMMAND_REGISTER;
 | |
|   ConsoleIn->DevicePath             = DevicePath;
 | |
| 
 | |
|   ConsoleIn->ConInEx.Reset               = KeyboardEfiResetEx;
 | |
|   ConsoleIn->ConInEx.ReadKeyStrokeEx     = KeyboardReadKeyStrokeEx;
 | |
|   ConsoleIn->ConInEx.SetState            = KeyboardSetState;
 | |
|   ConsoleIn->ConInEx.RegisterKeyNotify   = KeyboardRegisterKeyNotify;
 | |
|   ConsoleIn->ConInEx.UnregisterKeyNotify = KeyboardUnregisterKeyNotify;
 | |
| 
 | |
|   InitializeListHead (&ConsoleIn->NotifyList);
 | |
| 
 | |
|   //
 | |
|   // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS.
 | |
|   // When KBC decode (IO port 0x60/0x64 decode) is not enabled,
 | |
|   // KeyboardRead will read back as 0xFF and return status is EFI_SUCCESS.
 | |
|   // So instead we read status register to detect after read if KBC decode is enabled.
 | |
|   //
 | |
| 
 | |
|   //
 | |
|   // Return code is ignored on purpose.
 | |
|   //
 | |
|   if (!PcdGetBool (PcdFastPS2Detection)) {
 | |
|     KeyboardRead (ConsoleIn, &Data);
 | |
|     if ((KeyReadStatusRegister (ConsoleIn) & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) {
 | |
|       //
 | |
|       // If nobody decodes KBC I/O port, it will read back as 0xFF.
 | |
|       // Check the Time-Out and Parity bit to see if it has an active KBC in system
 | |
|       //
 | |
|       Status     = EFI_DEVICE_ERROR;
 | |
|       StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;
 | |
|       goto ErrorExit;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Setup the WaitForKey event
 | |
|   //
 | |
|   Status = gBS->CreateEvent (
 | |
|                   EVT_NOTIFY_WAIT,
 | |
|                   TPL_NOTIFY,
 | |
|                   KeyboardWaitForKey,
 | |
|                   ConsoleIn,
 | |
|                   &((ConsoleIn->ConIn).WaitForKey)
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Status     = EFI_OUT_OF_RESOURCES;
 | |
|     StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
 | |
|     goto ErrorExit;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Setup the WaitForKeyEx event
 | |
|   //
 | |
|   Status = gBS->CreateEvent (
 | |
|                   EVT_NOTIFY_WAIT,
 | |
|                   TPL_NOTIFY,
 | |
|                   KeyboardWaitForKeyEx,
 | |
|                   ConsoleIn,
 | |
|                   &(ConsoleIn->ConInEx.WaitForKeyEx)
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Status     = EFI_OUT_OF_RESOURCES;
 | |
|     StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
 | |
|     goto ErrorExit;
 | |
|   }
 | |
| 
 | |
|   // Setup a periodic timer, used for reading keystrokes at a fixed interval
 | |
|   //
 | |
|   Status = gBS->CreateEvent (
 | |
|                   EVT_TIMER | EVT_NOTIFY_SIGNAL,
 | |
|                   TPL_NOTIFY,
 | |
|                   KeyboardTimerHandler,
 | |
|                   ConsoleIn,
 | |
|                   &ConsoleIn->TimerEvent
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Status     = EFI_OUT_OF_RESOURCES;
 | |
|     StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
 | |
|     goto ErrorExit;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->SetTimer (
 | |
|                   ConsoleIn->TimerEvent,
 | |
|                   TimerPeriodic,
 | |
|                   KEYBOARD_TIMER_INTERVAL
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Status     = EFI_OUT_OF_RESOURCES;
 | |
|     StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
 | |
|     goto ErrorExit;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->CreateEvent (
 | |
|                   EVT_NOTIFY_SIGNAL,
 | |
|                   TPL_CALLBACK,
 | |
|                   KeyNotifyProcessHandler,
 | |
|                   ConsoleIn,
 | |
|                   &ConsoleIn->KeyNotifyProcessEvent
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Status     = EFI_OUT_OF_RESOURCES;
 | |
|     StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
 | |
|     goto ErrorExit;
 | |
|   }
 | |
| 
 | |
|   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
 | |
|     EFI_PROGRESS_CODE,
 | |
|     EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT,
 | |
|     DevicePath
 | |
|     );
 | |
| 
 | |
|   //
 | |
|   // Reset the keyboard device
 | |
|   //
 | |
|   Status = ConsoleIn->ConInEx.Reset (&ConsoleIn->ConInEx, FeaturePcdGet (PcdPs2KbdExtendedVerification));
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Status     = EFI_DEVICE_ERROR;
 | |
|     StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;
 | |
|     goto ErrorExit;
 | |
|   }
 | |
| 
 | |
|   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
 | |
|     EFI_PROGRESS_CODE,
 | |
|     EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DETECTED,
 | |
|     DevicePath
 | |
|     );
 | |
| 
 | |
|   ConsoleIn->ControllerNameTable = NULL;
 | |
|   AddUnicodeString2 (
 | |
|     "eng",
 | |
|     gPs2KeyboardComponentName.SupportedLanguages,
 | |
|     &ConsoleIn->ControllerNameTable,
 | |
|     L"PS/2 Keyboard Device",
 | |
|     TRUE
 | |
|     );
 | |
|   AddUnicodeString2 (
 | |
|     "en",
 | |
|     gPs2KeyboardComponentName2.SupportedLanguages,
 | |
|     &ConsoleIn->ControllerNameTable,
 | |
|     L"PS/2 Keyboard Device",
 | |
|     FALSE
 | |
|     );
 | |
| 
 | |
|   //
 | |
|   // Install protocol interfaces for the keyboard device.
 | |
|   //
 | |
|   Status = gBS->InstallMultipleProtocolInterfaces (
 | |
|                   &Controller,
 | |
|                   &gEfiSimpleTextInProtocolGuid,
 | |
|                   &ConsoleIn->ConIn,
 | |
|                   &gEfiSimpleTextInputExProtocolGuid,
 | |
|                   &ConsoleIn->ConInEx,
 | |
|                   NULL
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
 | |
|     goto ErrorExit;
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| 
 | |
| ErrorExit:
 | |
|   //
 | |
|   // Report error code
 | |
|   //
 | |
|   if (StatusCode != 0) {
 | |
|     REPORT_STATUS_CODE_WITH_DEVICE_PATH (
 | |
|       EFI_ERROR_CODE | EFI_ERROR_MINOR,
 | |
|       StatusCode,
 | |
|       DevicePath
 | |
|       );
 | |
|   }
 | |
| 
 | |
|   if ((ConsoleIn != NULL) && (ConsoleIn->ConIn.WaitForKey != NULL)) {
 | |
|     gBS->CloseEvent (ConsoleIn->ConIn.WaitForKey);
 | |
|   }
 | |
| 
 | |
|   if ((ConsoleIn != NULL) && (ConsoleIn->TimerEvent != NULL)) {
 | |
|     gBS->CloseEvent (ConsoleIn->TimerEvent);
 | |
|   }
 | |
| 
 | |
|   if ((ConsoleIn != NULL) && (ConsoleIn->ConInEx.WaitForKeyEx != NULL)) {
 | |
|     gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
 | |
|   }
 | |
| 
 | |
|   if ((ConsoleIn != NULL) && (ConsoleIn->KeyNotifyProcessEvent != NULL)) {
 | |
|     gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent);
 | |
|   }
 | |
| 
 | |
|   KbdFreeNotifyList (&ConsoleIn->NotifyList);
 | |
|   if ((ConsoleIn != NULL) && (ConsoleIn->ControllerNameTable != NULL)) {
 | |
|     FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Since there will be no timer handler for keyboard input any more,
 | |
|   // exhaust input data just in case there is still keyboard data left
 | |
|   //
 | |
|   if (ConsoleIn != NULL) {
 | |
|     Status1 = EFI_SUCCESS;
 | |
|     while (!EFI_ERROR (Status1) && (Status != EFI_DEVICE_ERROR)) {
 | |
|       Status1 = KeyboardRead (ConsoleIn, &Data);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (ConsoleIn != NULL) {
 | |
|     gBS->FreePool (ConsoleIn);
 | |
|   }
 | |
| 
 | |
|   gBS->CloseProtocol (
 | |
|          Controller,
 | |
|          &gEfiSioProtocolGuid,
 | |
|          This->DriverBindingHandle,
 | |
|          Controller
 | |
|          );
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Stop this driver on ControllerHandle. Support stopping any child handles
 | |
|   created by this driver.
 | |
| 
 | |
|   @param  This              Protocol instance pointer.
 | |
|   @param  ControllerHandle  Handle of device to stop driver on
 | |
|   @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
 | |
|                             children is zero stop the entire bus driver.
 | |
|   @param  ChildHandleBuffer List of Child Handles to Stop.
 | |
| 
 | |
|   @retval EFI_SUCCESS       This driver is removed ControllerHandle
 | |
|   @retval other             This driver was not removed from this device
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| KbdControllerDriverStop (
 | |
|   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN  EFI_HANDLE                   Controller,
 | |
|   IN  UINTN                        NumberOfChildren,
 | |
|   IN  EFI_HANDLE                   *ChildHandleBuffer
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                      Status;
 | |
|   EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *ConIn;
 | |
|   KEYBOARD_CONSOLE_IN_DEV         *ConsoleIn;
 | |
|   UINT8                           Data;
 | |
| 
 | |
|   //
 | |
|   // Disable Keyboard
 | |
|   //
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   Controller,
 | |
|                   &gEfiSimpleTextInProtocolGuid,
 | |
|                   (VOID **)&ConIn,
 | |
|                   This->DriverBindingHandle,
 | |
|                   Controller,
 | |
|                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   Controller,
 | |
|                   &gEfiSimpleTextInputExProtocolGuid,
 | |
|                   NULL,
 | |
|                   This->DriverBindingHandle,
 | |
|                   Controller,
 | |
|                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (ConIn);
 | |
| 
 | |
|   //
 | |
|   // Report that the keyboard is being disabled
 | |
|   //
 | |
|   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
 | |
|     EFI_PROGRESS_CODE,
 | |
|     EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE,
 | |
|     ConsoleIn->DevicePath
 | |
|     );
 | |
| 
 | |
|   if (ConsoleIn->TimerEvent != NULL) {
 | |
|     gBS->CloseEvent (ConsoleIn->TimerEvent);
 | |
|     ConsoleIn->TimerEvent = NULL;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Since there will be no timer handler for keyboard input any more,
 | |
|   // exhaust input data just in case there is still keyboard data left
 | |
|   //
 | |
|   Status = EFI_SUCCESS;
 | |
|   while (!EFI_ERROR (Status)) {
 | |
|     Status = KeyboardRead (ConsoleIn, &Data);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Uninstall the SimpleTextIn and SimpleTextInEx protocols
 | |
|   //
 | |
|   Status = gBS->UninstallMultipleProtocolInterfaces (
 | |
|                   Controller,
 | |
|                   &gEfiSimpleTextInProtocolGuid,
 | |
|                   &ConsoleIn->ConIn,
 | |
|                   &gEfiSimpleTextInputExProtocolGuid,
 | |
|                   &ConsoleIn->ConInEx,
 | |
|                   NULL
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   gBS->CloseProtocol (
 | |
|          Controller,
 | |
|          &gEfiSioProtocolGuid,
 | |
|          This->DriverBindingHandle,
 | |
|          Controller
 | |
|          );
 | |
| 
 | |
|   //
 | |
|   // Free other resources
 | |
|   //
 | |
|   if ((ConsoleIn->ConIn).WaitForKey != NULL) {
 | |
|     gBS->CloseEvent ((ConsoleIn->ConIn).WaitForKey);
 | |
|     (ConsoleIn->ConIn).WaitForKey = NULL;
 | |
|   }
 | |
| 
 | |
|   if (ConsoleIn->ConInEx.WaitForKeyEx != NULL) {
 | |
|     gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
 | |
|     ConsoleIn->ConInEx.WaitForKeyEx = NULL;
 | |
|   }
 | |
| 
 | |
|   if (ConsoleIn->KeyNotifyProcessEvent != NULL) {
 | |
|     gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent);
 | |
|     ConsoleIn->KeyNotifyProcessEvent = NULL;
 | |
|   }
 | |
| 
 | |
|   KbdFreeNotifyList (&ConsoleIn->NotifyList);
 | |
|   FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
 | |
|   gBS->FreePool (ConsoleIn);
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Free the waiting key notify list.
 | |
| 
 | |
|   @param ListHead  Pointer to list head
 | |
| 
 | |
|   @retval EFI_INVALID_PARAMETER  ListHead is NULL
 | |
|   @retval EFI_SUCCESS            Success to free NotifyList
 | |
| **/
 | |
| EFI_STATUS
 | |
| KbdFreeNotifyList (
 | |
|   IN OUT LIST_ENTRY  *ListHead
 | |
|   )
 | |
| {
 | |
|   KEYBOARD_CONSOLE_IN_EX_NOTIFY  *NotifyNode;
 | |
| 
 | |
|   if (ListHead == NULL) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   while (!IsListEmpty (ListHead)) {
 | |
|     NotifyNode = CR (
 | |
|                    ListHead->ForwardLink,
 | |
|                    KEYBOARD_CONSOLE_IN_EX_NOTIFY,
 | |
|                    NotifyEntry,
 | |
|                    KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
 | |
|                    );
 | |
|     RemoveEntryList (ListHead->ForwardLink);
 | |
|     gBS->FreePool (NotifyNode);
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   The module Entry Point for module Ps2Keyboard.
 | |
| 
 | |
|   @param[in] ImageHandle    The firmware allocated handle for the EFI image.
 | |
|   @param[in] SystemTable    A pointer to the EFI System Table.
 | |
| 
 | |
|   @retval EFI_SUCCESS       The entry point is executed successfully.
 | |
|   @retval other             Some error occurs when executing this entry point.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| InitializePs2Keyboard (
 | |
|   IN EFI_HANDLE        ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE  *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   //
 | |
|   // Install driver model protocol(s).
 | |
|   //
 | |
|   Status = EfiLibInstallDriverBindingComponentName2 (
 | |
|              ImageHandle,
 | |
|              SystemTable,
 | |
|              &gKeyboardControllerDriver,
 | |
|              ImageHandle,
 | |
|              &gPs2KeyboardComponentName,
 | |
|              &gPs2KeyboardComponentName2
 | |
|              );
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|   return Status;
 | |
| }
 |