]> 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 3acdd76187869575adbf2f4f33a4be97e950ca9e..b3b5fb9ff4c49136dcd679f28357592054ee1c94 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\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,126 +14,139 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "KeyBoard.h"\r
 \r
-//\r
-// Default English keyboard layout\r
-// Format:<efi key>, <unicode without shift>, <unicode with shift>, <Modifier>, <AffectedAttribute>\r
-//\r
-// According to Universal Serial Bus HID Usage Tables document ver 1.12,\r
-// a Boot Keyboard should support the keycode range from 0x0 to 0x65 and 0xE0 to 0xE7.\r
-// 0x0 to 0x3 are reserved for typical keyboard status or keyboard errors, so they are excluded.\r
-//\r
-UINT8 KeyboardLayoutTable[NUMBER_OF_VALID_USB_KEYCODE][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
+USB_KEYBOARD_LAYOUT_PACK_BIN  mUsbKeyboardLayoutBin = {\r
+  sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN),   // Binary size\r
+\r
+  //\r
+  // EFI_HII_PACKAGE_HEADER\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 Keycode 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
@@ -284,43 +297,70 @@ UINT8 ModifierValueToEfiScanCodeConvertionTable[] = {
   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
 /**\r
-  Initialize Key Convertion Table by using default keyboard layout.\r
+  Initialize Key Convention Table by using default keyboard layout.\r
 \r
   @param  UsbKeyboardDevice    The USB_KB_DEV instance.\r
 \r
+  @retval EFI_SUCCESS          The default keyboard layout was installed successfully\r
+  @retval Others               Failure to install default keyboard layout.\r
 **/\r
-VOID\r
-EFIAPI\r
-LoadDefaultKeyboardLayout (\r
-  IN OUT USB_KB_DEV                 *UsbKeyboardDevice\r
+EFI_STATUS\r
+InstallDefaultKeyboardLayout (\r
+   IN OUT USB_KB_DEV           *UsbKeyboardDevice\r
   )\r
 {\r
-  UINTN               Index;\r
-  EFI_KEY_DESCRIPTOR  *KeyDescriptor;\r
+  EFI_STATUS                   Status;\r
+  EFI_HII_DATABASE_PROTOCOL    *HiiDatabase;\r
+  EFI_HII_HANDLE               HiiHandle;\r
 \r
   //\r
-  // Construct KeyConvertionTable by default keyboard layout\r
+  // Locate Hii database protocol\r
   //\r
-  KeyDescriptor = &UsbKeyboardDevice->KeyConvertionTable[0];\r
-\r
-  for (Index = 0; Index < (NUMBER_OF_VALID_USB_KEYCODE); 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
+  Status = gBS->LocateProtocol (\r
+                  &gEfiHiiDatabaseProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &HiiDatabase\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
-    KeyDescriptor++;\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
 \r
@@ -331,7 +371,6 @@ LoadDefaultKeyboardLayout (
 \r
 **/\r
 BOOLEAN\r
-EFIAPI\r
 IsUSBKeyboard (\r
   IN  EFI_USB_IO_PROTOCOL       *UsbIo\r
   )\r
@@ -369,7 +408,6 @@ IsUSBKeyboard (
 \r
 **/\r
 EFI_HII_KEYBOARD_LAYOUT *\r
-EFIAPI\r
 GetCurrentKeyboardLayout (\r
   VOID\r
   )\r
@@ -413,7 +451,7 @@ GetCurrentKeyboardLayout (
                             KeyboardLayout\r
                             );\r
     if (EFI_ERROR (Status)) {\r
-      gBS->FreePool (KeyboardLayout);\r
+      FreePool (KeyboardLayout);\r
       KeyboardLayout = NULL;\r
     }\r
   }\r
@@ -432,7 +470,6 @@ GetCurrentKeyboardLayout (
 \r
 **/\r
 EFI_KEY_DESCRIPTOR *\r
-EFIAPI\r
 GetKeyDescriptor (\r
   IN USB_KB_DEV        *UsbKeyboardDevice,\r
   IN UINT8             KeyCode\r
@@ -470,24 +507,25 @@ GetKeyDescriptor (
 \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
@@ -509,7 +547,6 @@ FindUsbNsKey (
 \r
 **/\r
 EFI_KEY_DESCRIPTOR *\r
-EFIAPI\r
 FindPhysicalKey (\r
   IN USB_NS_KEY          *UsbNsKey,\r
   IN EFI_KEY_DESCRIPTOR  *KeyDescriptor\r
@@ -564,6 +601,9 @@ SetKeyboardLayoutEvent (
   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
@@ -595,13 +635,18 @@ SetKeyboardLayoutEvent (
     //\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
-      UsbNsKey = AllocatePool (sizeof (USB_NS_KEY));\r
+      UsbNsKey = AllocateZeroPool (sizeof (USB_NS_KEY));\r
       ASSERT (UsbNsKey != NULL);\r
 \r
       //\r
@@ -609,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
@@ -644,7 +689,7 @@ SetKeyboardLayoutEvent (
   KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, 0x28);\r
   CopyMem (TableEntry, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));\r
 \r
-  gBS->FreePool (KeyboardLayout);\r
+  FreePool (KeyboardLayout);\r
 }\r
 \r
 /**\r
@@ -654,7 +699,6 @@ SetKeyboardLayoutEvent (
 \r
 **/\r
 VOID\r
-EFIAPI\r
 ReleaseKeyboardLayoutResources (\r
   IN OUT USB_KB_DEV              *UsbKeyboardDevice\r
   )\r
@@ -693,7 +737,6 @@ ReleaseKeyboardLayoutResources (
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 InitKeyboardLayout (\r
   OUT USB_KB_DEV   *UsbKeyboardDevice\r
   )\r
@@ -717,7 +760,7 @@ InitKeyboardLayout (
                   TPL_NOTIFY,\r
                   SetKeyboardLayoutEvent,\r
                   UsbKeyboardDevice,\r
-                  &mKeyboardLayoutEventGuid,\r
+                  &gEfiHiiKeyBoardLayoutGuid,\r
                   &UsbKeyboardDevice->KeyboardLayoutEvent\r
                   );\r
   if (EFI_ERROR (Status)) {\r
@@ -743,9 +786,9 @@ InitKeyboardLayout (
     // If no keyboard layout can be retrieved from HII database, and default layout\r
     // is enabled, then load the default keyboard layout.\r
     //\r
-    LoadDefaultKeyboardLayout (UsbKeyboardDevice);\r
+    InstallDefaultKeyboardLayout (UsbKeyboardDevice);\r
   }\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -760,48 +803,58 @@ InitKeyboardLayout (
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 InitUSBKeyboard (\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
   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
+  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
-  ConfigValue = 0x01;\r
-  Status = UsbSetConfiguration (\r
+  Status = UsbGetConfiguration (\r
              UsbKeyboardDevice->UsbIo,\r
-             (UINT16) ConfigValue,\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
-    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-      PcdGet32 (PcdStatusCodeValueKeyboardInterfaceError),\r
-      UsbKeyboardDevice->DevicePath\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
@@ -812,7 +865,6 @@ InitUSBKeyboard (
   //\r
   // Set boot protocol for the USB Keyboard.\r
   // This driver only supports boot protocol.\r
-  // The device that does not support boot protocol is not supported.\r
   //\r
   if (Protocol != BOOT_PROTOCOL) {\r
     UsbSetProtocolRequest (\r
@@ -822,30 +874,13 @@ InitUSBKeyboard (
       );\r
   }\r
 \r
-  //\r
-  // ReportId is zero, which means the idle rate applies to all input reports.\r
-  //\r
-  ReportId = 0;\r
-  //\r
-  // Duration is zero, which means the duration is infinite.\r
-  // so the endpoint will inhibit reporting forever,\r
-  // and only reporting when a change is detected in the report data.\r
-  //\r
-  Duration = 0;\r
-  UsbSetIdleRequest (\r
-    UsbKeyboardDevice->UsbIo,\r
-    UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,\r
-    ReportId,\r
-    Duration\r
-    );\r
-\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
+\r
   UsbKeyboardDevice->LeftCtrlOn   = FALSE;\r
   UsbKeyboardDevice->LeftAltOn    = FALSE;\r
   UsbKeyboardDevice->LeftShiftOn  = FALSE;\r
@@ -869,33 +904,36 @@ InitUSBKeyboard (
   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 = 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 = 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
@@ -935,12 +973,10 @@ KeyboardHandler (
   UINT8               CurModifierMap;\r
   UINT8               OldModifierMap;\r
   UINT8               Mask;\r
-  UINT8               Index;\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
@@ -961,7 +997,7 @@ KeyboardHandler (
     //\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
@@ -986,7 +1022,7 @@ KeyboardHandler (
 \r
     //\r
     // Delete & Submit this interrupt again\r
-    // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt. \r
+    // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt.\r
     //\r
     UsbIo->UsbAsyncInterruptTransfer (\r
              UsbIo,\r
@@ -1068,8 +1104,9 @@ KeyboardHandler (
       // otherwise it is a non-zero value.\r
       // Insert the changed modifier key into key buffer.\r
       //\r
-      Down = (BOOLEAN) ((CurModifierMap & Mask) != 0);\r
-      InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), (UINT8) (0xe0 + Index), 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
@@ -1101,11 +1138,9 @@ KeyboardHandler (
     }\r
 \r
     if (KeyRelease) {\r
-      InsertKeyCode (\r
-        &(UsbKeyboardDevice->KeyboardBuffer),\r
-        OldKeyCodeBuffer[Index],\r
-        FALSE\r
-        );\r
+      UsbKey.KeyCode = OldKeyCodeBuffer[Index];\r
+      UsbKey.Down    = FALSE;\r
+      Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));\r
       //\r
       // The original repeat key is released.\r
       //\r
@@ -1153,12 +1188,18 @@ KeyboardHandler (
     }\r
 \r
     if (KeyPress) {\r
-      InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), CurKeyCodeBuffer[Index], TRUE);\r
+      UsbKey.KeyCode = CurKeyCodeBuffer[Index];\r
+      UsbKey.Down    = TRUE;\r
+      Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));\r
 \r
       //\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
@@ -1181,71 +1222,6 @@ KeyboardHandler (
     UsbKeyboardDevice->LastKeyCodeArray[Index] = CurKeyCodeBuffer[Index];\r
   }\r
 \r
-  //\r
-  // Pre-process KeyboardBuffer to check if Ctrl + Alt + Del is pressed.\r
-  //\r
-  SavedTail = UsbKeyboardDevice->KeyboardBuffer.BufferTail;\r
-  Index     = UsbKeyboardDevice->KeyboardBuffer.BufferHead;\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) {\r
-        UsbKeyboardDevice->CtrlOn = TRUE;\r
-      } else {\r
-        UsbKeyboardDevice->CtrlOn = FALSE;\r
-      }\r
-      break;\r
-\r
-    case EFI_LEFT_ALT_MODIFIER:\r
-    case EFI_RIGHT_ALT_MODIFIER:\r
-      if (UsbKey.Down) {\r
-        UsbKeyboardDevice->AltOn = TRUE;\r
-      } else {\r
-        UsbKeyboardDevice->AltOn = FALSE;\r
-      }\r
-      break;\r
-\r
-    case EFI_ALT_GR_MODIFIER:\r
-      if (UsbKey.Down) {\r
-        UsbKeyboardDevice->AltGrOn = TRUE;\r
-      } else {\r
-        UsbKeyboardDevice->AltGrOn = FALSE;\r
-      }\r
-      break;\r
-\r
-    //\r
-    // For Del Key, check if Ctrl + Alt + Del occurs for reset.\r
-    //\r
-    case EFI_DELETE_MODIFIER:\r
-      if (UsbKey.Down) {\r
-        if ((UsbKeyboardDevice->CtrlOn) && (UsbKeyboardDevice->AltOn)) {\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.BufferHead;\r
-\r
-  }\r
   //\r
   // If there is new key pressed, update the RepeatKey value, and set the\r
   // timer to repeate delay timer\r
@@ -1282,7 +1258,6 @@ KeyboardHandler (
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 USBParseKey (\r
   IN OUT  USB_KB_DEV  *UsbKeyboardDevice,\r
      OUT  UINT8       *KeyCode\r
@@ -1293,13 +1268,16 @@ USBParseKey (
 \r
   *KeyCode = 0;\r
 \r
-  while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice->KeyboardBuffer)) {\r
+  while (!IsQueueEmpty (&UsbKeyboardDevice->UsbKeyQueue)) {\r
     //\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 (KeyDescriptor == NULL) {\r
+      continue;\r
+    }\r
     if (!UsbKey.Down) {\r
       //\r
       // Key is released.\r
@@ -1396,12 +1374,10 @@ USBParseKey (
     case EFI_LEFT_CONTROL_MODIFIER:\r
       UsbKeyboardDevice->LeftCtrlOn = TRUE;\r
       UsbKeyboardDevice->CtrlOn = TRUE;\r
-      continue;\r
       break;\r
     case EFI_RIGHT_CONTROL_MODIFIER:\r
       UsbKeyboardDevice->RightCtrlOn = TRUE;\r
       UsbKeyboardDevice->CtrlOn = TRUE;\r
-      continue;\r
       break;\r
 \r
     //\r
@@ -1410,12 +1386,10 @@ USBParseKey (
     case EFI_LEFT_SHIFT_MODIFIER:\r
       UsbKeyboardDevice->LeftShiftOn = TRUE;\r
       UsbKeyboardDevice->ShiftOn = TRUE;\r
-      continue;\r
       break;\r
     case EFI_RIGHT_SHIFT_MODIFIER:\r
       UsbKeyboardDevice->RightShiftOn = TRUE;\r
       UsbKeyboardDevice->ShiftOn = TRUE;\r
-      continue;\r
       break;\r
 \r
     //\r
@@ -1424,12 +1398,10 @@ USBParseKey (
     case EFI_LEFT_ALT_MODIFIER:\r
       UsbKeyboardDevice->LeftAltOn = TRUE;\r
       UsbKeyboardDevice->AltOn = TRUE;\r
-      continue;\r
       break;\r
     case EFI_RIGHT_ALT_MODIFIER:\r
       UsbKeyboardDevice->RightAltOn = TRUE;\r
       UsbKeyboardDevice->AltOn = TRUE;\r
-      continue;\r
       break;\r
 \r
     //\r
@@ -1459,7 +1431,6 @@ USBParseKey (
     case EFI_PRINT_MODIFIER:\r
     case EFI_SYS_REQUEST_MODIFIER:\r
       UsbKeyboardDevice->SysReqOn = TRUE;\r
-      continue;\r
       break;\r
 \r
     //\r
@@ -1475,7 +1446,6 @@ USBParseKey (
       //\r
       UsbKeyboardDevice->NumLockOn = (BOOLEAN) (!(UsbKeyboardDevice->NumLockOn));\r
       SetKeyLED (UsbKeyboardDevice);\r
-      continue;\r
       break;\r
 \r
     case EFI_CAPS_LOCK_MODIFIER:\r
@@ -1484,7 +1454,6 @@ USBParseKey (
       //\r
       UsbKeyboardDevice->CapsOn = (BOOLEAN) (!(UsbKeyboardDevice->CapsOn));\r
       SetKeyLED (UsbKeyboardDevice);\r
-      continue;\r
       break;\r
 \r
     case EFI_SCROLL_LOCK_MODIFIER:\r
@@ -1493,21 +1462,6 @@ USBParseKey (
       //\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 SimpleTextInEx 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
@@ -1530,13 +1484,72 @@ USBParseKey (
   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 Keycode ranging from 0x4 to 0x65 to EFI_INPUT_KEY.\r
 \r
   @param  UsbKeyboardDevice     The USB_KB_DEV instance.\r
   @param  KeyCode               Indicates the key code that will be interpreted.\r
-  @param  Key                   A pointer to a buffer that is filled in with\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
@@ -1544,29 +1557,28 @@ USBParseKey (
   @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
 UsbKeyCodeToEfiInputKey (\r
-  IN  USB_KB_DEV      *UsbKeyboardDevice,\r
-  IN  UINT8           KeyCode,\r
-  OUT EFI_INPUT_KEY   *Key\r
+  IN  USB_KB_DEV                *UsbKeyboardDevice,\r
+  IN  UINT8                     KeyCode,\r
+  OUT EFI_KEY_DATA              *KeyData\r
   )\r
 {\r
-  EFI_KEY_DESCRIPTOR  *KeyDescriptor;\r
+  EFI_KEY_DESCRIPTOR            *KeyDescriptor;\r
+  LIST_ENTRY                    *Link;\r
+  LIST_ENTRY                    *NotifyList;\r
+  KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
 \r
   //\r
-  // KeyCode must in the range of 0x4 to 0x65\r
+  // KeyCode must in the range of  [0x4, 0x65] or [0xe0, 0xe7].\r
   //\r
-  if (!USBKBD_VALID_KEYCODE (KeyCode)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  if ((KeyCode - 4) >= NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
   KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, KeyCode);\r
+  if (KeyDescriptor == NULL) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
 \r
   if (KeyDescriptor->Modifier == EFI_NS_KEY_MODIFIER) {\r
     //\r
@@ -1585,261 +1597,256 @@ UsbKeyCodeToEfiInputKey (
     UsbKeyboardDevice->CurrentNsKey = NULL;\r
   }\r
 \r
-  Key->ScanCode = ModifierValueToEfiScanCodeConvertionTable[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)!= 0) {\r
     if (UsbKeyboardDevice->ShiftOn) {\r
-      Key->UnicodeChar = KeyDescriptor->ShiftedUnicode;\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) != 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) {\r
-        Key->UnicodeChar = KeyDescriptor->ShiftedAltGrUnicode;\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) {\r
-        Key->UnicodeChar = KeyDescriptor->AltGrUnicode;\r
+        KeyData->Key.UnicodeChar = KeyDescriptor->AltGrUnicode;\r
       }\r
     }\r
   }\r
 \r
   if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) != 0) {\r
     if (UsbKeyboardDevice->CapsOn) {\r
-      if (Key->UnicodeChar == KeyDescriptor->Unicode) {\r
-        Key->UnicodeChar = KeyDescriptor->ShiftedUnicode;\r
-      } else if (Key->UnicodeChar == KeyDescriptor->ShiftedUnicode) {\r
-        Key->UnicodeChar = KeyDescriptor->Unicode;\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\r
-  // (ctrl-a = 0x0001 through ctrl-Z = 0x001A)\r
-  //\r
-  if (UsbKeyboardDevice->CtrlOn) {\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
+  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
-      Key->ScanCode = SCAN_NULL;\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
   //\r
   // Not valid for key without both unicode key code and EFI Scan Code.\r
   //\r
-  if (Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) {\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) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->RightCtrlOn) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->LeftAltOn) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->RightAltOn) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->LeftShiftOn) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->RightShiftOn) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->LeftLogoOn) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->RightLogoOn) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->MenuKeyOn) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;\r
-  }\r
-  if (UsbKeyboardDevice->SysReqOn) {\r
-    UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;\r
-  }\r
+  InitializeKeyState (UsbKeyboardDevice, &KeyData->KeyState);\r
 \r
-  if (UsbKeyboardDevice->ScrollOn) {\r
-    UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
-  }\r
-  if (UsbKeyboardDevice->NumLockOn) {\r
-    UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;\r
-  }\r
-  if (UsbKeyboardDevice->CapsOn) {\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
+  Create the queue.\r
 \r
-  @param  KeyboardBuffer     Points to the USB keyboard buffer.\r
+  @param  Queue     Points to the queue.\r
+  @param  ItemSize  Size of the single item.\r
 \r
 **/\r
 VOID\r
-EFIAPI\r
-InitUSBKeyBuffer (\r
-  OUT  USB_KB_BUFFER   *KeyboardBuffer\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
+  Queue->ItemSize  = ItemSize;\r
+  Queue->Head      = 0;\r
+  Queue->Tail      = 0;\r
+\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
-  KeyboardBuffer->BufferHead = KeyboardBuffer->BufferTail;\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               Keyboard buffer is empty.\r
-  @retval FALSE              Keyboard 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
   //\r
-  return (BOOLEAN) (KeyboardBuffer->BufferHead == KeyboardBuffer->BufferTail);\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               Keyboard buffer is full.\r
-  @retval FALSE              Keyboard 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->BufferTail + 1) % (MAX_KEY_ALLOWED + 1)) == KeyboardBuffer->BufferHead);\r
+  return (BOOLEAN) (((Queue->Tail + 1) % (MAX_KEY_ALLOWED + 1)) == Queue->Head);\r
 }\r
 \r
 \r
 /**\r
-  Inserts a keycode into keyboard buffer.\r
-\r
-  @param  KeyboardBuffer     Points to the USB keyboard buffer.\r
-  @param  Key                Keycode to insert.\r
-  @param  Down               TRUE means key is pressed.\r
-                             FALSE means key is released.\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
 VOID\r
-EFIAPI\r
-InsertKeyCode (\r
-  IN OUT  USB_KB_BUFFER *KeyboardBuffer,\r
-  IN      UINT8         Key,\r
-  IN      BOOLEAN       Down\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
   // 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->BufferTail].KeyCode = Key;\r
-  KeyboardBuffer->Buffer[KeyboardBuffer->BufferTail].Down    = Down;\r
+  CopyMem (Queue->Buffer[Queue->Tail], Item, ItemSize);\r
 \r
   //\r
   // Adjust the tail pointer of the FIFO keyboard buffer.\r
   //\r
-  KeyboardBuffer->BufferTail = (UINT8) ((KeyboardBuffer->BufferTail + 1) % (MAX_KEY_ALLOWED + 1));\r
+  Queue->Tail = (Queue->Tail + 1) % (MAX_KEY_ALLOWED + 1);\r
 }\r
 \r
 \r
 /**\r
-  Remove a keycode from keyboard buffer and return it.\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 keycode for output.\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        Keycode successfully removed from keyboard buffer.\r
-  @retval EFI_DEVICE_ERROR   Keyboard buffer is empty.\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->BufferHead].KeyCode;\r
-  UsbKey->Down    = KeyboardBuffer->Buffer[KeyboardBuffer->BufferHead].Down;\r
+  CopyMem (Item, Queue->Buffer[Queue->Head], ItemSize);\r
 \r
   //\r
   // Adjust the head pointer of the FIFO keyboard buffer.\r
   //\r
-  KeyboardBuffer->BufferHead = (UINT8) ((KeyboardBuffer->BufferHead + 1) % (MAX_KEY_ALLOWED + 1));\r
+  Queue->Head = (Queue->Head + 1) % (MAX_KEY_ALLOWED + 1);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -1852,7 +1859,6 @@ RemoveKeyCode (
 \r
 **/\r
 VOID\r
-EFIAPI\r
 SetKeyLED (\r
   IN  USB_KB_DEV    *UsbKeyboardDevice\r
   )\r
@@ -1904,6 +1910,7 @@ USBKeyboardRepeatHandler (
   )\r
 {\r
   USB_KB_DEV  *UsbKeyboardDevice;\r
+  USB_KEY     UsbKey;\r
 \r
   UsbKeyboardDevice = (USB_KB_DEV *) Context;\r
 \r
@@ -1914,14 +1921,12 @@ USBKeyboardRepeatHandler (
     //\r
     // Inserts the repeat key into keyboard buffer,\r
     //\r
-    InsertKeyCode (\r
-      &(UsbKeyboardDevice->KeyboardBuffer),\r
-      UsbKeyboardDevice->RepeatKey,\r
-      TRUE\r
-      );\r
+    UsbKey.KeyCode = UsbKeyboardDevice->RepeatKey;\r
+    UsbKey.Down    = TRUE;\r
+    Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));\r
 \r
     //\r
-    // Set repeate rate for next repeat key generation.\r
+    // Set repeat rate for next repeat key generation.\r
     //\r
     gBS->SetTimer (\r
            UsbKeyboardDevice->RepeatTimer,\r