]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c
MdeModulePkg/UsbKb: fix shell edit cannot read '!@#$%^&*' characters
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbKbDxe / KeyBoard.c
index 36c80ce4703bcdb14d0ad165f595f8b3d770a45d..b3b5fb9ff4c49136dcd679f28357592054ee1c94 100644 (file)
@@ -1,9 +1,8 @@
 /** @file\r
-\r
   Helper functions for USB Keyboard Driver.\r
 \r
-Copyright (c) 2004 - 2008, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2004 - 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
@@ -14,160 +13,144 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/\r
 \r
 #include "KeyBoard.h"\r
-#include <Library/UefiUsbLib.h>\r
-\r
-//\r
-// Static English keyboard layout\r
-// Format:<efi key>, <unicode without shift>, <unicode with shift>, <Modifier>, <AffectedAttribute>\r
-//\r
-UINT8 KeyboardLayoutTable[USB_KEYCODE_MAX_MAKE + 8][5] = {\r
-  {EfiKeyC1,         'a',      'A',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x04\r
-  {EfiKeyB5,         'b',      'B',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x05\r
-  {EfiKeyB3,         'c',      'C',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x06\r
-  {EfiKeyC3,         'd',      'D',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x07\r
-  {EfiKeyD3,         'e',      'E',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x08\r
-  {EfiKeyC4,         'f',      'F',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x09\r
-  {EfiKeyC5,         'g',      'G',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x0A\r
-  {EfiKeyC6,         'h',      'H',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x0B\r
-  {EfiKeyD8,         'i',      'I',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x0C\r
-  {EfiKeyC7,         'j',      'J',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x0D\r
-  {EfiKeyC8,         'k',      'K',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x0E\r
-  {EfiKeyC9,         'l',      'L',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x0F\r
-  {EfiKeyB7,         'm',      'M',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x10\r
-  {EfiKeyB6,         'n',      'N',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x11\r
-  {EfiKeyD9,         'o',      'O',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x12\r
-  {EfiKeyD10,        'p',      'P',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x13\r
-  {EfiKeyD1,         'q',      'Q',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x14\r
-  {EfiKeyD4,         'r',      'R',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x15\r
-  {EfiKeyC2,         's',      'S',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x16\r
-  {EfiKeyD5,         't',      'T',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x17\r
-  {EfiKeyD7,         'u',      'U',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x18\r
-  {EfiKeyB4,         'v',      'V',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x19\r
-  {EfiKeyD2,         'w',      'W',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x1A\r
-  {EfiKeyB2,         'x',      'X',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x1B\r
-  {EfiKeyD6,         'y',      'Y',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x1C\r
-  {EfiKeyB1,         'z',      'Z',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},   // 0x1D\r
-  {EfiKeyE1,         '1',      '!',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x1E\r
-  {EfiKeyE2,         '2',      '@',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x1F\r
-  {EfiKeyE3,         '3',      '#',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x20\r
-  {EfiKeyE4,         '4',      '$',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x21\r
-  {EfiKeyE5,         '5',      '%',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x22\r
-  {EfiKeyE6,         '6',      '^',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x23\r
-  {EfiKeyE7,         '7',      '&',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x24\r
-  {EfiKeyE8,         '8',      '*',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x25\r
-  {EfiKeyE9,         '9',      '(',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x26\r
-  {EfiKeyE10,        '0',      ')',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x27\r
-  {EfiKeyEnter,      0x0d,     0x0d,  EFI_NULL_MODIFIER,   0},                                // 0x28   Enter\r
-  {EfiKeyEsc,        0x1b,     0x1b,  EFI_NULL_MODIFIER,   0},                                // 0x29   Esc\r
-  {EfiKeyBackSpace,  0x08,     0x08,  EFI_NULL_MODIFIER,   0},                                // 0x2A   Backspace\r
-  {EfiKeyTab,        0x09,     0x09,  EFI_NULL_MODIFIER,   0},                                // 0x2B   Tab\r
-  {EfiKeySpaceBar,   ' ',      ' ',   EFI_NULL_MODIFIER,   0},                                // 0x2C   Spacebar\r
-  {EfiKeyE11,        '-',      '_',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x2D\r
-  {EfiKeyE12,        '=',      '+',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x2E\r
-  {EfiKeyD11,        '[',      '{',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x2F\r
-  {EfiKeyD12,        ']',      '}',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x30\r
-  {EfiKeyD13,        '\\',     '|',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x31\r
-  {EfiKeyC12,        '\\',     '|',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x32  Keyboard Non-US # and ~\r
-  {EfiKeyC10,        ';',      ':',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x33\r
-  {EfiKeyC11,        '\'',     '"',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x34\r
-  {EfiKeyE0,         '`',      '~',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x35  Keyboard Grave Accent and Tlide\r
-  {EfiKeyB8,         ',',      '<',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x36\r
-  {EfiKeyB9,         '.',      '>',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x37\r
-  {EfiKeyB10,        '/',      '?',   EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},   // 0x38\r
-  {EfiKeyCapsLock,   0x00,     0x00,  EFI_CAPS_LOCK_MODIFIER,            0},                  // 0x39   CapsLock\r
-  {EfiKeyF1,         0x00,     0x00,  EFI_FUNCTION_KEY_ONE_MODIFIER,     0},                  // 0x3A\r
-  {EfiKeyF2,         0x00,     0x00,  EFI_FUNCTION_KEY_TWO_MODIFIER,     0},                  // 0x3B\r
-  {EfiKeyF3,         0x00,     0x00,  EFI_FUNCTION_KEY_THREE_MODIFIER,   0},                  // 0x3C\r
-  {EfiKeyF4,         0x00,     0x00,  EFI_FUNCTION_KEY_FOUR_MODIFIER,    0},                  // 0x3D\r
-  {EfiKeyF5,         0x00,     0x00,  EFI_FUNCTION_KEY_FIVE_MODIFIER,    0},                  // 0x3E\r
-  {EfiKeyF6,         0x00,     0x00,  EFI_FUNCTION_KEY_SIX_MODIFIER,     0},                  // 0x3F\r
-  {EfiKeyF7,         0x00,     0x00,  EFI_FUNCTION_KEY_SEVEN_MODIFIER,   0},                  // 0x40\r
-  {EfiKeyF8,         0x00,     0x00,  EFI_FUNCTION_KEY_EIGHT_MODIFIER,   0},                  // 0x41\r
-  {EfiKeyF9,         0x00,     0x00,  EFI_FUNCTION_KEY_NINE_MODIFIER,    0},                  // 0x42\r
-  {EfiKeyF10,        0x00,     0x00,  EFI_FUNCTION_KEY_TEN_MODIFIER,     0},                  // 0x43\r
-  {EfiKeyF11,        0x00,     0x00,  EFI_FUNCTION_KEY_ELEVEN_MODIFIER,  0},                  // 0x44   F11\r
-  {EfiKeyF12,        0x00,     0x00,  EFI_FUNCTION_KEY_TWELVE_MODIFIER,  0},                  // 0x45   F12\r
-  {EfiKeyPrint,      0x00,     0x00,  EFI_PRINT_MODIFIER,                0},                  // 0x46   PrintScreen\r
-  {EfiKeySLck,       0x00,     0x00,  EFI_SCROLL_LOCK_MODIFIER,          0},                  // 0x47   Scroll Lock\r
-  {EfiKeyPause,      0x00,     0x00,  EFI_PAUSE_MODIFIER,                0},                  // 0x48   Pause\r
-  {EfiKeyIns,        0x00,     0x00,  EFI_INSERT_MODIFIER,               0},                  // 0x49\r
-  {EfiKeyHome,       0x00,     0x00,  EFI_HOME_MODIFIER,                 0},                  // 0x4A\r
-  {EfiKeyPgUp,       0x00,     0x00,  EFI_PAGE_UP_MODIFIER,              0},                  // 0x4B\r
-  {EfiKeyDel,        0x00,     0x00,  EFI_DELETE_MODIFIER,               0},                  // 0x4C\r
-  {EfiKeyEnd,        0x00,     0x00,  EFI_END_MODIFIER,                  0},                  // 0x4D\r
-  {EfiKeyPgDn,       0x00,     0x00,  EFI_PAGE_DOWN_MODIFIER,            0},                  // 0x4E\r
-  {EfiKeyRightArrow, 0x00,     0x00,  EFI_RIGHT_ARROW_MODIFIER,          0},                  // 0x4F\r
-  {EfiKeyLeftArrow,  0x00,     0x00,  EFI_LEFT_ARROW_MODIFIER,           0},                  // 0x50\r
-  {EfiKeyDownArrow,  0x00,     0x00,  EFI_DOWN_ARROW_MODIFIER,           0},                  // 0x51\r
-  {EfiKeyUpArrow,    0x00,     0x00,  EFI_UP_ARROW_MODIFIER,             0},                  // 0x52\r
-  {EfiKeyNLck,       0x00,     0x00,  EFI_NUM_LOCK_MODIFIER,             0},                  // 0x53   NumLock\r
-  {EfiKeySlash,      '/',      '/',   EFI_NULL_MODIFIER,                 0},                  // 0x54\r
-  {EfiKeyAsterisk,   '*',      '*',   EFI_NULL_MODIFIER,                 0},                  // 0x55\r
-  {EfiKeyMinus,      '-',      '-',   EFI_NULL_MODIFIER,                 0},                  // 0x56\r
-  {EfiKeyPlus,       '+',      '+',   EFI_NULL_MODIFIER,                 0},                  // 0x57\r
-  {EfiKeyEnter,      0x0d,     0x0d,  EFI_NULL_MODIFIER,                 0},                  // 0x58\r
-  {EfiKeyOne,        '1',      '1',   EFI_END_MODIFIER,         EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},   // 0x59\r
-  {EfiKeyTwo,        '2',      '2',   EFI_DOWN_ARROW_MODIFIER,  EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},   // 0x5A\r
-  {EfiKeyThree,      '3',      '3',   EFI_PAGE_DOWN_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},   // 0x5B\r
-  {EfiKeyFour,       '4',      '4',   EFI_LEFT_ARROW_MODIFIER,  EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},   // 0x5C\r
-  {EfiKeyFive,       '5',      '5',   EFI_NULL_MODIFIER,        EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},   // 0x5D\r
-  {EfiKeySix,        '6',      '6',   EFI_RIGHT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},   // 0x5E\r
-  {EfiKeySeven,      '7',      '7',   EFI_HOME_MODIFIER,        EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},   // 0x5F\r
-  {EfiKeyEight,      '8',      '8',   EFI_UP_ARROW_MODIFIER,    EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},   // 0x60\r
-  {EfiKeyNine,       '9',      '9',   EFI_PAGE_UP_MODIFIER,     EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},   // 0x61\r
-  {EfiKeyZero,       '0',      '0',   EFI_INSERT_MODIFIER,      EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},   // 0x62\r
-  {EfiKeyPeriod,     '.',      '.',   EFI_DELETE_MODIFIER,      EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},   // 0x63\r
-  {EfiKeyB0,         '\\',     '|',   EFI_NULL_MODIFIER,        EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x64 Keyboard Non-US \ and |\r
-  {EfiKeyA4,         0x00,     0x00,  EFI_MENU_MODIFIER,        0},                              // 0x65 Keyboard Application\r
-\r
-  {EfiKeyLCtrl,      0,        0,     EFI_LEFT_CONTROL_MODIFIER,    0},  // 0xe0\r
-  {EfiKeyLShift,     0,        0,     EFI_LEFT_SHIFT_MODIFIER,      0},  // 0xe1\r
-  {EfiKeyLAlt,       0,        0,     EFI_LEFT_ALT_MODIFIER,        0},  // 0xe2\r
-  {EfiKeyA0,         0,        0,     EFI_LEFT_LOGO_MODIFIER,       0},  // 0xe3\r
-  {EfiKeyRCtrl,      0,        0,     EFI_RIGHT_CONTROL_MODIFIER,   0},  // 0xe4\r
-  {EfiKeyRShift,     0,        0,     EFI_RIGHT_SHIFT_MODIFIER,     0},  // 0xe5\r
-  {EfiKeyA2,         0,        0,     EFI_RIGHT_ALT_MODIFIER,       0},  // 0xe6\r
-  {EfiKeyA3,         0,        0,     EFI_RIGHT_LOGO_MODIFIER,      0},  // 0xe7\r
-};\r
 \r
-/**\r
-  Initialize KeyConvertionTable by using default keyboard layout.\r
-\r
-  @param  UsbKeyboardDevice    The USB_KB_DEV instance.\r
-  @retval None.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-LoadDefaultKeyboardLayout (\r
-  IN USB_KB_DEV                 *UsbKeyboardDevice\r
-  )\r
-{\r
-  UINTN               Index;\r
-  EFI_KEY_DESCRIPTOR  *KeyDescriptor;\r
+USB_KEYBOARD_LAYOUT_PACK_BIN  mUsbKeyboardLayoutBin = {\r
+  sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN),   // Binary size\r
 \r
   //\r
-  // Construct KeyConvertionTable by default keyboard layout\r
+  // EFI_HII_PACKAGE_HEADER\r
   //\r
-  KeyDescriptor = &UsbKeyboardDevice->KeyConvertionTable[0];\r
-\r
-  for (Index = 0; Index < (USB_KEYCODE_MAX_MAKE + 8); Index++) {\r
-    KeyDescriptor->Key                 = (EFI_KEY) KeyboardLayoutTable[Index][0];\r
-    KeyDescriptor->Unicode             = KeyboardLayoutTable[Index][1];\r
-    KeyDescriptor->ShiftedUnicode      = KeyboardLayoutTable[Index][2];\r
-    KeyDescriptor->AltGrUnicode        = 0;\r
-    KeyDescriptor->ShiftedAltGrUnicode = 0;\r
-    KeyDescriptor->Modifier            = KeyboardLayoutTable[Index][3];\r
-    KeyDescriptor->AffectedAttribute   = KeyboardLayoutTable[Index][4];\r
-\r
-    KeyDescriptor++;\r
-  }\r
-}\r
+  {\r
+    sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN) - sizeof (UINT32),\r
+    EFI_HII_PACKAGE_KEYBOARD_LAYOUT\r
+  },\r
+  1,  // LayoutCount\r
+  sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN) - sizeof (UINT32) - sizeof (EFI_HII_PACKAGE_HEADER) - sizeof (UINT16), // LayoutLength\r
+  USB_KEYBOARD_LAYOUT_KEY_GUID,  // KeyGuid\r
+  sizeof (UINT16) + sizeof (EFI_GUID) + sizeof (UINT32) + sizeof (UINT8) + (USB_KEYBOARD_KEY_COUNT * sizeof (EFI_KEY_DESCRIPTOR)), // LayoutDescriptorStringOffset\r
+  USB_KEYBOARD_KEY_COUNT, // DescriptorCount\r
+  {\r
+    //\r
+    // EFI_KEY_DESCRIPTOR (total number is USB_KEYBOARD_KEY_COUNT)\r
+    //\r
+    {EfiKeyC1,         'a',      'A',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyB5,         'b',      'B',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyB3,         'c',      'C',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyC3,         'd',      'D',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyD3,         'e',      'E',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyC4,         'f',      'F',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyC5,         'g',      'G',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyC6,         'h',      'H',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyD8,         'i',      'I',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyC7,         'j',      'J',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyC8,         'k',      'K',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyC9,         'l',      'L',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyB7,         'm',      'M',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyB6,         'n',      'N',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyD9,         'o',      'O',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyD10,        'p',      'P',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyD1,         'q',      'Q',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyD4,         'r',      'R',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyC2,         's',      'S',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyD5,         't',      'T',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyD7,         'u',      'U',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyB4,         'v',      'V',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyD2,         'w',      'W',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyB2,         'x',      'X',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyD6,         'y',      'Y',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyB1,         'z',      'Z',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+    {EfiKeyE1,         '1',      '!',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyE2,         '2',      '@',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyE3,         '3',      '#',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyE4,         '4',      '$',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyE5,         '5',      '%',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyE6,         '6',      '^',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyE7,         '7',      '&',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyE8,         '8',      '*',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyE9,         '9',      '(',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyE10,        '0',      ')',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyEnter,      0x0d,     0x0d, 0, 0,  EFI_NULL_MODIFIER,   0},\r
+    {EfiKeyEsc,        0x1b,     0x1b, 0, 0,  EFI_NULL_MODIFIER,   0},\r
+    {EfiKeyBackSpace,  0x08,     0x08, 0, 0,  EFI_NULL_MODIFIER,   0},\r
+    {EfiKeyTab,        0x09,     0x09, 0, 0,  EFI_NULL_MODIFIER,   0},\r
+    {EfiKeySpaceBar,   ' ',      ' ',  0, 0,  EFI_NULL_MODIFIER,   0},\r
+    {EfiKeyE11,        '-',      '_',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyE12,        '=',      '+',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyD11,        '[',      '{',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyD12,        ']',      '}',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyD13,        '\\',     '|',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyC12,        '\\',     '|',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyC10,        ';',      ':',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyC11,        '\'',     '"',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyE0,         '`',      '~',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyB8,         ',',      '<',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyB9,         '.',      '>',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyB10,        '/',      '?',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+    {EfiKeyCapsLock,   0x00,     0x00, 0, 0,  EFI_CAPS_LOCK_MODIFIER,            0},\r
+    {EfiKeyF1,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_ONE_MODIFIER,     0},\r
+    {EfiKeyF2,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_TWO_MODIFIER,     0},\r
+    {EfiKeyF3,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_THREE_MODIFIER,   0},\r
+    {EfiKeyF4,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_FOUR_MODIFIER,    0},\r
+    {EfiKeyF5,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_FIVE_MODIFIER,    0},\r
+    {EfiKeyF6,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_SIX_MODIFIER,     0},\r
+    {EfiKeyF7,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_SEVEN_MODIFIER,   0},\r
+    {EfiKeyF8,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_EIGHT_MODIFIER,   0},\r
+    {EfiKeyF9,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_NINE_MODIFIER,    0},\r
+    {EfiKeyF10,        0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_TEN_MODIFIER,     0},\r
+    {EfiKeyF11,        0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_ELEVEN_MODIFIER,  0},\r
+    {EfiKeyF12,        0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_TWELVE_MODIFIER,  0},\r
+    {EfiKeyPrint,      0x00,     0x00, 0, 0,  EFI_PRINT_MODIFIER,                0},\r
+    {EfiKeySLck,       0x00,     0x00, 0, 0,  EFI_SCROLL_LOCK_MODIFIER,          0},\r
+    {EfiKeyPause,      0x00,     0x00, 0, 0,  EFI_PAUSE_MODIFIER,                0},\r
+    {EfiKeyIns,        0x00,     0x00, 0, 0,  EFI_INSERT_MODIFIER,               0},\r
+    {EfiKeyHome,       0x00,     0x00, 0, 0,  EFI_HOME_MODIFIER,                 0},\r
+    {EfiKeyPgUp,       0x00,     0x00, 0, 0,  EFI_PAGE_UP_MODIFIER,              0},\r
+    {EfiKeyDel,        0x00,     0x00, 0, 0,  EFI_DELETE_MODIFIER,               0},\r
+    {EfiKeyEnd,        0x00,     0x00, 0, 0,  EFI_END_MODIFIER,                  0},\r
+    {EfiKeyPgDn,       0x00,     0x00, 0, 0,  EFI_PAGE_DOWN_MODIFIER,            0},\r
+    {EfiKeyRightArrow, 0x00,     0x00, 0, 0,  EFI_RIGHT_ARROW_MODIFIER,          0},\r
+    {EfiKeyLeftArrow,  0x00,     0x00, 0, 0,  EFI_LEFT_ARROW_MODIFIER,           0},\r
+    {EfiKeyDownArrow,  0x00,     0x00, 0, 0,  EFI_DOWN_ARROW_MODIFIER,           0},\r
+    {EfiKeyUpArrow,    0x00,     0x00, 0, 0,  EFI_UP_ARROW_MODIFIER,             0},\r
+    {EfiKeyNLck,       0x00,     0x00, 0, 0,  EFI_NUM_LOCK_MODIFIER,             0},\r
+    {EfiKeySlash,      '/',      '/',  0, 0,  EFI_NULL_MODIFIER,                 0},\r
+    {EfiKeyAsterisk,   '*',      '*',  0, 0,  EFI_NULL_MODIFIER,                 0},\r
+    {EfiKeyMinus,      '-',      '-',  0, 0,  EFI_NULL_MODIFIER,                 0},\r
+    {EfiKeyPlus,       '+',      '+',  0, 0,  EFI_NULL_MODIFIER,                 0},\r
+    {EfiKeyEnter,      0x0d,     0x0d, 0, 0,  EFI_NULL_MODIFIER,                 0},\r
+    {EfiKeyOne,        '1',      '1',  0, 0,  EFI_END_MODIFIER,         EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+    {EfiKeyTwo,        '2',      '2',  0, 0,  EFI_DOWN_ARROW_MODIFIER,  EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+    {EfiKeyThree,      '3',      '3',  0, 0,  EFI_PAGE_DOWN_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+    {EfiKeyFour,       '4',      '4',  0, 0,  EFI_LEFT_ARROW_MODIFIER,  EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+    {EfiKeyFive,       '5',      '5',  0, 0,  EFI_NULL_MODIFIER,        EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+    {EfiKeySix,        '6',      '6',  0, 0,  EFI_RIGHT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+    {EfiKeySeven,      '7',      '7',  0, 0,  EFI_HOME_MODIFIER,        EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+    {EfiKeyEight,      '8',      '8',  0, 0,  EFI_UP_ARROW_MODIFIER,    EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+    {EfiKeyNine,       '9',      '9',  0, 0,  EFI_PAGE_UP_MODIFIER,     EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+    {EfiKeyZero,       '0',      '0',  0, 0,  EFI_INSERT_MODIFIER,      EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+    {EfiKeyPeriod,     '.',      '.',  0, 0,  EFI_DELETE_MODIFIER,      EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+    {EfiKeyA4,         0x00,     0x00, 0, 0,  EFI_MENU_MODIFIER,            0},\r
+    {EfiKeyLCtrl,      0,        0,    0, 0,  EFI_LEFT_CONTROL_MODIFIER,    0},\r
+    {EfiKeyLShift,     0,        0,    0, 0,  EFI_LEFT_SHIFT_MODIFIER,      0},\r
+    {EfiKeyLAlt,       0,        0,    0, 0,  EFI_LEFT_ALT_MODIFIER,        0},\r
+    {EfiKeyA0,         0,        0,    0, 0,  EFI_LEFT_LOGO_MODIFIER,       0},\r
+    {EfiKeyRCtrl,      0,        0,    0, 0,  EFI_RIGHT_CONTROL_MODIFIER,   0},\r
+    {EfiKeyRShift,     0,        0,    0, 0,  EFI_RIGHT_SHIFT_MODIFIER,     0},\r
+    {EfiKeyA2,         0,        0,    0, 0,  EFI_RIGHT_ALT_MODIFIER,       0},\r
+    {EfiKeyA3,         0,        0,    0, 0,  EFI_RIGHT_LOGO_MODIFIER,      0},\r
+  },\r
+  1,                          // DescriptionCount\r
+  {'e', 'n', '-', 'U', 'S'},  // RFC4646 language code\r
+  ' ',                        // Space\r
+  {'E', 'n', 'g', 'l', 'i', 's', 'h', ' ', 'K', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '\0'}, // DescriptionString[]\r
+};\r
 \r
 //\r
-// EFI_KEY to USB Scan Code convertion table\r
+// EFI_KEY to USB Keycode conversion table\r
+// EFI_KEY is defined in UEFI spec.\r
+// USB Keycode is defined in USB HID Firmware spec.\r
 //\r
-UINT8 UsbScanCodeConvertionTable[] = {\r
+UINT8 EfiKeyToUsbKeyCodeConvertionTable[] = {\r
   0xe0,  //  EfiKeyLCtrl\r
   0xe3,  //  EfiKeyA0\r
   0xe2,  //  EfiKeyLAlt\r
@@ -276,9 +259,10 @@ UINT8 UsbScanCodeConvertionTable[] = {
 };\r
 \r
 //\r
-// Keyboard Layout Modifier to EFI Scan Code convertion table\r
+// Keyboard modifier value to EFI Scan Code convertion table\r
+// EFI Scan Code and the modifier values are defined in UEFI spec.\r
 //\r
-UINT8 EfiScanCodeConvertionTable[] = {\r
+UINT8 ModifierValueToEfiScanCodeConvertionTable[] = {\r
   SCAN_NULL,       // EFI_NULL_MODIFIER\r
   SCAN_NULL,       // EFI_LEFT_CONTROL_MODIFIER\r
   SCAN_NULL,       // EFI_RIGHT_CONTROL_MODIFIER\r
@@ -313,33 +297,80 @@ UINT8 EfiScanCodeConvertionTable[] = {
   SCAN_F10,        // EFI_FUNCTION_KEY_TEN_MODIFIER\r
   SCAN_F11,        // EFI_FUNCTION_KEY_ELEVEN_MODIFIER\r
   SCAN_F12,        // EFI_FUNCTION_KEY_TWELVE_MODIFIER\r
+  //\r
+  // For Partial Keystroke support\r
+  //\r
+  SCAN_NULL,       // EFI_PRINT_MODIFIER\r
+  SCAN_NULL,       // EFI_SYS_REQUEST_MODIFIER\r
+  SCAN_NULL,       // EFI_SCROLL_LOCK_MODIFIER\r
+  SCAN_PAUSE,      // EFI_PAUSE_MODIFIER\r
+  SCAN_NULL,       // EFI_BREAK_MODIFIER\r
+  SCAN_NULL,       // EFI_LEFT_LOGO_MODIFIER\r
+  SCAN_NULL,       // EFI_RIGHT_LOGO_MODIFER\r
+  SCAN_NULL,       // EFI_MENU_MODIFER\r
 };\r
 \r
-EFI_GUID  mKeyboardLayoutEventGuid = EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID;\r
+/**\r
+  Initialize Key Convention Table by using default keyboard layout.\r
 \r
+  @param  UsbKeyboardDevice    The USB_KB_DEV instance.\r
 \r
-KB_MODIFIER  KB_Mod[8] = {\r
-  { MOD_CONTROL_L,  0xe0 }, // 11100000\r
-  { MOD_CONTROL_R,  0xe4 }, // 11100100\r
-  { MOD_SHIFT_L,    0xe1 }, // 11100001\r
-  { MOD_SHIFT_R,    0xe5 }, // 11100101\r
-  { MOD_ALT_L,      0xe2 }, // 11100010\r
-  { MOD_ALT_R,      0xe6 }, // 11100110\r
-  { MOD_WIN_L,      0xe3 }, // 11100011\r
-  { MOD_WIN_R,      0xe7 }, // 11100111 \r
-};\r
+  @retval EFI_SUCCESS          The default keyboard layout was installed successfully\r
+  @retval Others               Failure to install default keyboard layout.\r
+**/\r
+EFI_STATUS\r
+InstallDefaultKeyboardLayout (\r
+   IN OUT USB_KB_DEV           *UsbKeyboardDevice\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  EFI_HII_DATABASE_PROTOCOL    *HiiDatabase;\r
+  EFI_HII_HANDLE               HiiHandle;\r
+\r
+  //\r
+  // Locate Hii database protocol\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiHiiDatabaseProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &HiiDatabase\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
+  //\r
+  // Install Keyboard Layout package to HII database\r
+  //\r
+  HiiHandle = HiiAddPackages (\r
+                &gUsbKeyboardLayoutPackageGuid,\r
+                UsbKeyboardDevice->ControllerHandle,\r
+                &mUsbKeyboardLayoutBin,\r
+                NULL\r
+                );\r
+  if (HiiHandle == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Set current keyboard layout\r
+  //\r
+  Status = HiiDatabase->SetKeyboardLayout (HiiDatabase, &gUsbKeyboardLayoutKeyGuid);\r
+\r
+  return Status;\r
+}\r
 \r
 \r
 /**\r
-  Uses USB I/O to check whether the device is a USB Keyboard device.\r
+  Uses USB I/O to check whether the device is a USB keyboard device.\r
 \r
-  @param  UsbIo    Points to a USB I/O protocol instance.\r
-  @retval None\r
+  @param  UsbIo    Pointer to a USB I/O protocol instance.\r
+\r
+  @retval TRUE     Device is a USB keyboard device.\r
+  @retval FALSE    Device is a not USB keyboard device.\r
 \r
 **/\r
 BOOLEAN\r
-EFIAPI\r
 IsUSBKeyboard (\r
   IN  EFI_USB_IO_PROTOCOL       *UsbIo\r
   )\r
@@ -348,8 +379,7 @@ IsUSBKeyboard (
   EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;\r
 \r
   //\r
-  // Get the Default interface descriptor, currently we\r
-  // assume it is interface 1\r
+  // Get the default interface descriptor\r
   //\r
   Status = UsbIo->UsbGetInterfaceDescriptor (\r
                     UsbIo,\r
@@ -364,7 +394,6 @@ IsUSBKeyboard (
       InterfaceDescriptor.InterfaceSubClass == SUBCLASS_BOOT &&\r
       InterfaceDescriptor.InterfaceProtocol == PROTOCOL_KEYBOARD\r
       ) {\r
-\r
     return TRUE;\r
   }\r
 \r
@@ -374,11 +403,11 @@ IsUSBKeyboard (
 /**\r
   Get current keyboard layout from HII database.\r
 \r
-  @retval Pointer to EFI_HII_KEYBOARD_LAYOUT.\r
+  @return Pointer to HII Keyboard Layout.\r
+          NULL means failure occurred while trying to get keyboard layout.\r
 \r
 **/\r
 EFI_HII_KEYBOARD_LAYOUT *\r
-EFIAPI\r
 GetCurrentKeyboardLayout (\r
   VOID\r
   )\r
@@ -389,7 +418,7 @@ GetCurrentKeyboardLayout (
   UINT16                    Length;\r
 \r
   //\r
-  // Locate Hii database protocol\r
+  // Locate HII Database Protocol\r
   //\r
   Status = gBS->LocateProtocol (\r
                   &gEfiHiiDatabaseProtocolGuid,\r
@@ -422,7 +451,7 @@ GetCurrentKeyboardLayout (
                             KeyboardLayout\r
                             );\r
     if (EFI_ERROR (Status)) {\r
-      gBS->FreePool (KeyboardLayout);\r
+      FreePool (KeyboardLayout);\r
       KeyboardLayout = NULL;\r
     }\r
   }\r
@@ -431,81 +460,93 @@ GetCurrentKeyboardLayout (
 }\r
 \r
 /**\r
-  Find Key Descriptor in KeyConvertionTable given its scan code.\r
+  Find Key Descriptor in Key Convertion Table given its USB keycode.\r
 \r
   @param  UsbKeyboardDevice   The USB_KB_DEV instance.\r
-  @param  ScanCode            USB scan code.\r
+  @param  KeyCode             USB Keycode.\r
 \r
-  @return The Key descriptor in KeyConvertionTable.\r
+  @return The Key Descriptor in Key Convertion Table.\r
+          NULL means not found.\r
 \r
 **/\r
 EFI_KEY_DESCRIPTOR *\r
-EFIAPI\r
 GetKeyDescriptor (\r
   IN USB_KB_DEV        *UsbKeyboardDevice,\r
-  IN UINT8             ScanCode\r
+  IN UINT8             KeyCode\r
   )\r
 {\r
   UINT8  Index;\r
 \r
-  if (((ScanCode > 0x65) && (ScanCode < 0xe0)) || (ScanCode > 0xe7)) {\r
+  //\r
+  // Make sure KeyCode is in the range of [0x4, 0x65] or [0xe0, 0xe7]\r
+  //\r
+  if ((!USBKBD_VALID_KEYCODE (KeyCode)) || ((KeyCode > 0x65) && (KeyCode < 0xe0)) || (KeyCode > 0xe7)) {\r
     return NULL;\r
   }\r
 \r
-  if (ScanCode <= 0x65) {\r
-    Index = (UINT8) (ScanCode - 4);\r
+  //\r
+  // Calculate the index of Key Descriptor in Key Convertion Table\r
+  //\r
+  if (KeyCode <= 0x65) {\r
+    Index = (UINT8) (KeyCode - 4);\r
   } else {\r
-    Index = (UINT8) (ScanCode - 0xe0 + USB_KEYCODE_MAX_MAKE);\r
+    Index = (UINT8) (KeyCode - 0xe0 + NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE);\r
   }\r
 \r
   return &UsbKeyboardDevice->KeyConvertionTable[Index];\r
 }\r
 \r
 /**\r
-  Find Non-Spacing key for given KeyDescriptor.\r
+  Find Non-Spacing key for given Key descriptor.\r
 \r
   @param  UsbKeyboardDevice    The USB_KB_DEV instance.\r
   @param  KeyDescriptor        Key descriptor.\r
 \r
-  @retval NULL                 Key list is empty.\r
-  @return Other                The Non-Spacing key.\r
+  @return The Non-Spacing key corresponding to KeyDescriptor\r
+          NULL means not found.\r
 \r
 **/\r
 USB_NS_KEY *\r
-EFIAPI\r
 FindUsbNsKey (\r
   IN USB_KB_DEV          *UsbKeyboardDevice,\r
   IN EFI_KEY_DESCRIPTOR  *KeyDescriptor\r
   )\r
 {\r
   LIST_ENTRY      *Link;\r
+  LIST_ENTRY      *NsKeyList;\r
   USB_NS_KEY      *UsbNsKey;\r
 \r
-  Link = GetFirstNode (&UsbKeyboardDevice->NsKeyList);\r
-  while (!IsNull (&UsbKeyboardDevice->NsKeyList, Link)) {\r
+  NsKeyList = &UsbKeyboardDevice->NsKeyList;\r
+  Link = GetFirstNode (NsKeyList);\r
+  while (!IsNull (NsKeyList, Link)) {\r
     UsbNsKey = USB_NS_KEY_FORM_FROM_LINK (Link);\r
 \r
     if (UsbNsKey->NsKey[0].Key == KeyDescriptor->Key) {\r
       return UsbNsKey;\r
     }\r
 \r
-    Link = GetNextNode (&UsbKeyboardDevice->NsKeyList, Link);\r
+    Link = GetNextNode (NsKeyList, Link);\r
   }\r
 \r
   return NULL;\r
 }\r
 \r
 /**\r
-  Find physical key definition for a given Key stroke.\r
+  Find physical key definition for a given key descriptor.\r
 \r
-  @param  UsbNsKey          The Non-Spacing key information.\r
-  @param  KeyDescriptor     The key stroke.\r
+  For a specified non-spacing key, there are a list of physical\r
+  keys following it. This function traverses the list of\r
+  physical keys and tries to find the physical key matching\r
+  the KeyDescriptor.\r
+\r
+  @param  UsbNsKey          The non-spacing key information.\r
+  @param  KeyDescriptor     The key descriptor.\r
 \r
   @return The physical key definition.\r
+          If no physical key is found, parameter KeyDescriptor is returned.\r
 \r
 **/\r
 EFI_KEY_DESCRIPTOR *\r
-EFIAPI\r
 FindPhysicalKey (\r
   IN USB_NS_KEY          *UsbNsKey,\r
   IN EFI_KEY_DESCRIPTOR  *KeyDescriptor\r
@@ -530,17 +571,21 @@ FindPhysicalKey (
 }\r
 \r
 /**\r
-  The notification function for SET_KEYBOARD_LAYOUT_EVENT.\r
+  The notification function for EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID.\r
 \r
-  @param  Event           The instance of EFI_EVENT.\r
-  @param  Context         passing parameter.\r
+  This function is registered to event of EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID\r
+  group type, which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().\r
+  It tries to get curent keyboard layout from HII database.\r
+\r
+  @param  Event        Event being signaled.\r
+  @param  Context      Points to USB_KB_DEV instance.\r
 \r
 **/\r
 VOID\r
 EFIAPI\r
 SetKeyboardLayoutEvent (\r
-  EFI_EVENT                  Event,\r
-  VOID                       *Context\r
+  IN EFI_EVENT              Event,\r
+  IN VOID                   *Context\r
   )\r
 {\r
   USB_KB_DEV                *UsbKeyboardDevice;\r
@@ -553,12 +598,15 @@ SetKeyboardLayoutEvent (
   UINTN                     Index;\r
   UINTN                     Index2;\r
   UINTN                     KeyCount;\r
-  UINT8                     ScanCode;\r
+  UINT8                     KeyCode;\r
 \r
   UsbKeyboardDevice = (USB_KB_DEV *) Context;\r
+  if (UsbKeyboardDevice->Signature != USB_KB_DEV_SIGNATURE) {\r
+    return;\r
+  }\r
 \r
   //\r
-  // Try to get current Keyboard Layout from HII database\r
+  // Try to get current keyboard layout from HII database\r
   //\r
   KeyboardLayout = GetCurrentKeyboardLayout ();\r
   if (KeyboardLayout == NULL) {\r
@@ -566,12 +614,15 @@ SetKeyboardLayoutEvent (
   }\r
 \r
   //\r
-  // Allocate resource for KeyConvertionTable\r
+  // Re-allocate resource for KeyConvertionTable\r
   //\r
   ReleaseKeyboardLayoutResources (UsbKeyboardDevice);\r
-  UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((USB_KEYCODE_MAX_MAKE + 8) * sizeof (EFI_KEY_DESCRIPTOR));\r
+  UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE) * sizeof (EFI_KEY_DESCRIPTOR));\r
   ASSERT (UsbKeyboardDevice->KeyConvertionTable != NULL);\r
 \r
+  //\r
+  // Traverse the list of key descriptors following the header of EFI_HII_KEYBOARD_LAYOUT\r
+  //\r
   KeyDescriptor = (EFI_KEY_DESCRIPTOR *) (((UINT8 *) KeyboardLayout) + sizeof (EFI_HII_KEYBOARD_LAYOUT));\r
   for (Index = 0; Index < KeyboardLayout->DescriptorCount; Index++) {\r
     //\r
@@ -580,17 +631,22 @@ SetKeyboardLayoutEvent (
     CopyMem (&TempKey, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));\r
 \r
     //\r
-    // Fill the key into KeyConvertionTable (which use USB Scan Code as index)\r
+    // Fill the key into KeyConvertionTable, whose index is calculated from USB keycode.\r
     //\r
-    ScanCode = UsbScanCodeConvertionTable [(UINT8) (TempKey.Key)];\r
-    TableEntry = GetKeyDescriptor (UsbKeyboardDevice, ScanCode);\r
+    KeyCode = EfiKeyToUsbKeyCodeConvertionTable [(UINT8) (TempKey.Key)];\r
+    TableEntry = GetKeyDescriptor (UsbKeyboardDevice, KeyCode);\r
+    if (TableEntry == NULL) {\r
+      ReleaseKeyboardLayoutResources (UsbKeyboardDevice);\r
+      FreePool (KeyboardLayout);\r
+      return;\r
+    }\r
     CopyMem (TableEntry, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));\r
 \r
+    //\r
+    // For non-spacing key, create the list with a non-spacing key followed by physical keys.\r
+    //\r
     if (TempKey.Modifier == EFI_NS_KEY_MODIFIER) {\r
-      //\r
-      // Non-spacing key\r
-      //\r
-      UsbNsKey = AllocatePool (sizeof (USB_NS_KEY));\r
+      UsbNsKey = AllocateZeroPool (sizeof (USB_NS_KEY));\r
       ASSERT (UsbNsKey != NULL);\r
 \r
       //\r
@@ -598,9 +654,9 @@ SetKeyboardLayoutEvent (
       //\r
       KeyCount = 0;\r
       NsKey = KeyDescriptor + 1;\r
-      for (Index2 = Index + 1; Index2 < KeyboardLayout->DescriptorCount; Index2++) {\r
+      for (Index2 = (UINT8) Index + 1; Index2 < KeyboardLayout->DescriptorCount; Index2++) {\r
         CopyMem (&TempKey, NsKey, sizeof (EFI_KEY_DESCRIPTOR));\r
-        if (TempKey.Modifier & EFI_NS_KEY_DEPENDENCY_MODIFIER) {\r
+        if (TempKey.Modifier == EFI_NS_KEY_DEPENDENCY_MODIFIER) {\r
           KeyCount++;\r
         } else {\r
           break;\r
@@ -627,25 +683,24 @@ SetKeyboardLayoutEvent (
   }\r
 \r
   //\r
-  // There are two EfiKeyEnter, duplicate its Key Descriptor\r
+  // There are two EfiKeyEnter, duplicate its key descriptor\r
   //\r
   TableEntry = GetKeyDescriptor (UsbKeyboardDevice, 0x58);\r
   KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, 0x28);\r
   CopyMem (TableEntry, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));\r
 \r
-  gBS->FreePool (KeyboardLayout);\r
+  FreePool (KeyboardLayout);\r
 }\r
 \r
 /**\r
-  Destroy resources for Keyboard layout.\r
+  Destroy resources for keyboard layout.\r
 \r
   @param  UsbKeyboardDevice    The USB_KB_DEV instance.\r
 \r
 **/\r
 VOID\r
-EFIAPI\r
 ReleaseKeyboardLayoutResources (\r
-  IN USB_KB_DEV              *UsbKeyboardDevice\r
+  IN OUT USB_KB_DEV              *UsbKeyboardDevice\r
   )\r
 {\r
   USB_NS_KEY      *UsbNsKey;\r
@@ -667,24 +722,29 @@ ReleaseKeyboardLayoutResources (
 }\r
 \r
 /**\r
-  Initialize USB Keyboard layout.\r
+  Initialize USB keyboard layout.\r
+\r
+  This function initializes Key Convertion Table for the USB keyboard device.\r
+  It first tries to retrieve layout from HII database. If failed and default\r
+  layout is enabled, then it just uses the default layout.\r
 \r
   @param  UsbKeyboardDevice      The USB_KB_DEV instance.\r
 \r
-  @retval EFI_SUCCESS            Initialization Success.\r
-  @retval Other                  Keyboard layout initial failed.\r
+  @retval EFI_SUCCESS            Initialization succeeded.\r
+  @retval EFI_NOT_READY          Keyboard layout cannot be retrieve from HII\r
+                                 database, and default layout is disabled.\r
+  @retval Other                  Fail to register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group.\r
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 InitKeyboardLayout (\r
-  IN USB_KB_DEV   *UsbKeyboardDevice\r
+  OUT USB_KB_DEV   *UsbKeyboardDevice\r
   )\r
 {\r
   EFI_HII_KEYBOARD_LAYOUT   *KeyboardLayout;\r
   EFI_STATUS                Status;\r
 \r
-  UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((USB_KEYCODE_MAX_MAKE + 8) * sizeof (EFI_KEY_DESCRIPTOR));\r
+  UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE) * sizeof (EFI_KEY_DESCRIPTOR));\r
   ASSERT (UsbKeyboardDevice->KeyConvertionTable != NULL);\r
 \r
   InitializeListHead (&UsbKeyboardDevice->NsKeyList);\r
@@ -692,102 +752,109 @@ InitKeyboardLayout (
   UsbKeyboardDevice->KeyboardLayoutEvent = NULL;\r
 \r
   //\r
-  // Register SET_KEYBOARD_LAYOUT_EVENT notification\r
+  // Register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group,\r
+  // which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().\r
   //\r
   Status = gBS->CreateEventEx (\r
                   EVT_NOTIFY_SIGNAL,\r
                   TPL_NOTIFY,\r
                   SetKeyboardLayoutEvent,\r
                   UsbKeyboardDevice,\r
-                  &mKeyboardLayoutEventGuid,\r
+                  &gEfiHiiKeyBoardLayoutGuid,\r
                   &UsbKeyboardDevice->KeyboardLayoutEvent\r
                   );\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
-  //\r
-  // Try to get current keyboard layout from HII database\r
-  //\r
   KeyboardLayout = GetCurrentKeyboardLayout ();\r
   if (KeyboardLayout != NULL) {\r
     //\r
-    // Force to initialize the keyboard layout\r
+    // If current keyboard layout is successfully retrieved from HII database,\r
+    // force to initialize the keyboard layout.\r
     //\r
     gBS->SignalEvent (UsbKeyboardDevice->KeyboardLayoutEvent);\r
   } else {\r
     if (FeaturePcdGet (PcdDisableDefaultKeyboardLayoutInUsbKbDriver)) {\r
-      return EFI_NOT_READY;\r
-    } else {\r
-\r
       //\r
-      // Fail to get keyboard layout from HII database,\r
-      // use default keyboard layout\r
+      // If no keyboard layout can be retrieved from HII database, and default layout\r
+      // is disabled, then return EFI_NOT_READY.\r
       //\r
-      LoadDefaultKeyboardLayout (UsbKeyboardDevice);\r
+      return EFI_NOT_READY;\r
     }\r
+    //\r
+    // If no keyboard layout can be retrieved from HII database, and default layout\r
+    // is enabled, then load the default keyboard layout.\r
+    //\r
+    InstallDefaultKeyboardLayout (UsbKeyboardDevice);\r
   }\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 \r
 /**\r
-  Initialize USB Keyboard device and all private data structures.\r
+  Initialize USB keyboard device and all private data structures.\r
 \r
   @param  UsbKeyboardDevice  The USB_KB_DEV instance.\r
 \r
   @retval EFI_SUCCESS        Initialization is successful.\r
-  @retval EFI_DEVICE_ERROR   Configure hardware failed.\r
+  @retval EFI_DEVICE_ERROR   Keyboard initialization failed.\r
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 InitUSBKeyboard (\r
-  IN USB_KB_DEV   *UsbKeyboardDevice\r
+  IN OUT USB_KB_DEV   *UsbKeyboardDevice\r
   )\r
 {\r
-  UINT              ConfigValue;\r
+  UINT16              ConfigValue;\r
   UINT8               Protocol;\r
-  UINT8               ReportId;\r
-  UINT8               Duration;\r
   EFI_STATUS          Status;\r
   UINT32              TransferResult;\r
 \r
-  KbdReportStatusCode (\r
-    UsbKeyboardDevice->DevicePath,\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
     EFI_PROGRESS_CODE,\r
-    PcdGet32 (PcdStatusCodeValueKeyboardSelfTest)\r
+    (EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST),\r
+    UsbKeyboardDevice->DevicePath\r
     );\r
 \r
-  InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer));\r
-\r
-  //\r
-  // default configurations\r
-  //\r
-  ConfigValue = 0x01;\r
+  InitQueue (&UsbKeyboardDevice->UsbKeyQueue, sizeof (USB_KEY));\r
+  InitQueue (&UsbKeyboardDevice->EfiKeyQueue, sizeof (EFI_KEY_DATA));\r
+  InitQueue (&UsbKeyboardDevice->EfiKeyQueueForNotify, sizeof (EFI_KEY_DATA));\r
 \r
   //\r
-  // Uses default configuration to configure the USB Keyboard device.\r
+  // Use the config out of the descriptor\r
+  // Assumed the first config is the correct one and this is not always the case\r
   //\r
-  Status = UsbSetConfiguration (\r
-            UsbKeyboardDevice->UsbIo,\r
-            (UINT16) ConfigValue,\r
-            &TransferResult\r
-            );\r
+  Status = UsbGetConfiguration (\r
+             UsbKeyboardDevice->UsbIo,\r
+             &ConfigValue,\r
+             &TransferResult\r
+             );\r
   if (EFI_ERROR (Status)) {\r
+    ConfigValue = 0x01;\r
     //\r
-    // If configuration could not be set here, it means\r
-    // the keyboard interface has some errors and could\r
-    // not be initialized\r
+    // Uses default configuration to configure the USB Keyboard device.\r
     //\r
-    KbdReportStatusCode (\r
-      UsbKeyboardDevice->DevicePath,\r
-      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-      PcdGet32 (PcdStatusCodeValueKeyboardInterfaceError)\r
-      );\r
+    Status = UsbSetConfiguration (\r
+               UsbKeyboardDevice->UsbIo,\r
+               ConfigValue,\r
+               &TransferResult\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // If configuration could not be set here, it means\r
+      // the keyboard interface has some errors and could\r
+      // not be initialized\r
+      //\r
+      REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+        EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+        (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_INTERFACE_ERROR),\r
+        UsbKeyboardDevice->DevicePath\r
+        );\r
 \r
-    return EFI_DEVICE_ERROR;\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
   }\r
 \r
   UsbGetProtocolRequest (\r
@@ -796,9 +863,8 @@ InitUSBKeyboard (
     &Protocol\r
     );\r
   //\r
-  // Sets boot protocol for the USB Keyboard.\r
+  // Set boot protocol for the USB Keyboard.\r
   // This driver only supports boot protocol.\r
-  // !!BugBug: How about the device that does not support boot protocol?\r
   //\r
   if (Protocol != BOOT_PROTOCOL) {\r
     UsbSetProtocolRequest (\r
@@ -807,90 +873,79 @@ InitUSBKeyboard (
       BOOT_PROTOCOL\r
       );\r
   }\r
-  //\r
-  // the duration is indefinite, so the endpoint will inhibit reporting forever,\r
-  // and only reporting when a change is detected in the report data.\r
-  //\r
-\r
-  //\r
-  // idle value for all report ID\r
-  //\r
-  ReportId = 0;\r
-  //\r
-  // idle forever until there is a key pressed and released.\r
-  //\r
-  Duration = 0;\r
-  UsbSetIdleRequest (\r
-    UsbKeyboardDevice->UsbIo,\r
-    UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,\r
-    ReportId,\r
-    Duration\r
-    );\r
 \r
-  UsbKeyboardDevice->CtrlOn     = 0;\r
-  UsbKeyboardDevice->AltOn      = 0;\r
-  UsbKeyboardDevice->ShiftOn    = 0;\r
-  UsbKeyboardDevice->NumLockOn  = 0;\r
-  UsbKeyboardDevice->CapsOn     = 0;\r
-  UsbKeyboardDevice->ScrollOn   = 0;\r
-  \r
-  UsbKeyboardDevice->LeftCtrlOn   = 0;\r
-  UsbKeyboardDevice->LeftAltOn    = 0;\r
-  UsbKeyboardDevice->LeftShiftOn  = 0;\r
-  UsbKeyboardDevice->LeftLogoOn   = 0;\r
-  UsbKeyboardDevice->RightCtrlOn  = 0;\r
-  UsbKeyboardDevice->RightAltOn   = 0;\r
-  UsbKeyboardDevice->RightShiftOn = 0;\r
-  UsbKeyboardDevice->RightLogoOn  = 0;\r
-  UsbKeyboardDevice->MenuKeyOn    = 0;\r
-  UsbKeyboardDevice->SysReqOn     = 0;\r
-\r
-  UsbKeyboardDevice->AltGrOn      = 0;\r
+  UsbKeyboardDevice->CtrlOn     = FALSE;\r
+  UsbKeyboardDevice->AltOn      = FALSE;\r
+  UsbKeyboardDevice->ShiftOn    = FALSE;\r
+  UsbKeyboardDevice->NumLockOn  = FALSE;\r
+  UsbKeyboardDevice->CapsOn     = FALSE;\r
+  UsbKeyboardDevice->ScrollOn   = FALSE;\r
+\r
+  UsbKeyboardDevice->LeftCtrlOn   = FALSE;\r
+  UsbKeyboardDevice->LeftAltOn    = FALSE;\r
+  UsbKeyboardDevice->LeftShiftOn  = FALSE;\r
+  UsbKeyboardDevice->LeftLogoOn   = FALSE;\r
+  UsbKeyboardDevice->RightCtrlOn  = FALSE;\r
+  UsbKeyboardDevice->RightAltOn   = FALSE;\r
+  UsbKeyboardDevice->RightShiftOn = FALSE;\r
+  UsbKeyboardDevice->RightLogoOn  = FALSE;\r
+  UsbKeyboardDevice->MenuKeyOn    = FALSE;\r
+  UsbKeyboardDevice->SysReqOn     = FALSE;\r
+\r
+  UsbKeyboardDevice->AltGrOn      = FALSE;\r
 \r
   UsbKeyboardDevice->CurrentNsKey = NULL;\r
 \r
   //\r
-  // Sync the initial state of lights\r
+  // Sync the initial state of lights on keyboard.\r
   //\r
   SetKeyLED (UsbKeyboardDevice);\r
 \r
   ZeroMem (UsbKeyboardDevice->LastKeyCodeArray, sizeof (UINT8) * 8);\r
 \r
   //\r
-  // Set a timer for repeat keys' generation.\r
+  // Create event for repeat keys' generation.\r
   //\r
   if (UsbKeyboardDevice->RepeatTimer != NULL) {\r
     gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);\r
-    UsbKeyboardDevice->RepeatTimer = 0;\r
+    UsbKeyboardDevice->RepeatTimer = NULL;\r
   }\r
 \r
-  Status = gBS->CreateEvent (\r
-                  EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-                  TPL_NOTIFY,\r
-                  USBKeyboardRepeatHandler,\r
-                  UsbKeyboardDevice,\r
-                  &UsbKeyboardDevice->RepeatTimer\r
-                  );\r
+  gBS->CreateEvent (\r
+         EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
+         TPL_CALLBACK,\r
+         USBKeyboardRepeatHandler,\r
+         UsbKeyboardDevice,\r
+         &UsbKeyboardDevice->RepeatTimer\r
+         );\r
 \r
+  //\r
+  // Create event for delayed recovery, which deals with device error.\r
+  //\r
   if (UsbKeyboardDevice->DelayedRecoveryEvent != NULL) {\r
     gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);\r
-    UsbKeyboardDevice->DelayedRecoveryEvent = 0;\r
+    UsbKeyboardDevice->DelayedRecoveryEvent = NULL;\r
   }\r
 \r
-  Status = gBS->CreateEvent (\r
-                  EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-                  TPL_NOTIFY,\r
-                  USBKeyboardRecoveryHandler,\r
-                  UsbKeyboardDevice,\r
-                  &UsbKeyboardDevice->DelayedRecoveryEvent\r
-                  );\r
+  gBS->CreateEvent (\r
+         EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
+         TPL_NOTIFY,\r
+         USBKeyboardRecoveryHandler,\r
+         UsbKeyboardDevice,\r
+         &UsbKeyboardDevice->DelayedRecoveryEvent\r
+         );\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
 \r
 /**\r
-  Handler function for USB Keyboard's asynchronous interrupt transfer.\r
+  Handler function for USB keyboard's asynchronous interrupt transfer.\r
+\r
+  This function is the handler function for USB keyboard's asynchronous interrupt transfer\r
+  to manage the keyboard. It parses the USB keyboard input report, and inserts data to\r
+  keyboard buffer according to state of modifer keys and normal keys. Timer for repeat key\r
+  is also set accordingly.\r
 \r
   @param  Data             A pointer to a buffer that is filled with key data which is\r
                            retrieved via asynchronous interrupt transfer.\r
@@ -898,8 +953,8 @@ InitUSBKeyboard (
   @param  Context          Pointing to USB_KB_DEV instance.\r
   @param  Result           Indicates the result of the asynchronous interrupt transfer.\r
 \r
-  @retval EFI_SUCCESS      Handler is successful.\r
-  @retval EFI_DEVICE_ERROR Hardware Error\r
+  @retval EFI_SUCCESS      Asynchronous interrupt transfer is handled successfully.\r
+  @retval EFI_DEVICE_ERROR Hardware error occurs.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -917,38 +972,37 @@ KeyboardHandler (
   UINT8               *OldKeyCodeBuffer;\r
   UINT8               CurModifierMap;\r
   UINT8               OldModifierMap;\r
-  UINT8               Index;\r
+  UINT8               Mask;\r
+  UINTN               Index;\r
   UINT8               Index2;\r
-  BOOLEAN             Down;\r
   BOOLEAN             KeyRelease;\r
   BOOLEAN             KeyPress;\r
-  UINT8               SavedTail;\r
   USB_KEY             UsbKey;\r
   UINT8               NewRepeatKey;\r
   UINT32              UsbStatus;\r
   EFI_KEY_DESCRIPTOR  *KeyDescriptor;\r
 \r
-  ASSERT (Context);\r
+  ASSERT (Context != NULL);\r
 \r
   NewRepeatKey      = 0;\r
   UsbKeyboardDevice = (USB_KB_DEV *) Context;\r
   UsbIo             = UsbKeyboardDevice->UsbIo;\r
 \r
   //\r
-  // Analyzes the Result and performs corresponding action.\r
+  // Analyzes Result and performs corresponding action.\r
   //\r
   if (Result != EFI_USB_NOERROR) {\r
     //\r
     // Some errors happen during the process\r
     //\r
-    KbdReportStatusCode (\r
-      UsbKeyboardDevice->DevicePath,\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
       EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-      PcdGet32 (PcdStatusCodeValueKeyboardInputError)\r
+      (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_INPUT_ERROR),\r
+      UsbKeyboardDevice->DevicePath\r
       );\r
 \r
     //\r
-    // stop the repeat key generation if any\r
+    // Stop the repeat key generation if any\r
     //\r
     UsbKeyboardDevice->RepeatKey = 0;\r
 \r
@@ -968,37 +1022,48 @@ KeyboardHandler (
 \r
     //\r
     // Delete & Submit this interrupt again\r
+    // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt.\r
     //\r
-\r
     UsbIo->UsbAsyncInterruptTransfer (\r
-                      UsbIo,\r
-                      UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,\r
-                      FALSE,\r
-                      0,\r
-                      0,\r
-                      NULL,\r
-                      NULL\r
-                      );\r
-\r
+             UsbIo,\r
+             UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,\r
+             FALSE,\r
+             0,\r
+             0,\r
+             NULL,\r
+             NULL\r
+             );\r
+    //\r
+    // EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling.\r
+    //\r
     gBS->SetTimer (\r
-          UsbKeyboardDevice->DelayedRecoveryEvent,\r
-          TimerRelative,\r
-          EFI_USB_INTERRUPT_DELAY\r
-          );\r
+           UsbKeyboardDevice->DelayedRecoveryEvent,\r
+           TimerRelative,\r
+           EFI_USB_INTERRUPT_DELAY\r
+           );\r
 \r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
+  //\r
+  // If no error and no data, just return EFI_SUCCESS.\r
+  //\r
   if (DataLength == 0 || Data == NULL) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
+  //\r
+  // Following code checks current keyboard input report against old key code buffer.\r
+  // According to USB HID Firmware Specification, the report consists of 8 bytes.\r
+  // Byte 0 is map of Modifier keys.\r
+  // Byte 1 is reserved.\r
+  // Bytes 2 to 7 are keycodes.\r
+  //\r
   CurKeyCodeBuffer  = (UINT8 *) Data;\r
   OldKeyCodeBuffer  = UsbKeyboardDevice->LastKeyCodeArray;\r
 \r
   //\r
-  // checks for new key stroke.\r
-  // if no new key got, return immediately.\r
+  // Checks for new key stroke.\r
   //\r
   for (Index = 0; Index < 8; Index++) {\r
     if (OldKeyCodeBuffer[Index] != CurKeyCodeBuffer[Index]) {\r
@@ -1006,35 +1071,48 @@ KeyboardHandler (
     }\r
   }\r
 \r
+  //\r
+  // If no new key, return EFI_SUCCESS immediately.\r
+  //\r
   if (Index == 8) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
   //\r
-  // Parse the modifier key\r
+  // Parse the modifier key, which is the first byte of keyboard input report.\r
   //\r
   CurModifierMap  = CurKeyCodeBuffer[0];\r
   OldModifierMap  = OldKeyCodeBuffer[0];\r
 \r
   //\r
-  // handle modifier key's pressing or releasing situation.\r
+  // Handle modifier key's pressing or releasing situation.\r
+  // According to USB HID Firmware spec, Byte 0 uses folloing map of Modifier keys:\r
+  // Bit0: Left Control,  Keycode: 0xe0\r
+  // Bit1: Left Shift,    Keycode: 0xe1\r
+  // Bit2: Left Alt,      Keycode: 0xe2\r
+  // Bit3: Left GUI,      Keycode: 0xe3\r
+  // Bit4: Right Control, Keycode: 0xe4\r
+  // Bit5: Right Shift,   Keycode: 0xe5\r
+  // Bit6: Right Alt,     Keycode: 0xe6\r
+  // Bit7: Right GUI,     Keycode: 0xe7\r
   //\r
   for (Index = 0; Index < 8; Index++) {\r
-\r
-    if ((CurModifierMap & KB_Mod[Index].Mask) != (OldModifierMap & KB_Mod[Index].Mask)) {\r
+    Mask = (UINT8) (1 << Index);\r
+    if ((CurModifierMap & Mask) != (OldModifierMap & Mask)) {\r
       //\r
-      // if current modifier key is up, then\r
-      // CurModifierMap & KB_Mod[Index].Mask = 0;\r
-      // otherwize it is a non-zero value.\r
-      // Inserts the pressed modifier key into key buffer.\r
+      // If current modifier key is up, then CurModifierMap & Mask = 0;\r
+      // otherwise it is a non-zero value.\r
+      // Insert the changed modifier key into key buffer.\r
       //\r
-      Down = (UINT8) (CurModifierMap & KB_Mod[Index].Mask);\r
-      InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), KB_Mod[Index].Key, Down);\r
+      UsbKey.KeyCode = (UINT8) (0xe0 + Index);\r
+      UsbKey.Down    = (BOOLEAN) ((CurModifierMap & Mask) != 0);\r
+      Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));\r
     }\r
   }\r
 \r
   //\r
-  // handle normal key's releasing situation\r
+  // Handle normal key's releasing situation\r
+  // Bytes 2 to 7 are for normal keycodes\r
   //\r
   KeyRelease = FALSE;\r
   for (Index = 2; Index < 8; Index++) {\r
@@ -1042,7 +1120,10 @@ KeyboardHandler (
     if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index])) {\r
       continue;\r
     }\r
-\r
+    //\r
+    // For any key in old keycode buffer, if it is not in current keycode buffer,\r
+    // then it is released. Otherwise, it is not released.\r
+    //\r
     KeyRelease = TRUE;\r
     for (Index2 = 2; Index2 < 8; Index2++) {\r
 \r
@@ -1057,13 +1138,11 @@ KeyboardHandler (
     }\r
 \r
     if (KeyRelease) {\r
-      InsertKeyCode (\r
-        &(UsbKeyboardDevice->KeyboardBuffer),\r
-        OldKeyCodeBuffer[Index],\r
-        0\r
-        );\r
+      UsbKey.KeyCode = OldKeyCodeBuffer[Index];\r
+      UsbKey.Down    = FALSE;\r
+      Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));\r
       //\r
-      // the original reapeat key is released.\r
+      // The original repeat key is released.\r
       //\r
       if (OldKeyCodeBuffer[Index] == UsbKeyboardDevice->RepeatKey) {\r
         UsbKeyboardDevice->RepeatKey = 0;\r
@@ -1072,18 +1151,18 @@ KeyboardHandler (
   }\r
 \r
   //\r
-  // original repeat key is released, cancel the repeat timer\r
+  // If original repeat key is released, cancel the repeat timer\r
   //\r
   if (UsbKeyboardDevice->RepeatKey == 0) {\r
     gBS->SetTimer (\r
-          UsbKeyboardDevice->RepeatTimer,\r
-          TimerCancel,\r
-          USBKBD_REPEAT_RATE\r
-          );\r
+           UsbKeyboardDevice->RepeatTimer,\r
+           TimerCancel,\r
+           USBKBD_REPEAT_RATE\r
+           );\r
   }\r
 \r
   //\r
-  // handle normal key's pressing situation\r
+  // Handle normal key's pressing situation\r
   //\r
   KeyPress = FALSE;\r
   for (Index = 2; Index < 8; Index++) {\r
@@ -1091,7 +1170,10 @@ KeyboardHandler (
     if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index])) {\r
       continue;\r
     }\r
-\r
+    //\r
+    // For any key in current keycode buffer, if it is not in old keycode buffer,\r
+    // then it is pressed. Otherwise, it is not pressed.\r
+    //\r
     KeyPress = TRUE;\r
     for (Index2 = 2; Index2 < 8; Index2++) {\r
 \r
@@ -1106,112 +1188,55 @@ KeyboardHandler (
     }\r
 \r
     if (KeyPress) {\r
-      InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), CurKeyCodeBuffer[Index], 1);\r
+      UsbKey.KeyCode = CurKeyCodeBuffer[Index];\r
+      UsbKey.Down    = TRUE;\r
+      Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));\r
+\r
       //\r
-      // NumLock pressed or CapsLock pressed\r
+      // Handle repeat key\r
       //\r
       KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, CurKeyCodeBuffer[Index]);\r
+      if (KeyDescriptor == NULL) {\r
+        continue;\r
+      }\r
+\r
       if (KeyDescriptor->Modifier == EFI_NUM_LOCK_MODIFIER || KeyDescriptor->Modifier == EFI_CAPS_LOCK_MODIFIER) {\r
+        //\r
+        // For NumLock or CapsLock pressed, there is no need to handle repeat key for them.\r
+        //\r
         UsbKeyboardDevice->RepeatKey = 0;\r
       } else {\r
-        NewRepeatKey = CurKeyCodeBuffer[Index];\r
         //\r
-        // do not repeat the original repeated key\r
+        // Prepare new repeat key, and clear the original one.\r
         //\r
+        NewRepeatKey = CurKeyCodeBuffer[Index];\r
         UsbKeyboardDevice->RepeatKey = 0;\r
       }\r
     }\r
   }\r
 \r
   //\r
-  // Update LastKeycodeArray[] buffer in the\r
-  // Usb Keyboard Device data structure.\r
+  // Update LastKeycodeArray buffer in the UsbKeyboardDevice data structure.\r
   //\r
   for (Index = 0; Index < 8; Index++) {\r
     UsbKeyboardDevice->LastKeyCodeArray[Index] = CurKeyCodeBuffer[Index];\r
   }\r
 \r
   //\r
-  // pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence\r
-  // and judge whether it will invoke reset event.\r
-  //\r
-  SavedTail = UsbKeyboardDevice->KeyboardBuffer.bTail;\r
-  Index     = UsbKeyboardDevice->KeyboardBuffer.bHead;\r
-  while (Index != SavedTail) {\r
-    RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey);\r
-\r
-    KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode);\r
-\r
-    switch (KeyDescriptor->Modifier) {\r
-\r
-    case EFI_LEFT_CONTROL_MODIFIER:\r
-    case EFI_RIGHT_CONTROL_MODIFIER:\r
-      if (UsbKey.Down != 0) {\r
-        UsbKeyboardDevice->CtrlOn = 1;\r
-      } else {\r
-        UsbKeyboardDevice->CtrlOn = 0;\r
-      }\r
-      break;\r
-\r
-    case EFI_LEFT_ALT_MODIFIER:\r
-    case EFI_RIGHT_ALT_MODIFIER:\r
-      if (UsbKey.Down != 0) {\r
-        UsbKeyboardDevice->AltOn = 1;\r
-      } else {\r
-        UsbKeyboardDevice->AltOn = 0;\r
-      }\r
-      break;\r
-\r
-    case EFI_ALT_GR_MODIFIER:\r
-      if (UsbKey.Down != 0) {\r
-        UsbKeyboardDevice->AltGrOn = 1;\r
-      } else {\r
-        UsbKeyboardDevice->AltGrOn = 0;\r
-      }\r
-      break;\r
-\r
-    //\r
-    // Del Key Code\r
-    //\r
-    case EFI_DELETE_MODIFIER:\r
-      if (UsbKey.Down != 0) {\r
-        if ((UsbKeyboardDevice->CtrlOn != 0) && (UsbKeyboardDevice->AltOn != 0)) {\r
-          gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
-        }\r
-      }\r
-      break;\r
-\r
-    default:\r
-      break;\r
-    }\r
-\r
-    //\r
-    // insert the key back to the buffer.\r
-    // so the key sequence will not be destroyed.\r
-    //\r
-    InsertKeyCode (\r
-      &(UsbKeyboardDevice->KeyboardBuffer),\r
-      UsbKey.KeyCode,\r
-      UsbKey.Down\r
-      );\r
-    Index = UsbKeyboardDevice->KeyboardBuffer.bHead;\r
-\r
-  }\r
-  //\r
-  // If have new key pressed, update the RepeatKey value, and set the\r
+  // If there is new key pressed, update the RepeatKey value, and set the\r
   // timer to repeate delay timer\r
   //\r
   if (NewRepeatKey != 0) {\r
     //\r
-    // sets trigger time to "Repeat Delay Time",\r
+    // Sets trigger time to "Repeat Delay Time",\r
     // to trigger the repeat timer when the key is hold long\r
     // enough time.\r
     //\r
     gBS->SetTimer (\r
-          UsbKeyboardDevice->RepeatTimer,\r
-          TimerRelative,\r
-          USBKBD_REPEAT_DELAY\r
-          );\r
+           UsbKeyboardDevice->RepeatTimer,\r
+           TimerRelative,\r
+           USBKBD_REPEAT_DELAY\r
+           );\r
     UsbKeyboardDevice->RepeatKey = NewRepeatKey;\r
   }\r
 \r
@@ -1220,92 +1245,100 @@ KeyboardHandler (
 \r
 \r
 /**\r
-  Retrieves a key character after parsing the raw data in keyboard buffer.\r
+  Retrieves a USB keycode after parsing the raw data in keyboard buffer.\r
+\r
+  This function parses keyboard buffer. It updates state of modifier key for\r
+  USB_KB_DEV instancem, and returns keycode for output.\r
 \r
   @param  UsbKeyboardDevice    The USB_KB_DEV instance.\r
-  @param  KeyChar              Points to the Key character after key parsing.\r
+  @param  KeyCode              Pointer to the USB keycode for output.\r
 \r
-  @retval EFI_SUCCESS          Parse key is successful.\r
-  @retval EFI_NOT_READY        Device is not ready.\r
+  @retval EFI_SUCCESS          Keycode successfully parsed.\r
+  @retval EFI_NOT_READY        Keyboard buffer is not ready for a valid keycode\r
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 USBParseKey (\r
   IN OUT  USB_KB_DEV  *UsbKeyboardDevice,\r
-  OUT     UINT8       *KeyChar\r
+     OUT  UINT8       *KeyCode\r
   )\r
 {\r
   USB_KEY             UsbKey;\r
   EFI_KEY_DESCRIPTOR  *KeyDescriptor;\r
 \r
-  *KeyChar = 0;\r
+  *KeyCode = 0;\r
 \r
-  while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice->KeyboardBuffer)) {\r
+  while (!IsQueueEmpty (&UsbKeyboardDevice->UsbKeyQueue)) {\r
     //\r
-    // pops one raw data off.\r
+    // Pops one raw data off.\r
     //\r
-    RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey);\r
+    Dequeue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));\r
 \r
     KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode);\r
-    if (UsbKey.Down == 0) {\r
+    if (KeyDescriptor == NULL) {\r
+      continue;\r
+    }\r
+    if (!UsbKey.Down) {\r
+      //\r
+      // Key is released.\r
+      //\r
       switch (KeyDescriptor->Modifier) {\r
 \r
       //\r
-      // CTRL release\r
+      // Ctrl release\r
       //\r
       case EFI_LEFT_CONTROL_MODIFIER:\r
-        UsbKeyboardDevice->LeftCtrlOn = 0;\r
-        UsbKeyboardDevice->CtrlOn = 0;\r
+        UsbKeyboardDevice->LeftCtrlOn = FALSE;\r
+        UsbKeyboardDevice->CtrlOn = FALSE;\r
         break;\r
       case EFI_RIGHT_CONTROL_MODIFIER:\r
-        UsbKeyboardDevice->RightCtrlOn = 0;\r
-        UsbKeyboardDevice->CtrlOn = 0;\r
+        UsbKeyboardDevice->RightCtrlOn = FALSE;\r
+        UsbKeyboardDevice->CtrlOn = FALSE;\r
         break;\r
 \r
       //\r
       // Shift release\r
       //\r
       case EFI_LEFT_SHIFT_MODIFIER:\r
-        UsbKeyboardDevice->LeftShiftOn = 0;\r
-        UsbKeyboardDevice->ShiftOn = 0;\r
+        UsbKeyboardDevice->LeftShiftOn = FALSE;\r
+        UsbKeyboardDevice->ShiftOn = FALSE;\r
         break;\r
       case EFI_RIGHT_SHIFT_MODIFIER:\r
-        UsbKeyboardDevice->RightShiftOn = 0;\r
-        UsbKeyboardDevice->ShiftOn = 0;\r
+        UsbKeyboardDevice->RightShiftOn = FALSE;\r
+        UsbKeyboardDevice->ShiftOn = FALSE;\r
         break;\r
 \r
       //\r
       // Alt release\r
       //\r
       case EFI_LEFT_ALT_MODIFIER:\r
-        UsbKeyboardDevice->LeftAltOn = 0;\r
-        UsbKeyboardDevice->AltOn = 0;\r
+        UsbKeyboardDevice->LeftAltOn = FALSE;\r
+        UsbKeyboardDevice->AltOn = FALSE;\r
         break;\r
       case EFI_RIGHT_ALT_MODIFIER:\r
-        UsbKeyboardDevice->RightAltOn = 0;\r
-        UsbKeyboardDevice->AltOn = 0;\r
+        UsbKeyboardDevice->RightAltOn = FALSE;\r
+        UsbKeyboardDevice->AltOn = FALSE;\r
         break;\r
 \r
       //\r
       // Left Logo release\r
       //\r
       case EFI_LEFT_LOGO_MODIFIER:\r
-        UsbKeyboardDevice->LeftLogoOn = 0;\r
+        UsbKeyboardDevice->LeftLogoOn = FALSE;\r
         break;\r
 \r
       //\r
       // Right Logo release\r
       //\r
       case EFI_RIGHT_LOGO_MODIFIER:\r
-        UsbKeyboardDevice->RightLogoOn = 0;\r
+        UsbKeyboardDevice->RightLogoOn = FALSE;\r
         break;\r
 \r
       //\r
       // Menu key release\r
       //\r
       case EFI_MENU_MODIFIER:\r
-        UsbKeyboardDevice->MenuKeyOn = 0;\r
+        UsbKeyboardDevice->MenuKeyOn = FALSE;\r
         break;\r
 \r
       //\r
@@ -1313,14 +1346,14 @@ USBParseKey (
       //\r
       case EFI_PRINT_MODIFIER:\r
       case EFI_SYS_REQUEST_MODIFIER:\r
-        UsbKeyboardDevice->SysReqOn = 0;\r
+        UsbKeyboardDevice->SysReqOn = FALSE;\r
         break;\r
 \r
       //\r
       // AltGr release\r
       //\r
       case EFI_ALT_GR_MODIFIER:\r
-        UsbKeyboardDevice->AltGrOn = 0;\r
+        UsbKeyboardDevice->AltGrOn = FALSE;\r
         break;\r
 \r
       default:\r
@@ -1336,66 +1369,60 @@ USBParseKey (
     switch (KeyDescriptor->Modifier) {\r
 \r
     //\r
-    // CTRL press\r
+    // Ctrl press\r
     //\r
     case EFI_LEFT_CONTROL_MODIFIER:\r
-      UsbKeyboardDevice->LeftCtrlOn = 1;\r
-      UsbKeyboardDevice->CtrlOn = 1;\r
-      continue;\r
+      UsbKeyboardDevice->LeftCtrlOn = TRUE;\r
+      UsbKeyboardDevice->CtrlOn = TRUE;\r
       break;\r
     case EFI_RIGHT_CONTROL_MODIFIER:\r
-      UsbKeyboardDevice->RightCtrlOn = 1;\r
-      UsbKeyboardDevice->CtrlOn = 1;\r
-      continue;\r
+      UsbKeyboardDevice->RightCtrlOn = TRUE;\r
+      UsbKeyboardDevice->CtrlOn = TRUE;\r
       break;\r
 \r
     //\r
     // Shift press\r
     //\r
     case EFI_LEFT_SHIFT_MODIFIER:\r
-      UsbKeyboardDevice->LeftShiftOn = 1;\r
-      UsbKeyboardDevice->ShiftOn = 1;\r
-      continue;\r
+      UsbKeyboardDevice->LeftShiftOn = TRUE;\r
+      UsbKeyboardDevice->ShiftOn = TRUE;\r
       break;\r
     case EFI_RIGHT_SHIFT_MODIFIER:\r
-      UsbKeyboardDevice->RightShiftOn = 1;\r
-      UsbKeyboardDevice->ShiftOn = 1;\r
-      continue;\r
+      UsbKeyboardDevice->RightShiftOn = TRUE;\r
+      UsbKeyboardDevice->ShiftOn = TRUE;\r
       break;\r
 \r
     //\r
     // Alt press\r
     //\r
     case EFI_LEFT_ALT_MODIFIER:\r
-      UsbKeyboardDevice->LeftAltOn = 1;\r
-      UsbKeyboardDevice->AltOn = 1;\r
-      continue;\r
+      UsbKeyboardDevice->LeftAltOn = TRUE;\r
+      UsbKeyboardDevice->AltOn = TRUE;\r
       break;\r
     case EFI_RIGHT_ALT_MODIFIER:\r
-      UsbKeyboardDevice->RightAltOn = 1;\r
-      UsbKeyboardDevice->AltOn = 1;\r
-      continue;\r
+      UsbKeyboardDevice->RightAltOn = TRUE;\r
+      UsbKeyboardDevice->AltOn = TRUE;\r
       break;\r
 \r
     //\r
     // Left Logo press\r
     //\r
     case EFI_LEFT_LOGO_MODIFIER:\r
-      UsbKeyboardDevice->LeftLogoOn = 1;\r
+      UsbKeyboardDevice->LeftLogoOn = TRUE;\r
       break;\r
 \r
     //\r
     // Right Logo press\r
     //\r
     case EFI_RIGHT_LOGO_MODIFIER:\r
-      UsbKeyboardDevice->RightLogoOn = 1;\r
+      UsbKeyboardDevice->RightLogoOn = TRUE;\r
       break;\r
 \r
     //\r
     // Menu key press\r
     //\r
     case EFI_MENU_MODIFIER:\r
-      UsbKeyboardDevice->MenuKeyOn = 1;\r
+      UsbKeyboardDevice->MenuKeyOn = TRUE;\r
       break;\r
 \r
     //\r
@@ -1403,56 +1430,38 @@ USBParseKey (
     //\r
     case EFI_PRINT_MODIFIER:\r
     case EFI_SYS_REQUEST_MODIFIER:\r
-      UsbKeyboardDevice->SysReqOn = 1;\r
-      continue;\r
+      UsbKeyboardDevice->SysReqOn = TRUE;\r
       break;\r
 \r
     //\r
     // AltGr press\r
     //\r
     case EFI_ALT_GR_MODIFIER:\r
-      UsbKeyboardDevice->AltGrOn = 1;\r
+      UsbKeyboardDevice->AltGrOn = TRUE;\r
       break;\r
 \r
     case EFI_NUM_LOCK_MODIFIER:\r
-      UsbKeyboardDevice->NumLockOn ^= 1;\r
       //\r
-      // Turn on the NumLock light on KB\r
+      // Toggle NumLock\r
       //\r
+      UsbKeyboardDevice->NumLockOn = (BOOLEAN) (!(UsbKeyboardDevice->NumLockOn));\r
       SetKeyLED (UsbKeyboardDevice);\r
-      continue;\r
       break;\r
 \r
     case EFI_CAPS_LOCK_MODIFIER:\r
-      UsbKeyboardDevice->CapsOn ^= 1;\r
       //\r
-      // Turn on the CapsLock light on KB\r
+      // Toggle CapsLock\r
       //\r
+      UsbKeyboardDevice->CapsOn = (BOOLEAN) (!(UsbKeyboardDevice->CapsOn));\r
       SetKeyLED (UsbKeyboardDevice);\r
-      continue;\r
       break;\r
 \r
     case EFI_SCROLL_LOCK_MODIFIER:\r
-      UsbKeyboardDevice->ScrollOn ^= 1;\r
       //\r
-      // Turn on the ScrollLock light on KB\r
+      // Toggle ScrollLock\r
       //\r
+      UsbKeyboardDevice->ScrollOn = (BOOLEAN) (!(UsbKeyboardDevice->ScrollOn));\r
       SetKeyLED (UsbKeyboardDevice);\r
-      continue;\r
-      break;\r
-\r
-    //\r
-    // F11,F12,PrintScreen,Pause/Break\r
-    // could not be retrieved via SimpleTxtInEx protocol\r
-    //\r
-    case EFI_FUNCTION_KEY_ELEVEN_MODIFIER:\r
-    case EFI_FUNCTION_KEY_TWELVE_MODIFIER:\r
-    case EFI_PAUSE_MODIFIER:\r
-    case EFI_BREAK_MODIFIER:\r
-      //\r
-      // fall through\r
-      //\r
-      continue;\r
       break;\r
 \r
     default:\r
@@ -1460,354 +1469,396 @@ USBParseKey (
     }\r
 \r
     //\r
-    // When encountered Del Key...\r
+    // When encountering Ctrl + Alt + Del, then warm reset.\r
     //\r
     if (KeyDescriptor->Modifier == EFI_DELETE_MODIFIER) {\r
-      if ((UsbKeyboardDevice->CtrlOn != 0) && (UsbKeyboardDevice->AltOn != 0)) {\r
+      if ((UsbKeyboardDevice->CtrlOn) && (UsbKeyboardDevice->AltOn)) {\r
         gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
       }\r
     }\r
 \r
-    *KeyChar = UsbKey.KeyCode;\r
+    *KeyCode = UsbKey.KeyCode;\r
     return EFI_SUCCESS;\r
   }\r
 \r
   return EFI_NOT_READY;\r
 }\r
 \r
+/**\r
+  Initialize the key state.\r
+\r
+  @param  UsbKeyboardDevice     The USB_KB_DEV instance.\r
+  @param  KeyState              A pointer to receive the key state information.\r
+**/\r
+VOID\r
+InitializeKeyState (\r
+  IN  USB_KB_DEV           *UsbKeyboardDevice,\r
+  OUT EFI_KEY_STATE        *KeyState\r
+  )\r
+{\r
+  KeyState->KeyShiftState  = EFI_SHIFT_STATE_VALID;\r
+  KeyState->KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
+\r
+  if (UsbKeyboardDevice->LeftCtrlOn) {\r
+    KeyState->KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;\r
+  }\r
+  if (UsbKeyboardDevice->RightCtrlOn) {\r
+    KeyState->KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;\r
+  }\r
+  if (UsbKeyboardDevice->LeftAltOn) {\r
+    KeyState->KeyShiftState |= EFI_LEFT_ALT_PRESSED;\r
+  }\r
+  if (UsbKeyboardDevice->RightAltOn) {\r
+    KeyState->KeyShiftState |= EFI_RIGHT_ALT_PRESSED;\r
+  }\r
+  if (UsbKeyboardDevice->LeftShiftOn) {\r
+    KeyState->KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;\r
+  }\r
+  if (UsbKeyboardDevice->RightShiftOn) {\r
+    KeyState->KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;\r
+  }\r
+  if (UsbKeyboardDevice->LeftLogoOn) {\r
+    KeyState->KeyShiftState |= EFI_LEFT_LOGO_PRESSED;\r
+  }\r
+  if (UsbKeyboardDevice->RightLogoOn) {\r
+    KeyState->KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;\r
+  }\r
+  if (UsbKeyboardDevice->MenuKeyOn) {\r
+    KeyState->KeyShiftState |= EFI_MENU_KEY_PRESSED;\r
+  }\r
+  if (UsbKeyboardDevice->SysReqOn) {\r
+    KeyState->KeyShiftState |= EFI_SYS_REQ_PRESSED;\r
+  }\r
+\r
+  if (UsbKeyboardDevice->ScrollOn) {\r
+    KeyState->KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
+  }\r
+  if (UsbKeyboardDevice->NumLockOn) {\r
+    KeyState->KeyToggleState |= EFI_NUM_LOCK_ACTIVE;\r
+  }\r
+  if (UsbKeyboardDevice->CapsOn) {\r
+    KeyState->KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
+  }\r
+  if (UsbKeyboardDevice->IsSupportPartialKey) {\r
+    KeyState->KeyToggleState |= EFI_KEY_STATE_EXPOSED;\r
+  }\r
+}\r
 \r
 /**\r
-  Converts USB Keyboard code to EFI Scan Code.\r
+  Converts USB Keycode ranging from 0x4 to 0x65 to EFI_INPUT_KEY.\r
 \r
-  @param  UsbKeyboardDevice    The USB_KB_DEV instance.\r
-  @param  KeyChar              Indicates the key code that will be interpreted.\r
-  @param  Key                  A pointer to a buffer that is filled in with\r
-                               the keystroke information for the key that\r
-                               was pressed.\r
+  @param  UsbKeyboardDevice     The USB_KB_DEV instance.\r
+  @param  KeyCode               Indicates the key code that will be interpreted.\r
+  @param  KeyData               A pointer to a buffer that is filled in with\r
+                                the keystroke information for the key that\r
+                                was pressed.\r
 \r
-  @retval EFI_NOT_READY        Device is not ready\r
-  @retval EFI_SUCCESS          Success.\r
+  @retval EFI_SUCCESS           Success.\r
+  @retval EFI_INVALID_PARAMETER KeyCode is not in the range of 0x4 to 0x65.\r
+  @retval EFI_INVALID_PARAMETER Translated EFI_INPUT_KEY has zero for both ScanCode and UnicodeChar.\r
+  @retval EFI_NOT_READY         KeyCode represents a dead key with EFI_NS_KEY_MODIFIER\r
+  @retval EFI_DEVICE_ERROR      Keyboard layout is invalid.\r
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
-USBKeyCodeToEFIScanCode (\r
-  IN  USB_KB_DEV      *UsbKeyboardDevice,\r
-  IN  UINT8           KeyChar,\r
-  OUT EFI_INPUT_KEY   *Key\r
+UsbKeyCodeToEfiInputKey (\r
+  IN  USB_KB_DEV                *UsbKeyboardDevice,\r
+  IN  UINT8                     KeyCode,\r
+  OUT EFI_KEY_DATA              *KeyData\r
   )\r
 {\r
-  UINT8               Index;\r
-  EFI_KEY_DESCRIPTOR  *KeyDescriptor;\r
-\r
-  if (!USBKBD_VALID_KEYCODE (KeyChar)) {\r
-    return EFI_NOT_READY;\r
-  }\r
+  EFI_KEY_DESCRIPTOR            *KeyDescriptor;\r
+  LIST_ENTRY                    *Link;\r
+  LIST_ENTRY                    *NotifyList;\r
+  KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
 \r
   //\r
-  // valid USB Key Code starts from 4\r
+  // KeyCode must in the range of  [0x4, 0x65] or [0xe0, 0xe7].\r
   //\r
-  Index = (UINT8) (KeyChar - 4);\r
-\r
-  if (Index >= USB_KEYCODE_MAX_MAKE) {\r
-    return EFI_NOT_READY;\r
+  KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, KeyCode);\r
+  if (KeyDescriptor == NULL) {\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, KeyChar);\r
-\r
-  //\r
-  // Check for Non-spacing key\r
-  //\r
   if (KeyDescriptor->Modifier == EFI_NS_KEY_MODIFIER) {\r
+    //\r
+    // If this is a dead key with EFI_NS_KEY_MODIFIER, then record it and return.\r
+    //\r
     UsbKeyboardDevice->CurrentNsKey = FindUsbNsKey (UsbKeyboardDevice, KeyDescriptor);\r
     return EFI_NOT_READY;\r
   }\r
 \r
-  //\r
-  // Check whether this keystroke follows a Non-spacing key\r
-  //\r
   if (UsbKeyboardDevice->CurrentNsKey != NULL) {\r
+    //\r
+    // If this keystroke follows a non-spacing key, then find the descriptor for corresponding\r
+    // physical key.\r
+    //\r
     KeyDescriptor = FindPhysicalKey (UsbKeyboardDevice->CurrentNsKey, KeyDescriptor);\r
     UsbKeyboardDevice->CurrentNsKey = NULL;\r
   }\r
 \r
-  Key->ScanCode = EfiScanCodeConvertionTable[KeyDescriptor->Modifier];\r
-  Key->UnicodeChar = KeyDescriptor->Unicode;\r
+  //\r
+  // Make sure modifier of Key Descriptor is in the valid range according to UEFI spec.\r
+  //\r
+  if (KeyDescriptor->Modifier >= (sizeof (ModifierValueToEfiScanCodeConvertionTable) / sizeof (UINT8))) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  KeyData->Key.ScanCode    = ModifierValueToEfiScanCodeConvertionTable[KeyDescriptor->Modifier];\r
+  KeyData->Key.UnicodeChar = KeyDescriptor->Unicode;\r
 \r
-  if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_STANDARD_SHIFT) {\r
-    if (UsbKeyboardDevice->ShiftOn != 0) {\r
-      Key->UnicodeChar = KeyDescriptor->ShiftedUnicode;\r
+  if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_STANDARD_SHIFT)!= 0) {\r
+    if (UsbKeyboardDevice->ShiftOn) {\r
+      KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedUnicode;\r
 \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
-      if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) {\r
-        UsbKeyboardDevice->LeftShiftOn = 0;\r
-        UsbKeyboardDevice->RightShiftOn = 0;\r
+      if ((KeyDescriptor->Unicode != CHAR_NULL) && (KeyDescriptor->ShiftedUnicode != CHAR_NULL) &&\r
+          (KeyDescriptor->Unicode != KeyDescriptor->ShiftedUnicode)) {\r
+        UsbKeyboardDevice->LeftShiftOn = FALSE;\r
+        UsbKeyboardDevice->RightShiftOn = FALSE;\r
       }\r
 \r
-      if (UsbKeyboardDevice->AltGrOn != 0) {\r
-        Key->UnicodeChar = KeyDescriptor->ShiftedAltGrUnicode;\r
+      if (UsbKeyboardDevice->AltGrOn) {\r
+        KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedAltGrUnicode;\r
       }\r
     } else {\r
       //\r
       // Shift off\r
       //\r
-      Key->UnicodeChar = KeyDescriptor->Unicode;\r
+      KeyData->Key.UnicodeChar = KeyDescriptor->Unicode;\r
 \r
-      if (UsbKeyboardDevice->AltGrOn != 0) {\r
-        Key->UnicodeChar = KeyDescriptor->AltGrUnicode;\r
+      if (UsbKeyboardDevice->AltGrOn) {\r
+        KeyData->Key.UnicodeChar = KeyDescriptor->AltGrUnicode;\r
       }\r
     }\r
   }\r
 \r
-  if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) {\r
-    if (UsbKeyboardDevice->CapsOn != 0) {\r
-\r
-      if (Key->UnicodeChar == KeyDescriptor->Unicode) {\r
-\r
-        Key->UnicodeChar = KeyDescriptor->ShiftedUnicode;\r
-\r
-      } else if (Key->UnicodeChar == KeyDescriptor->ShiftedUnicode) {\r
-\r
-        Key->UnicodeChar = KeyDescriptor->Unicode;\r
-\r
+  if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) != 0) {\r
+    if (UsbKeyboardDevice->CapsOn) {\r
+      if (KeyData->Key.UnicodeChar == KeyDescriptor->Unicode) {\r
+        KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedUnicode;\r
+      } else if (KeyData->Key.UnicodeChar == KeyDescriptor->ShiftedUnicode) {\r
+        KeyData->Key.UnicodeChar = KeyDescriptor->Unicode;\r
       }\r
     }\r
   }\r
 \r
-  //\r
-  // Translate the CTRL-Alpha characters to their corresponding control value  (ctrl-a = 0x0001 through ctrl-Z = 0x001A)\r
-  //\r
-  if (UsbKeyboardDevice->CtrlOn != 0) {\r
-    if (Key->UnicodeChar >= 'a' && Key->UnicodeChar <= 'z') {\r
-      Key->UnicodeChar = (UINT8) (Key->UnicodeChar - 'a' + 1);\r
-    } else if (Key->UnicodeChar >= 'A' && Key->UnicodeChar <= 'Z') {\r
-      Key->UnicodeChar = (UINT8) (Key->UnicodeChar - 'A' + 1);\r
-    }\r
-  }\r
-\r
-  if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_NUM_LOCK) {\r
-\r
-    if ((UsbKeyboardDevice->NumLockOn != 0) && (UsbKeyboardDevice->ShiftOn == 0)) {\r
-\r
-      Key->ScanCode = SCAN_NULL;\r
-\r
+  if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_NUM_LOCK) != 0) {\r
+    //\r
+    // For key affected by NumLock, if NumLock is on and Shift is not pressed, then it means\r
+    // normal key, instead of original control key. So the ScanCode should be cleaned.\r
+    // Otherwise, it means control key, so preserve the EFI Scan Code and clear the unicode keycode.\r
+    //\r
+    if ((UsbKeyboardDevice->NumLockOn) && (!(UsbKeyboardDevice->ShiftOn))) {\r
+      KeyData->Key.ScanCode = SCAN_NULL;\r
     } else {\r
-      Key->UnicodeChar = 0x00;\r
+      KeyData->Key.UnicodeChar = CHAR_NULL;\r
     }\r
   }\r
 \r
   //\r
   // Translate Unicode 0x1B (ESC) to EFI Scan Code\r
   //\r
-  if (Key->UnicodeChar == 0x1B && Key->ScanCode == SCAN_NULL) {\r
-    Key->ScanCode = SCAN_ESC;\r
-    Key->UnicodeChar = 0x00;\r
+  if (KeyData->Key.UnicodeChar == 0x1B && KeyData->Key.ScanCode == SCAN_NULL) {\r
+    KeyData->Key.ScanCode = SCAN_ESC;\r
+    KeyData->Key.UnicodeChar = CHAR_NULL;\r
   }\r
 \r
-  if (Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) {\r
+  //\r
+  // Not valid for key without both unicode key code and EFI Scan Code.\r
+  //\r
+  if (KeyData->Key.UnicodeChar == 0 && KeyData->Key.ScanCode == SCAN_NULL) {\r
+    if (!UsbKeyboardDevice->IsSupportPartialKey) {\r
     return EFI_NOT_READY;\r
+    }\r
   }\r
 \r
-\r
   //\r
   // Save Shift/Toggle state\r
   //\r
-  if (UsbKeyboardDevice->LeftCtrlOn == 1) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->RightCtrlOn == 1) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->LeftAltOn == 1) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->RightAltOn == 1) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->LeftShiftOn == 1) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->RightShiftOn == 1) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->LeftLogoOn == 1) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->RightLogoOn == 1) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->MenuKeyOn == 1) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->SysReqOn == 1) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;\r
-  }\r
+  InitializeKeyState (UsbKeyboardDevice, &KeyData->KeyState);\r
 \r
-  if (UsbKeyboardDevice->ScrollOn == 1) {\r
-    UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
-  }\r
-  if (UsbKeyboardDevice->NumLockOn == 1) {\r
-    UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;\r
-  }\r
-  if (UsbKeyboardDevice->CapsOn == 1) {\r
-    UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
+  //\r
+  // Signal KeyNotify process event if this key pressed matches any key registered.\r
+  //\r
+  NotifyList = &UsbKeyboardDevice->NotifyList;\r
+  for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {\r
+    CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE);\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
+      Enqueue (&UsbKeyboardDevice->EfiKeyQueueForNotify, KeyData, sizeof (*KeyData));\r
+      gBS->SignalEvent (UsbKeyboardDevice->KeyNotifyProcessEvent);\r
+    }\r
   }\r
 \r
   return EFI_SUCCESS;\r
-\r
 }\r
 \r
-\r
 /**\r
-  Resets USB Keyboard Buffer.\r
-\r
-  @param  KeyboardBuffer     Points to the USB Keyboard Buffer.\r
+  Create the queue.\r
 \r
-  @retval EFI_SUCCESS        Init key buffer successfully.\r
+  @param  Queue     Points to the queue.\r
+  @param  ItemSize  Size of the single item.\r
 \r
 **/\r
-EFI_STATUS\r
-EFIAPI\r
-InitUSBKeyBuffer (\r
-  IN OUT  USB_KB_BUFFER   *KeyboardBuffer\r
+VOID\r
+InitQueue (\r
+  IN OUT  USB_SIMPLE_QUEUE   *Queue,\r
+  IN      UINTN              ItemSize\r
   )\r
 {\r
-  ZeroMem (KeyboardBuffer, sizeof (USB_KB_BUFFER));\r
+  UINTN                      Index;\r
 \r
-  KeyboardBuffer->bHead = KeyboardBuffer->bTail;\r
+  Queue->ItemSize  = ItemSize;\r
+  Queue->Head      = 0;\r
+  Queue->Tail      = 0;\r
 \r
-  return EFI_SUCCESS;\r
+  if (Queue->Buffer[0] != NULL) {\r
+    FreePool (Queue->Buffer[0]);\r
+  }\r
+\r
+  Queue->Buffer[0] = AllocatePool (sizeof (Queue->Buffer) / sizeof (Queue->Buffer[0]) * ItemSize);\r
+  ASSERT (Queue->Buffer[0] != NULL);\r
+\r
+  for (Index = 1; Index < sizeof (Queue->Buffer) / sizeof (Queue->Buffer[0]); Index++) {\r
+    Queue->Buffer[Index] = ((UINT8 *) Queue->Buffer[Index - 1]) + ItemSize;\r
+  }\r
+}\r
+\r
+/**\r
+  Destroy the queue\r
+\r
+  @param Queue    Points to the queue.\r
+**/\r
+VOID\r
+DestroyQueue (\r
+  IN OUT USB_SIMPLE_QUEUE   *Queue\r
+  )\r
+{\r
+  FreePool (Queue->Buffer[0]);\r
 }\r
 \r
 \r
 /**\r
-  Check whether USB Keyboard buffer is empty.\r
+  Check whether the queue is empty.\r
 \r
-  @param  KeyboardBuffer     USB Keyboard Buffer.\r
+  @param  Queue     Points to the queue.\r
 \r
-  @retval TRUE               Key buffer is empty.\r
-  @retval FALSE              Key buffer is not empty.\r
+  @retval TRUE      Queue is empty.\r
+  @retval FALSE     Queue is not empty.\r
 \r
 **/\r
 BOOLEAN\r
-EFIAPI\r
-IsUSBKeyboardBufferEmpty (\r
-  IN  USB_KB_BUFFER   *KeyboardBuffer\r
+IsQueueEmpty (\r
+  IN  USB_SIMPLE_QUEUE   *Queue\r
   )\r
 {\r
   //\r
-  // meet FIFO empty condition\r
+  // Meet FIFO empty condition\r
   //\r
-  return (BOOLEAN) (KeyboardBuffer->bHead == KeyboardBuffer->bTail);\r
+  return (BOOLEAN) (Queue->Head == Queue->Tail);\r
 }\r
 \r
 \r
 /**\r
-  Check whether USB Keyboard buffer is full.\r
+  Check whether the queue is full.\r
 \r
-  @param  KeyboardBuffer     USB Keyboard Buffer.\r
+  @param  Queue     Points to the queue.\r
 \r
-  @retval TRUE               Key buffer is full.\r
-  @retval FALSE              Key buffer is not full.\r
+  @retval TRUE      Queue is full.\r
+  @retval FALSE     Queue is not full.\r
 \r
 **/\r
 BOOLEAN\r
-EFIAPI\r
-IsUSBKeyboardBufferFull (\r
-  IN  USB_KB_BUFFER   *KeyboardBuffer\r
+IsQueueFull (\r
+  IN  USB_SIMPLE_QUEUE   *Queue\r
   )\r
 {\r
-  return (BOOLEAN)(((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1)) ==\r
-                                                        KeyboardBuffer->bHead);\r
+  return (BOOLEAN) (((Queue->Tail + 1) % (MAX_KEY_ALLOWED + 1)) == Queue->Head);\r
 }\r
 \r
 \r
 /**\r
-  Inserts a key code into keyboard buffer.\r
-\r
-  @param  KeyboardBuffer     Points to the USB Keyboard Buffer.\r
-  @param  Key                Key code\r
-  @param  Down               Special key\r
-\r
-  @retval EFI_SUCCESS        Success\r
+  Enqueue the item to the queue.\r
 \r
+  @param  Queue     Points to the queue.\r
+  @param  Item      Points to the item to be enqueued.\r
+  @param  ItemSize  Size of the item.\r
 **/\r
-EFI_STATUS\r
-EFIAPI\r
-InsertKeyCode (\r
-  IN OUT  USB_KB_BUFFER *KeyboardBuffer,\r
-  IN      UINT8         Key,\r
-  IN      UINT8         Down\r
+VOID\r
+Enqueue (\r
+  IN OUT  USB_SIMPLE_QUEUE *Queue,\r
+  IN      VOID             *Item,\r
+  IN      UINTN            ItemSize\r
   )\r
 {\r
-  USB_KEY UsbKey;\r
-\r
+  ASSERT (ItemSize == Queue->ItemSize);\r
   //\r
-  // if keyboard buffer is full, throw the\r
+  // If keyboard buffer is full, throw the\r
   // first key out of the keyboard buffer.\r
   //\r
-  if (IsUSBKeyboardBufferFull (KeyboardBuffer)) {\r
-    RemoveKeyCode (KeyboardBuffer, &UsbKey);\r
+  if (IsQueueFull (Queue)) {\r
+    Queue->Head = (Queue->Head + 1) % (MAX_KEY_ALLOWED + 1);\r
   }\r
 \r
-  KeyboardBuffer->buffer[KeyboardBuffer->bTail].KeyCode = Key;\r
-  KeyboardBuffer->buffer[KeyboardBuffer->bTail].Down    = Down;\r
+  CopyMem (Queue->Buffer[Queue->Tail], Item, ItemSize);\r
 \r
   //\r
-  // adjust the tail pointer of the FIFO keyboard buffer.\r
+  // Adjust the tail pointer of the FIFO keyboard buffer.\r
   //\r
-  KeyboardBuffer->bTail = (UINT8) ((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1));\r
-\r
-  return EFI_SUCCESS;\r
+  Queue->Tail = (Queue->Tail + 1) % (MAX_KEY_ALLOWED + 1);\r
 }\r
 \r
 \r
 /**\r
-  Pops a key code off from keyboard buffer.\r
+  Dequeue a item from the queue.\r
 \r
-  @param  KeyboardBuffer     Points to the USB Keyboard Buffer.\r
-  @param  UsbKey             Points to the buffer that contains a usb key code.\r
+  @param  Queue     Points to the queue.\r
+  @param  Item      Receives the item.\r
+  @param  ItemSize  Size of the item.\r
 \r
-  @retval EFI_SUCCESS        Success\r
-  @retval EFI_DEVICE_ERROR   Hardware Error\r
+  @retval EFI_SUCCESS        Item was successfully dequeued.\r
+  @retval EFI_DEVICE_ERROR   The queue is empty.\r
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
-RemoveKeyCode (\r
-  IN OUT  USB_KB_BUFFER *KeyboardBuffer,\r
-  OUT     USB_KEY       *UsbKey\r
+Dequeue (\r
+  IN OUT  USB_SIMPLE_QUEUE *Queue,\r
+     OUT  VOID             *Item,\r
+  IN      UINTN            ItemSize\r
   )\r
 {\r
-  if (IsUSBKeyboardBufferEmpty (KeyboardBuffer)) {\r
+  ASSERT (Queue->ItemSize == ItemSize);\r
+\r
+  if (IsQueueEmpty (Queue)) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  UsbKey->KeyCode = KeyboardBuffer->buffer[KeyboardBuffer->bHead].KeyCode;\r
-  UsbKey->Down    = KeyboardBuffer->buffer[KeyboardBuffer->bHead].Down;\r
+  CopyMem (Item, Queue->Buffer[Queue->Head], ItemSize);\r
 \r
   //\r
-  // adjust the head pointer of the FIFO keyboard buffer.\r
+  // Adjust the head pointer of the FIFO keyboard buffer.\r
   //\r
-  KeyboardBuffer->bHead = (UINT8) ((KeyboardBuffer->bHead + 1) % (MAX_KEY_ALLOWED + 1));\r
+  Queue->Head = (Queue->Head + 1) % (MAX_KEY_ALLOWED + 1);\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
 \r
 /**\r
-  Sets USB Keyboard LED state.\r
+  Sets USB keyboard LED state.\r
 \r
   @param  UsbKeyboardDevice  The USB_KB_DEV instance.\r
 \r
-  @retval EFI_SUCCESS        Success\r
-\r
 **/\r
-EFI_STATUS\r
-EFIAPI\r
+VOID\r
 SetKeyLED (\r
   IN  USB_KB_DEV    *UsbKeyboardDevice\r
   )\r
@@ -1818,14 +1869,14 @@ SetKeyLED (
   //\r
   // Set each field in Led map.\r
   //\r
-  Led.NumLock    = (UINT8) UsbKeyboardDevice->NumLockOn;\r
-  Led.CapsLock   = (UINT8) UsbKeyboardDevice->CapsOn;\r
-  Led.ScrollLock = (UINT8) UsbKeyboardDevice->ScrollOn;\r
+  Led.NumLock    = (UINT8) ((UsbKeyboardDevice->NumLockOn) ? 1 : 0);\r
+  Led.CapsLock   = (UINT8) ((UsbKeyboardDevice->CapsOn) ? 1 : 0);\r
+  Led.ScrollLock = (UINT8) ((UsbKeyboardDevice->ScrollOn) ? 1 : 0);\r
   Led.Resrvd     = 0;\r
 \r
   ReportId       = 0;\r
   //\r
-  // call Set Report Request to lighten the LED.\r
+  // Call Set_Report Request to lighten the LED.\r
   //\r
   UsbSetReportRequest (\r
     UsbKeyboardDevice->UsbIo,\r
@@ -1835,18 +1886,21 @@ SetKeyLED (
     1,\r
     (UINT8 *) &Led\r
     );\r
-\r
-  return EFI_SUCCESS;\r
 }\r
 \r
 \r
 /**\r
-  Timer handler for Repeat Key timer.\r
+  Handler for Repeat Key event.\r
+\r
+  This function is the handler for Repeat Key event triggered\r
+  by timer.\r
+  After a repeatable key is pressed, the event would be triggered\r
+  with interval of USBKBD_REPEAT_DELAY. Once the event is triggered,\r
+  following trigger will come with interval of USBKBD_REPEAT_RATE.\r
 \r
   @param  Event              The Repeat Key event.\r
   @param  Context            Points to the USB_KB_DEV instance.\r
 \r
-\r
 **/\r
 VOID\r
 EFIAPI\r
@@ -1856,6 +1910,7 @@ USBKeyboardRepeatHandler (
   )\r
 {\r
   USB_KB_DEV  *UsbKeyboardDevice;\r
+  USB_KEY     UsbKey;\r
 \r
   UsbKeyboardDevice = (USB_KB_DEV *) Context;\r
 \r
@@ -1864,34 +1919,36 @@ USBKeyboardRepeatHandler (
   //\r
   if (UsbKeyboardDevice->RepeatKey != 0) {\r
     //\r
-    // Inserts one Repeat key into keyboard buffer,\r
+    // Inserts the repeat key into keyboard buffer,\r
     //\r
-    InsertKeyCode (\r
-      &(UsbKeyboardDevice->KeyboardBuffer),\r
-      UsbKeyboardDevice->RepeatKey,\r
-      1\r
-      );\r
+    UsbKey.KeyCode = UsbKeyboardDevice->RepeatKey;\r
+    UsbKey.Down    = TRUE;\r
+    Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));\r
 \r
     //\r
-    // set repeate rate for repeat key generation.\r
+    // Set repeat rate for next repeat key generation.\r
     //\r
     gBS->SetTimer (\r
-          UsbKeyboardDevice->RepeatTimer,\r
-          TimerRelative,\r
-          USBKBD_REPEAT_RATE\r
-          );\r
-\r
+           UsbKeyboardDevice->RepeatTimer,\r
+           TimerRelative,\r
+           USBKBD_REPEAT_RATE\r
+           );\r
   }\r
 }\r
 \r
 \r
 /**\r
-  Timer handler for Delayed Recovery timer.\r
+  Handler for Delayed Recovery event.\r
+\r
+  This function is the handler for Delayed Recovery event triggered\r
+  by timer.\r
+  After a device error occurs, the event would be triggered\r
+  with interval of EFI_USB_INTERRUPT_DELAY. EFI_USB_INTERRUPT_DELAY\r
+  is defined in USB standard for error handling.\r
 \r
   @param  Event              The Delayed Recovery event.\r
   @param  Context            Points to the USB_KB_DEV instance.\r
 \r
-\r
 **/\r
 VOID\r
 EFIAPI\r
@@ -1911,13 +1968,16 @@ USBKeyboardRecoveryHandler (
 \r
   PacketSize        = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize);\r
 \r
+  //\r
+  // Re-submit Asynchronous Interrupt Transfer for recovery.\r
+  //\r
   UsbIo->UsbAsyncInterruptTransfer (\r
-          UsbIo,\r
-          UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,\r
-          TRUE,\r
-          UsbKeyboardDevice->IntEndpointDescriptor.Interval,\r
-          PacketSize,\r
-          KeyboardHandler,\r
-          UsbKeyboardDevice\r
-          );\r
+           UsbIo,\r
+           UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,\r
+           TRUE,\r
+           UsbKeyboardDevice->IntEndpointDescriptor.Interval,\r
+           PacketSize,\r
+           KeyboardHandler,\r
+           UsbKeyboardDevice\r
+           );\r
 }\r