]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c
IntelFrameworkModulePkg Ps2KbDxe: Execute key notify func at TPL_CALLBACK
[mirror_edk2.git] / IntelFrameworkModulePkg / Csm / BiosThunk / KeyboardDxe / BiosKeyboard.c
index 06ef9d3345648e11824cbd2fc16ee18276b0f183..8dcb13177881cd51ba263df0a834376fb416f6a6 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   ConsoleOut Routines that speak VGA.\r
 \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
 \r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
@@ -279,19 +279,12 @@ BiosKeyboardDriverBindingStart (
   BiosKeyboardPrivate->SimpleTextInputEx.UnregisterKeyNotify = BiosKeyboardUnregisterKeyNotify;    \r
   InitializeListHead (&BiosKeyboardPrivate->NotifyList);\r
 \r
-  Status = gBS->HandleProtocol (\r
-                  Controller,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID **) &BiosKeyboardPrivate->DevicePath\r
-                  );\r
-\r
   //\r
   // Report that the keyboard is being enabled\r
   //\r
-  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+  REPORT_STATUS_CODE (\r
     EFI_PROGRESS_CODE,\r
-    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE,\r
-    BiosKeyboardPrivate->DevicePath\r
+    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE\r
     );\r
 \r
   //\r
@@ -350,10 +343,9 @@ BiosKeyboardDriverBindingStart (
   //\r
   // Report a Progress Code for an attempt to detect the precense of the keyboard device in the system\r
   //\r
-  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+  REPORT_STATUS_CODE (\r
     EFI_PROGRESS_CODE,\r
-    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT,\r
-    BiosKeyboardPrivate->DevicePath\r
+    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT\r
     );\r
 \r
   //\r
@@ -361,10 +353,10 @@ BiosKeyboardDriverBindingStart (
   //\r
   Status = BiosKeyboardPrivate->SimpleTextInputEx.Reset (\r
                                                     &BiosKeyboardPrivate->SimpleTextInputEx,\r
-                                                    FALSE\r
+                                                    FeaturePcdGet (PcdPs2KbdExtendedVerification)\r
                                                     );\r
-\r
   if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "[KBD]Reset Failed. Status - %r\n", Status));  \r
     StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;\r
     goto Done;\r
   }\r
@@ -436,6 +428,7 @@ BiosKeyboardDriverBindingStart (
       }\r
     }\r
   }\r
+  DEBUG ((EFI_D_INFO, "[KBD]Extended keystrokes supported by CSM16 - %02x\n", (UINTN)BiosKeyboardPrivate->ExtendedKeyboard));\r
   //\r
   // Install protocol interfaces for the keyboard device.\r
   //\r
@@ -453,10 +446,9 @@ Done:
     //\r
     // Report an Error Code for failing to start the keyboard device\r
     //\r
-    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    REPORT_STATUS_CODE (\r
       EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-      StatusCode,\r
-      BiosKeyboardPrivate->DevicePath\r
+      StatusCode\r
       );\r
   }\r
 \r
@@ -942,7 +934,7 @@ KeyboardReadKeyStrokeWorker (
   }\r
 \r
   //\r
-  // Use TimerEvent callback funciton to check whether there's any key pressed\r
+  // Use TimerEvent callback function to check whether there's any key pressed\r
   //\r
   \r
   //\r
@@ -986,7 +978,7 @@ KeyboardReadKeyStrokeWorker (
   @param  ExtendedVerification  Whether perform the extra validation of keyboard. True: perform; FALSE: skip.\r
 \r
   @retval EFI_SUCCESS           The command byte is written successfully.\r
-  @retval EFI_DEVICE_ERROR      Errors occurred during reseting keyboard.\r
+  @retval EFI_DEVICE_ERROR      Errors occurred during resetting keyboard.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1010,19 +1002,17 @@ BiosKeyboardReset (
   // 1\r
   // Report reset progress code\r
   //\r
-  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+  REPORT_STATUS_CODE (\r
     EFI_PROGRESS_CODE,\r
-    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET,\r
-    BiosKeyboardPrivate->DevicePath\r
+    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET\r
     );\r
 \r
   //\r
   // Report a Progress Code for clearing the keyboard buffer\r
   //\r
-  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+  REPORT_STATUS_CODE (\r
     EFI_PROGRESS_CODE,\r
-    EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER,\r
-    BiosKeyboardPrivate->DevicePath\r
+    EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER\r
     );\r
 \r
   //\r
@@ -1047,96 +1037,96 @@ BiosKeyboardReset (
   // if not skip step 4&5 and jump to step 6 to selftest KBC and report this\r
   // else   go step 4\r
   //\r
-  if ((KeyReadStatusRegister (BiosKeyboardPrivate) & KBC_STSREG_VIA64_SYSF) != 0) {\r
-    //\r
-    // 4\r
-    // CheckMouseStatus to decide enable it later or not\r
-    //\r
-    //\r
-    // Read the command byte of KBC\r
-    //\r
-    Status = KeyboardCommand (\r
-               BiosKeyboardPrivate,\r
-               KBC_CMDREG_VIA64_CMDBYTE_R\r
-               );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-\r
-    Status = KeyboardRead (\r
-               BiosKeyboardPrivate,\r
-               &CommandByte\r
-               );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-    //\r
-    // Check mouse enabled or not before\r
-    //\r
-    if ((CommandByte & KB_CMMBYTE_DISABLE_AUX) != 0) {\r
-      MouseEnable = FALSE;\r
+  if (!PcdGetBool (PcdFastPS2Detection)) {\r
+    if ((KeyReadStatusRegister (BiosKeyboardPrivate) & KBC_STSREG_VIA64_SYSF) != 0) {\r
+      //\r
+      // 4\r
+      // CheckMouseStatus to decide enable it later or not\r
+      //\r
+      //\r
+      // Read the command byte of KBC\r
+      //\r
+      Status = KeyboardCommand (\r
+                 BiosKeyboardPrivate,\r
+                 KBC_CMDREG_VIA64_CMDBYTE_R\r
+                 );\r
+      \r
+      if (EFI_ERROR (Status)) {\r
+        Status    = EFI_DEVICE_ERROR;\r
+        goto Exit;\r
+      }\r
+      \r
+      Status = KeyboardRead (\r
+                 BiosKeyboardPrivate,\r
+                 &CommandByte\r
+                 );\r
+      \r
+      if (EFI_ERROR (Status)) {\r
+        Status    = EFI_DEVICE_ERROR;\r
+        goto Exit;\r
+      }\r
+      //\r
+      // Check mouse enabled or not before\r
+      //\r
+      if ((CommandByte & KB_CMMBYTE_DISABLE_AUX) != 0) {\r
+        MouseEnable = FALSE;\r
+      } else {\r
+        MouseEnable = TRUE;\r
+      }\r
+      //\r
+      // 5\r
+      // disable mouse (via KBC) and Keyborad device\r
+      //\r
+      Status = KeyboardCommand (\r
+                 BiosKeyboardPrivate,\r
+                 KBC_CMDREG_VIA64_AUX_DISABLE\r
+                 );\r
+      \r
+      if (EFI_ERROR (Status)) {\r
+        Status    = EFI_DEVICE_ERROR;\r
+        goto Exit;\r
+      }\r
+      \r
+      Status = KeyboardCommand (\r
+                 BiosKeyboardPrivate,\r
+                 KBC_CMDREG_VIA64_KB_DISABLE\r
+                 );\r
+      \r
+      if (EFI_ERROR (Status)) {\r
+        Status    = EFI_DEVICE_ERROR;\r
+        goto Exit;\r
+      }\r
     } else {\r
-      MouseEnable = TRUE;\r
-    }\r
-    //\r
-    // 5\r
-    // disable mouse (via KBC) and Keyborad device\r
-    //\r
-    Status = KeyboardCommand (\r
-               BiosKeyboardPrivate,\r
-               KBC_CMDREG_VIA64_AUX_DISABLE\r
-               );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-\r
-    Status = KeyboardCommand (\r
-               BiosKeyboardPrivate,\r
-               KBC_CMDREG_VIA64_KB_DISABLE\r
-               );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-\r
-  } else {\r
-    //\r
-    // 6\r
-    // KBC Self Test\r
-    //\r
-    //\r
-    // Report a Progress Code for performing a self test on the keyboard controller\r
-    //\r
-    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-      EFI_PROGRESS_CODE,\r
-      EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST,\r
-      BiosKeyboardPrivate->DevicePath\r
-      );\r
-\r
-    Status = KeyboardCommand (\r
-               BiosKeyboardPrivate,\r
-               KBC_CMDREG_VIA64_KBC_SLFTEST\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-\r
-    Status = KeyboardWaitForValue (\r
-               BiosKeyboardPrivate,\r
-               KBC_CMDECHO_KBCSLFTEST_OK,\r
-               KEYBOARD_WAITFORVALUE_TIMEOUT\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
+      //\r
+      // 6\r
+      // KBC Self Test\r
+      //\r
+      //\r
+      // Report a Progress Code for performing a self test on the keyboard controller\r
+      //    \r
+      REPORT_STATUS_CODE (\r
+        EFI_PROGRESS_CODE,\r
+        EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST\r
+        );\r
+      \r
+      Status = KeyboardCommand (\r
+                 BiosKeyboardPrivate,\r
+                 KBC_CMDREG_VIA64_KBC_SLFTEST\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        Status    = EFI_DEVICE_ERROR;\r
+        goto Exit;\r
+      }\r
+      \r
+      Status = KeyboardWaitForValue (\r
+                 BiosKeyboardPrivate,\r
+                 KBC_CMDECHO_KBCSLFTEST_OK,\r
+                 KEYBOARD_WAITFORVALUE_TIMEOUT\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        Status    = EFI_DEVICE_ERROR;\r
+        goto Exit;\r
+      }\r
     }\r
   }\r
   //\r
@@ -1186,8 +1176,8 @@ BiosKeyboardReset (
              );\r
 \r
   //\r
-  // For reseting keyboard is not mandatory before booting OS and sometimes keyboard responses very slow,\r
-  // so we only do the real reseting for keyboard when user asks, and normally during booting an OS, it's skipped.\r
+  // For resetting keyboard is not mandatory before booting OS and sometimes keyboard responses very slow,\r
+  // so we only do the real resetting for keyboard when user asks, and normally during booting an OS, it's skipped.\r
   // Call CheckKeyboardConnect() to check whether keyboard is connected, if it is not connected,\r
   // Real reset will not do.\r
   //\r
@@ -1332,14 +1322,16 @@ BiosKeyboardReset (
   // Done for validating keyboard. Enable keyboard (via KBC)\r
   // and recover the command byte to proper value\r
   //\r
-  Status = KeyboardCommand (\r
-             BiosKeyboardPrivate,\r
-             KBC_CMDREG_VIA64_KB_ENABLE\r
-             );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    Status    = EFI_DEVICE_ERROR;\r
-    goto Exit;\r
+  if (!PcdGetBool (PcdFastPS2Detection)) {\r
+    Status = KeyboardCommand (\r
+               BiosKeyboardPrivate,\r
+               KBC_CMDREG_VIA64_KB_ENABLE\r
+               );\r
+    \r
+    if (EFI_ERROR (Status)) {\r
+      Status    = EFI_DEVICE_ERROR;\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   //\r
@@ -1397,6 +1389,17 @@ BiosKeyboardReadKeyStroke (
     return Status;\r
   }\r
 \r
+  //\r
+  // Convert the Ctrl+[a-z] to Ctrl+[1-26]\r
+  //\r
+  if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {\r
+    if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') {\r
+      KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'a' + 1);\r
+    } else if (KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') {\r
+      KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'A' + 1);\r
+    }\r
+  }\r
+\r
   CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));  \r
 \r
   return EFI_SUCCESS;\r
@@ -1428,7 +1431,7 @@ BiosKeyboardWaitForKey (
   //\r
   gBS->Stall (1000);\r
   //\r
-  // Use TimerEvent callback funciton to check whether there's any key pressed\r
+  // Use TimerEvent callback function to check whether there's any key pressed\r
   //\r
   BiosKeyboardTimerHandler (NULL, BIOS_KEYBOARD_DEV_FROM_THIS (Context));\r
 \r
@@ -1674,25 +1677,38 @@ CheckKeyboardConnect (
   // enable keyboard itself and wait for its ack\r
   // If can't receive ack, Keyboard should not be connected.\r
   //\r
-  Status = KeyboardWrite (\r
-             BiosKeyboardPrivate,\r
-             KBC_INPBUF_VIA60_KBEN\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    return FALSE;\r
-  }\r
+  if (!PcdGetBool (PcdFastPS2Detection)) {\r
+    Status = KeyboardWrite (\r
+               BiosKeyboardPrivate,\r
+               KBC_INPBUF_VIA60_KBEN\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "[KBD]CheckKeyboardConnect - Keyboard enable failed!\n"));\r
+      REPORT_STATUS_CODE (\r
+        EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+        EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR\r
+        );\r
+      return FALSE;\r
+    }\r
 \r
-  Status = KeyboardWaitForValue (\r
-             BiosKeyboardPrivate,\r
-             KBC_CMDECHO_ACK,\r
-             KEYBOARD_WAITFORVALUE_TIMEOUT\r
-             );\r
+    Status = KeyboardWaitForValue (\r
+               BiosKeyboardPrivate,\r
+               KBC_CMDECHO_ACK,\r
+               KEYBOARD_WAITFORVALUE_TIMEOUT\r
+               );\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    return FALSE;\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "[KBD]CheckKeyboardConnect - Timeout!\n"));\r
+      REPORT_STATUS_CODE (\r
+        EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+        EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR\r
+        );\r
+      return FALSE;\r
+    }\r
+    return TRUE;\r
+  } else {\r
+    return TRUE;\r
   }\r
-\r
-  return TRUE;\r
 }\r
 \r
 /**\r
@@ -1763,6 +1779,13 @@ BiosKeyboardTimerHandler (
 \r
   KeyData.Key.ScanCode            = (UINT16) Regs.H.AH;\r
   KeyData.Key.UnicodeChar         = (UINT16) Regs.H.AL;\r
+  DEBUG ((\r
+    EFI_D_INFO,\r
+    "[KBD]INT16 returns EFI_INPUT_KEY.ScanCode - %x, EFI_INPUT_KEY.UnicodeChar - %x\n",\r
+    KeyData.Key.ScanCode,\r
+    KeyData.Key.UnicodeChar\r
+    ));\r
+  \r
   KeyData.KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID;\r
   KeyData.KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
   //\r
@@ -1772,7 +1795,7 @@ BiosKeyboardTimerHandler (
   // will be disabled after the thunk call finish, which means if user crazy input during int 9 being disabled, some keystrokes will be lost when \r
   // KB device own hardware buffer overflows. And if the lost keystroke code is CTRL or ALT or SHIFT release code, these function key flags bit \r
   // in BDA will not be updated. So the Int 16 will believe the CTRL or ALT or SHIFT is still pressed, and Int 16 will translate later scancode \r
-  // to wrong ASCII code. We can increase the Thunk frequence to let Int 9 response in time, but this way will much hurt other dirvers \r
+  // to wrong ASCII code. We can increase the Thunk frequence to let Int 9 response in time, but this way will much hurt other drivers\r
   // performance, like USB.\r
   //\r
   // 1. If CTRL or ALT release code is missed,  all later input keys will be translated to wrong ASCII codes which the Tiano cannot support. In \r
@@ -1801,6 +1824,40 @@ BiosKeyboardTimerHandler (
   KbFlag1 = *((UINT8 *) (UINTN) 0x417);  // read the STATUS FLAGS 1\r
   KbFlag2 = *((UINT8 *) (UINTN) 0x418); // read STATUS FLAGS 2\r
 \r
+  DEBUG_CODE (\r
+    {\r
+      if ((KbFlag1 & KB_CAPS_LOCK_BIT) == KB_CAPS_LOCK_BIT) {\r
+        DEBUG ((EFI_D_INFO, "[KBD]Caps Lock Key is pressed.\n"));\r
+      }\r
+      if ((KbFlag1 & KB_NUM_LOCK_BIT) == KB_NUM_LOCK_BIT) {\r
+        DEBUG ((EFI_D_INFO, "[KBD]Num Lock Key is pressed.\n"));\r
+      }\r
+      if ((KbFlag1 & KB_SCROLL_LOCK_BIT) == KB_SCROLL_LOCK_BIT) {\r
+        DEBUG ((EFI_D_INFO, "[KBD]Scroll Lock Key is pressed.\n"));\r
+      } \r
+      if ((KbFlag1 & KB_ALT_PRESSED) == KB_ALT_PRESSED) {\r
+        if ((KbFlag2 & KB_LEFT_ALT_PRESSED) == KB_LEFT_ALT_PRESSED) {\r
+          DEBUG ((EFI_D_INFO, "[KBD]Left Alt Key is pressed.\n"));\r
+        } else {\r
+          DEBUG ((EFI_D_INFO, "[KBD]Right Alt Key is pressed.\n"));\r
+        }\r
+      }  \r
+      if ((KbFlag1 & KB_CTRL_PRESSED) == KB_CTRL_PRESSED) {\r
+        if ((KbFlag2 & KB_LEFT_CTRL_PRESSED) == KB_LEFT_CTRL_PRESSED) {\r
+          DEBUG ((EFI_D_INFO, "[KBD]Left Ctrl Key is pressed.\n"));\r
+        } else {\r
+          DEBUG ((EFI_D_INFO, "[KBD]Right Ctrl Key is pressed.\n"));\r
+        }\r
+      }  \r
+      if ((KbFlag1 & KB_LEFT_SHIFT_PRESSED) == KB_LEFT_SHIFT_PRESSED) {\r
+        DEBUG ((EFI_D_INFO, "[KBD]Left Shift Key is pressed.\n"));\r
+      }\r
+      if ((KbFlag1 & KB_RIGHT_SHIFT_PRESSED) == KB_RIGHT_SHIFT_PRESSED) {\r
+        DEBUG ((EFI_D_INFO, "[KBD]Right Shift Key is pressed.\n"));\r
+      }\r
+    }\r
+  );\r
+\r
   //\r
   // Record toggle state\r
   //\r
@@ -1864,6 +1921,13 @@ BiosKeyboardTimerHandler (
     }\r
   }\r
 \r
+  DEBUG ((\r
+    EFI_D_INFO,\r
+    "[KBD]Convert to EFI Scan Code, EFI_INPUT_KEY.ScanCode - %x, EFI_INPUT_KEY.UnicodeChar - %x\n",\r
+    KeyData.Key.ScanCode,\r
+    KeyData.Key.UnicodeChar\r
+    ));\r
+\r
   //\r
   // Need not return associated shift state if a class of printable characters that\r
   // are normally adjusted by shift modifiers.\r
@@ -1872,6 +1936,7 @@ BiosKeyboardTimerHandler (
   if ((KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') ||\r
       (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z')\r
      ) {\r
+    DEBUG ((EFI_D_INFO, "[KBD]Shift key with a~z are pressed, remove shift state in EFI_KEY_STATE.\n"));\r
     KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED);\r
   }\r
 \r
@@ -1890,16 +1955,6 @@ BiosKeyboardTimerHandler (
     }\r
   }\r
 \r
-  //\r
-  // Convert the Ctrl+[a-z] to Ctrl+[1-26]\r
-  //\r
-  if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {\r
-    if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') {\r
-      KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar - L'a' + 1);\r
-    } else if (KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') {\r
-      KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar - L'A' + 1);\r
-    }\r
-  }\r
   Enqueue (&BiosKeyboardPrivate->Queue, &KeyData);\r
   //\r
   // Leave critical section and return\r
@@ -2109,7 +2164,12 @@ BiosKeyboardSetState (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) {\r
+  //\r
+  // Thunk keyboard driver doesn't support partial keystroke.\r
+  //\r
+  if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID ||\r
+      (*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED\r
+      ) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -2142,15 +2202,18 @@ BiosKeyboardSetState (
 \r
   Status = KeyboardWrite (BiosKeyboardPrivate, 0xed);\r
   if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Exit;\r
   }  \r
   Status = KeyboardWaitForValue (BiosKeyboardPrivate, 0xfa, KEYBOARD_WAITFORVALUE_TIMEOUT);\r
   if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Exit;\r
   }\r
   Status = KeyboardWrite (BiosKeyboardPrivate, Command);\r
   if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Exit;\r
   }  \r
   //\r
   // Call Legacy BIOS Protocol to set whatever is necessary\r
@@ -2159,6 +2222,7 @@ BiosKeyboardSetState (
 \r
   Status = EFI_SUCCESS;\r
 \r
+Exit:\r
   //\r
   // Leave critical section and return\r
   //\r
@@ -2190,7 +2254,7 @@ BiosKeyboardRegisterKeyNotify (
   IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,\r
   IN EFI_KEY_DATA                       *KeyData,\r
   IN EFI_KEY_NOTIFY_FUNCTION            KeyNotificationFunction,\r
-  OUT EFI_HANDLE                        *NotifyHandle\r
+  OUT VOID                              **NotifyHandle\r
   )\r
 {\r
   EFI_STATUS                            Status;\r
@@ -2223,7 +2287,7 @@ BiosKeyboardRegisterKeyNotify (
                       );\r
     if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { \r
       if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
-        *NotifyHandle = CurrentNotify->NotifyHandle;        \r
+        *NotifyHandle = CurrentNotify;\r
         Status = EFI_SUCCESS;\r
         goto Exit;\r
       }\r
@@ -2242,11 +2306,10 @@ BiosKeyboardRegisterKeyNotify (
 \r
   NewNotify->Signature         = BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE;\r
   NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
-  NewNotify->NotifyHandle      = (EFI_HANDLE) NewNotify;\r
   CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));\r
   InsertTailList (&BiosKeyboardPrivate->NotifyList, &NewNotify->NotifyEntry);\r
 \r
-  *NotifyHandle                = NewNotify->NotifyHandle;  \r
+  *NotifyHandle                = NewNotify;\r
   Status                       = EFI_SUCCESS;\r
   \r
 Exit:\r
@@ -2271,7 +2334,7 @@ EFI_STATUS
 EFIAPI\r
 BiosKeyboardUnregisterKeyNotify (\r
   IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,\r
-  IN EFI_HANDLE                         NotificationHandle\r
+  IN VOID                               *NotificationHandle\r
   )\r
 {\r
   EFI_STATUS                            Status;\r
@@ -2296,7 +2359,7 @@ BiosKeyboardUnregisterKeyNotify (
   //\r
   // Enter critical section\r
   //\r
-  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);  \r
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
 \r
   for (Link = BiosKeyboardPrivate->NotifyList.ForwardLink; Link != &BiosKeyboardPrivate->NotifyList; Link = Link->ForwardLink) {\r
     CurrentNotify = CR (\r
@@ -2305,7 +2368,7 @@ BiosKeyboardUnregisterKeyNotify (
                       NotifyEntry, \r
                       BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
                       );    \r
-    if (CurrentNotify->NotifyHandle == NotificationHandle) {\r
+    if (CurrentNotify == NotificationHandle) {\r
       //\r
       // Remove the notification function from NotifyList and free resources\r
       //\r