From: niruiyu Date: Tue, 19 Apr 2011 06:51:44 +0000 (+0000) Subject: Fix the terminal driver to call hotkey callback even no one is calling ReadKeyStroke X-Git-Tag: edk2-stable201903~14939 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=f0368006b0d04820a44ae21b0d55ee2d0f5aee3d Fix the terminal driver to call hotkey callback even no one is calling ReadKeyStroke git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11562 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c index 313092c2c9..9574390eb0 100644 --- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c +++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c @@ -2,7 +2,7 @@ Produces Simple Text Input Protocol, Simple Text Input Extended Protocol and Simple Text Output Protocol upon Serial IO Protocol. -Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -75,6 +75,7 @@ TERMINAL_DEV mTerminalDevTemplate = { NULL, // EfiKeyFiFo NULL, // ControllerNameTable + NULL, // TimerEvent NULL, // TwoSecondTimeOut INPUT_STATE_DEFAULT, RESET_STATE_DEFAULT, @@ -648,7 +649,7 @@ TerminalDriverBindingStart ( EVT_NOTIFY_WAIT, TPL_NOTIFY, TerminalConInWaitForKeyEx, - &TerminalDevice->SimpleInputEx, + TerminalDevice, &TerminalDevice->SimpleInputEx.WaitForKeyEx ); if (EFI_ERROR (Status)) { @@ -659,7 +660,7 @@ TerminalDriverBindingStart ( EVT_NOTIFY_WAIT, TPL_NOTIFY, TerminalConInWaitForKey, - &TerminalDevice->SimpleInput, + TerminalDevice, &TerminalDevice->SimpleInput.WaitForKey ); if (EFI_ERROR (Status)) { @@ -842,6 +843,22 @@ TerminalDriverBindingStart ( goto ReportError; } + Status = gBS->CreateEvent ( + EVT_TIMER | EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + TerminalConInTimerHandler, + TerminalDevice, + &TerminalDevice->TimerEvent + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->SetTimer ( + TerminalDevice->TimerEvent, + TimerPeriodic, + KEYBOARD_TIMER_INTERVAL + ); + ASSERT_EFI_ERROR (Status); + Status = gBS->CreateEvent ( EVT_TIMER, TPL_CALLBACK, @@ -849,6 +866,7 @@ TerminalDriverBindingStart ( NULL, &TerminalDevice->TwoSecondTimeOut ); + ASSERT_EFI_ERROR (Status); Status = gBS->InstallProtocolInterface ( &TerminalDevice->Handle, @@ -1052,6 +1070,10 @@ Error: gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut); } + if (TerminalDevice->TimerEvent != NULL) { + gBS->CloseEvent (TerminalDevice->TimerEvent); + } + if (TerminalDevice->SimpleInput.WaitForKey != NULL) { gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey); } @@ -1245,6 +1267,7 @@ TerminalDriverBindingStop ( FreeUnicodeStringTable (TerminalDevice->ControllerNameTable); } + gBS->CloseEvent (TerminalDevice->TimerEvent); gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut); gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey); gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx); diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h index 34c1c02f3d..fd42138a71 100644 --- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h +++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h @@ -1,7 +1,7 @@ /** @file Header file for Terminal driver. -Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -61,6 +61,8 @@ typedef struct { EFI_INPUT_KEY Data[FIFO_MAX_NUMBER + 1]; } EFI_KEY_FIFO; +#define KEYBOARD_TIMER_INTERVAL 200000 // 0.02s + #define TERMINAL_DEV_SIGNATURE SIGNATURE_32 ('t', 'm', 'n', 'l') #define TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('t', 'm', 'e', 'n') @@ -86,6 +88,7 @@ typedef struct { UNICODE_FIFO *UnicodeFiFo; EFI_KEY_FIFO *EfiKeyFiFo; EFI_UNICODE_STRING_TABLE *ControllerNameTable; + EFI_EVENT TimerEvent; EFI_EVENT TwoSecondTimeOut; UINT32 InputState; UINT32 ResetState; @@ -954,7 +957,7 @@ IsRawFiFoFull ( BOOLEAN EfiKeyFiFoInsertOneKey ( TERMINAL_DEV *TerminalDevice, - EFI_INPUT_KEY Key + EFI_INPUT_KEY *Key ); /** @@ -1348,4 +1351,16 @@ IsHotPlugDevice ( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath ); +/** + Timer handler to poll the key from serial. + + @param Event Indicates the event that invoke this function. + @param Context Indicates the calling context. +**/ +VOID +EFIAPI +TerminalConInTimerHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ); #endif diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c index 1c5fd7be47..b5dbaf9280 100644 --- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c +++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c @@ -1,7 +1,7 @@ /** @file Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol. -Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -26,8 +26,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. @retval EFI_SUCCESS The keystroke information was returned. @retval EFI_NOT_READY There was no keystroke data available. - @retval EFI_DEVICE_ERROR The keystroke information was not returned due - to hardware errors. @retval EFI_INVALID_PARAMETER KeyData is NULL. **/ @@ -37,26 +35,10 @@ ReadKeyStrokeWorker ( OUT EFI_KEY_DATA *KeyData ) { - EFI_STATUS Status; - LIST_ENTRY *Link; - LIST_ENTRY *NotifyList; - TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify; - if (KeyData == NULL) { return EFI_INVALID_PARAMETER; } - // - // Initialize *Key to nonsense value. - // - KeyData->Key.ScanCode = SCAN_NULL; - KeyData->Key.UnicodeChar = 0; - - Status = TerminalConInCheckForKey (&TerminalDevice->SimpleInput); - if (EFI_ERROR (Status)) { - return EFI_NOT_READY; - } - if (!EfiKeyFiFoRemoveOneKey (TerminalDevice, &KeyData->Key)) { return EFI_NOT_READY; } @@ -64,21 +46,6 @@ ReadKeyStrokeWorker ( KeyData->KeyState.KeyShiftState = 0; KeyData->KeyState.KeyToggleState = 0; - // - // Invoke notification functions if exist - // - NotifyList = &TerminalDevice->NotifyList; - for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList,Link); Link = GetNextNode (NotifyList,Link)) { - CurrentNotify = CR ( - Link, - TERMINAL_CONSOLE_IN_EX_NOTIFY, - NotifyEntry, - TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE - ); - if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { - CurrentNotify->KeyNotificationFn (KeyData); - } - } return EFI_SUCCESS; @@ -226,12 +193,7 @@ TerminalConInWaitForKeyEx ( IN VOID *Context ) { - TERMINAL_DEV *TerminalDevice; - - TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (Context); - - TerminalConInWaitForKey (Event, &TerminalDevice->SimpleInput); - + TerminalConInWaitForKey (Event, Context); } // @@ -532,43 +494,37 @@ TerminalConInWaitForKey ( // Someone is waiting on the keystroke event, if there's // a key pending, signal the event // - // Context is the pointer to EFI_SIMPLE_TEXT_INPUT_PROTOCOL - // - if (!EFI_ERROR (TerminalConInCheckForKey (Context))) { + if (!IsEfiKeyFiFoEmpty ((TERMINAL_DEV *) Context)) { gBS->SignalEvent (Event); } } - /** - Check for a pending key in the Efi Key FIFO or Serial device buffer. - - @param This Indicates the calling context. - - @retval EFI_SUCCESS There is key pending. - @retval EFI_NOT_READY There is no key pending. - @retval EFI_DEVICE_ERROR If Serial IO is not attached to serial device. + Timer handler to poll the key from serial. + @param Event Indicates the event that invoke this function. + @param Context Indicates the calling context. **/ -EFI_STATUS -TerminalConInCheckForKey ( - IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This +VOID +EFIAPI +TerminalConInTimerHandler ( + IN EFI_EVENT Event, + IN VOID *Context ) { EFI_STATUS Status; TERMINAL_DEV *TerminalDevice; - UINT32 Control; UINT8 Input; EFI_SERIAL_IO_MODE *Mode; EFI_SERIAL_IO_PROTOCOL *SerialIo; UINTN SerialInTimeOut; - TerminalDevice = TERMINAL_CON_IN_DEV_FROM_THIS (This); + TerminalDevice = (TERMINAL_DEV *) Context; SerialIo = TerminalDevice->SerialIo; if (SerialIo == NULL) { - return EFI_DEVICE_ERROR; + return ; } // // if current timeout value for serial device is not identical with @@ -602,28 +558,7 @@ TerminalConInCheckForKey ( TerminalDevice->SerialInTimeOut = SerialInTimeOut; } } - // - // Check whether serial buffer is empty. - // - Status = SerialIo->GetControl (SerialIo, &Control); - - if ((Control & EFI_SERIAL_INPUT_BUFFER_EMPTY) != 0) { - // - // Translate all the raw data in RawFIFO into EFI Key, - // according to different terminal type supported. - // - TranslateRawDataToEfiKey (TerminalDevice); - // - // if there is pre-fetched Efi Key in EfiKeyFIFO buffer, - // return directly. - // - if (!IsEfiKeyFiFoEmpty (TerminalDevice)) { - return EFI_SUCCESS; - } else { - return EFI_NOT_READY; - } - } // // Fetch all the keys in the serial buffer, // and insert the byte stream into RawFIFO. @@ -651,12 +586,6 @@ TerminalConInCheckForKey ( // according to different terminal type supported. // TranslateRawDataToEfiKey (TerminalDevice); - - if (IsEfiKeyFiFoEmpty (TerminalDevice)) { - return EFI_NOT_READY; - } - - return EFI_SUCCESS; } /** @@ -837,15 +766,37 @@ IsRawFiFoFull ( **/ BOOLEAN EfiKeyFiFoInsertOneKey ( - TERMINAL_DEV *TerminalDevice, - EFI_INPUT_KEY Key + TERMINAL_DEV *TerminalDevice, + EFI_INPUT_KEY *Key ) { - UINT8 Tail; + UINT8 Tail; + LIST_ENTRY *Link; + LIST_ENTRY *NotifyList; + TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify; + EFI_KEY_DATA KeyData; Tail = TerminalDevice->EfiKeyFiFo->Tail; - ASSERT (Tail < FIFO_MAX_NUMBER + 1); + CopyMem (&KeyData.Key, Key, sizeof (EFI_INPUT_KEY)); + KeyData.KeyState.KeyShiftState = 0; + KeyData.KeyState.KeyToggleState = 0; + + // + // Invoke notification functions if exist + // + NotifyList = &TerminalDevice->NotifyList; + for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList,Link); Link = GetNextNode (NotifyList,Link)) { + CurrentNotify = CR ( + Link, + TERMINAL_CONSOLE_IN_EX_NOTIFY, + NotifyEntry, + TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE + ); + if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) { + CurrentNotify->KeyNotificationFn (&KeyData); + } + } if (IsEfiKeyFiFoFull (TerminalDevice)) { // // Efi Key FIFO is full @@ -853,9 +804,9 @@ EfiKeyFiFoInsertOneKey ( return FALSE; } - TerminalDevice->EfiKeyFiFo->Data[Tail] = Key; + CopyMem (&TerminalDevice->EfiKeyFiFo->Data[Tail], Key, sizeof (EFI_INPUT_KEY)); - TerminalDevice->EfiKeyFiFo->Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1)); + TerminalDevice->EfiKeyFiFo->Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1)); return TRUE; } @@ -1113,31 +1064,31 @@ UnicodeToEfiKeyFlushState ( if ((InputState & INPUT_STATE_ESC) != 0) { Key.ScanCode = SCAN_ESC; Key.UnicodeChar = 0; - EfiKeyFiFoInsertOneKey (TerminalDevice, Key); + EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); } if ((InputState & INPUT_STATE_CSI) != 0) { Key.ScanCode = SCAN_NULL; Key.UnicodeChar = CSI; - EfiKeyFiFoInsertOneKey (TerminalDevice, Key); + EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); } if ((InputState & INPUT_STATE_LEFTOPENBRACKET) != 0) { Key.ScanCode = SCAN_NULL; Key.UnicodeChar = LEFTOPENBRACKET; - EfiKeyFiFoInsertOneKey (TerminalDevice, Key); + EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); } if ((InputState & INPUT_STATE_O) != 0) { Key.ScanCode = SCAN_NULL; Key.UnicodeChar = 'O'; - EfiKeyFiFoInsertOneKey (TerminalDevice, Key); + EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); } if ((InputState & INPUT_STATE_2) != 0) { Key.ScanCode = SCAN_NULL; Key.UnicodeChar = '2'; - EfiKeyFiFoInsertOneKey (TerminalDevice, Key); + EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); } // @@ -1368,7 +1319,7 @@ UnicodeToEfiKey ( if (Key.ScanCode != SCAN_NULL) { Key.UnicodeChar = 0; - EfiKeyFiFoInsertOneKey (TerminalDevice,Key); + EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); TerminalDevice->InputState = INPUT_STATE_DEFAULT; UnicodeToEfiKeyFlushState (TerminalDevice); continue; @@ -1423,7 +1374,7 @@ UnicodeToEfiKey ( if (Key.ScanCode != SCAN_NULL) { Key.UnicodeChar = 0; - EfiKeyFiFoInsertOneKey (TerminalDevice,Key); + EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); TerminalDevice->InputState = INPUT_STATE_DEFAULT; UnicodeToEfiKeyFlushState (TerminalDevice); continue; @@ -1561,7 +1512,7 @@ UnicodeToEfiKey ( if (Key.ScanCode != SCAN_NULL) { Key.UnicodeChar = 0; - EfiKeyFiFoInsertOneKey (TerminalDevice,Key); + EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); TerminalDevice->InputState = INPUT_STATE_DEFAULT; UnicodeToEfiKeyFlushState (TerminalDevice); continue; @@ -1613,6 +1564,6 @@ UnicodeToEfiKey ( Key.UnicodeChar = UnicodeChar; } - EfiKeyFiFoInsertOneKey (TerminalDevice,Key); + EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); } }