]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c
IntelFrameworkModulePkg: Clean up source files
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / Ps2KeyboardDxe / Ps2Keyboard.c
index ef2e4a23749e76c4a572603ccd3f4b57e99b3ebb..3fbb37820d20b950a1c01d6c914ce4e58ef9c17f 100644 (file)
@@ -1,36 +1,34 @@
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved. <BR>\r
-This software and associated documentation (if any) is furnished\r
-under a license and may only be used or copied in accordance\r
-with the terms of the license. Except as permitted by such\r
-license, no part of this software or documentation may be\r
-reproduced, stored in a retrieval system, or transmitted in any\r
-form or by any means without the express written consent of\r
-Intel Corporation.\r
-\r
-\r
-Module Name:\r
-\r
-  Ps2Keyboard.c\r
-\r
-Abstract:\r
+/** @file\r
 \r
   PS/2 Keyboard driver. Routines that interacts with callers,\r
   conforming to EFI driver model\r
 \r
---*/\r
+Copyright (c) 2006 - 2018, 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
-//\r
-// Include common header file for this module.\r
-//\r
-#include "CommonHeader.h"\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 "Ps2Keyboard.h"\r
 \r
 //\r
 // Function prototypes\r
 //\r
+/**\r
+  Test controller is a keyboard Controller.\r
+\r
+  @param This                 Pointer of EFI_DRIVER_BINDING_PROTOCOL\r
+  @param Controller           driver's controller\r
+  @param RemainingDevicePath  children device path\r
+\r
+  @retval EFI_UNSUPPORTED controller is not floppy disk\r
+  @retval EFI_SUCCESS     controller is floppy disk\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 KbdControllerDriverSupported (\r
@@ -39,6 +37,15 @@ KbdControllerDriverSupported (
   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
   );\r
 \r
+/**\r
+  Create KEYBOARD_CONSOLE_IN_DEV instance on controller.\r
+\r
+  @param This         Pointer of EFI_DRIVER_BINDING_PROTOCOL\r
+  @param Controller   driver controller handle\r
+  @param RemainingDevicePath Children's device path\r
+\r
+  @retval whether success to create floppy control instance.\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 KbdControllerDriverStart (\r
@@ -47,6 +54,20 @@ KbdControllerDriverStart (
   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
   );\r
 \r
+/**\r
+  Stop this driver on ControllerHandle. Support stopping 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
 KbdControllerDriverStop (\r
@@ -56,9 +77,19 @@ KbdControllerDriverStop (
   IN  EFI_HANDLE                     *ChildHandleBuffer\r
   );\r
 \r
-//\r
-// Global variables\r
-//\r
+/**\r
+  Free the waiting key notify list.\r
+\r
+  @param ListHead  Pointer to list head\r
+\r
+  @retval EFI_INVALID_PARAMETER  ListHead is NULL\r
+  @retval EFI_SUCCESS            Sucess to free NotifyList\r
+**/\r
+EFI_STATUS\r
+KbdFreeNotifyList (\r
+  IN OUT LIST_ENTRY           *ListHead\r
+  );\r
+\r
 //\r
 // DriverBinding Protocol Instance\r
 //\r
@@ -71,6 +102,16 @@ EFI_DRIVER_BINDING_PROTOCOL gKeyboardControllerDriver = {
   NULL\r
 };\r
 \r
+/**\r
+  Test controller is a keyboard Controller.\r
+\r
+  @param This                 Pointer of EFI_DRIVER_BINDING_PROTOCOL\r
+  @param Controller           driver's controller\r
+  @param RemainingDevicePath  children device path\r
+\r
+  @retval EFI_UNSUPPORTED controller is not floppy disk\r
+  @retval EFI_SUCCESS     controller is floppy disk\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 KbdControllerDriverSupported (\r
@@ -78,20 +119,6 @@ KbdControllerDriverSupported (
   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
@@ -129,6 +156,15 @@ Returns:
   return Status;\r
 }\r
 \r
+/**\r
+  Create KEYBOARD_CONSOLE_IN_DEV instance on controller.\r
+\r
+  @param This         Pointer of EFI_DRIVER_BINDING_PROTOCOL\r
+  @param Controller   driver controller handle\r
+  @param RemainingDevicePath Children's device path\r
+\r
+  @retval whether success to create floppy control instance.\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 KbdControllerDriverStart (\r
@@ -136,19 +172,6 @@ KbdControllerDriverStart (
   IN EFI_HANDLE                     Controller,\r
   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\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:    RemainingDevicePath - add argument and description to function comment\r
-// GC_TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
 {\r
   EFI_STATUS                                Status;\r
   EFI_STATUS                                Status1;\r
@@ -220,13 +243,39 @@ Returns:
   ConsoleIn->StatusRegisterAddress  = KEYBOARD_8042_STATUS_REGISTER;\r
   ConsoleIn->CommandRegisterAddress = KEYBOARD_8042_COMMAND_REGISTER;\r
   ConsoleIn->IsaIo                  = IsaIo;\r
-  ConsoleIn->ScancodeBufStartPos    = 0;\r
-  ConsoleIn->ScancodeBufEndPos      = KEYBOARD_BUFFER_MAX_COUNT - 1;\r
-  ConsoleIn->ScancodeBufCount       = 0;\r
-  ConsoleIn->Ctrled                 = FALSE;\r
-  ConsoleIn->Alted                  = FALSE;\r
   ConsoleIn->DevicePath             = ParentDevicePath;\r
 \r
+  ConsoleIn->ConInEx.Reset               = KeyboardEfiResetEx;\r
+  ConsoleIn->ConInEx.ReadKeyStrokeEx     = KeyboardReadKeyStrokeEx;\r
+  ConsoleIn->ConInEx.SetState            = KeyboardSetState;\r
+  ConsoleIn->ConInEx.RegisterKeyNotify   = KeyboardRegisterKeyNotify;\r
+  ConsoleIn->ConInEx.UnregisterKeyNotify = KeyboardUnregisterKeyNotify;\r
+\r
+  InitializeListHead (&ConsoleIn->NotifyList);\r
+\r
+  //\r
+  // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS.\r
+  // When KBC decode (IO port 0x60/0x64 decode) is not enabled,\r
+  // KeyboardRead will read back as 0xFF and return status is EFI_SUCCESS.\r
+  // So instead we read status register to detect after read if KBC decode is enabled.\r
+  //\r
+\r
+  //\r
+  // Return code is ignored on purpose.\r
+  //\r
+  if (!PcdGetBool (PcdFastPS2Detection)) {\r
+    KeyboardRead (ConsoleIn, &Data);\r
+    if ((KeyReadStatusRegister (ConsoleIn) & (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_KEYBOARD | EFI_P_EC_NOT_DETECTED;\r
+      goto ErrorExit;\r
+    }\r
+  }\r
+\r
   //\r
   // Setup the WaitForKey event\r
   //\r
@@ -234,7 +283,7 @@ Returns:
                   EVT_NOTIFY_WAIT,\r
                   TPL_NOTIFY,\r
                   KeyboardWaitForKey,\r
-                  &(ConsoleIn->ConIn),\r
+                  ConsoleIn,\r
                   &((ConsoleIn->ConIn).WaitForKey)\r
                   );\r
   if (EFI_ERROR (Status)) {\r
@@ -243,6 +292,21 @@ Returns:
     goto ErrorExit;\r
   }\r
   //\r
+  // Setup the WaitForKeyEx event\r
+  //\r
+  Status = gBS->CreateEvent (\r
+                  EVT_NOTIFY_WAIT,\r
+                  TPL_NOTIFY,\r
+                  KeyboardWaitForKeyEx,\r
+                  ConsoleIn,\r
+                  &(ConsoleIn->ConInEx.WaitForKeyEx)\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    Status      = EFI_OUT_OF_RESOURCES;\r
+    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;\r
+    goto ErrorExit;\r
+  }\r
+\r
   // Setup a periodic timer, used for reading keystrokes at a fixed interval\r
   //\r
   Status = gBS->CreateEvent (\r
@@ -269,6 +333,19 @@ Returns:
     goto ErrorExit;\r
   }\r
 \r
+  Status = gBS->CreateEvent (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_CALLBACK,\r
+                  KeyNotifyProcessHandler,\r
+                  ConsoleIn,\r
+                  &ConsoleIn->KeyNotifyProcessEvent\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    Status      = EFI_OUT_OF_RESOURCES;\r
+    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;\r
+    goto ErrorExit;\r
+  }\r
+\r
   REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
     EFI_PROGRESS_CODE,\r
     EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT,\r
@@ -278,21 +355,36 @@ Returns:
   //\r
   // Reset the keyboard device\r
   //\r
-  Status = ConsoleIn->ConIn.Reset (&ConsoleIn->ConIn, TRUE);\r
+  Status = ConsoleIn->ConInEx.Reset (&ConsoleIn->ConInEx, FeaturePcdGet (PcdPs2KbdExtendedVerification));\r
   if (EFI_ERROR (Status)) {\r
     Status      = EFI_DEVICE_ERROR;\r
     StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;\r
     goto ErrorExit;\r
   }\r
 \r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DETECTED,\r
+    ParentDevicePath\r
+    );\r
+\r
   ConsoleIn->ControllerNameTable = NULL;\r
-  AddUnicodeString (\r
+  AddUnicodeString2 (\r
     "eng",\r
     gPs2KeyboardComponentName.SupportedLanguages,\r
     &ConsoleIn->ControllerNameTable,\r
-    L"PS/2 Keyboard Device"\r
+    L"PS/2 Keyboard Device",\r
+    TRUE\r
+    );\r
+  AddUnicodeString2 (\r
+    "en",\r
+    gPs2KeyboardComponentName2.SupportedLanguages,\r
+    &ConsoleIn->ControllerNameTable,\r
+    L"PS/2 Keyboard Device",\r
+    FALSE\r
     );\r
 \r
+\r
   //\r
   // Install protocol interfaces for the keyboard device.\r
   //\r
@@ -300,6 +392,8 @@ Returns:
                   &Controller,\r
                   &gEfiSimpleTextInProtocolGuid,\r
                   &ConsoleIn->ConIn,\r
+                  &gEfiSimpleTextInputExProtocolGuid,\r
+                  &ConsoleIn->ConInEx,\r
                   NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
@@ -328,7 +422,13 @@ ErrorExit:
   if ((ConsoleIn != NULL) && (ConsoleIn->TimerEvent != NULL)) {\r
     gBS->CloseEvent (ConsoleIn->TimerEvent);\r
   }\r
-\r
+  if ((ConsoleIn != NULL) && (ConsoleIn->ConInEx.WaitForKeyEx != NULL)) {\r
+    gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);\r
+  }\r
+  if ((ConsoleIn != NULL) && (ConsoleIn->KeyNotifyProcessEvent != NULL)) {\r
+    gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent);\r
+  }\r
+  KbdFreeNotifyList (&ConsoleIn->NotifyList);\r
   if ((ConsoleIn != NULL) && (ConsoleIn->ControllerNameTable != NULL)) {\r
     FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);\r
   }\r
@@ -336,9 +436,11 @@ ErrorExit:
   // Since there will be no timer handler for keyboard input any more,\r
   // exhaust input data just in case there is still keyboard data left\r
   //\r
-  Status1 = EFI_SUCCESS;\r
-  while (!EFI_ERROR (Status1)) {\r
-    Status1 = KeyboardRead (ConsoleIn, &Data);;\r
+  if (ConsoleIn != NULL) {\r
+    Status1 = EFI_SUCCESS;\r
+    while (!EFI_ERROR (Status1) && (Status != EFI_DEVICE_ERROR)) {\r
+      Status1 = KeyboardRead (ConsoleIn, &Data);;\r
+    }\r
   }\r
 \r
   if (ConsoleIn != NULL) {\r
@@ -362,6 +464,20 @@ ErrorExit:
   return Status;\r
 }\r
 \r
+/**\r
+  Stop this driver on ControllerHandle. Support stopping 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
 KbdControllerDriverStop (\r
@@ -370,20 +486,6 @@ KbdControllerDriverStop (
   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
 {\r
   EFI_STATUS                     Status;\r
   EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;\r
@@ -404,6 +506,17 @@ KbdControllerDriverStop (
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiSimpleTextInputExProtocolGuid,\r
+                  NULL,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
   ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (ConIn);\r
 \r
@@ -416,14 +529,10 @@ KbdControllerDriverStop (
     ConsoleIn->DevicePath\r
     );\r
 \r
-  if (ConsoleIn->TimerEvent) {\r
+  if (ConsoleIn->TimerEvent != NULL) {\r
     gBS->CloseEvent (ConsoleIn->TimerEvent);\r
     ConsoleIn->TimerEvent = NULL;\r
   }\r
-  //\r
-  // Disable the keyboard interface\r
-  //\r
-  Status = DisableKeyboard (ConsoleIn);\r
 \r
   //\r
   // Since there will be no timer handler for keyboard input any more,\r
@@ -434,12 +543,15 @@ KbdControllerDriverStop (
     Status = KeyboardRead (ConsoleIn, &Data);;\r
   }\r
   //\r
-  // Uninstall the Simple TextIn Protocol\r
+  // Uninstall the SimpleTextIn and SimpleTextInEx protocols\r
   //\r
-  Status = gBS->UninstallProtocolInterface (\r
+  Status = gBS->UninstallMultipleProtocolInterfaces (\r
                   Controller,\r
                   &gEfiSimpleTextInProtocolGuid,\r
-                  &ConsoleIn->ConIn\r
+                  &ConsoleIn->ConIn,\r
+                  &gEfiSimpleTextInputExProtocolGuid,\r
+                  &ConsoleIn->ConInEx,\r
+                  NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
@@ -462,13 +574,90 @@ KbdControllerDriverStop (
   //\r
   // Free other resources\r
   //\r
-  if ((ConsoleIn->ConIn).WaitForKey) {\r
+  if ((ConsoleIn->ConIn).WaitForKey != NULL) {\r
     gBS->CloseEvent ((ConsoleIn->ConIn).WaitForKey);\r
     (ConsoleIn->ConIn).WaitForKey = NULL;\r
   }\r
-\r
+  if (ConsoleIn->ConInEx.WaitForKeyEx != NULL) {\r
+    gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);\r
+    ConsoleIn->ConInEx.WaitForKeyEx = NULL;\r
+  }\r
+  if (ConsoleIn->KeyNotifyProcessEvent != NULL) {\r
+    gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent);\r
+    ConsoleIn->KeyNotifyProcessEvent = NULL;\r
+  }\r
+  KbdFreeNotifyList (&ConsoleIn->NotifyList);\r
   FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);\r
   gBS->FreePool (ConsoleIn);\r
 \r
   return EFI_SUCCESS;\r
 }\r
+\r
+/**\r
+  Free the waiting key notify list.\r
+\r
+  @param ListHead  Pointer to list head\r
+\r
+  @retval EFI_INVALID_PARAMETER  ListHead is NULL\r
+  @retval EFI_SUCCESS            Sucess to free NotifyList\r
+**/\r
+EFI_STATUS\r
+KbdFreeNotifyList (\r
+  IN OUT LIST_ENTRY           *ListHead\r
+  )\r
+{\r
+  KEYBOARD_CONSOLE_IN_EX_NOTIFY *NotifyNode;\r
+\r
+  if (ListHead == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  while (!IsListEmpty (ListHead)) {\r
+    NotifyNode = CR (\r
+                   ListHead->ForwardLink,\r
+                   KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
+                   NotifyEntry,\r
+                   KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
+                   );\r
+    RemoveEntryList (ListHead->ForwardLink);\r
+    gBS->FreePool (NotifyNode);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  The module Entry Point for module Ps2Keyboard.\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
+InitializePs2Keyboard(\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
+             &gKeyboardControllerDriver,\r
+             ImageHandle,\r
+             &gPs2KeyboardComponentName,\r
+             &gPs2KeyboardComponentName2\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+  return Status;\r
+}\r
+\r