]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c
IntelFrameworkModulePkg: Clean up source files
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / Ps2KeyboardDxe / Ps2KbdCtrller.c
index c4f1ee1780ee54a4d03896f80e2943b031d84d89..78c4e3b3919da5e9754e98cbd406a56bb9554225 100644 (file)
@@ -1,9 +1,8 @@
-/**@file\r
-  PS/2 Keyboard driver\r
+/** @file\r
   Routines that access 8042 keyboard controller\r
 \r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\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
@@ -13,90 +12,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-//\r
-// Include common header file for this module.\r
-//\r
 #include "Ps2Keyboard.h"\r
 \r
-//\r
-// Function declarations\r
-//\r
-STATIC\r
-UINT8\r
-KeyReadDataRegister (\r
-  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
-  );\r
-\r
-STATIC\r
-VOID\r
-KeyWriteDataRegister (\r
-  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
-  IN UINT8                   Data\r
-  );\r
-\r
-STATIC\r
-VOID\r
-KeyWriteCommandRegister (\r
-  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
-  IN UINT8                   Data\r
-  );\r
-\r
-STATIC\r
-VOID\r
-KeyboardError (\r
-  IN KEYBOARD_CONSOLE_IN_DEV*ConsoleIn,\r
-  IN CHAR16                 *ErrMsg // should be a unicode string\r
-  );\r
-\r
-STATIC\r
-EFI_STATUS\r
-GetScancodeBufHead (\r
-  KEYBOARD_CONSOLE_IN_DEV  *ConsoleIn,\r
-  IN UINT32                Count,\r
-  OUT UINT8                *Buf\r
-  );\r
-\r
-STATIC\r
-EFI_STATUS\r
-PopScancodeBufHead (\r
-  KEYBOARD_CONSOLE_IN_DEV  *ConsoleIn,\r
-  IN UINT32                Count,\r
-  OUT UINT8                *Buf\r
-  );\r
-\r
-STATIC\r
-EFI_STATUS\r
-KeyboardWrite (\r
-  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
-  IN UINT8                   Data\r
-  );\r
-\r
-STATIC\r
-EFI_STATUS\r
-KeyboardCommand (\r
-  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
-  IN UINT8                   Data\r
-  );\r
-\r
-STATIC\r
-EFI_STATUS\r
-KeyboardWaitForValue (\r
-  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
-  IN UINT8                   Value\r
-  );\r
-\r
-STATIC\r
-EFI_STATUS\r
-UpdateStatusLights (\r
-  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
-  );\r
-\r
-//\r
-// Global variables\r
-//\r
-\r
-STATIC struct {\r
-  UINT8  ScanCode;\r
+struct {\r
+  UINT8   ScanCode;             ///< follows value defined in Scan Code Set1\r
   UINT16  EfiScanCode;\r
   CHAR16  UnicodeChar;\r
   CHAR16  ShiftUnicodeChar;\r
@@ -106,512 +25,530 @@ ConvertKeyboardScanCodeToEfiKey[] = {
   {\r
     0x01,  //   Escape\r
     SCAN_ESC,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x02,\r
     SCAN_NULL,\r
-    '1',\r
-    '!'\r
+    L'1',\r
+    L'!'\r
   },\r
   {\r
     0x03,\r
     SCAN_NULL,\r
-    '2',\r
-    '@'\r
+    L'2',\r
+    L'@'\r
   },\r
   {\r
     0x04,\r
     SCAN_NULL,\r
-    '3',\r
-    '#'\r
+    L'3',\r
+    L'#'\r
   },\r
   {\r
     0x05,\r
     SCAN_NULL,\r
-    '4',\r
-    '$'\r
+    L'4',\r
+    L'$'\r
   },\r
   {\r
     0x06,\r
     SCAN_NULL,\r
-    '5',\r
-    '%'\r
+    L'5',\r
+    L'%'\r
   },\r
   {\r
     0x07,\r
     SCAN_NULL,\r
-    '6',\r
-    '^'\r
+    L'6',\r
+    L'^'\r
   },\r
   {\r
     0x08,\r
     SCAN_NULL,\r
-    '7',\r
-    '&'\r
+    L'7',\r
+    L'&'\r
   },\r
   {\r
     0x09,\r
     SCAN_NULL,\r
-    '8',\r
-    '*'\r
+    L'8',\r
+    L'*'\r
   },\r
   {\r
     0x0A,\r
     SCAN_NULL,\r
-    '9',\r
-    '('\r
+    L'9',\r
+    L'('\r
   },\r
   {\r
     0x0B,\r
     SCAN_NULL,\r
-    '0',\r
-    ')'\r
+    L'0',\r
+    L')'\r
   },\r
   {\r
     0x0C,\r
     SCAN_NULL,\r
-    '-',\r
-    '_'\r
+    L'-',\r
+    L'_'\r
   },\r
   {\r
     0x0D,\r
     SCAN_NULL,\r
-    '=',\r
-    '+'\r
+    L'=',\r
+    L'+'\r
   },\r
   {\r
     0x0E, //  BackSpace\r
     SCAN_NULL,\r
-    0x08,\r
-    0x08\r
+    0x0008,\r
+    0x0008\r
   },\r
   {\r
     0x0F, //  Tab\r
     SCAN_NULL,\r
-    0x09,\r
-    0x09\r
+    0x0009,\r
+    0x0009\r
   },\r
   {\r
     0x10,\r
     SCAN_NULL,\r
-    'q',\r
-    'Q'\r
+    L'q',\r
+    L'Q'\r
   },\r
   {\r
     0x11,\r
     SCAN_NULL,\r
-    'w',\r
-    'W'\r
+    L'w',\r
+    L'W'\r
   },\r
   {\r
     0x12,\r
     SCAN_NULL,\r
-    'e',\r
-    'E'\r
+    L'e',\r
+    L'E'\r
   },\r
   {\r
     0x13,\r
     SCAN_NULL,\r
-    'r',\r
-    'R'\r
+    L'r',\r
+    L'R'\r
   },\r
   {\r
     0x14,\r
     SCAN_NULL,\r
-    't',\r
-    'T'\r
+    L't',\r
+    L'T'\r
   },\r
   {\r
     0x15,\r
     SCAN_NULL,\r
-    'y',\r
-    'Y'\r
+    L'y',\r
+    L'Y'\r
   },\r
   {\r
     0x16,\r
     SCAN_NULL,\r
-    'u',\r
-    'U'\r
+    L'u',\r
+    L'U'\r
   },\r
   {\r
     0x17,\r
     SCAN_NULL,\r
-    'i',\r
-    'I'\r
+    L'i',\r
+    L'I'\r
   },\r
   {\r
     0x18,\r
     SCAN_NULL,\r
-    'o',\r
-    'O'\r
+    L'o',\r
+    L'O'\r
   },\r
   {\r
     0x19,\r
     SCAN_NULL,\r
-    'p',\r
-    'P'\r
+    L'p',\r
+    L'P'\r
   },\r
   {\r
     0x1a,\r
     SCAN_NULL,\r
-    '[',\r
-    '{'\r
+    L'[',\r
+    L'{'\r
   },\r
   {\r
     0x1b,\r
     SCAN_NULL,\r
-    ']',\r
-    '}'\r
+    L']',\r
+    L'}'\r
   },\r
   {\r
     0x1c, //   Enter\r
     SCAN_NULL,\r
-    0x0d,\r
-    0x0d\r
+    0x000d,\r
+    0x000d\r
   },\r
   {\r
     0x1d,\r
     SCAN_NULL,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x1e,\r
     SCAN_NULL,\r
-    'a',\r
-    'A'\r
+    L'a',\r
+    L'A'\r
   },\r
   {\r
     0x1f,\r
     SCAN_NULL,\r
-    's',\r
-    'S'\r
+    L's',\r
+    L'S'\r
   },\r
   {\r
     0x20,\r
     SCAN_NULL,\r
-    'd',\r
-    'D'\r
+    L'd',\r
+    L'D'\r
   },\r
   {\r
     0x21,\r
     SCAN_NULL,\r
-    'f',\r
-    'F'\r
+    L'f',\r
+    L'F'\r
   },\r
   {\r
     0x22,\r
     SCAN_NULL,\r
-    'g',\r
-    'G'\r
+    L'g',\r
+    L'G'\r
   },\r
   {\r
     0x23,\r
     SCAN_NULL,\r
-    'h',\r
-    'H'\r
+    L'h',\r
+    L'H'\r
   },\r
   {\r
     0x24,\r
     SCAN_NULL,\r
-    'j',\r
-    'J'\r
+    L'j',\r
+    L'J'\r
   },\r
   {\r
     0x25,\r
     SCAN_NULL,\r
-    'k',\r
-    'K'\r
+    L'k',\r
+    L'K'\r
   },\r
   {\r
     0x26,\r
     SCAN_NULL,\r
-    'l',\r
-    'L'\r
+    L'l',\r
+    L'L'\r
   },\r
   {\r
     0x27,\r
     SCAN_NULL,\r
-    ';',\r
-    ':'\r
+    L';',\r
+    L':'\r
   },\r
   {\r
     0x28,\r
     SCAN_NULL,\r
-    '\'',\r
-    '"'\r
+    L'\'',\r
+    L'"'\r
   },\r
   {\r
     0x29,\r
     SCAN_NULL,\r
-    '`',\r
-    '~'\r
+    L'`',\r
+    L'~'\r
   },\r
   {\r
     0x2a, //   Left Shift\r
     SCAN_NULL,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x2b,\r
     SCAN_NULL,\r
-    '\\',\r
-    '|'\r
+    L'\\',\r
+    L'|'\r
   },\r
   {\r
     0x2c,\r
     SCAN_NULL,\r
-    'z',\r
-    'Z'\r
+    L'z',\r
+    L'Z'\r
   },\r
   {\r
     0x2d,\r
     SCAN_NULL,\r
-    'x',\r
-    'X'\r
+    L'x',\r
+    L'X'\r
   },\r
   {\r
     0x2e,\r
     SCAN_NULL,\r
-    'c',\r
-    'C'\r
+    L'c',\r
+    L'C'\r
   },\r
   {\r
     0x2f,\r
     SCAN_NULL,\r
-    'v',\r
-    'V'\r
+    L'v',\r
+    L'V'\r
   },\r
   {\r
     0x30,\r
     SCAN_NULL,\r
-    'b',\r
-    'B'\r
+    L'b',\r
+    L'B'\r
   },\r
   {\r
     0x31,\r
     SCAN_NULL,\r
-    'n',\r
-    'N'\r
+    L'n',\r
+    L'N'\r
   },\r
   {\r
     0x32,\r
     SCAN_NULL,\r
-    'm',\r
-    'M'\r
+    L'm',\r
+    L'M'\r
   },\r
   {\r
     0x33,\r
     SCAN_NULL,\r
-    ',',\r
-    '<'\r
+    L',',\r
+    L'<'\r
   },\r
   {\r
     0x34,\r
     SCAN_NULL,\r
-    '.',\r
-    '>'\r
+    L'.',\r
+    L'>'\r
   },\r
   {\r
     0x35,\r
     SCAN_NULL,\r
-    '/',\r
-    '?'\r
+    L'/',\r
+    L'?'\r
   },\r
   {\r
     0x36, //Right Shift\r
     SCAN_NULL,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x37, // Numeric Keypad *\r
     SCAN_NULL,\r
-    '*',\r
-    '*'\r
+    L'*',\r
+    L'*'\r
   },\r
   {\r
     0x38,  //Left Alt/Extended Right Alt\r
     SCAN_NULL,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x39,\r
     SCAN_NULL,\r
-    ' ',\r
-    ' '\r
+    L' ',\r
+    L' '\r
   },\r
   {\r
     0x3A, //CapsLock\r
     SCAN_NULL,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x3B,\r
     SCAN_F1,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x3C,\r
     SCAN_F2,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x3D,\r
     SCAN_F3,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x3E,\r
     SCAN_F4,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x3F,\r
     SCAN_F5,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x40,\r
     SCAN_F6,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x41,\r
     SCAN_F7,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x42,\r
     SCAN_F8,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x43,\r
     SCAN_F9,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x44,\r
     SCAN_F10,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x45, // NumLock\r
     SCAN_NULL,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x46, //  ScrollLock\r
     SCAN_NULL,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x47,\r
     SCAN_HOME,\r
-    '7',\r
-    '7'\r
+    L'7',\r
+    L'7'\r
   },\r
   {\r
     0x48,\r
     SCAN_UP,\r
-    '8',\r
-    '8'\r
+    L'8',\r
+    L'8'\r
   },\r
   {\r
     0x49,\r
     SCAN_PAGE_UP,\r
-    '9',\r
-    '9'\r
+    L'9',\r
+    L'9'\r
   },\r
   {\r
     0x4a,\r
     SCAN_NULL,\r
-    '-',\r
-    '-'\r
+    L'-',\r
+    L'-'\r
   },\r
   {\r
     0x4b,\r
     SCAN_LEFT,\r
-    '4',\r
-    '4'\r
+    L'4',\r
+    L'4'\r
   },\r
   {\r
     0x4c, //  Numeric Keypad 5\r
     SCAN_NULL,\r
-    '5',\r
-    '5'\r
+    L'5',\r
+    L'5'\r
   },\r
   {\r
     0x4d,\r
     SCAN_RIGHT,\r
-    '6',\r
-    '6'\r
+    L'6',\r
+    L'6'\r
   },\r
   {\r
     0x4e,\r
     SCAN_NULL,\r
-    '+',\r
-    '+'\r
+    L'+',\r
+    L'+'\r
   },\r
   {\r
     0x4f,\r
     SCAN_END,\r
-    '1',\r
-    '1'\r
+    L'1',\r
+    L'1'\r
   },\r
   {\r
     0x50,\r
     SCAN_DOWN,\r
-    '2',\r
-    '2'\r
+    L'2',\r
+    L'2'\r
   },\r
   {\r
     0x51,\r
     SCAN_PAGE_DOWN,\r
-    '3',\r
-    '3'\r
+    L'3',\r
+    L'3'\r
   },\r
   {\r
     0x52,\r
     SCAN_INSERT,\r
-    '0',\r
-    '0'\r
+    L'0',\r
+    L'0'\r
   },\r
   {\r
     0x53,\r
     SCAN_DELETE,\r
-    '.',\r
-    '.'\r
+    L'.',\r
+    L'.'\r
   },\r
   {\r
     0x57,\r
     SCAN_F11,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     0x58,\r
     SCAN_F12,\r
-    0x00,\r
-    0x00\r
+    0x0000,\r
+    0x0000\r
+  },\r
+  {\r
+    0x5B,  //Left LOGO\r
+    SCAN_NULL,\r
+    0x0000,\r
+    0x0000\r
+  },\r
+  {\r
+    0x5C,  //Right LOGO\r
+    SCAN_NULL,\r
+    0x0000,\r
+    0x0000\r
+  },\r
+  {\r
+    0x5D,  //Menu key\r
+    SCAN_NULL,\r
+    0x0000,\r
+    0x0000\r
   },\r
   {\r
     TABLE_END,\r
@@ -621,114 +558,144 @@ ConvertKeyboardScanCodeToEfiKey[] = {
   },\r
 };\r
 \r
-\r
 //\r
 // The WaitForValue time out\r
 //\r
-STATIC UINTN  mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;\r
+UINTN  mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;\r
+\r
+BOOLEAN          mEnableMouseInterface;\r
 \r
-STATIC\r
-UINT8\r
-KeyReadDataRegister (\r
-  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
-  )\r
-/*++\r
 \r
-Routine Description:\r
 \r
-  GC_TODO: Add function description\r
+/**\r
+  Return the count of scancode in the queue.\r
 \r
-Arguments:\r
+  @param Queue     Pointer to instance of SCAN_CODE_QUEUE.\r
 \r
-  ConsoleIn - GC_TODO: add argument description\r
+  @return          Count of the scancode.\r
+**/\r
+UINTN\r
+GetScancodeBufCount (\r
+  IN SCAN_CODE_QUEUE       *Queue\r
+  )\r
+{\r
+  if (Queue->Head <= Queue->Tail) {\r
+    return Queue->Tail - Queue->Head;\r
+  } else {\r
+    return Queue->Tail + KEYBOARD_SCAN_CODE_MAX_COUNT - Queue->Head;\r
+  }\r
+}\r
 \r
-Returns:\r
+/**\r
+  Read several bytes from the scancode buffer without removing them.\r
+  This function is called to see if there are enough bytes of scancode\r
+  representing a single key.\r
 \r
-  GC_TODO: add return values\r
+  @param Queue     Pointer to instance of SCAN_CODE_QUEUE.\r
+  @param Count     Number of bytes to be read\r
+  @param Buf       Store the results\r
 \r
---*/\r
+  @retval EFI_SUCCESS   success to scan the keyboard code\r
+  @retval EFI_NOT_READY invalid parameter\r
+**/\r
+EFI_STATUS\r
+GetScancodeBufHead (\r
+  IN  SCAN_CODE_QUEUE        *Queue,\r
+  IN  UINTN                  Count,\r
+  OUT UINT8                  *Buf\r
+  )\r
 {\r
-  EFI_ISA_IO_PROTOCOL                 *IsaIo;\r
-  UINT8                               Data;\r
+  UINTN                      Index;\r
+  UINTN                      Pos;\r
 \r
   //\r
-  // Use IsaIo protocol to perform IO operations\r
+  // check the valid range of parameter 'Count'\r
   //\r
-  IsaIo = ConsoleIn->IsaIo;\r
-\r
-  IsaIo->Io.Read (\r
-              IsaIo,\r
-              EfiIsaIoWidthUint8,\r
-              ConsoleIn->DataRegisterAddress,\r
-              1,\r
-              &Data\r
-              );\r
+  if (GetScancodeBufCount (Queue) < Count) {\r
+    return EFI_NOT_READY;\r
+  }\r
+  //\r
+  // retrieve the values\r
+  //\r
+  for (Index = 0, Pos = Queue->Head; Index < Count; Index++, Pos = (Pos + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT) {\r
+    Buf[Index] = Queue->Buffer[Pos];\r
+  }\r
 \r
-  return Data;\r
+  return EFI_SUCCESS;\r
 }\r
 \r
-STATIC\r
-VOID\r
-KeyWriteDataRegister (\r
-  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
-  IN UINT8                   Data\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  GC_TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  ConsoleIn - GC_TODO: add argument description\r
-  Data      - GC_TODO: add argument description\r
+/**\r
 \r
-Returns:\r
+  Read & remove several bytes from the scancode buffer.\r
+  This function is usually called after GetScancodeBufHead()\r
 \r
-  GC_TODO: add return values\r
+  @param Queue     Pointer to instance of SCAN_CODE_QUEUE.\r
+  @param Count     Number of bytes to be read\r
+  @param Buf       Store the results\r
 \r
---*/\r
+  @retval EFI_SUCCESS success to scan the keyboard code\r
+  @retval EFI_NOT_READY invalid parameter\r
+**/\r
+EFI_STATUS\r
+PopScancodeBufHead (\r
+  IN  SCAN_CODE_QUEUE       *Queue,\r
+  IN  UINTN                 Count,\r
+  OUT UINT8                 *Buf OPTIONAL\r
+  )\r
 {\r
-  EFI_ISA_IO_PROTOCOL                 *IsaIo;\r
+  UINTN                     Index;\r
 \r
   //\r
-  // Use IsaIo protocol to perform IO operations\r
+  // Check the valid range of parameter 'Count'\r
   //\r
-  IsaIo = ConsoleIn->IsaIo;\r
-\r
-  IsaIo->Io.Write (\r
-              IsaIo,\r
-              EfiIsaIoWidthUint8,\r
-              ConsoleIn->DataRegisterAddress,\r
-              1,\r
-              &Data\r
-              );\r
-\r
+  if (GetScancodeBufCount (Queue) < Count) {\r
+    return EFI_NOT_READY;\r
+  }\r
   //\r
-  // outp(ConsoleIn->DataRegisterAddress, Data);\r
+  // Retrieve and remove the values\r
   //\r
+  for (Index = 0; Index < Count; Index++, Queue->Head = (Queue->Head + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT) {\r
+    if (Buf != NULL) {\r
+      Buf[Index] = Queue->Buffer[Queue->Head];\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
-UINT8\r
-KeyReadStatusRegister (\r
-  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
-  )\r
-/*++\r
+/**\r
+  Push one byte to the scancode buffer.\r
 \r
-Routine Description:\r
+  @param Queue     Pointer to instance of SCAN_CODE_QUEUE.\r
+  @param Scancode  The byte to push.\r
+**/\r
+VOID\r
+PushScancodeBufTail (\r
+  IN  SCAN_CODE_QUEUE       *Queue,\r
+  IN  UINT8                 Scancode\r
+  )\r
+{\r
+  if (GetScancodeBufCount (Queue) == KEYBOARD_SCAN_CODE_MAX_COUNT - 1) {\r
+    PopScancodeBufHead (Queue, 1, NULL);\r
+  }\r
 \r
-  GC_TODO: Add function description\r
+  Queue->Buffer[Queue->Tail] = Scancode;\r
+  Queue->Tail = (Queue->Tail + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT;\r
+}\r
 \r
-Arguments:\r
+/**\r
+  Read data register .\r
 \r
-  ConsoleIn - GC_TODO: add argument description\r
+  @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
 \r
-Returns:\r
+  @return return the value\r
 \r
-  GC_TODO: add return values\r
+**/\r
+UINT8\r
+KeyReadDataRegister (\r
+  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
+  )\r
 \r
---*/\r
 {\r
   EFI_ISA_IO_PROTOCOL                 *IsaIo;\r
   UINT8                               Data;\r
@@ -741,113 +708,122 @@ Returns:
   IsaIo->Io.Read (\r
               IsaIo,\r
               EfiIsaIoWidthUint8,\r
-              ConsoleIn->StatusRegisterAddress,\r
+              ConsoleIn->DataRegisterAddress,\r
               1,\r
               &Data\r
               );\r
 \r
   return Data;\r
-\r
 }\r
 \r
-STATIC\r
+/**\r
+  Write data register.\r
+\r
+  @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
+  @param Data      value wanted to be written\r
+\r
+**/\r
 VOID\r
-KeyWriteCommandRegister (\r
+KeyWriteDataRegister (\r
   IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
   IN UINT8                   Data\r
   )\r
-/*++\r
+{\r
+  ConsoleIn->IsaIo->Io.Write (\r
+                         ConsoleIn->IsaIo,\r
+                         EfiIsaIoWidthUint8,\r
+                         ConsoleIn->DataRegisterAddress,\r
+                         1,\r
+                         &Data\r
+                         );\r
+}\r
 \r
-Routine Description:\r
+/**\r
+  Read status register.\r
 \r
-  GC_TODO: Add function description\r
+  @param ConsoleIn  Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
 \r
-Arguments:\r
+  @return value in status register\r
 \r
-  ConsoleIn - GC_TODO: add argument description\r
-  Data      - GC_TODO: add argument description\r
+**/\r
+UINT8\r
+KeyReadStatusRegister (\r
+  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
+  )\r
+{\r
+  UINT8                               Data;\r
+  ConsoleIn->IsaIo->Io.Read (\r
+                         ConsoleIn->IsaIo,\r
+                         EfiIsaIoWidthUint8,\r
+                         ConsoleIn->StatusRegisterAddress,\r
+                         1,\r
+                         &Data\r
+                         );\r
+  return Data;\r
+}\r
 \r
-Returns:\r
+/**\r
+  Write command register .\r
 \r
-  GC_TODO: add return values\r
+  @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
+  @param Data      The value wanted to be written\r
 \r
---*/\r
+**/\r
+VOID\r
+KeyWriteCommandRegister (\r
+  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
+  IN UINT8                   Data\r
+  )\r
 {\r
-  EFI_ISA_IO_PROTOCOL                 *IsaIo;\r
-\r
-  //\r
-  // Use IsaIo protocol to perform IO operations\r
-  //\r
-  IsaIo = ConsoleIn->IsaIo;\r
+  ConsoleIn->IsaIo->Io.Write (\r
+                         ConsoleIn->IsaIo,\r
+                         EfiIsaIoWidthUint8,\r
+                         ConsoleIn->CommandRegisterAddress,\r
+                         1,\r
+                         &Data\r
+                         );\r
+}\r
 \r
-  IsaIo->Io.Write (\r
-              IsaIo,\r
-              EfiIsaIoWidthUint8,\r
-              ConsoleIn->CommandRegisterAddress,\r
-              1,\r
-              &Data\r
-              );\r
+/**\r
+  Display error message.\r
 \r
-}\r
+  @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
+  @param ErrMsg    Unicode string of error message\r
 \r
-STATIC\r
+**/\r
 VOID\r
 KeyboardError (\r
   IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
   IN CHAR16                  *ErrMsg\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Display error message\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
-// GC_TODO:    ConsoleIn - add argument and description to function comment\r
-// GC_TODO:    ErrMsg - add argument and description to function comment\r
 {\r
   ConsoleIn->KeyboardErr = TRUE;\r
-\r
-  //\r
-  // gST -> ConOut -> OutputString (gST -> ConOut, L"Keyboard Driver: ");\r
-  // gST -> ConOut -> OutputString (gST -> ConOut, ErrMsg);\r
-  //\r
 }\r
 \r
-VOID\r
-EFIAPI\r
-KeyboardTimerHandler (\r
-  IN EFI_EVENT    Event,\r
-  IN VOID         *Context\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
+/**\r
   Timer event handler: read a series of scancodes from 8042\r
   and put them into memory scancode buffer.\r
   it read as much scancodes to either fill\r
   the memory buffer or empty the keyboard buffer.\r
   It is registered as running under TPL_NOTIFY\r
 \r
-Arguments:\r
+  @param Event       The timer event\r
+  @param Context     A KEYBOARD_CONSOLE_IN_DEV pointer\r
 \r
-  Event - The timer event\r
-  Context - A KEYBOARD_CONSOLE_IN_DEV pointer\r
-\r
-Returns:\r
+**/\r
+VOID\r
+EFIAPI\r
+KeyboardTimerHandler (\r
+  IN EFI_EVENT    Event,\r
+  IN VOID         *Context\r
+  )\r
 \r
---*/\r
 {\r
   UINT8                   Data;\r
   EFI_TPL                 OldTpl;\r
   KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
 \r
-  ConsoleIn = Context;\r
+  ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context;\r
 \r
   //\r
   // Enter critical section\r
@@ -861,230 +837,51 @@ Returns:
     gBS->RestoreTPL (OldTpl);\r
     return ;\r
   }\r
+\r
   //\r
   // To let KB driver support Hot plug, here should skip the 'resend' command  for the case that\r
-  // KB is not connected to system. If KB is not connected to system, driver will find there's  something\r
-  // error in the following code and wait for the input buffer empty, this waiting time shoulb be  short enough since\r
+  // KB is not connected to system. If KB is not connected to system, driver will find there's something\r
+  // error in the following code and wait for the input buffer empty, this waiting time shoulb be short enough since\r
   // this is a NOTIFY TPL period function, or the system performance will degrade hardly when KB is not connected.\r
   // Just skip the 'resend' process simply.\r
   //\r
 \r
-  Data = 0;\r
-\r
-  //\r
-  // if there is no key present, just return\r
-  //\r
-  if ((KeyReadStatusRegister (Context) & 0x21) != 0x1) {\r
+  while ((KeyReadStatusRegister (ConsoleIn) & (KEYBOARD_STATUS_REGISTER_TRANSMIT_TIMEOUT|KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA)) ==\r
+      KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA\r
+     ) {\r
     //\r
-    // Leave critical section and return\r
+    // Read one byte of the scan code and store it into the memory buffer\r
     //\r
-    gBS->RestoreTPL (OldTpl);\r
-\r
-    return ;\r
+    Data = KeyReadDataRegister (ConsoleIn);\r
+    PushScancodeBufTail (&ConsoleIn->ScancodeQueue, Data);\r
   }\r
+  KeyGetchar (ConsoleIn);\r
+\r
   //\r
-  // Read one byte of the scan code and store it into the memory buffer\r
+  // Leave critical section and return\r
   //\r
-  if (ConsoleIn->ScancodeBufCount < KEYBOARD_BUFFER_MAX_COUNT) {\r
+  gBS->RestoreTPL (OldTpl);\r
+}\r
 \r
-    Data = KeyReadDataRegister (Context);\r
-    //\r
-    // put the scancode into the memory scancode buffer\r
-    //\r
-    ConsoleIn->ScancodeBufCount++;\r
-    ConsoleIn->ScancodeBufEndPos++;\r
-    if (ConsoleIn->ScancodeBufEndPos >= KEYBOARD_BUFFER_MAX_COUNT) {\r
-      ConsoleIn->ScancodeBufEndPos = 0;\r
-    }\r
+/**\r
+  Read key value .\r
 \r
-    ConsoleIn->ScancodeBuf[ConsoleIn->ScancodeBufEndPos] = Data;\r
+  @param ConsoleIn - Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
+  @param Data      - Pointer to outof buffer for keeping key value\r
 \r
-    //\r
-    // Handle Alt+Ctrl+Del Key combination\r
-    //\r
-    switch (Data) {\r
-    case SCANCODE_CTRL_MAKE:\r
-      ConsoleIn->Ctrled = TRUE;\r
-      break;\r
+  @retval EFI_TIMEOUT Status resigter time out\r
+  @retval EFI_SUCCESS Success to read keyboard\r
 \r
-    case SCANCODE_CTRL_BREAK:\r
-      ConsoleIn->Ctrled = FALSE;\r
-      break;\r
+**/\r
+EFI_STATUS\r
+KeyboardRead (\r
+  IN KEYBOARD_CONSOLE_IN_DEV  *ConsoleIn,\r
+  OUT UINT8                   *Data\r
+  )\r
 \r
-    case SCANCODE_ALT_MAKE:\r
-      ConsoleIn->Alted = TRUE;\r
-      break;\r
-\r
-    case SCANCODE_ALT_BREAK:\r
-      ConsoleIn->Alted = FALSE;\r
-      break;\r
-    }\r
-    //\r
-    // if Alt+Ctrl+Del, Reboot the System\r
-    //\r
-    if (ConsoleIn->Ctrled && ConsoleIn->Alted && Data == 0x53) {\r
-      gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
-    }\r
-  }\r
-  //\r
-  // Leave critical section and return\r
-  //\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
-  return ;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-GetScancodeBufHead (\r
-  KEYBOARD_CONSOLE_IN_DEV    *ConsoleIn,\r
-  IN UINT32                  Count,\r
-  OUT UINT8                  *Buf\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Read several bytes from the scancode buffer without removing them.\r
-  This function is called to see if there are enough bytes of scancode\r
-  representing a single key.\r
-\r
-Arguments:\r
-\r
-  Count - Number of bytes to be read\r
-  Buf - Store the results\r
-\r
-Returns:\r
-\r
-  EFI_STATUS\r
-\r
---*/\r
-// GC_TODO:    ConsoleIn - add argument and description to function comment\r
-// GC_TODO:    EFI_NOT_READY - add return value to function comment\r
-// GC_TODO:    EFI_SUCCESS - add return value to function comment\r
-{\r
-  UINT32  Index;\r
-  UINT32  Pos;\r
-\r
-  Index = 0;\r
-  Pos   = 0;\r
-\r
-  //\r
-  // check the valid range of parameter 'Count'\r
-  //\r
-  if (Count <= 0 || ConsoleIn->ScancodeBufCount < Count) {\r
-    return EFI_NOT_READY;\r
-  }\r
-  //\r
-  // retrieve the values\r
-  //\r
-  for (Index = 0; Index < Count; Index++) {\r
-\r
-    if (Index == 0) {\r
-\r
-      Pos = ConsoleIn->ScancodeBufStartPos;\r
-    } else {\r
-\r
-      Pos = Pos + 1;\r
-      if (Pos >= KEYBOARD_BUFFER_MAX_COUNT) {\r
-        Pos = 0;\r
-      }\r
-    }\r
-\r
-    Buf[Index] = ConsoleIn->ScancodeBuf[Pos];\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-PopScancodeBufHead (\r
-  KEYBOARD_CONSOLE_IN_DEV   *ConsoleIn,\r
-  IN UINT32                 Count,\r
-  OUT UINT8                 *Buf\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Read & remove several bytes from the scancode buffer.\r
-  This function is usually called after GetScancodeBufHead()\r
-\r
-Arguments:\r
-\r
-  Count - Number of bytes to be read\r
-  Buf - Store the results\r
-\r
-Returns:\r
-\r
-  EFI_STATUS\r
-\r
---*/\r
-// GC_TODO:    ConsoleIn - add argument and description to function comment\r
-// GC_TODO:    EFI_NOT_READY - add return value to function comment\r
-// GC_TODO:    EFI_SUCCESS - add return value to function comment\r
-{\r
-  UINT32  Index;\r
-\r
-  Index = 0;\r
-\r
-  //\r
-  // Check the valid range of parameter 'Count'\r
-  //\r
-  if (Count <= 0 || ConsoleIn->ScancodeBufCount < Count) {\r
-    return EFI_NOT_READY;\r
-  }\r
-  //\r
-  // Retrieve and remove the values\r
-  //\r
-  for (Index = 0; Index < Count; Index++) {\r
-\r
-    if (Index != 0) {\r
-\r
-      ConsoleIn->ScancodeBufStartPos++;\r
-      if (ConsoleIn->ScancodeBufStartPos >= KEYBOARD_BUFFER_MAX_COUNT) {\r
-        ConsoleIn->ScancodeBufStartPos = 0;\r
-      }\r
-    }\r
-\r
-    Buf[Index] = ConsoleIn->ScancodeBuf[ConsoleIn->ScancodeBufStartPos];\r
-    ConsoleIn->ScancodeBufCount--;\r
-  }\r
-\r
-  ConsoleIn->ScancodeBufStartPos++;\r
-  if (ConsoleIn->ScancodeBufStartPos >= KEYBOARD_BUFFER_MAX_COUNT) {\r
-    ConsoleIn->ScancodeBufStartPos = 0;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-KeyboardRead (\r
-  IN KEYBOARD_CONSOLE_IN_DEV  *ConsoleIn,\r
-  OUT UINT8                   *Data\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  GC_TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  ConsoleIn - GC_TODO: add argument description\r
-  Data      - GC_TODO: add argument description\r
-\r
-Returns:\r
-\r
-  EFI_TIMEOUT - GC_TODO: Add description for return value\r
-  EFI_SUCCESS - GC_TODO: Add description for return value\r
-\r
---*/\r
-{\r
-  UINT32  TimeOut;\r
-  UINT32  RegFilled;\r
+{\r
+  UINT32  TimeOut;\r
+  UINT32  RegFilled;\r
 \r
   TimeOut   = 0;\r
   RegFilled = 0;\r
@@ -1093,45 +890,37 @@ Returns:
   // wait till output buffer full then perform the read\r
   //\r
   for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {\r
-    if (KeyReadStatusRegister (ConsoleIn) & 0x01) {\r
+    if (KeyReadStatusRegister (ConsoleIn) & KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA) {\r
       RegFilled = 1;\r
       *Data     = KeyReadDataRegister (ConsoleIn);\r
       break;\r
     }\r
 \r
-    gBS->Stall (30);\r
+    MicroSecondDelay (30);\r
   }\r
 \r
-  if (!RegFilled) {\r
+  if (RegFilled == 0) {\r
     return EFI_TIMEOUT;\r
   }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-STATIC\r
+/**\r
+  write key to keyboard\r
+\r
+  @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
+  @param Data      value wanted to be written\r
+\r
+  @retval EFI_TIMEOUT   The input buffer register is full for putting new value util timeout\r
+  @retval EFI_SUCCESS   The new value is sucess put into input buffer register.\r
+\r
+**/\r
 EFI_STATUS\r
 KeyboardWrite (\r
   IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
   IN UINT8                   Data\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  GC_TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  ConsoleIn - GC_TODO: add argument description\r
-  Data      - GC_TODO: add argument description\r
-\r
-Returns:\r
-\r
-  EFI_TIMEOUT - GC_TODO: Add description for return value\r
-  EFI_SUCCESS - GC_TODO: Add description for return value\r
-\r
---*/\r
 {\r
   UINT32  TimeOut;\r
   UINT32  RegEmptied;\r
@@ -1143,15 +932,15 @@ Returns:
   // wait for input buffer empty\r
   //\r
   for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {\r
-    if (!(KeyReadStatusRegister (ConsoleIn) & 0x02)) {\r
+    if ((KeyReadStatusRegister (ConsoleIn) & 0x02) == 0) {\r
       RegEmptied = 1;\r
       break;\r
     }\r
 \r
-    gBS->Stall (30);\r
+    MicroSecondDelay (30);\r
   }\r
 \r
-  if (!RegEmptied) {\r
+  if (RegEmptied == 0) {\r
     return EFI_TIMEOUT;\r
   }\r
   //\r
@@ -1162,30 +951,21 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
-STATIC\r
+/**\r
+  Issue keyboard command.\r
+\r
+  @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
+  @param Data      The buff holding the command\r
+\r
+  @retval EFI_TIMEOUT Keyboard is not ready to issuing\r
+  @retval EFI_SUCCESS Success to issue keyboard command\r
+\r
+**/\r
 EFI_STATUS\r
 KeyboardCommand (\r
   IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
   IN UINT8                   Data\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  GC_TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  ConsoleIn - GC_TODO: add argument description\r
-  Data      - GC_TODO: add argument description\r
-\r
-Returns:\r
-\r
-  EFI_TIMEOUT - GC_TODO: Add description for return value\r
-  EFI_TIMEOUT - GC_TODO: Add description for return value\r
-  EFI_SUCCESS - GC_TODO: Add description for return value\r
-\r
---*/\r
 {\r
   UINT32  TimeOut;\r
   UINT32  RegEmptied;\r
@@ -1197,15 +977,15 @@ Returns:
   // Wait For Input Buffer Empty\r
   //\r
   for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {\r
-    if (!(KeyReadStatusRegister (ConsoleIn) & 0x02)) {\r
+    if ((KeyReadStatusRegister (ConsoleIn) & 0x02) == 0) {\r
       RegEmptied = 1;\r
       break;\r
     }\r
 \r
-    gBS->Stall (30);\r
+    MicroSecondDelay (30);\r
   }\r
 \r
-  if (!RegEmptied) {\r
+  if (RegEmptied == 0) {\r
     return EFI_TIMEOUT;\r
   }\r
   //\r
@@ -1218,47 +998,38 @@ Returns:
   //\r
   RegEmptied = 0;\r
   for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {\r
-    if (!(KeyReadStatusRegister (ConsoleIn) & 0x02)) {\r
+    if ((KeyReadStatusRegister (ConsoleIn) & 0x02) == 0) {\r
       RegEmptied = 1;\r
       break;\r
     }\r
 \r
-    gBS->Stall (30);\r
+    MicroSecondDelay (30);\r
   }\r
 \r
-  if (!RegEmptied) {\r
+  if (RegEmptied == 0) {\r
     return EFI_TIMEOUT;\r
   }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-STATIC\r
-EFI_STATUS\r
-KeyboardWaitForValue (\r
-  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
-  IN UINT8                   Value\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
+/**\r
   wait for a specific value to be presented on\r
   8042 Data register by keyboard and then read it,\r
   used in keyboard commands ack\r
 \r
-Arguments:\r
-\r
-  ConsoleIn - The KEYBOARD_CONSOLE_IN_DEV instance pointer\r
-  Value - The value to be waited for\r
+  @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
+  @param Value     the value wanted to be waited.\r
 \r
-Returns:\r
+  @retval EFI_TIMEOUT Fail to get specific value in given time\r
+  @retval EFI_SUCCESS Success to get specific value in given time.\r
 \r
-  EFI_STATUS\r
-\r
---*/\r
-// GC_TODO:    EFI_SUCCESS - add return value to function comment\r
-// GC_TODO:    EFI_TIMEOUT - add return value to function comment\r
+**/\r
+EFI_STATUS\r
+KeyboardWaitForValue (\r
+  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
+  IN UINT8                   Value\r
+  )\r
 {\r
   UINT8   Data;\r
   UINT32  TimeOut;\r
@@ -1291,7 +1062,7 @@ Returns:
         break;\r
       }\r
 \r
-      gBS->Stall (30);\r
+      MicroSecondDelay (30);\r
     }\r
 \r
     SumTimeOut += TimeOut;\r
@@ -1308,7 +1079,7 @@ Returns:
   //\r
   // Check results\r
   //\r
-  if (GotIt) {\r
+  if (GotIt == 1) {\r
     return EFI_SUCCESS;\r
   } else {\r
     return EFI_TIMEOUT;\r
@@ -1316,24 +1087,19 @@ Returns:
 \r
 }\r
 \r
-STATIC\r
-EFI_STATUS\r
-UpdateStatusLights (\r
-  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
+/**\r
   Show keyboard status lights according to\r
   indicators in ConsoleIn.\r
 \r
-Arguments:\r
+  @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
 \r
-Returns:\r
+  @return status of updating keyboard register\r
 \r
---*/\r
-// GC_TODO:    ConsoleIn - add argument and description to function comment\r
+**/\r
+EFI_STATUS\r
+UpdateStatusLights (\r
+  IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
+  )\r
 {\r
   EFI_STATUS  Status;\r
   UINT8       Command;\r
@@ -1374,212 +1140,229 @@ Returns:
   return Status;\r
 }\r
 \r
-EFI_STATUS\r
-KeyGetchar (\r
-  IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Get scancode from scancode buffer\r
-  and translate into EFI-scancode and unicode defined by EFI spec\r
-  The function is always called in TPL_NOTIFY\r
+/**\r
+  Initialize the key state.\r
 \r
-Arguments:\r
+  @param  ConsoleIn     The KEYBOARD_CONSOLE_IN_DEV instance.\r
+  @param  KeyState      A pointer to receive the key state information.\r
+**/\r
+VOID\r
+InitializeKeyState (\r
+  IN  KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
+  OUT EFI_KEY_STATE           *KeyState\r
+  )\r
+{\r
+  KeyState->KeyShiftState  = EFI_SHIFT_STATE_VALID\r
+                           | (ConsoleIn->LeftCtrl   ? EFI_LEFT_CONTROL_PRESSED  : 0)\r
+                           | (ConsoleIn->RightCtrl  ? EFI_RIGHT_CONTROL_PRESSED : 0)\r
+                           | (ConsoleIn->LeftAlt    ? EFI_LEFT_ALT_PRESSED      : 0)\r
+                           | (ConsoleIn->RightAlt   ? EFI_RIGHT_ALT_PRESSED     : 0)\r
+                           | (ConsoleIn->LeftShift  ? EFI_LEFT_SHIFT_PRESSED    : 0)\r
+                           | (ConsoleIn->RightShift ? EFI_RIGHT_SHIFT_PRESSED   : 0)\r
+                           | (ConsoleIn->LeftLogo   ? EFI_LEFT_LOGO_PRESSED     : 0)\r
+                           | (ConsoleIn->RightLogo  ? EFI_RIGHT_LOGO_PRESSED    : 0)\r
+                           | (ConsoleIn->Menu       ? EFI_MENU_KEY_PRESSED      : 0)\r
+                           | (ConsoleIn->SysReq     ? EFI_SYS_REQ_PRESSED       : 0)\r
+                           ;\r
+  KeyState->KeyToggleState = EFI_TOGGLE_STATE_VALID\r
+                           | (ConsoleIn->CapsLock   ? EFI_CAPS_LOCK_ACTIVE :   0)\r
+                           | (ConsoleIn->NumLock    ? EFI_NUM_LOCK_ACTIVE :    0)\r
+                           | (ConsoleIn->ScrollLock ? EFI_SCROLL_LOCK_ACTIVE : 0)\r
+                           | (ConsoleIn->IsSupportPartialKey ? EFI_KEY_STATE_EXPOSED : 0)\r
+                           ;\r
+}\r
 \r
-  ConsoleIn - KEYBOARD_CONSOLE_IN_DEV instance pointer\r
+/**\r
+  Get scancode from scancode buffer and translate into EFI-scancode and unicode defined by EFI spec.\r
 \r
-Returns:\r
+  The function is always called in TPL_NOTIFY.\r
 \r
-  EFI_NOT_READY - Input from console not ready yet.\r
-  EFI_SUCCESS   - Function executed successfully.\r
+  @param ConsoleIn KEYBOARD_CONSOLE_IN_DEV instance pointer\r
 \r
---*/\r
+**/\r
+VOID\r
+KeyGetchar (\r
+  IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
+  )\r
 {\r
-  EFI_STATUS  Status;\r
-  UINT8       ScanCode;\r
-  UINT8       Readed;\r
-  BOOLEAN     Extended;\r
-  UINT8       ScancodeArr[4];\r
-  UINTN       Index;\r
-  //\r
-  // 4 bytes most\r
-  //\r
-  UINT32      ScancodeArrPos;\r
+  EFI_STATUS                     Status;\r
+  UINT16                         ScanCode;\r
+  BOOLEAN                        Extend0;\r
+  BOOLEAN                        Extend1;\r
+  UINTN                          Index;\r
+  EFI_KEY_DATA                   KeyData;\r
+  LIST_ENTRY                     *Link;\r
+  KEYBOARD_CONSOLE_IN_EX_NOTIFY  *CurrentNotify;\r
   //\r
-  // point to the current position in ScancodeArr\r
+  // 3 bytes most\r
   //\r
+  UINT8                          ScancodeArr[3];\r
+  UINT32                         ScancodeArrPos;\r
 \r
-  Readed          = 0;\r
-  Extended        = FALSE;\r
-  ScancodeArrPos  = 0;\r
-\r
-  //\r
-  // Read one byte of the scan code and store it into the memory buffer\r
-  // This block of code is added to insert an action that is equivalent to\r
-  // the timer event handling function, so as to increase the frequency of\r
-  // detecting the availability of keys. Timer event has a max frequency of\r
-  // 18Hz which is insufficient\r
-  //\r
-  //\r
-  // To let KB driver support Hot plug, here should skip the 'resend' command  for the case that\r
-  // KB is not connected to system. If KB is not connected to system, driver will find there's  something\r
-  // error in the following code and wait for the input buffer empty, this waiting time shoulb be  short enough since\r
-  // this is a NOTIFY TPL period function, or the system performance will degrade hardly when KB is not connected.\r
-  // Just skip the 'resend' process simply.\r
-  //\r
-\r
-\r
-  if (((KeyReadStatusRegister (ConsoleIn) & 0x21) == 0x1) && (ConsoleIn->ScancodeBufCount < KEYBOARD_BUFFER_MAX_COUNT)) {\r
-\r
-    Readed = KeyReadDataRegister (ConsoleIn);\r
-    //\r
-    // put the scancode into the memory scancode buffer\r
-    //\r
-    ConsoleIn->ScancodeBufCount++;\r
-    ConsoleIn->ScancodeBufEndPos++;\r
-    if (ConsoleIn->ScancodeBufEndPos >= KEYBOARD_BUFFER_MAX_COUNT) {\r
-      ConsoleIn->ScancodeBufEndPos = 0;\r
-    }\r
-\r
-    ConsoleIn->ScancodeBuf[ConsoleIn->ScancodeBufEndPos] = Readed;\r
-\r
-    //\r
-    // Handle Alt+Ctrl+Del Key combination\r
-    //\r
-    switch (Readed) {\r
-\r
-    case SCANCODE_CTRL_MAKE:\r
-      ConsoleIn->Ctrled = TRUE;\r
-      break;\r
-\r
-    case SCANCODE_CTRL_BREAK:\r
-      ConsoleIn->Ctrled = FALSE;\r
-      break;\r
-\r
-    case SCANCODE_ALT_MAKE:\r
-      ConsoleIn->Alted = TRUE;\r
-      break;\r
-\r
-    case SCANCODE_ALT_BREAK:\r
-      ConsoleIn->Alted = FALSE;\r
-      break;\r
-    }\r
-    //\r
-    // if Alt+Ctrl+Del, Reboot the System\r
-    //\r
-    if (ConsoleIn->Ctrled && ConsoleIn->Alted && Readed == 0x53) {\r
-      gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
-    }\r
-  }\r
   //\r
   // Check if there are enough bytes of scancode representing a single key\r
   // available in the buffer\r
   //\r
-  while (1) {\r
-\r
-    Status          = GetScancodeBufHead (ConsoleIn, 1, ScancodeArr);\r
-    ScancodeArrPos  = 0;\r
+  while (TRUE) {\r
+    Extend0        = FALSE;\r
+    Extend1        = FALSE;\r
+    ScancodeArrPos = 0;\r
+    Status  = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);\r
     if (EFI_ERROR (Status)) {\r
-      return EFI_NOT_READY;\r
+      return ;\r
     }\r
 \r
-    if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED) {\r
-      Extended        = TRUE;\r
-      Status          = GetScancodeBufHead (ConsoleIn, 2, ScancodeArr);\r
-      ScancodeArrPos  = 1;\r
-      if (EFI_ERROR (Status)) {\r
-        return EFI_NOT_READY;\r
-      }\r
-    }\r
-    //\r
-    // Checks for key scancode for PAUSE:E1-1D/45-E1/9D-C5\r
-    // if present, ignore them\r
-    //\r
-    if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED1) {\r
-\r
-      Status          = GetScancodeBufHead (ConsoleIn, 2, ScancodeArr);\r
-      ScancodeArrPos  = 1;\r
-\r
+    if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED0) {\r
+      //\r
+      // E0 to look ahead 2 bytes\r
+      //\r
+      Extend0 = TRUE;\r
+      ScancodeArrPos = 1;\r
+      Status         = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);\r
       if (EFI_ERROR (Status)) {\r
-        return EFI_NOT_READY;\r
+        return ;\r
       }\r
-\r
-      Status          = GetScancodeBufHead (ConsoleIn, 3, ScancodeArr);\r
-      ScancodeArrPos  = 2;\r
-\r
+    } else if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED1) {\r
+      //\r
+      // E1 to look ahead 3 bytes\r
+      //\r
+      Extend1 = TRUE;\r
+      ScancodeArrPos = 2;\r
+      Status         = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);\r
       if (EFI_ERROR (Status)) {\r
-        return EFI_NOT_READY;\r
+        return ;\r
       }\r
-\r
-      PopScancodeBufHead (ConsoleIn, 3, ScancodeArr);\r
-      return EFI_NOT_READY;\r
     }\r
     //\r
     // if we reach this position, scancodes for a key is in buffer now,pop them\r
     //\r
-    Status = PopScancodeBufHead (ConsoleIn, ScancodeArrPos + 1, ScancodeArr);\r
-    if (EFI_ERROR (Status)) {\r
-      return EFI_NOT_READY;\r
-    }\r
+    Status = PopScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
     //\r
     // store the last available byte, this byte of scancode will be checked\r
     //\r
     ScanCode = ScancodeArr[ScancodeArrPos];\r
 \r
-    //\r
-    // Check for special keys and update the driver state.\r
-    //\r
-    switch (ScanCode) {\r
+    if (!Extend1) {\r
+      //\r
+      // Check for special keys and update the driver state.\r
+      //\r
+      switch (ScanCode) {\r
 \r
-    case SCANCODE_CTRL_MAKE:\r
-      ConsoleIn->Ctrl = TRUE;\r
-      break;\r
+      case SCANCODE_CTRL_MAKE:\r
+        if (Extend0) {\r
+          ConsoleIn->RightCtrl = TRUE;\r
+        } else {\r
+          ConsoleIn->LeftCtrl  = TRUE;\r
+        }\r
+        break;\r
+      case SCANCODE_CTRL_BREAK:\r
+        if (Extend0) {\r
+          ConsoleIn->RightCtrl = FALSE;\r
+        } else {\r
+          ConsoleIn->LeftCtrl  = FALSE;\r
+        }\r
+        break;\r
 \r
-    case SCANCODE_CTRL_BREAK:\r
-      ConsoleIn->Ctrl = FALSE;\r
-      break;\r
+      case SCANCODE_ALT_MAKE:\r
+          if (Extend0) {\r
+            ConsoleIn->RightAlt = TRUE;\r
+          } else {\r
+            ConsoleIn->LeftAlt  = TRUE;\r
+          }\r
+        break;\r
+      case SCANCODE_ALT_BREAK:\r
+          if (Extend0) {\r
+            ConsoleIn->RightAlt = FALSE;\r
+          } else {\r
+            ConsoleIn->LeftAlt  = FALSE;\r
+          }\r
+        break;\r
 \r
-    case SCANCODE_ALT_MAKE:\r
-      ConsoleIn->Alt = TRUE;\r
-      break;\r
+      case SCANCODE_LEFT_SHIFT_MAKE:\r
+        //\r
+        // To avoid recognize PRNT_SCRN key as a L_SHIFT key\r
+        // because PRNT_SCRN key generates E0 followed by L_SHIFT scan code.\r
+        // If it the second byte of the PRNT_ScRN skip it.\r
+        //\r
+        if (!Extend0) {\r
+          ConsoleIn->LeftShift  = TRUE;\r
+          break;\r
+        }\r
+        continue;\r
 \r
-    case SCANCODE_ALT_BREAK:\r
-      ConsoleIn->Alt = FALSE;\r
-      break;\r
+      case SCANCODE_LEFT_SHIFT_BREAK:\r
+        if (!Extend0) {\r
+          ConsoleIn->LeftShift = FALSE;\r
+        }\r
+        break;\r
 \r
-    case SCANCODE_LEFT_SHIFT_MAKE:\r
-    case SCANCODE_RIGHT_SHIFT_MAKE:\r
-      if (!Extended) {\r
-        ConsoleIn->Shift = TRUE;\r
-      }\r
-      break;\r
+      case SCANCODE_RIGHT_SHIFT_MAKE:\r
+        ConsoleIn->RightShift = TRUE;\r
+        break;\r
+      case SCANCODE_RIGHT_SHIFT_BREAK:\r
+        ConsoleIn->RightShift = FALSE;\r
+        break;\r
 \r
-    case SCANCODE_LEFT_SHIFT_BREAK:\r
-    case SCANCODE_RIGHT_SHIFT_BREAK:\r
-      if (!Extended) {\r
-        ConsoleIn->Shift = FALSE;\r
-      }\r
-      break;\r
+      case SCANCODE_LEFT_LOGO_MAKE:\r
+        ConsoleIn->LeftLogo = TRUE;\r
+        break;\r
+      case SCANCODE_LEFT_LOGO_BREAK:\r
+        ConsoleIn->LeftLogo = FALSE;\r
+        break;\r
 \r
-    case SCANCODE_CAPS_LOCK_MAKE:\r
-      ConsoleIn->CapsLock = (BOOLEAN)!ConsoleIn->CapsLock;\r
-      UpdateStatusLights (ConsoleIn);\r
-      break;\r
+      case SCANCODE_RIGHT_LOGO_MAKE:\r
+        ConsoleIn->RightLogo = TRUE;\r
+        break;\r
+      case SCANCODE_RIGHT_LOGO_BREAK:\r
+        ConsoleIn->RightLogo = FALSE;\r
+        break;\r
 \r
-    case SCANCODE_NUM_LOCK_MAKE:\r
-      ConsoleIn->NumLock = (BOOLEAN)!ConsoleIn->NumLock;\r
-      UpdateStatusLights (ConsoleIn);\r
-      break;\r
+      case SCANCODE_MENU_MAKE:\r
+        ConsoleIn->Menu = TRUE;\r
+        break;\r
+      case SCANCODE_MENU_BREAK:\r
+        ConsoleIn->Menu = FALSE;\r
+        break;\r
 \r
-    case SCANCODE_SCROLL_LOCK_MAKE:\r
-      ConsoleIn->ScrollLock = (BOOLEAN)!ConsoleIn->ScrollLock;\r
-      UpdateStatusLights (ConsoleIn);\r
-      break;\r
+      case SCANCODE_SYS_REQ_MAKE:\r
+        if (Extend0) {\r
+          ConsoleIn->SysReq = TRUE;\r
+        }\r
+        break;\r
+      case SCANCODE_SYS_REQ_BREAK:\r
+        if (Extend0) {\r
+          ConsoleIn->SysReq = FALSE;\r
+        }\r
+        break;\r
+\r
+      case SCANCODE_SYS_REQ_MAKE_WITH_ALT:\r
+        ConsoleIn->SysReq = TRUE;\r
+        break;\r
+      case SCANCODE_SYS_REQ_BREAK_WITH_ALT:\r
+        ConsoleIn->SysReq = FALSE;\r
+        break;\r
+\r
+      case SCANCODE_CAPS_LOCK_MAKE:\r
+        ConsoleIn->CapsLock = (BOOLEAN)!ConsoleIn->CapsLock;\r
+        UpdateStatusLights (ConsoleIn);\r
+        break;\r
+      case SCANCODE_NUM_LOCK_MAKE:\r
+        ConsoleIn->NumLock = (BOOLEAN)!ConsoleIn->NumLock;\r
+        UpdateStatusLights (ConsoleIn);\r
+        break;\r
+      case SCANCODE_SCROLL_LOCK_MAKE:\r
+        if (!Extend0) {\r
+          ConsoleIn->ScrollLock = (BOOLEAN)!ConsoleIn->ScrollLock;\r
+          UpdateStatusLights (ConsoleIn);\r
+        }\r
+        break;\r
+      }\r
     }\r
+\r
     //\r
-    // If this is a BREAK Key or above the valid range, ignore it\r
+    // If this is above the valid range, ignore it\r
     //\r
     if (ScanCode >= SCANCODE_MAX_MAKE) {\r
       continue;\r
@@ -1587,53 +1370,82 @@ Returns:
       break;\r
     }\r
   }\r
+\r
   //\r
-  // If this is the SysRq, ignore it\r
+  // Handle Ctrl+Alt+Del hotkey\r
   //\r
-  if (Extended && ScanCode == 0x37) {\r
-    return EFI_NOT_READY;\r
+  if ((ConsoleIn->LeftCtrl || ConsoleIn->RightCtrl) &&\r
+      (ConsoleIn->LeftAlt  || ConsoleIn->RightAlt ) &&\r
+      ScanCode == SCANCODE_DELETE_MAKE\r
+     ) {\r
+    gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
   }\r
+\r
   //\r
-  // Treat Numeric Key Pad "/" specially\r
+  // Save the Shift/Toggle state\r
   //\r
-  if (Extended && ScanCode == 0x35) {\r
-    ConsoleIn->Key.ScanCode     = SCAN_NULL;\r
-    ConsoleIn->Key.UnicodeChar  = '/';\r
-    return EFI_SUCCESS;\r
-  }\r
+  InitializeKeyState (ConsoleIn, &KeyData.KeyState);\r
+  KeyData.Key.ScanCode    = SCAN_NULL;\r
+  KeyData.Key.UnicodeChar = CHAR_NULL;\r
+\r
   //\r
-  // Convert Keyboard ScanCode into an EFI Key\r
+  // Key Pad "/" shares the same scancode as that of "/" except Key Pad "/" has E0 prefix\r
   //\r
-  for (Index = 0; ConvertKeyboardScanCodeToEfiKey[Index].ScanCode != TABLE_END; Index += 1) {\r
-    if (ScanCode == ConvertKeyboardScanCodeToEfiKey[Index].ScanCode) {\r
-      ConsoleIn->Key.ScanCode = ConvertKeyboardScanCodeToEfiKey[Index].EfiScanCode;\r
-      if (ConsoleIn->Shift) {\r
-        ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar;\r
-      } else {\r
-        ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;\r
-      }\r
-      //\r
-      // alphabetic key is affected by CapsLock State\r
-      //\r
-      if (ConsoleIn->CapsLock) {\r
-        if (ConsoleIn->Key.UnicodeChar >= 'a' && ConsoleIn->Key.UnicodeChar <= 'z') {\r
-          ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar;\r
-        } else if (ConsoleIn->Key.UnicodeChar >= 'A' && ConsoleIn->Key.UnicodeChar <= 'Z') {\r
-          ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;\r
+  if (Extend0 && ScanCode == 0x35) {\r
+    KeyData.Key.UnicodeChar = L'/';\r
+    KeyData.Key.ScanCode    = SCAN_NULL;\r
+\r
+  //\r
+  // PAUSE shares the same scancode as that of NUM except PAUSE has E1 prefix\r
+  //\r
+  } else if (Extend1 && ScanCode == SCANCODE_NUM_LOCK_MAKE) {\r
+    KeyData.Key.UnicodeChar = CHAR_NULL;\r
+    KeyData.Key.ScanCode    = SCAN_PAUSE;\r
+\r
+  //\r
+  // PAUSE shares the same scancode as that of SCROLL except PAUSE (CTRL pressed) has E0 prefix\r
+  //\r
+  } else if (Extend0 && ScanCode == SCANCODE_SCROLL_LOCK_MAKE) {\r
+    KeyData.Key.UnicodeChar = CHAR_NULL;\r
+    KeyData.Key.ScanCode    = SCAN_PAUSE;\r
+\r
+  //\r
+  // PRNT_SCRN shares the same scancode as that of Key Pad "*" except PRNT_SCRN has E0 prefix\r
+  //\r
+  } else if (Extend0 && ScanCode == SCANCODE_SYS_REQ_MAKE) {\r
+    KeyData.Key.UnicodeChar = CHAR_NULL;\r
+    KeyData.Key.ScanCode    = SCAN_NULL;\r
+\r
+  //\r
+  // Except the above special case, all others can be handled by convert table\r
+  //\r
+  } else {\r
+    for (Index = 0; ConvertKeyboardScanCodeToEfiKey[Index].ScanCode != TABLE_END; Index++) {\r
+      if (ScanCode == ConvertKeyboardScanCodeToEfiKey[Index].ScanCode) {\r
+        KeyData.Key.ScanCode    = ConvertKeyboardScanCodeToEfiKey[Index].EfiScanCode;\r
+        KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;\r
+\r
+        if ((ConsoleIn->LeftShift || ConsoleIn->RightShift) &&\r
+            (ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar != ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar)) {\r
+          KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar;\r
+          //\r
+          // Need not return associated shift state if a class of printable characters that\r
+          // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'\r
+          //\r
+          KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED);\r
         }\r
-      }\r
-      //\r
-      // Translate the CTRL-Alpha characters to their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A)\r
-      //\r
-      if (ConsoleIn->Ctrled) {\r
-        if (ConsoleIn->Key.UnicodeChar >= 'a' && ConsoleIn->Key.UnicodeChar <= 'z') {\r
-          ConsoleIn->Key.UnicodeChar = (UINT16) (ConsoleIn->Key.UnicodeChar - 'a' + 1);\r
-        } else if (ConsoleIn->Key.UnicodeChar >= 'A' && ConsoleIn->Key.UnicodeChar <= 'Z') {\r
-          ConsoleIn->Key.UnicodeChar = (UINT16) (ConsoleIn->Key.UnicodeChar - 'A' + 1);\r
+        //\r
+        // alphabetic key is affected by CapsLock State\r
+        //\r
+        if (ConsoleIn->CapsLock) {\r
+          if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') {\r
+            KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar - L'a' + L'A');\r
+          } else if (KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') {\r
+            KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar - L'A' + L'a');\r
+          }\r
         }\r
+        break;\r
       }\r
-\r
-      break;\r
     }\r
   }\r
 \r
@@ -1641,67 +1453,81 @@ Returns:
   // distinguish numeric key pad keys' 'up symbol' and 'down symbol'\r
   //\r
   if (ScanCode >= 0x47 && ScanCode <= 0x53) {\r
-\r
-    if (ConsoleIn->NumLock && !ConsoleIn->Shift && !Extended) {\r
-      ConsoleIn->Key.ScanCode = SCAN_NULL;\r
+    if (ConsoleIn->NumLock && !(ConsoleIn->LeftShift || ConsoleIn->RightShift) && !Extend0) {\r
+      KeyData.Key.ScanCode = SCAN_NULL;\r
     } else if (ScanCode != 0x4a && ScanCode != 0x4e) {\r
-      ConsoleIn->Key.UnicodeChar = 0x00;\r
+      KeyData.Key.UnicodeChar = CHAR_NULL;\r
     }\r
   }\r
+\r
   //\r
   // If the key can not be converted then just return.\r
   //\r
-  if (ConsoleIn->Key.ScanCode == SCAN_NULL && ConsoleIn->Key.UnicodeChar == 0x00) {\r
-    return EFI_NOT_READY;\r
+  if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {\r
+    if (!ConsoleIn->IsSupportPartialKey) {\r
+      return ;\r
+    }\r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  //\r
+  // Signal KeyNotify process event if this key pressed matches any key registered.\r
+  //\r
+  for (Link = GetFirstNode (&ConsoleIn->NotifyList); !IsNull (&ConsoleIn->NotifyList, Link); Link = GetNextNode (&ConsoleIn->NotifyList, Link)) {\r
+    CurrentNotify = CR (\r
+                      Link,\r
+                      KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
+                      NotifyEntry,\r
+                      KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
+                      );\r
+    if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {\r
+      //\r
+      // The key notification function needs to run at TPL_CALLBACK\r
+      // while current TPL is TPL_NOTIFY. It will be invoked in\r
+      // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.\r
+      //\r
+      PushEfikeyBufTail (&ConsoleIn->EfiKeyQueueForNotify, &KeyData);\r
+      gBS->SignalEvent (ConsoleIn->KeyNotifyProcessEvent);\r
+    }\r
+  }\r
+\r
+  PushEfikeyBufTail (&ConsoleIn->EfiKeyQueue, &KeyData);\r
 }\r
 \r
+/**\r
+  Perform 8042 controller and keyboard Initialization.\r
+  If ExtendedVerification is TRUE, do additional test for\r
+  the keyboard interface\r
+\r
+  @param ConsoleIn - KEYBOARD_CONSOLE_IN_DEV instance pointer\r
+  @param ExtendedVerification - indicates a thorough initialization\r
+\r
+  @retval EFI_DEVICE_ERROR Fail to init keyboard\r
+  @retval EFI_SUCCESS      Success to init keyboard\r
+**/\r
 EFI_STATUS\r
 InitKeyboard (\r
   IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
   IN BOOLEAN                     ExtendedVerification\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Perform 8042 controller and keyboard Initialization\r
-  If ExtendedVerification is TRUE, do additional test for\r
-  the keyboard interface\r
-\r
-Arguments:\r
-\r
-  ConsoleIn - KEYBOARD_CONSOLE_IN_DEV instance pointer\r
-  ExtendedVerification - indicates a thorough initialization\r
-\r
-Returns:\r
-\r
-  EFI_STATUS\r
-\r
---*/\r
-// GC_TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-// GC_TODO:    EFI_SUCCESS - add return value to function comment\r
-// GC_TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
 {\r
   EFI_STATUS              Status;\r
   EFI_STATUS              Status1;\r
   UINT8                   CommandByte;\r
-  STATIC BOOLEAN          EnableMouseInterface;\r
   EFI_PS2_POLICY_PROTOCOL *Ps2Policy;\r
+  UINT32                  TryTime;\r
 \r
-  Status                = EFI_SUCCESS;\r
-  EnableMouseInterface  = TRUE;\r
+  Status                 = EFI_SUCCESS;\r
+  mEnableMouseInterface  = TRUE;\r
+  TryTime                = 0;\r
 \r
   //\r
   // Get Ps2 policy to set this\r
   //\r
-  Status = gBS->LocateProtocol (\r
-                  &gEfiPs2PolicyProtocolGuid,\r
-                  NULL,\r
-                  (VOID **) &Ps2Policy\r
-                  );\r
+  gBS->LocateProtocol (\r
+        &gEfiPs2PolicyProtocolGuid,\r
+        NULL,\r
+        (VOID **) &Ps2Policy\r
+        );\r
 \r
   REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
     EFI_PROGRESS_CODE,\r
@@ -1711,10 +1537,20 @@ Returns:
 \r
   //\r
   // Perform a read to cleanup the Status Register's\r
-  // output buffer full bits\r
+  // output buffer full bits within MAX TRY times\r
   //\r
-  while (!EFI_ERROR (Status)) {\r
-    Status = KeyboardRead (ConsoleIn, &CommandByte);\r
+  if ((KeyReadStatusRegister (ConsoleIn) & KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA) != 0) {\r
+    while (!EFI_ERROR (Status) && TryTime < KEYBOARD_MAX_TRY) {\r
+      Status = KeyboardRead (ConsoleIn, &CommandByte);\r
+      TryTime ++;\r
+    }\r
+    //\r
+    // Exceed the max try times. The device may be error.\r
+    //\r
+    if (TryTime == KEYBOARD_MAX_TRY) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Done;\r
+    }\r
   }\r
   //\r
   // We should disable mouse interface during the initialization process\r
@@ -1728,35 +1564,38 @@ Returns:
   // Test the system flag in to determine whether this is the first\r
   // time initialization\r
   //\r
-  if ((KeyReadStatusRegister (ConsoleIn) & 0x04)) {\r
-    //\r
-    // 8042 controller is already setup (by myself or by mouse driver):\r
-    //   See whether mouse interface is already enabled\r
-    //   which determines whether we should enable it later\r
-    //\r
-    //\r
-    // Read the command byte of 8042 controller\r
-    //\r
-    Status = KeyboardCommand (ConsoleIn, 0x20);\r
-    if (EFI_ERROR (Status)) {\r
-      KeyboardError (ConsoleIn, L"\n\r");\r
-      goto Done;\r
-    }\r
+  if ((KeyReadStatusRegister (ConsoleIn) & KEYBOARD_STATUS_REGISTER_SYSTEM_FLAG) != 0) {\r
+    if (!PcdGetBool (PcdFastPS2Detection)) {\r
+      //\r
+      // 8042 controller is already setup (by myself or by mouse driver):\r
+      //   See whether mouse interface is already enabled\r
+      //   which determines whether we should enable it later\r
+      //\r
+      //\r
+      // Read the command byte of 8042 controller\r
+      //\r
+      Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_READ);\r
+      if (EFI_ERROR (Status)) {\r
+        KeyboardError (ConsoleIn, L"\n\r");\r
+        goto Done;\r
+      }\r
 \r
-    Status = KeyboardRead (ConsoleIn, &CommandByte);\r
-    if (EFI_ERROR (Status)) {\r
-      KeyboardError (ConsoleIn, L"\n\r");\r
-      goto Done;\r
-    }\r
-    //\r
-    // Test the mouse enabling bit\r
-    //\r
-    if (CommandByte & 0x20) {\r
-      EnableMouseInterface = FALSE;\r
+      Status = KeyboardRead (ConsoleIn, &CommandByte);\r
+      if (EFI_ERROR (Status)) {\r
+        KeyboardError (ConsoleIn, L"\n\r");\r
+        goto Done;\r
+      }\r
+      //\r
+      // Test the mouse enabling bit\r
+      //\r
+      if ((CommandByte & 0x20) != 0) {\r
+        mEnableMouseInterface = FALSE;\r
+      } else {\r
+        mEnableMouseInterface = TRUE;\r
+      }\r
     } else {\r
-      EnableMouseInterface = TRUE;\r
+      mEnableMouseInterface = FALSE;\r
     }\r
-\r
   } else {\r
     //\r
     // 8042 controller is not setup yet:\r
@@ -1766,41 +1605,43 @@ Returns:
     //\r
     // Disable keyboard and mouse interfaces\r
     //\r
-    Status = KeyboardCommand (ConsoleIn, 0xad);\r
-    if (EFI_ERROR (Status)) {\r
-      KeyboardError (ConsoleIn, L"\n\r");\r
-      goto Done;\r
-    }\r
+    if (!PcdGetBool (PcdFastPS2Detection)) {\r
+      Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_DISABLE_KEYBOARD_INTERFACE);\r
+      if (EFI_ERROR (Status)) {\r
+        KeyboardError (ConsoleIn, L"\n\r");\r
+        goto Done;\r
+      }\r
 \r
-    Status = KeyboardCommand (ConsoleIn, 0xa7);\r
-    if (EFI_ERROR (Status)) {\r
-      KeyboardError (ConsoleIn, L"\n\r");\r
-      goto Done;\r
-    }\r
+      Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_DISABLE_MOUSE_INTERFACE);\r
+      if (EFI_ERROR (Status)) {\r
+        KeyboardError (ConsoleIn, L"\n\r");\r
+        goto Done;\r
+      }\r
 \r
-    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-      EFI_PROGRESS_CODE,\r
-      EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST,\r
-      ConsoleIn->DevicePath\r
-      );\r
-    //\r
-    // 8042 Controller Self Test\r
-    //\r
-    Status = KeyboardCommand (ConsoleIn, 0xaa);\r
-    if (EFI_ERROR (Status)) {\r
-      KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");\r
-      goto Done;\r
-    }\r
+      REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+        EFI_PROGRESS_CODE,\r
+        EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST,\r
+        ConsoleIn->DevicePath\r
+        );\r
+      //\r
+      // 8042 Controller Self Test\r
+      //\r
+      Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_CONTROLLER_SELF_TEST);\r
+      if (EFI_ERROR (Status)) {\r
+        KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");\r
+        goto Done;\r
+      }\r
 \r
-    Status = KeyboardWaitForValue (ConsoleIn, 0x55);\r
-    if (EFI_ERROR (Status)) {\r
-      KeyboardError (ConsoleIn, L"8042 controller self test failed!\n\r");\r
-      goto Done;\r
+      Status = KeyboardWaitForValue (ConsoleIn, 0x55);\r
+      if (EFI_ERROR (Status)) {\r
+        KeyboardError (ConsoleIn, L"8042 controller self test failed!\n\r");\r
+        goto Done;\r
+      }\r
     }\r
     //\r
     // Don't enable mouse interface later\r
     //\r
-    EnableMouseInterface = FALSE;\r
+    mEnableMouseInterface = FALSE;\r
 \r
   }\r
 \r
@@ -1825,7 +1666,7 @@ Returns:
   //  1: Enable Auxiliary device interrupt\r
   //  0: Enable Keyboard interrupt )\r
   //\r
-  Status = KeyboardCommand (ConsoleIn, 0x60);\r
+  Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_WRITE);\r
   if (EFI_ERROR (Status)) {\r
     KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");\r
     goto Done;\r
@@ -1840,26 +1681,35 @@ Returns:
   //\r
   // Clear Memory Scancode Buffer\r
   //\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->ScancodeQueue.Head = 0;\r
+  ConsoleIn->ScancodeQueue.Tail = 0;\r
+  ConsoleIn->EfiKeyQueue.Head   = 0;\r
+  ConsoleIn->EfiKeyQueue.Tail   = 0;\r
+  ConsoleIn->EfiKeyQueueForNotify.Head = 0;\r
+  ConsoleIn->EfiKeyQueueForNotify.Tail = 0;\r
 \r
   //\r
   // Reset the status indicators\r
   //\r
-  ConsoleIn->Ctrl       = FALSE;\r
-  ConsoleIn->Alt        = FALSE;\r
-  ConsoleIn->Shift      = FALSE;\r
   ConsoleIn->CapsLock   = FALSE;\r
   ConsoleIn->NumLock    = FALSE;\r
   ConsoleIn->ScrollLock = FALSE;\r
-\r
-  //\r
-  // For reseting keyboard is not mandatory before booting OS and sometimes keyboard responses very slow,\r
+  ConsoleIn->LeftCtrl   = FALSE;\r
+  ConsoleIn->RightCtrl  = FALSE;\r
+  ConsoleIn->LeftAlt    = FALSE;\r
+  ConsoleIn->RightAlt   = FALSE;\r
+  ConsoleIn->LeftShift  = FALSE;\r
+  ConsoleIn->RightShift = FALSE;\r
+  ConsoleIn->LeftLogo   = FALSE;\r
+  ConsoleIn->RightLogo  = FALSE;\r
+  ConsoleIn->Menu       = FALSE;\r
+  ConsoleIn->SysReq     = FALSE;\r
+\r
+  ConsoleIn->IsSupportPartialKey = FALSE;\r
+  //\r
+  // For resetting keyboard is not mandatory before booting OS and sometimes keyboard responses very slow,\r
   // and to support KB hot plug, we need to let the InitKB succeed no matter whether there is a KB device connected\r
-  // to system. So we only do the real reseting for keyboard when user asks and there is a real KB connected t system,\r
+  // to system. So we only do the real resetting for keyboard when user asks and there is a real KB connected t system,\r
   // and normally during booting an OS, it's skipped.\r
   //\r
   if (ExtendedVerification && CheckKeyboardConnect (ConsoleIn)) {\r
@@ -1869,7 +1719,7 @@ Returns:
     //\r
     // Keyboard Interface Test\r
     //\r
-    Status = KeyboardCommand (ConsoleIn, 0xab);\r
+    Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_KEYBOARD_INTERFACE_SELF_TEST);\r
     if (EFI_ERROR (Status)) {\r
       KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");\r
       goto Done;\r
@@ -1886,13 +1736,13 @@ Returns:
     //\r
     // Keyboard reset with a BAT(Basic Assurance Test)\r
     //\r
-    Status = KeyboardWrite (ConsoleIn, 0xff);\r
+    Status = KeyboardWrite (ConsoleIn, KEYBOARD_8048_COMMAND_RESET);\r
     if (EFI_ERROR (Status)) {\r
       KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");\r
       goto Done;\r
     }\r
 \r
-    Status = KeyboardWaitForValue (ConsoleIn, 0xfa);\r
+    Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);\r
     if (EFI_ERROR (Status)) {\r
       KeyboardError (ConsoleIn, L"Some specific value not aquired from 8042 controller!\n\r");\r
       goto Done;\r
@@ -1902,7 +1752,7 @@ Returns:
     //\r
     mWaitForValueTimeOut  = KEYBOARD_BAT_TIMEOUT;\r
 \r
-    Status                = KeyboardWaitForValue (ConsoleIn, 0xaa);\r
+    Status                = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_BAT_SUCCESS);\r
     if (EFI_ERROR (Status)) {\r
       KeyboardError (ConsoleIn, L"Keyboard self test failed!\n\r");\r
       goto Done;\r
@@ -1913,13 +1763,13 @@ Returns:
     //\r
     // Set Keyboard to use Scan Code Set 2\r
     //\r
-    Status = KeyboardWrite (ConsoleIn, 0xf0);\r
+    Status = KeyboardWrite (ConsoleIn, KEYBOARD_8048_COMMAND_SELECT_SCAN_CODE_SET);\r
     if (EFI_ERROR (Status)) {\r
       KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");\r
       goto Done;\r
     }\r
 \r
-    Status = KeyboardWaitForValue (ConsoleIn, 0xfa);\r
+    Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);\r
     if (EFI_ERROR (Status)) {\r
       KeyboardError (ConsoleIn, L"Some specific value not aquired from 8042 controller!\n\r");\r
       goto Done;\r
@@ -1931,7 +1781,7 @@ Returns:
       goto Done;\r
     }\r
 \r
-    Status = KeyboardWaitForValue (ConsoleIn, 0xfa);\r
+    Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);\r
     if (EFI_ERROR (Status)) {\r
       KeyboardError (ConsoleIn, L"Some specific value not aquired from 8042 controller!\n\r");\r
       goto Done;\r
@@ -1940,13 +1790,13 @@ Returns:
   //\r
   // Clear Keyboard Scancode Buffer\r
   //\r
-  Status = KeyboardWrite (ConsoleIn, 0xf4);\r
+  Status = KeyboardWrite (ConsoleIn, KEYBOARD_8048_COMMAND_CLEAR_OUTPUT_DATA);\r
   if (EFI_ERROR (Status)) {\r
     KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");\r
     goto Done;\r
   }\r
 \r
-  Status = KeyboardWaitForValue (ConsoleIn, 0xfa);\r
+  Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);\r
   if (EFI_ERROR (Status)) {\r
     KeyboardError (ConsoleIn, L"Some specific value not aquired from 8042 controller!\n\r");\r
     goto Done;\r
@@ -1979,11 +1829,11 @@ Returns:
   //\r
 Done:\r
 \r
-  if (EnableMouseInterface) {\r
+  if (mEnableMouseInterface) {\r
     //\r
     // Enable mouse interface\r
     //\r
-    Status1 = KeyboardCommand (ConsoleIn, 0xa8);\r
+    Status1 = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_ENABLE_MOUSE_INTERFACE);\r
     if (EFI_ERROR (Status1)) {\r
       KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");\r
       return EFI_DEVICE_ERROR;\r
@@ -1998,33 +1848,25 @@ Done:
 \r
 }\r
 \r
+/**\r
+  Disable the keyboard interface of the 8042 controller.\r
+\r
+  @param ConsoleIn   The device instance\r
+\r
+  @return status of issuing disable command\r
+\r
+**/\r
 EFI_STATUS\r
 DisableKeyboard (\r
   IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Disable the keyboard interface of the 8042 controller\r
-\r
-Arguments:\r
-\r
-  ConsoleIn   - the device instance\r
-\r
-Returns:\r
-\r
-  EFI_STATUS\r
-\r
---*/\r
-// GC_TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
 {\r
   EFI_STATUS  Status;\r
 \r
   //\r
   // Disable keyboard interface\r
   //\r
-  Status = KeyboardCommand (ConsoleIn, 0xad);\r
+  Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_DISABLE_KEYBOARD_INTERFACE);\r
   if (EFI_ERROR (Status)) {\r
     KeyboardError (ConsoleIn, L"\n\r");\r
     return EFI_DEVICE_ERROR;\r
@@ -2038,10 +1880,10 @@ Returns:
   If Keyboard receives 0xF4, it will respond with 'ACK'. If it doesn't respond, the device\r
   should not be in system.\r
 \r
-  @param[in]  BiosKeyboardPrivate   Keyboard Private Data Structure\r
+  @param[in]  ConsoleIn             Keyboard Private Data Structure\r
 \r
-  @retval              TRUE                                                            Keyboard in System.\r
-  @retval              FALSE                                                           Keyboard not in System.\r
+  @retval     TRUE                  Keyboard in System.\r
+  @retval     FALSE                 Keyboard not in System.\r
 **/\r
 BOOLEAN\r
 EFIAPI\r
@@ -2052,33 +1894,37 @@ CheckKeyboardConnect (
   EFI_STATUS     Status;\r
   UINTN          WaitForValueTimeOutBcakup;\r
 \r
-  Status = EFI_SUCCESS;\r
   //\r
   // enable keyboard itself and wait for its ack\r
   // If can't receive ack, Keyboard should not be connected.\r
   //\r
-  Status = KeyboardWrite (\r
-             ConsoleIn,\r
-             KEYBOARD_KBEN\r
-             );\r
+  if (!PcdGetBool (PcdFastPS2Detection)) {\r
+    Status = KeyboardWrite (\r
+               ConsoleIn,\r
+               KEYBOARD_KBEN\r
+               );\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    return FALSE;\r
-  }\r
-  //\r
-  // wait for 1s\r
-  //\r
-  WaitForValueTimeOutBcakup = mWaitForValueTimeOut;\r
-  mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;\r
-  Status = KeyboardWaitForValue (\r
-             ConsoleIn,\r
-             KEYBOARD_CMDECHO_ACK\r
-             );\r
-  mWaitForValueTimeOut = WaitForValueTimeOutBcakup;\r
+    if (EFI_ERROR (Status)) {\r
+      return FALSE;\r
+    }\r
+    //\r
+    // wait for 1s\r
+    //\r
+    WaitForValueTimeOutBcakup = mWaitForValueTimeOut;\r
+    mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;\r
+    Status = KeyboardWaitForValue (\r
+               ConsoleIn,\r
+               KEYBOARD_CMDECHO_ACK\r
+               );\r
+    mWaitForValueTimeOut = WaitForValueTimeOutBcakup;\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    return FALSE;\r
-  }\r
+    if (EFI_ERROR (Status)) {\r
+      return FALSE;\r
+    }\r
 \r
-  return TRUE;\r
+    return TRUE;\r
+  } else {\r
+    return TRUE;\r
+  }\r
 }\r
+\r