]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Fix the PS2 keyboard driver to call hotkey callback even no one is calling ReadKeyStroke
authorniruiyu <niruiyu@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 19 Apr 2011 06:53:29 +0000 (06:53 +0000)
committerniruiyu <niruiyu@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 19 Apr 2011 06:53:29 +0000 (06:53 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11564 6f19259b-4bc3-4df7-8a09-765794883524

IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c
IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c
IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c
IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h

index aadc1bf2aeadf4da709ac35769c490aa66e464c6..fa0f53b7422065aa6f30b752278af52b1de0c6b7 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Routines that access 8042 keyboard controller\r
 \r
 /** @file\r
   Routines that access 8042 keyboard controller\r
 \r
-Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2011, 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
 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
@@ -558,7 +558,6 @@ ConvertKeyboardScanCodeToEfiKey[] = {
   },\r
 };\r
 \r
   },\r
 };\r
 \r
-\r
 //\r
 // The WaitForValue time out\r
 //\r
 //\r
 // The WaitForValue time out\r
 //\r
@@ -566,6 +565,122 @@ UINTN  mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;
 \r
 BOOLEAN          mEnableMouseInterface;\r
 \r
 \r
 BOOLEAN          mEnableMouseInterface;\r
 \r
+\r
+\r
+/**\r
+  Return the count of scancode in the queue.\r
+  \r
+  @param Queue     Pointer to instance of SCAN_CODE_QUEUE.\r
+\r
+  @return          Count of the scancode.\r
+**/\r
+UINTN\r
+GetScancodeBufCount (\r
+  IN SCAN_CODE_QUEUE       *Queue\r
+  )\r
+{\r
+  if (Queue->Head <= Queue->Tail) {\r
+    return Queue->Tail - Queue->Head;\r
+  } else {\r
+    return Queue->Tail + KEYBOARD_SCAN_CODE_MAX_COUNT - Queue->Head;\r
+  }\r
+}\r
+\r
+/**\r
+  Read several bytes from the scancode buffer without removing them.\r
+  This function is called to see if there are enough bytes of scancode\r
+  representing a single key.\r
+  \r
+  @param Queue     Pointer to instance of SCAN_CODE_QUEUE.\r
+  @param Count     Number of bytes to be read\r
+  @param Buf       Store the results\r
+\r
+  @retval EFI_SUCCESS   success to scan the keyboard code\r
+  @retval EFI_NOT_READY invalid parameter\r
+**/\r
+EFI_STATUS\r
+GetScancodeBufHead (\r
+  IN  SCAN_CODE_QUEUE        *Queue,\r
+  IN  UINTN                  Count,\r
+  OUT UINT8                  *Buf\r
+  )\r
+{\r
+  UINTN                      Index;\r
+  UINTN                      Pos;\r
+\r
+  //\r
+  // check the valid range of parameter 'Count'\r
+  //\r
+  if (GetScancodeBufCount (Queue) < Count) {\r
+    return EFI_NOT_READY;\r
+  }\r
+  //\r
+  // retrieve the values\r
+  //\r
+  for (Index = 0, Pos = Queue->Head; Index < Count; Index++, Pos = (Pos + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT) {\r
+    Buf[Index] = Queue->Buffer[Pos];\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Push one byte to the scancode buffer.\r
+\r
+  @param Queue     Pointer to instance of SCAN_CODE_QUEUE.\r
+  @param Scancode  The byte to push.\r
+**/\r
+VOID\r
+PushScancodeBufTail (\r
+  IN  SCAN_CODE_QUEUE       *Queue,\r
+  IN  UINT8                 Scancode\r
+  )\r
+{\r
+  if (GetScancodeBufCount (Queue) == KEYBOARD_SCAN_CODE_MAX_COUNT - 1) {\r
+    return;\r
+  }\r
+\r
+  Queue->Buffer[Queue->Tail] = Scancode;\r
+  Queue->Tail = (Queue->Tail + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT;\r
+}\r
+\r
+/**\r
+\r
+  Read & remove several bytes from the scancode buffer.\r
+  This function is usually called after GetScancodeBufHead()\r
+  \r
+  @param Queue     Pointer to instance of SCAN_CODE_QUEUE.\r
+  @param Count     Number of bytes to be read\r
+  @param Buf       Store the results\r
+\r
+  @retval EFI_SUCCESS success to scan the keyboard code\r
+  @retval EFI_NOT_READY invalid parameter\r
+**/\r
+EFI_STATUS\r
+PopScancodeBufHead (\r
+  IN  SCAN_CODE_QUEUE       *Queue,\r
+  IN  UINTN                 Count,\r
+  OUT UINT8                 *Buf\r
+  )\r
+{\r
+  UINTN                     Index;\r
+\r
+  //\r
+  // Check the valid range of parameter 'Count'\r
+  //\r
+  if (GetScancodeBufCount (Queue) < Count) {\r
+    return EFI_NOT_READY;\r
+  }\r
+  //\r
+  // Retrieve and remove the values\r
+  //\r
+  for (Index = 0; Index < Count; Index++, Queue->Head = (Queue->Head + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT) {\r
+    Buf[Index] = Queue->Buffer[Queue->Head];\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Read data register .\r
 \r
 /**\r
   Read data register .\r
 \r
@@ -611,23 +726,14 @@ KeyWriteDataRegister (
   IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
   IN UINT8                   Data\r
   )\r
   IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
   IN UINT8                   Data\r
   )\r
-\r
 {\r
 {\r
-  EFI_ISA_IO_PROTOCOL                 *IsaIo;\r
-\r
-  //\r
-  // Use IsaIo protocol to perform IO operations\r
-  //\r
-  IsaIo = ConsoleIn->IsaIo;\r
-\r
-  IsaIo->Io.Write (\r
-              IsaIo,\r
-              EfiIsaIoWidthUint8,\r
-              ConsoleIn->DataRegisterAddress,\r
-              1,\r
-              &Data\r
-              );\r
-\r
+  ConsoleIn->IsaIo->Io.Write (\r
+                         ConsoleIn->IsaIo,\r
+                         EfiIsaIoWidthUint8,\r
+                         ConsoleIn->DataRegisterAddress,\r
+                         1,\r
+                         &Data\r
+                         );\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -643,24 +749,15 @@ KeyReadStatusRegister (
   IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
   )\r
 {\r
   IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
   )\r
 {\r
-  EFI_ISA_IO_PROTOCOL                 *IsaIo;\r
   UINT8                               Data;\r
   UINT8                               Data;\r
-\r
-  //\r
-  // Use IsaIo protocol to perform IO operations\r
-  //\r
-  IsaIo = ConsoleIn->IsaIo;\r
-\r
-  IsaIo->Io.Read (\r
-              IsaIo,\r
-              EfiIsaIoWidthUint8,\r
-              ConsoleIn->StatusRegisterAddress,\r
-              1,\r
-              &Data\r
-              );\r
-\r
+  ConsoleIn->IsaIo->Io.Read (\r
+                         ConsoleIn->IsaIo,\r
+                         EfiIsaIoWidthUint8,\r
+                         ConsoleIn->StatusRegisterAddress,\r
+                         1,\r
+                         &Data\r
+                         );\r
   return Data;\r
   return Data;\r
-\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -676,21 +773,13 @@ KeyWriteCommandRegister (
   IN UINT8                   Data\r
   )\r
 {\r
   IN UINT8                   Data\r
   )\r
 {\r
-  EFI_ISA_IO_PROTOCOL                 *IsaIo;\r
-\r
-  //\r
-  // Use IsaIo protocol to perform IO operations\r
-  //\r
-  IsaIo = ConsoleIn->IsaIo;\r
-\r
-  IsaIo->Io.Write (\r
-              IsaIo,\r
-              EfiIsaIoWidthUint8,\r
-              ConsoleIn->CommandRegisterAddress,\r
-              1,\r
-              &Data\r
-              );\r
-\r
+  ConsoleIn->IsaIo->Io.Write (\r
+                         ConsoleIn->IsaIo,\r
+                         EfiIsaIoWidthUint8,\r
+                         ConsoleIn->CommandRegisterAddress,\r
+                         1,\r
+                         &Data\r
+                         );\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -732,7 +821,7 @@ KeyboardTimerHandler (
   EFI_TPL                 OldTpl;\r
   KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
 \r
   EFI_TPL                 OldTpl;\r
   KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
 \r
-  ConsoleIn = Context;\r
+  ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context;\r
 \r
   //\r
   // Enter critical section\r
 \r
   //\r
   // Enter critical section\r
@@ -749,182 +838,27 @@ KeyboardTimerHandler (
 \r
   //\r
   // To let KB driver support Hot plug, here should skip the 'resend' command  for the case that\r
 \r
   //\r
   // To let KB driver support Hot plug, here should skip the 'resend' command  for the case that\r
-  // KB is not connected to system. If KB is not connected to system, driver will find there's  something\r
-  // error in the following code and wait for the input buffer empty, this waiting time shoulb be  short enough since\r
+  // KB is not connected to system. If KB is not connected to system, driver will find there's something\r
+  // error in the following code and wait for the input buffer empty, this waiting time shoulb be short enough since\r
   // this is a NOTIFY TPL period function, or the system performance will degrade hardly when KB is not connected.\r
   // Just skip the 'resend' process simply.\r
   //\r
 \r
   // this is a NOTIFY TPL period function, or the system performance will degrade hardly when KB is not connected.\r
   // Just skip the 'resend' process simply.\r
   //\r
 \r
-  Data = 0;\r
-\r
-  //\r
-  // if there is no key present, just return\r
-  //\r
-  if ((KeyReadStatusRegister (Context) & (KEYBOARD_STATUS_REGISTER_TRANSMIT_TIMEOUT|KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA)) != KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA) {\r
+  while ((KeyReadStatusRegister (ConsoleIn) & (KEYBOARD_STATUS_REGISTER_TRANSMIT_TIMEOUT|KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA)) ==\r
+      KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA\r
+     ) {\r
     //\r
     //\r
-    // Leave critical section and return\r
+    // Read one byte of the scan code and store it into the memory buffer\r
     //\r
     //\r
-    gBS->RestoreTPL (OldTpl);\r
-\r
-    return ;\r
+    Data = KeyReadDataRegister (ConsoleIn);\r
+    PushScancodeBufTail (&ConsoleIn->ScancodeQueue, Data);\r
   }\r
   }\r
-  //\r
-  // Read one byte of the scan code and store it into the memory buffer\r
-  //\r
-  if (ConsoleIn->ScancodeBufCount < KEYBOARD_BUFFER_MAX_COUNT) {\r
-\r
-    Data = KeyReadDataRegister (Context);\r
-    //\r
-    // put the scancode into the memory scancode buffer\r
-    //\r
-    ConsoleIn->ScancodeBufCount++;\r
-    ConsoleIn->ScancodeBufEndPos++;\r
-    if (ConsoleIn->ScancodeBufEndPos >= KEYBOARD_BUFFER_MAX_COUNT) {\r
-      ConsoleIn->ScancodeBufEndPos = 0;\r
-    }\r
+  KeyGetchar (ConsoleIn);\r
 \r
 \r
-    ConsoleIn->ScancodeBuf[ConsoleIn->ScancodeBufEndPos] = Data;\r
-\r
-    //\r
-    // Handle Alt+Ctrl+Del Key combination\r
-    //\r
-    switch (Data) {\r
-    case SCANCODE_CTRL_MAKE:\r
-      ConsoleIn->Ctrled = TRUE;\r
-      break;\r
-\r
-    case SCANCODE_CTRL_BREAK:\r
-      ConsoleIn->Ctrled = FALSE;\r
-      break;\r
-\r
-    case SCANCODE_ALT_MAKE:\r
-      ConsoleIn->Alted = TRUE;\r
-      break;\r
-\r
-    case SCANCODE_ALT_BREAK:\r
-      ConsoleIn->Alted = FALSE;\r
-      break;\r
-    }\r
-    //\r
-    // if Alt+Ctrl+Del, Reboot the System\r
-    //\r
-    if (ConsoleIn->Ctrled && ConsoleIn->Alted && Data == 0x53) {\r
-      gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
-    }\r
-  }\r
   //\r
   // Leave critical section and return\r
   //\r
   gBS->RestoreTPL (OldTpl);\r
   //\r
   // Leave critical section and return\r
   //\r
   gBS->RestoreTPL (OldTpl);\r
-\r
-  return ;\r
-}\r
-\r
-/**\r
-  Read several bytes from the scancode buffer without removing them.\r
-  This function is called to see if there are enough bytes of scancode\r
-  representing a single key.\r
-\r
-  @param ConsoleIn  Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
-  @param Count      Number of bytes to be read\r
-  @param Buf        Store the results\r
-\r
-  @retval EFI_SUCCESS success to scan the keyboard code\r
-  @retval EFI_NOT_READY invalid parameter\r
-**/\r
-EFI_STATUS\r
-GetScancodeBufHead (\r
-  KEYBOARD_CONSOLE_IN_DEV    *ConsoleIn,\r
-  IN UINT32                  Count,\r
-  OUT UINT8                  *Buf\r
-  )\r
-{\r
-  UINT32  Index;\r
-  UINT32  Pos;\r
-\r
-  Index = 0;\r
-  Pos   = 0;\r
-\r
-  //\r
-  // check the valid range of parameter 'Count'\r
-  //\r
-  if (Count <= 0 || ConsoleIn->ScancodeBufCount < Count) {\r
-    return EFI_NOT_READY;\r
-  }\r
-  //\r
-  // retrieve the values\r
-  //\r
-  for (Index = 0; Index < Count; Index++) {\r
-\r
-    if (Index == 0) {\r
-\r
-      Pos = ConsoleIn->ScancodeBufStartPos;\r
-    } else {\r
-\r
-      Pos = Pos + 1;\r
-      if (Pos >= KEYBOARD_BUFFER_MAX_COUNT) {\r
-        Pos = 0;\r
-      }\r
-    }\r
-\r
-    Buf[Index] = ConsoleIn->ScancodeBuf[Pos];\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-\r
-  Read & remove several bytes from the scancode buffer.\r
-  This function is usually called after GetScancodeBufHead()\r
-\r
-  @param ConsoleIn  Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
-  @param Count      Number of bytes to be read\r
-  @param Buf        Store the results\r
-\r
-  @retval EFI_SUCCESS success to scan the keyboard code\r
-  @retval EFI_NOT_READY invalid parameter\r
-**/\r
-EFI_STATUS\r
-PopScancodeBufHead (\r
-  KEYBOARD_CONSOLE_IN_DEV   *ConsoleIn,\r
-  IN UINT32                 Count,\r
-  OUT UINT8                 *Buf\r
-  )\r
-{\r
-  UINT32  Index;\r
-\r
-  Index = 0;\r
-\r
-  //\r
-  // Check the valid range of parameter 'Count'\r
-  //\r
-  if (Count <= 0 || ConsoleIn->ScancodeBufCount < Count) {\r
-    return EFI_NOT_READY;\r
-  }\r
-  //\r
-  // Retrieve and remove the values\r
-  //\r
-  for (Index = 0; Index < Count; Index++) {\r
-\r
-    if (Index != 0) {\r
-\r
-      ConsoleIn->ScancodeBufStartPos++;\r
-      if (ConsoleIn->ScancodeBufStartPos >= KEYBOARD_BUFFER_MAX_COUNT) {\r
-        ConsoleIn->ScancodeBufStartPos = 0;\r
-      }\r
-    }\r
-\r
-    Buf[Index] = ConsoleIn->ScancodeBuf[ConsoleIn->ScancodeBufStartPos];\r
-    ConsoleIn->ScancodeBufCount--;\r
-  }\r
-\r
-  ConsoleIn->ScancodeBufStartPos++;\r
-  if (ConsoleIn->ScancodeBufStartPos >= KEYBOARD_BUFFER_MAX_COUNT) {\r
-    ConsoleIn->ScancodeBufStartPos = 0;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -1205,115 +1139,55 @@ UpdateStatusLights (
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
-  Get scancode from scancode buffer\r
-  and translate into EFI-scancode and unicode defined by EFI spec\r
-  The function is always called in TPL_NOTIFY\r
+  Get scancode from scancode buffer and translate into EFI-scancode and unicode defined by EFI spec.\r
 \r
 \r
-  @param ConsoleIn KEYBOARD_CONSOLE_IN_DEV instance pointer\r
+  The function is always called in TPL_NOTIFY.\r
 \r
 \r
-  @retval EFI_NOT_READY  Input from console not ready yet.\r
-  @retval EFI_SUCCESS    Function executed successfully.\r
+  @param ConsoleIn KEYBOARD_CONSOLE_IN_DEV instance pointer\r
 \r
 **/\r
 \r
 **/\r
-EFI_STATUS\r
+VOID\r
 KeyGetchar (\r
   IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
   )\r
 {\r
 KeyGetchar (\r
   IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-  UINT8       ScanCode;\r
-  UINT8       Readed;\r
-  BOOLEAN     Extended;\r
-  UINT8       ScancodeArr[4];\r
-  UINTN       Index;\r
+  EFI_STATUS                     Status;\r
+  UINT8                          ScanCode;\r
+  BOOLEAN                        Extended;\r
+  UINTN                          Index;\r
+  EFI_KEY_DATA                   KeyData;\r
+  LIST_ENTRY                     *Link;\r
+  KEYBOARD_CONSOLE_IN_EX_NOTIFY  *CurrentNotify;\r
   //\r
   // 4 bytes most\r
   //\r
   //\r
   // 4 bytes most\r
   //\r
-  UINT32      ScancodeArrPos;\r
+  UINT8                          ScancodeArr[4];\r
+  UINT32                         ScancodeArrPos;\r
   //\r
   // point to the current position in ScancodeArr\r
   //\r
 \r
   //\r
   // point to the current position in ScancodeArr\r
   //\r
 \r
-  Readed          = 0;\r
   Extended        = FALSE;\r
   ScancodeArrPos  = 0;\r
   Extended        = FALSE;\r
   ScancodeArrPos  = 0;\r
-\r
-  //\r
-  // Read one byte of the scan code and store it into the memory buffer\r
-  // This block of code is added to insert an action that is equivalent to\r
-  // the timer event handling function, so as to increase the frequency of\r
-  // detecting the availability of keys. Timer event has a max frequency of\r
-  // 18Hz which is insufficient\r
-  //\r
-  //\r
-  // To let KB driver support Hot plug, here should skip the 'resend' command  for the case that\r
-  // KB is not connected to system. If KB is not connected to system, driver will find there's  something\r
-  // error in the following code and wait for the input buffer empty, this waiting time shoulb be  short enough since\r
-  // this is a NOTIFY TPL period function, or the system performance will degrade hardly when KB is not connected.\r
-  // Just skip the 'resend' process simply.\r
-  //\r
-\r
-\r
-  if (((KeyReadStatusRegister (ConsoleIn) & 0x21) == 0x1) && (ConsoleIn->ScancodeBufCount < KEYBOARD_BUFFER_MAX_COUNT)) {\r
-\r
-    Readed = KeyReadDataRegister (ConsoleIn);\r
-    //\r
-    // put the scancode into the memory scancode buffer\r
-    //\r
-    ConsoleIn->ScancodeBufCount++;\r
-    ConsoleIn->ScancodeBufEndPos++;\r
-    if (ConsoleIn->ScancodeBufEndPos >= KEYBOARD_BUFFER_MAX_COUNT) {\r
-      ConsoleIn->ScancodeBufEndPos = 0;\r
-    }\r
-\r
-    ConsoleIn->ScancodeBuf[ConsoleIn->ScancodeBufEndPos] = Readed;\r
-\r
-    //\r
-    // Handle Alt+Ctrl+Del Key combination\r
-    //\r
-    switch (Readed) {\r
-\r
-    case SCANCODE_CTRL_MAKE:\r
-      ConsoleIn->Ctrled = TRUE;\r
-      break;\r
-\r
-    case SCANCODE_CTRL_BREAK:\r
-      ConsoleIn->Ctrled = FALSE;\r
-      break;\r
-\r
-    case SCANCODE_ALT_MAKE:\r
-      ConsoleIn->Alted = TRUE;\r
-      break;\r
-\r
-    case SCANCODE_ALT_BREAK:\r
-      ConsoleIn->Alted = FALSE;\r
-      break;\r
-    }\r
-    //\r
-    // if Alt+Ctrl+Del, Reboot the System\r
-    //\r
-    if (ConsoleIn->Ctrled && ConsoleIn->Alted && Readed == 0x53) {\r
-      gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
-    }\r
-  }\r
+  \r
   //\r
   // Check if there are enough bytes of scancode representing a single key\r
   // available in the buffer\r
   //\r
   while (TRUE) {\r
 \r
   //\r
   // Check if there are enough bytes of scancode representing a single key\r
   // available in the buffer\r
   //\r
   while (TRUE) {\r
 \r
-    Status          = GetScancodeBufHead (ConsoleIn, 1, ScancodeArr);\r
-    ScancodeArrPos  = 0;\r
+    Status            = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, 1, ScancodeArr);\r
+    ScancodeArrPos    = 0;\r
     if (EFI_ERROR (Status)) {\r
     if (EFI_ERROR (Status)) {\r
-      return EFI_NOT_READY;\r
+      return ;\r
     }\r
 \r
     if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED) {\r
       Extended        = TRUE;\r
     }\r
 \r
     if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED) {\r
       Extended        = TRUE;\r
-      Status          = GetScancodeBufHead (ConsoleIn, 2, ScancodeArr);\r
+      Status          = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, 2, ScancodeArr);\r
       ScancodeArrPos  = 1;\r
       if (EFI_ERROR (Status)) {\r
       ScancodeArrPos  = 1;\r
       if (EFI_ERROR (Status)) {\r
-        return EFI_NOT_READY;\r
+        return ;\r
       }\r
     }\r
     //\r
       }\r
     }\r
     //\r
@@ -1322,29 +1196,29 @@ KeyGetchar (
     //\r
     if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED1) {\r
 \r
     //\r
     if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED1) {\r
 \r
-      Status          = GetScancodeBufHead (ConsoleIn, 2, ScancodeArr);\r
+      Status          = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, 2, ScancodeArr);\r
       ScancodeArrPos  = 1;\r
 \r
       if (EFI_ERROR (Status)) {\r
       ScancodeArrPos  = 1;\r
 \r
       if (EFI_ERROR (Status)) {\r
-        return EFI_NOT_READY;\r
+        return ;\r
       }\r
 \r
       }\r
 \r
-      Status          = GetScancodeBufHead (ConsoleIn, 3, ScancodeArr);\r
+      Status          = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, 3, ScancodeArr);\r
       ScancodeArrPos  = 2;\r
 \r
       if (EFI_ERROR (Status)) {\r
       ScancodeArrPos  = 2;\r
 \r
       if (EFI_ERROR (Status)) {\r
-        return EFI_NOT_READY;\r
+        return ;\r
       }\r
 \r
       }\r
 \r
-      PopScancodeBufHead (ConsoleIn, 3, ScancodeArr);\r
-      return EFI_NOT_READY;\r
+      PopScancodeBufHead (&ConsoleIn->ScancodeQueue, 3, ScancodeArr);\r
+      return ;\r
     }\r
     //\r
     // if we reach this position, scancodes for a key is in buffer now,pop them\r
     //\r
     }\r
     //\r
     // if we reach this position, scancodes for a key is in buffer now,pop them\r
     //\r
-    Status = PopScancodeBufHead (ConsoleIn, ScancodeArrPos + 1, ScancodeArr);\r
+    Status = PopScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);\r
     if (EFI_ERROR (Status)) {\r
     if (EFI_ERROR (Status)) {\r
-      return EFI_NOT_READY;\r
+      return ;\r
     }\r
     //\r
     // store the last available byte, this byte of scancode will be checked\r
     }\r
     //\r
     // store the last available byte, this byte of scancode will be checked\r
@@ -1446,55 +1320,56 @@ KeyGetchar (
       break;\r
     }\r
   }\r
       break;\r
     }\r
   }\r
+\r
   //\r
   //\r
-  // Treat Numeric Key Pad "/" specially\r
+  // Handle Ctrl+Alt+Del hotkey\r
   //\r
   //\r
-  if (Extended && ScanCode == 0x35) {\r
-    ConsoleIn->Key.ScanCode     = SCAN_NULL;\r
-    ConsoleIn->Key.UnicodeChar  = L'/';\r
-    return EFI_SUCCESS;\r
+  if (ConsoleIn->Alt && ConsoleIn->Ctrl && ScanCode == SCANCODE_DELETE_MAKE) {\r
+    gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
   }\r
   }\r
+\r
+  KeyData.Key.ScanCode            = SCAN_NULL;\r
+  KeyData.Key.UnicodeChar         = CHAR_NULL;\r
+  KeyData.KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID;\r
+  KeyData.KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
+\r
   //\r
   //\r
-  // Convert Keyboard ScanCode into an EFI Key\r
+  // Treat Numeric Key Pad "/" specially\r
   //\r
   //\r
-  for (Index = 0; ConvertKeyboardScanCodeToEfiKey[Index].ScanCode != TABLE_END; Index += 1) {\r
-    if (ScanCode == ConvertKeyboardScanCodeToEfiKey[Index].ScanCode) {\r
-      ConsoleIn->Key.ScanCode = ConvertKeyboardScanCodeToEfiKey[Index].EfiScanCode;\r
-      if (ConsoleIn->Shift) {\r
-        ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar;\r
-        //\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 (ConsoleIn->Key.UnicodeChar >= L'A' && ConsoleIn->Key.UnicodeChar <= L'Z') {\r
+  if (Extended && ScanCode == 0x35) {\r
+    KeyData.Key.UnicodeChar = L'/';\r
+    KeyData.Key.ScanCode    = SCAN_NULL;\r
+  } else {\r
+    //\r
+    // Convert Keyboard ScanCode into an EFI Key\r
+    //\r
+    for (Index = 0; ConvertKeyboardScanCodeToEfiKey[Index].ScanCode != TABLE_END; Index += 1) {\r
+      if (ScanCode == ConvertKeyboardScanCodeToEfiKey[Index].ScanCode) {\r
+        KeyData.Key.ScanCode    = ConvertKeyboardScanCodeToEfiKey[Index].EfiScanCode;\r
+        KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;\r
+\r
+        if (ConsoleIn->Shift && \r
+            (ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar != ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar)) {\r
+          KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar;\r
+          //\r
+          // Need not return associated shift state if a class of printable characters that\r
+          // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'\r
+          //\r
           ConsoleIn->LeftShift  = FALSE;\r
           ConsoleIn->RightShift = FALSE;\r
         }\r
           ConsoleIn->LeftShift  = FALSE;\r
           ConsoleIn->RightShift = FALSE;\r
         }\r
-      } else {\r
-        ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;\r
-      }\r
-      //\r
-      // alphabetic key is affected by CapsLock State\r
-      //\r
-      if (ConsoleIn->CapsLock) {\r
-        if (ConsoleIn->Key.UnicodeChar >= L'a' && ConsoleIn->Key.UnicodeChar <= L'z') {\r
-          ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar;\r
-        } else if (ConsoleIn->Key.UnicodeChar >= L'A' && ConsoleIn->Key.UnicodeChar <= L'Z') {\r
-          ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;\r
-        }\r
-      }\r
-      //\r
-      // Translate the CTRL-Alpha characters to their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A)\r
-      //\r
-      if (ConsoleIn->Ctrled) {\r
-        if (ConsoleIn->Key.UnicodeChar >= L'a' && ConsoleIn->Key.UnicodeChar <= L'z') {\r
-          ConsoleIn->Key.UnicodeChar = (UINT16) (ConsoleIn->Key.UnicodeChar - L'a' + 1);\r
-        } else if (ConsoleIn->Key.UnicodeChar >= L'A' && ConsoleIn->Key.UnicodeChar <= L'Z') {\r
-          ConsoleIn->Key.UnicodeChar = (UINT16) (ConsoleIn->Key.UnicodeChar - L'A' + 1);\r
+        //\r
+        // alphabetic key is affected by CapsLock State\r
+        //\r
+        if (ConsoleIn->CapsLock) {\r
+          if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') {\r
+            KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar - L'a' + L'A');\r
+          } else if (KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') {\r
+            KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar - L'A' + L'a');\r
+          }\r
         }\r
         }\r
+        break;\r
       }\r
       }\r
-\r
-      break;\r
     }\r
   }\r
 \r
     }\r
   }\r
 \r
@@ -1502,58 +1377,83 @@ KeyGetchar (
   // distinguish numeric key pad keys' 'up symbol' and 'down symbol'\r
   //\r
   if (ScanCode >= 0x47 && ScanCode <= 0x53) {\r
   // distinguish numeric key pad keys' 'up symbol' and 'down symbol'\r
   //\r
   if (ScanCode >= 0x47 && ScanCode <= 0x53) {\r
-\r
     if (ConsoleIn->NumLock && !ConsoleIn->Shift && !Extended) {\r
     if (ConsoleIn->NumLock && !ConsoleIn->Shift && !Extended) {\r
-      ConsoleIn->Key.ScanCode = SCAN_NULL;\r
+      KeyData.Key.ScanCode = SCAN_NULL;\r
     } else if (ScanCode != 0x4a && ScanCode != 0x4e) {\r
     } else if (ScanCode != 0x4a && ScanCode != 0x4e) {\r
-      ConsoleIn->Key.UnicodeChar = 0x0000;\r
+      KeyData.Key.UnicodeChar = CHAR_NULL;\r
     }\r
   }\r
   //\r
   // If the key can not be converted then just return.\r
   //\r
     }\r
   }\r
   //\r
   // If the key can not be converted then just return.\r
   //\r
-  if (ConsoleIn->Key.ScanCode == SCAN_NULL && ConsoleIn->Key.UnicodeChar == 0x0000) {\r
-    return EFI_NOT_READY;\r
+  if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {\r
+    return ;\r
   }\r
 \r
   //\r
   // Save the Shift/Toggle state\r
   //\r
   if (ConsoleIn->Ctrl) {\r
   }\r
 \r
   //\r
   // Save the Shift/Toggle state\r
   //\r
   if (ConsoleIn->Ctrl) {\r
-    ConsoleIn->KeyState.KeyShiftState  |= (Extended) ? EFI_RIGHT_CONTROL_PRESSED : EFI_LEFT_CONTROL_PRESSED;\r
+    KeyData.KeyState.KeyShiftState  |= (Extended) ? EFI_RIGHT_CONTROL_PRESSED : EFI_LEFT_CONTROL_PRESSED;\r
   }                                    \r
   if (ConsoleIn->Alt) {                \r
   }                                    \r
   if (ConsoleIn->Alt) {                \r
-    ConsoleIn->KeyState.KeyShiftState  |= (Extended) ? EFI_RIGHT_ALT_PRESSED : EFI_LEFT_ALT_PRESSED;\r
+    KeyData.KeyState.KeyShiftState  |= (Extended) ? EFI_RIGHT_ALT_PRESSED : EFI_LEFT_ALT_PRESSED;\r
   }                                    \r
   if (ConsoleIn->LeftShift) {          \r
   }                                    \r
   if (ConsoleIn->LeftShift) {          \r
-    ConsoleIn->KeyState.KeyShiftState  |= EFI_LEFT_SHIFT_PRESSED;\r
+    KeyData.KeyState.KeyShiftState  |= EFI_LEFT_SHIFT_PRESSED;\r
   }                                    \r
   if (ConsoleIn->RightShift) {         \r
   }                                    \r
   if (ConsoleIn->RightShift) {         \r
-    ConsoleIn->KeyState.KeyShiftState  |= EFI_RIGHT_SHIFT_PRESSED;\r
+    KeyData.KeyState.KeyShiftState  |= EFI_RIGHT_SHIFT_PRESSED;\r
   }                                    \r
   if (ConsoleIn->LeftLogo) {           \r
   }                                    \r
   if (ConsoleIn->LeftLogo) {           \r
-    ConsoleIn->KeyState.KeyShiftState  |= EFI_LEFT_LOGO_PRESSED;\r
+    KeyData.KeyState.KeyShiftState  |= EFI_LEFT_LOGO_PRESSED;\r
   }                                    \r
   if (ConsoleIn->RightLogo) {          \r
   }                                    \r
   if (ConsoleIn->RightLogo) {          \r
-    ConsoleIn->KeyState.KeyShiftState  |= EFI_RIGHT_LOGO_PRESSED;\r
+    KeyData.KeyState.KeyShiftState  |= EFI_RIGHT_LOGO_PRESSED;\r
   }                                    \r
   if (ConsoleIn->Menu) {               \r
   }                                    \r
   if (ConsoleIn->Menu) {               \r
-    ConsoleIn->KeyState.KeyShiftState  |= EFI_MENU_KEY_PRESSED;\r
+    KeyData.KeyState.KeyShiftState  |= EFI_MENU_KEY_PRESSED;\r
   }                                    \r
   if (ConsoleIn->SysReq) {             \r
   }                                    \r
   if (ConsoleIn->SysReq) {             \r
-    ConsoleIn->KeyState.KeyShiftState  |= EFI_SYS_REQ_PRESSED;\r
+    KeyData.KeyState.KeyShiftState  |= EFI_SYS_REQ_PRESSED;\r
   }  \r
   if (ConsoleIn->CapsLock) {\r
   }  \r
   if (ConsoleIn->CapsLock) {\r
-    ConsoleIn->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
+    KeyData.KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
   }\r
   if (ConsoleIn->NumLock) {\r
   }\r
   if (ConsoleIn->NumLock) {\r
-    ConsoleIn->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;\r
+    KeyData.KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;\r
   }\r
   if (ConsoleIn->ScrollLock) {\r
   }\r
   if (ConsoleIn->ScrollLock) {\r
-    ConsoleIn->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
+    KeyData.KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
   }\r
 \r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  //\r
+  // Invoke notification functions if exist\r
+  //\r
+  for (Link = GetFirstNode (&ConsoleIn->NotifyList); !IsNull (&ConsoleIn->NotifyList, Link); Link = GetNextNode (&ConsoleIn->NotifyList, Link)) {\r
+    CurrentNotify = CR (\r
+                      Link, \r
+                      KEYBOARD_CONSOLE_IN_EX_NOTIFY, \r
+                      NotifyEntry, \r
+                      KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
+                      );\r
+    if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) { \r
+      CurrentNotify->KeyNotificationFn (&KeyData);\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 (ConsoleIn->Ctrl) {\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
+\r
+  PushEfikeyBufTail (&ConsoleIn->EfiKeyQueue, &KeyData);\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -1737,11 +1637,10 @@ InitKeyboard (
   //\r
   // Clear Memory Scancode Buffer\r
   //\r
   //\r
   // Clear Memory Scancode Buffer\r
   //\r
-  ConsoleIn->ScancodeBufStartPos  = 0;\r
-  ConsoleIn->ScancodeBufEndPos    = KEYBOARD_BUFFER_MAX_COUNT - 1;\r
-  ConsoleIn->ScancodeBufCount     = 0;\r
-  ConsoleIn->Ctrled               = FALSE;\r
-  ConsoleIn->Alted                = FALSE;\r
+  ConsoleIn->ScancodeQueue.Head = 0;\r
+  ConsoleIn->ScancodeQueue.Tail = 0;\r
+  ConsoleIn->EfiKeyQueue.Head   = 0;\r
+  ConsoleIn->EfiKeyQueue.Tail   = 0;\r
 \r
   //\r
   // Reset the status indicators\r
 \r
   //\r
   // Reset the status indicators\r
index 26f1ea3de42aed608f6d27bbab2ceb9f656bd6c0..eb3c9338ce80740d2c91f5cdd0f9650046e2393e 100644 (file)
@@ -2,7 +2,7 @@
   Routines implements SIMPLE_TEXT_IN protocol's interfaces based on 8042 interfaces\r
   provided by Ps2KbdCtrller.c.\r
 \r
   Routines implements SIMPLE_TEXT_IN protocol's interfaces based on 8042 interfaces\r
   provided by Ps2KbdCtrller.c.\r
 \r
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2011, 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
 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
@@ -17,29 +17,66 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include "Ps2Keyboard.h"\r
 \r
 /**\r
 #include "Ps2Keyboard.h"\r
 \r
 /**\r
-  Check keyboard for given key value.\r
+  Check whether the EFI key buffer is empty.\r
+\r
+  @param Queue     Pointer to instance of EFI_KEY_QUEUE.\r
+\r
+  @retval TRUE    The EFI key buffer is empty.\r
+  @retval FALSE   The EFI key buffer isn't empty.\r
+**/\r
+BOOLEAN\r
+IsEfikeyBufEmpty (\r
+  IN  EFI_KEY_QUEUE         *Queue\r
+  )\r
+{\r
+  return (BOOLEAN) (Queue->Head == Queue->Tail);\r
+}\r
+\r
+\r
+\r
+/**\r
+  Push one key data to the EFI key buffer.\r
+\r
+  @param Queue     Pointer to instance of EFI_KEY_QUEUE.\r
+  @param KeyData   The key data to push.\r
+**/\r
+VOID\r
+PushEfikeyBufTail (\r
+  IN  EFI_KEY_QUEUE         *Queue,\r
+  IN  EFI_KEY_DATA          *KeyData\r
+  )\r
+{\r
+  if ((Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT == Queue->Head) {\r
+    return;\r
+  }\r
   \r
   \r
-  @param  This  Point to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL\r
+  CopyMem (&Queue->Buffer[Queue->Tail], KeyData, sizeof (EFI_KEY_DATA));\r
+  Queue->Tail = (Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;\r
+}\r
+\r
+/**\r
+  Read & remove one key data from the EFI key buffer.\r
   \r
   \r
-  @retval EFI_SUCCESS   success check keyboard value\r
-  @retval !EFI_SUCCESS  Fail to get char from keyboard\r
+  @param Queue     Pointer to instance of EFI_KEY_QUEUE.\r
+  @param KeyData   Receive the key data.\r
+\r
+  @retval EFI_SUCCESS   The key data is popped successfully.\r
+  @retval EFI_NOT_READY There is no key data available.\r
 **/\r
 EFI_STATUS\r
 **/\r
 EFI_STATUS\r
-KeyboardCheckForKey (\r
-  IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This\r
+PopEfikeyBufHead (\r
+  IN  EFI_KEY_QUEUE         *Queue,\r
+  OUT EFI_KEY_DATA          *KeyData\r
   )\r
 {\r
   )\r
 {\r
-  KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
-\r
-  ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
-\r
+  if (IsEfikeyBufEmpty (Queue)) {\r
+    return EFI_NOT_READY;\r
+  }\r
   //\r
   //\r
-  // If ready to read next key, check it\r
+  // Retrieve and remove the values\r
   //\r
   //\r
-  if (ConsoleIn->Key.ScanCode == SCAN_NULL && ConsoleIn->Key.UnicodeChar == 0x00) {\r
-    return KeyGetchar (ConsoleIn);\r
-  }\r
-\r
+  CopyMem (KeyData, &Queue->Buffer[Queue->Head], sizeof (EFI_KEY_DATA));\r
+  Queue->Head = (Queue->Head + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;\r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -110,9 +147,6 @@ KeyboardReadKeyStrokeWorker (
 {\r
   EFI_STATUS                            Status;\r
   EFI_TPL                               OldTpl;\r
 {\r
   EFI_STATUS                            Status;\r
   EFI_TPL                               OldTpl;\r
-  LIST_ENTRY                            *Link;\r
-  KEYBOARD_CONSOLE_IN_EX_NOTIFY         *CurrentNotify;\r
-  EFI_KEY_DATA                          OriginalKeyData;\r
   \r
   if (KeyData == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   \r
   if (KeyData == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -123,58 +157,16 @@ KeyboardReadKeyStrokeWorker (
   //\r
   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
 \r
   //\r
   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
 \r
-  if (ConsoleInDev->KeyboardErr) {\r
-    gBS->RestoreTPL (OldTpl);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-  //\r
-  // If there's no key, just return\r
-  //\r
-  Status = KeyboardCheckForKey (&ConsoleInDev->ConIn);\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->RestoreTPL (OldTpl);\r
-    return EFI_NOT_READY;\r
-  }\r
+  KeyboardTimerHandler (NULL, ConsoleInDev);\r
   \r
   \r
-  CopyMem (&KeyData->Key, &ConsoleInDev->Key, sizeof (EFI_INPUT_KEY));\r
-\r
-  ConsoleInDev->Key.ScanCode    = SCAN_NULL;          \r
-  ConsoleInDev->Key.UnicodeChar = 0x0000;     \r
-  CopyMem (&KeyData->KeyState, &ConsoleInDev->KeyState, sizeof (EFI_KEY_STATE));\r
-                                          \r
-  ConsoleInDev->KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID;\r
-  ConsoleInDev->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
-  gBS->RestoreTPL (OldTpl);\r
-  //\r
-  //Switch the control value to their original characters. In KeyGetchar() the  CTRL-Alpha characters have been switched to \r
-  // their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A), here switch them back for notification function.\r
-  //\r
-  CopyMem (&OriginalKeyData, KeyData, sizeof (EFI_KEY_DATA));\r
-  if (ConsoleInDev->Ctrled) {\r
-    if (OriginalKeyData.Key.UnicodeChar >= 0x01 && OriginalKeyData.Key.UnicodeChar <= 0x1A) {\r
-      if (ConsoleInDev->CapsLock) {\r
-        OriginalKeyData.Key.UnicodeChar = (CHAR16)(OriginalKeyData.Key.UnicodeChar + L'A' - 1);\r
-      } else {\r
-        OriginalKeyData.Key.UnicodeChar = (CHAR16)(OriginalKeyData.Key.UnicodeChar + L'a' - 1);\r
-      } \r
-    }\r
-  }\r
-  //\r
-  // Invoke notification functions if exist\r
-  //\r
-  for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) {\r
-    CurrentNotify = CR (\r
-                      Link, \r
-                      KEYBOARD_CONSOLE_IN_EX_NOTIFY, \r
-                      NotifyEntry, \r
-                      KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
-                      );\r
-    if (IsKeyRegistered (&CurrentNotify->KeyData, &OriginalKeyData)) { \r
-      CurrentNotify->KeyNotificationFn (&OriginalKeyData);\r
-    }\r
+  if (ConsoleInDev->KeyboardErr) {\r
+    Status = EFI_DEVICE_ERROR;\r
+  } else {\r
+    Status = PopEfikeyBufHead (&ConsoleInDev->EfiKeyQueue, KeyData);\r
   }\r
 \r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  gBS->RestoreTPL (OldTpl);\r
+  return Status;\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -224,11 +216,6 @@ KeyboardEfiReset (
     gBS->RestoreTPL (OldTpl);\r
     return EFI_DEVICE_ERROR;\r
   }\r
     gBS->RestoreTPL (OldTpl);\r
     return EFI_DEVICE_ERROR;\r
   }\r
-  //\r
-  // Clear the status of ConsoleIn.Key\r
-  //\r
-  ConsoleIn->Key.ScanCode     = SCAN_NULL;\r
-  ConsoleIn->Key.UnicodeChar  = 0x0000;\r
 \r
   //\r
   // Leave critical section and return\r
 \r
   //\r
   // Leave critical section and return\r
@@ -304,36 +291,31 @@ KeyboardWaitForKey (
   IN  VOID                    *Context\r
   )\r
 {\r
   IN  VOID                    *Context\r
   )\r
 {\r
-  EFI_TPL                 OldTpl;\r
-  KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
+  EFI_TPL                     OldTpl;\r
+  KEYBOARD_CONSOLE_IN_DEV     *ConsoleIn;\r
 \r
 \r
-  ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (Context);\r
+  ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context;\r
 \r
   //\r
   // Enter critical section\r
   //\r
   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
 \r
   //\r
   // Enter critical section\r
   //\r
   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+  \r
+  KeyboardTimerHandler (NULL, ConsoleIn);\r
 \r
 \r
-  if (ConsoleIn->KeyboardErr) {\r
+  if (!ConsoleIn->KeyboardErr) {\r
     //\r
     //\r
-    // Leave critical section and return\r
+    // Someone is waiting on the keyboard event, if there's\r
+    // a key pending, signal the event\r
     //\r
     //\r
-    gBS->RestoreTPL (OldTpl);\r
-    return ;\r
-  }\r
-  //\r
-  // Someone is waiting on the keyboard event, if there's\r
-  // a key pending, signal the event\r
-  //\r
-  if (!EFI_ERROR (KeyboardCheckForKey (Context))) {\r
-    gBS->SignalEvent (Event);\r
+    if (!IsEfikeyBufEmpty (&ConsoleIn->EfiKeyQueue)) {\r
+      gBS->SignalEvent (Event);\r
+    }\r
   }\r
   //\r
   // Leave critical section and return\r
   //\r
   gBS->RestoreTPL (OldTpl);\r
   }\r
   //\r
   // Leave critical section and return\r
   //\r
   gBS->RestoreTPL (OldTpl);\r
-\r
-  return ;\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -352,11 +334,7 @@ KeyboardWaitForKeyEx (
   )\r
 \r
 {\r
   )\r
 \r
 {\r
-  KEYBOARD_CONSOLE_IN_DEV               *ConsoleInDev;\r
-\r
-  ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (Context); \r
-  KeyboardWaitForKey (Event, &ConsoleInDev->ConIn);\r
-  \r
+  KeyboardWaitForKey (Event, Context);\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -378,31 +356,14 @@ KeyboardEfiResetEx (
   )\r
 \r
 {\r
   )\r
 \r
 {\r
-  EFI_STATUS                            Status;\r
   KEYBOARD_CONSOLE_IN_DEV               *ConsoleInDev;\r
   KEYBOARD_CONSOLE_IN_DEV               *ConsoleInDev;\r
-  EFI_TPL                               OldTpl;\r
 \r
   ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This); \r
 \r
   ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This); \r
-  if (ConsoleInDev->KeyboardErr) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  Status = ConsoleInDev->ConIn.Reset (\r
-                                 &ConsoleInDev->ConIn, \r
-                                 ExtendedVerification\r
-                                 );\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
 \r
 \r
-  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  ConsoleInDev->KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID;\r
-  ConsoleInDev->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
-\r
-  gBS->RestoreTPL (OldTpl);  \r
-  \r
-  return EFI_SUCCESS;\r
+  return ConsoleInDev->ConIn.Reset (\r
+                               &ConsoleInDev->ConIn, \r
+                               ExtendedVerification\r
+                               );\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -482,8 +443,7 @@ KeyboardSetState (
     goto Exit;\r
   }\r
 \r
     goto Exit;\r
   }\r
 \r
-  if (((ConsoleInDev->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) ||\r
-      ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID)) {\r
+  if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) {\r
     Status = EFI_UNSUPPORTED;\r
     goto Exit;\r
   }\r
     Status = EFI_UNSUPPORTED;\r
     goto Exit;\r
   }\r
@@ -510,8 +470,6 @@ KeyboardSetState (
     Status = EFI_DEVICE_ERROR;    \r
   }\r
 \r
     Status = EFI_DEVICE_ERROR;    \r
   }\r
 \r
-  ConsoleInDev->KeyState.KeyToggleState = *KeyToggleState;\r
-  \r
 Exit:   \r
   //\r
   // Leave critical section and return\r
 Exit:   \r
   //\r
   // Leave critical section and return\r
index 428758fd99f8e4f7b533ac3de0fdd5342c3a74e7..362533f930d2da7c52a719141e42d5e9e72e65e5 100644 (file)
@@ -3,7 +3,7 @@
   PS/2 Keyboard driver. Routines that interacts with callers,\r
   conforming to EFI driver model\r
 \r
   PS/2 Keyboard driver. Routines that interacts with callers,\r
   conforming to EFI driver model\r
 \r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2011, 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
 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
@@ -243,11 +243,6 @@ KbdControllerDriverStart (
   ConsoleIn->StatusRegisterAddress  = KEYBOARD_8042_STATUS_REGISTER;\r
   ConsoleIn->CommandRegisterAddress = KEYBOARD_8042_COMMAND_REGISTER;\r
   ConsoleIn->IsaIo                  = IsaIo;\r
   ConsoleIn->StatusRegisterAddress  = KEYBOARD_8042_STATUS_REGISTER;\r
   ConsoleIn->CommandRegisterAddress = KEYBOARD_8042_COMMAND_REGISTER;\r
   ConsoleIn->IsaIo                  = IsaIo;\r
-  ConsoleIn->ScancodeBufStartPos    = 0;\r
-  ConsoleIn->ScancodeBufEndPos      = KEYBOARD_BUFFER_MAX_COUNT - 1;\r
-  ConsoleIn->ScancodeBufCount       = 0;\r
-  ConsoleIn->Ctrled                 = FALSE;\r
-  ConsoleIn->Alted                  = FALSE;\r
   ConsoleIn->DevicePath             = ParentDevicePath;\r
 \r
   ConsoleIn->ConInEx.Reset               = KeyboardEfiResetEx;\r
   ConsoleIn->DevicePath             = ParentDevicePath;\r
 \r
   ConsoleIn->ConInEx.Reset               = KeyboardEfiResetEx;\r
@@ -279,7 +274,7 @@ KbdControllerDriverStart (
                   EVT_NOTIFY_WAIT,\r
                   TPL_NOTIFY,\r
                   KeyboardWaitForKey,\r
                   EVT_NOTIFY_WAIT,\r
                   TPL_NOTIFY,\r
                   KeyboardWaitForKey,\r
-                  &(ConsoleIn->ConIn),\r
+                  ConsoleIn,\r
                   &((ConsoleIn->ConIn).WaitForKey)\r
                   );\r
   if (EFI_ERROR (Status)) {\r
                   &((ConsoleIn->ConIn).WaitForKey)\r
                   );\r
   if (EFI_ERROR (Status)) {\r
@@ -294,7 +289,7 @@ KbdControllerDriverStart (
                   EVT_NOTIFY_WAIT,\r
                   TPL_NOTIFY,\r
                   KeyboardWaitForKeyEx,\r
                   EVT_NOTIFY_WAIT,\r
                   TPL_NOTIFY,\r
                   KeyboardWaitForKeyEx,\r
-                  &(ConsoleIn->ConInEx),\r
+                  ConsoleIn,\r
                   &(ConsoleIn->ConInEx.WaitForKeyEx)\r
                   );\r
   if (EFI_ERROR (Status)) {\r
                   &(ConsoleIn->ConInEx.WaitForKeyEx)\r
                   );\r
   if (EFI_ERROR (Status)) {\r
index 4ac3cb4184ffe619261af9cf70ecca99ddc98efe..7cf90caa6f19acc54dc17bc5d872b120f42d209a 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   PS/2 keyboard driver header file\r
 \r
 /** @file\r
   PS/2 keyboard driver header file\r
 \r
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2011, 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
 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
@@ -44,18 +44,30 @@ extern EFI_COMPONENT_NAME2_PROTOCOL  gPs2KeyboardComponentName2;
 //\r
 // Driver Private Data\r
 //\r
 //\r
 // Driver Private Data\r
 //\r
-#define KEYBOARD_BUFFER_MAX_COUNT         32\r
-#define KEYBOARD_CONSOLE_IN_DEV_SIGNATURE SIGNATURE_32 ('k', 'k', 'e', 'y')\r
+#define KEYBOARD_CONSOLE_IN_DEV_SIGNATURE       SIGNATURE_32 ('k', 'k', 'e', 'y')\r
 #define KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('k', 'c', 'e', 'n')\r
 \r
 typedef struct _KEYBOARD_CONSOLE_IN_EX_NOTIFY {\r
 #define KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('k', 'c', 'e', 'n')\r
 \r
 typedef struct _KEYBOARD_CONSOLE_IN_EX_NOTIFY {\r
-  UINTN                                 Signature;\r
-  EFI_HANDLE                            NotifyHandle;\r
-  EFI_KEY_DATA                          KeyData;\r
-  EFI_KEY_NOTIFY_FUNCTION               KeyNotificationFn;\r
-  LIST_ENTRY                            NotifyEntry;\r
+  UINTN                               Signature;\r
+  EFI_HANDLE                          NotifyHandle;\r
+  EFI_KEY_DATA                        KeyData;\r
+  EFI_KEY_NOTIFY_FUNCTION             KeyNotificationFn;\r
+  LIST_ENTRY                          NotifyEntry;\r
 } KEYBOARD_CONSOLE_IN_EX_NOTIFY;\r
 \r
 } KEYBOARD_CONSOLE_IN_EX_NOTIFY;\r
 \r
+#define KEYBOARD_SCAN_CODE_MAX_COUNT  32\r
+typedef struct {\r
+  UINT8                               Buffer[KEYBOARD_SCAN_CODE_MAX_COUNT];\r
+  UINTN                               Head;\r
+  UINTN                               Tail;\r
+} SCAN_CODE_QUEUE;\r
+\r
+#define KEYBOARD_EFI_KEY_MAX_COUNT    256\r
+typedef struct {\r
+  EFI_KEY_DATA                        Buffer[KEYBOARD_EFI_KEY_MAX_COUNT];\r
+  UINTN                               Head;\r
+  UINTN                               Tail;\r
+} EFI_KEY_QUEUE;\r
 \r
 typedef struct {\r
   UINTN                               Signature;\r
 \r
 typedef struct {\r
   UINTN                               Signature;\r
@@ -71,9 +83,6 @@ typedef struct {
   UINT32                              StatusRegisterAddress;\r
   UINT32                              CommandRegisterAddress;\r
 \r
   UINT32                              StatusRegisterAddress;\r
   UINT32                              CommandRegisterAddress;\r
 \r
-  EFI_INPUT_KEY                       Key;\r
-  EFI_KEY_STATE                       KeyState;\r
-\r
   BOOLEAN                             LeftShift;\r
   BOOLEAN                             RightShift;  \r
   BOOLEAN                             LeftLogo;\r
   BOOLEAN                             LeftShift;\r
   BOOLEAN                             RightShift;  \r
   BOOLEAN                             LeftLogo;\r
@@ -89,18 +98,10 @@ typedef struct {
   BOOLEAN                             ScrollLock;\r
 \r
   //\r
   BOOLEAN                             ScrollLock;\r
 \r
   //\r
-  // Buffer storing key scancodes\r
+  // Queue storing key scancodes\r
   //\r
   //\r
-  UINT8                               ScancodeBuf[KEYBOARD_BUFFER_MAX_COUNT];\r
-  UINT32                              ScancodeBufStartPos;\r
-  UINT32                              ScancodeBufEndPos;\r
-  UINT32                              ScancodeBufCount;\r
-\r
-  //\r
-  // Indicators of the key pressing state, used in detecting Alt+Ctrl+Del\r
-  //\r
-  BOOLEAN                             Ctrled;\r
-  BOOLEAN                             Alted;\r
+  SCAN_CODE_QUEUE                     ScancodeQueue;\r
+  EFI_KEY_QUEUE                       EfiKeyQueue;\r
 \r
   //\r
   // Error state\r
 \r
   //\r
   // Error state\r
@@ -171,6 +172,7 @@ InstallPs2KeyboardDriver (
 #define SCANCODE_CAPS_LOCK_MAKE         0x3A\r
 #define SCANCODE_NUM_LOCK_MAKE          0x45\r
 #define SCANCODE_SCROLL_LOCK_MAKE       0x46\r
 #define SCANCODE_CAPS_LOCK_MAKE         0x3A\r
 #define SCANCODE_NUM_LOCK_MAKE          0x45\r
 #define SCANCODE_SCROLL_LOCK_MAKE       0x46\r
+#define SCANCODE_DELETE_MAKE            0x53\r
 #define SCANCODE_LEFT_LOGO_MAKE         0x5B //GUI key defined in Keyboard scan code\r
 #define SCANCODE_LEFT_LOGO_BREAK        0xDB\r
 #define SCANCODE_RIGHT_LOGO_MAKE        0x5C\r
 #define SCANCODE_LEFT_LOGO_MAKE         0x5B //GUI key defined in Keyboard scan code\r
 #define SCANCODE_LEFT_LOGO_BREAK        0xDB\r
 #define SCANCODE_RIGHT_LOGO_MAKE        0x5C\r
@@ -246,17 +248,14 @@ KeyboardRead (
   );\r
 \r
 /**\r
   );\r
 \r
 /**\r
-  Get scancode from scancode buffer\r
-  and translate into EFI-scancode and unicode defined by EFI spec\r
-  The function is always called in TPL_NOTIFY\r
+  Get scancode from scancode buffer and translate into EFI-scancode and unicode defined by EFI spec.\r
 \r
 \r
-  @param ConsoleIn KEYBOARD_CONSOLE_IN_DEV instance pointer\r
+  The function is always called in TPL_NOTIFY.\r
 \r
 \r
-  @retval EFI_NOT_READY - Input from console not ready yet.\r
-  @retval EFI_SUCCESS   - Function executed successfully.\r
+  @param ConsoleIn KEYBOARD_CONSOLE_IN_DEV instance pointer\r
 \r
 **/\r
 \r
 **/\r
-EFI_STATUS\r
+VOID\r
 KeyGetchar (\r
   IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
   );\r
 KeyGetchar (\r
   IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
   );\r
@@ -511,4 +510,33 @@ KeyboardUnregisterKeyNotify (
   IN EFI_HANDLE                         NotificationHandle\r
   );\r
 \r
   IN EFI_HANDLE                         NotificationHandle\r
   );\r
 \r
+/**\r
+  Push one key data to the EFI key buffer.\r
+\r
+  @param Queue     Pointer to instance of EFI_KEY_QUEUE.\r
+  @param KeyData   The key data to push.\r
+**/\r
+VOID\r
+PushEfikeyBufTail (\r
+  IN  EFI_KEY_QUEUE         *Queue,\r
+  IN  EFI_KEY_DATA          *KeyData\r
+  );\r
+\r
+/**\r
+  Judge whether is a registed key\r
+\r
+  @param RegsiteredData       A pointer to a buffer that is filled in with the keystroke \r
+                              state data for the key that was registered.\r
+  @param InputData            A pointer to a buffer that is filled in with the keystroke \r
+                              state data for the key that was pressed.\r
+\r
+  @retval TRUE                Key be pressed matches a registered key.\r
+  @retval FLASE               Match failed. \r
+  \r
+**/\r
+BOOLEAN\r
+IsKeyRegistered (\r
+  IN EFI_KEY_DATA  *RegsiteredData,\r
+  IN EFI_KEY_DATA  *InputData\r
+  );\r
 #endif\r
 #endif\r