-/*++\r
+/** @file\r
\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
+ PS/2 Keyboard driver. Routines that interacts with callers,\r
+ conforming to EFI driver model\r
+\r
+Copyright (c) 2006 - 2009, 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
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
-Module Name:\r
-\r
- Ps2Keyboard.c\r
-\r
-Abstract:\r
-\r
- PS/2 Keyboard driver. Routines that interacts with callers,\r
- conforming to EFI driver model\r
-\r
---*/\r
-\r
-//\r
-// Include common header file for this module.\r
-//\r
-#include "CommonHeader.h"\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
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
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\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
KbdControllerDriverStop (\r
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
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
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
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
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
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
+ //\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
// Setup the WaitForKey event\r
//\r
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->ConInEx),\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
// Setup a periodic timer, used for reading keystrokes at a fixed interval\r
//\r
Status = gBS->CreateEvent (\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
&Controller,\r
&gEfiSimpleTextInProtocolGuid,\r
&ConsoleIn->ConIn,\r
+ &gEfiSimpleTextInputExProtocolGuid,\r
+ &ConsoleIn->ConInEx,\r
NULL\r
);\r
if (EFI_ERROR (Status)) {\r
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
+ KbdFreeNotifyList (&ConsoleIn->NotifyList);\r
if ((ConsoleIn != NULL) && (ConsoleIn->ControllerNameTable != NULL)) {\r
FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);\r
}\r
// 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
+ \r
if (ConsoleIn != NULL) {\r
gBS->FreePool (ConsoleIn);\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
KbdControllerDriverStop (\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
{\r
EFI_STATUS Status;\r
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\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
//\r
ConsoleIn->DevicePath\r
);\r
\r
- if (ConsoleIn->TimerEvent) {\r
+ if (ConsoleIn->TimerEvent != NULL) {\r
gBS->CloseEvent (ConsoleIn->TimerEvent);\r
ConsoleIn->TimerEvent = NULL;\r
}\r
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
//\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
+ 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