diff options
Diffstat (limited to 'Core/CORE_DXE/ConSplitter/In.c')
-rw-r--r-- | Core/CORE_DXE/ConSplitter/In.c | 1159 |
1 files changed, 1159 insertions, 0 deletions
diff --git a/Core/CORE_DXE/ConSplitter/In.c b/Core/CORE_DXE/ConSplitter/In.c new file mode 100644 index 0000000..9d8d561 --- /dev/null +++ b/Core/CORE_DXE/ConSplitter/In.c @@ -0,0 +1,1159 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/ConSplitter/In.c 5 7/08/15 4:32a Chienhsieh $ +// +// $Revision: 5 $ +// +// $Date: 7/08/15 4:32a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/ConSplitter/In.c $ +// +// 5 7/08/15 4:32a Chienhsieh +// Update for eip217417. +// +// 4 8/02/13 4:26a Thomaschen +// Add for EIP109384. +// [Files] ConSplit.c, ConSplit.h, In.c, CsmSimpleIn.c. +// +// 3 6/26/13 3:11a Thomaschen +// Remove EIP109384. +// +// 1 6/04/13 1:52a Thomaschen +// Fixed for EIP118202. +// +// 32 10/25/12 2:33a Deepthins +// [TAG] EIP99475 +// [Category] Improvement +// [Description] Multi language module Support in the console splitter +// +// [Files] ConSplit.c, ConSplit.h , In.c and AmiKeycode.h +// +// 31 7/20/12 10:38a Artems +// [TAG] EIP93929 +// [Description] Implement support to initialize the Keyboard in first +// call of readkeystoke in fast boot case +// [Files] In.c +// +// 30 4/11/12 5:35p Artems +// [TAG] EIPN/A +// [Category] Bug Fix +// [Symptom] Function SetState was not broadcasted to third party +// drivers +// [RootCause] Splitter uses AMI proprietary protocol to broadcast +// SetState function +// which is not installed by third party drivers +// [Solution] Modified splitter to broadcast SetState function via +// SimpleTextInEx protocol +// [Files] in.c +// +// 29 3/21/12 12:53p Artems +// EIP 83358: Fixed bug in SimplePointerGetState function, where +// EFI_SUCCESS was lost if ohter device returns DEVICE_ERROR +// +// 28 9/22/11 6:29a Rameshr +// [TAG] EIP63054 +// [Category] New Feature +// [Description] 0000790: Add warning to ReadKeyStrokeEx for partial key +// press +// [Files] KeyboardCommonDefinitions.h, In.c, Kbc.h, Ps2Kbd.c, +// Efiusbkb.c, efiusbkb.h +// +// 27 7/21/11 3:41p Aaronp +// // [TAG] EIP65187 +// // [Category] Bug Fix +// // [Severity] Minor +// // [Symptom] unicode character was not returned when english selected +// // and alt key pressed +// // [RootCause] The EFI_HII_KEYBOARD_LAYOUT table provides the +// AltGraphic +// // and Shifted AltGraphic unicode definitions for key combinations, and +// // there are NULL values for undefined key combinations. +// // [Solution] Changed how the EFI_HII_KEYBOARD_LAYOUT table is +// consumed +// // so that the current unicode character in the AMI_EFI_KEY_DATA +// structure +// // will not be overwritten when the EFI_HII_KEYBOARD_LAYOUT has a NULL +// // value in the matching table entry. +// // [Files] In.c +// +// 25 5/05/11 4:53p Artems +// Removed unnecessary checks +// +// 24 5/05/11 3:54p Artems +// Added multi-language keyboard support +// +// 23 8/10/10 2:29p Vyacheslava +// Initialized default value of Status in the +// ConSplitterSimplePointerReset function. +// +// 22 6/23/10 3:02p Felixp +// SimplePointer splitter support is added. +// +// 21 1/18/10 3:40a Rameshr +// NumLock,Capslock,Scroll Lock LED's synced properly between Keyboard +// connect and disconnect. +// EIP 27917 +// +// 20 10/09/09 12:15p Felixp +// SetState function is updated to process all the physical devices +// despite the errors returned by some of them. +// +// 19 8/13/09 3:04p Rameshr +// When item "num-lock status" set off, Num-lock will keep open until in +// DOS. +// EIP:21757 +// +// 18 7/07/09 3:35p Artems +// Added functions headers according to code standard +// +// 17 4/30/09 5:45p Felixp +// Minor improvements on the pause key implementation. +// +// 16 3/30/09 10:24a Pats +// Issue: EIP 19547 - Pause key support needed in Aptio +// Solution: Function CsReadEfiKey modified to enter pause loop when pause +// key detected. Requires mod in Ps2Kbd.c and efiusbkb.c. +// +// 15 1/23/09 9:55a Rameshr +// Symptom:SCT failure in ReadKeystrokeEx function. +// Solution: Validated the Input parameters Keydata for the +// ReadKeystrokeEx Function. +// Eip: 19039 +// +// 14 11/17/08 10:22a Rameshraju +// Problem:SCT failure on RegisterKeyNotify, SetState and +// UnregisterKeyNotify. +// Fix : Validated the input parameters for RegisterKeyNotify, SetState +// and UnregisterKeyNotify. +// EIP:17578 +// +// 13 10/08/08 4:27p Olegi +// Implemented the Register/Unregister key notofocation function in +// SimpletextinEx protocol. +// +// 12 3/17/08 4:49p Rameshraju +// ReadEfiKey doesnt not return correct key value randomly. +// +// 11 1/31/08 12:00p Olegi +// Numlock bootup state made setup driven. +// +// 10 11/16/07 4:05p Olegi +// Modifications in CSReadKeyStroke function. +// +// 9 10/23/07 4:14p Olegi +// Modifications in CSInSetState that allow the sync between the Input +// Devices' LEDs. +// +// 8 10/16/07 10:47a Olegi +// Modification in CSReadEfiKey(). +// +// 7 9/17/07 4:04p Olegi +// Added support for AMI_EFIKEYCODE_PROTOCOL and +// EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL. +// +// 6 9/05/07 11:13a Felixp +// SimpleTextInEx support removed. It causes problems. Support will add +// again after Core labeling. +// +// 3 3/13/06 2:37a Felixp +// +// 2 11/07/05 10:37a Felixp +// LockStdIn function of ConsoleControl protocol implemented +// +// 1 1/28/05 1:16p Felixp +// +// 2 1/18/05 3:22p Felixp +// PrintDebugMessage renamed to Trace +// +// 1 1/07/05 11:57a Felixp +// +// 2 1/03/05 5:47p Robert +// Working beta version of the consplitter +// +// 1 12/30/04 9:47a Robert +// Initial check in +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: Out.c +// +// Description: File contains the Simple Text Output functionality for the +// Console Splitter Driver +// +//<AMI_FHDR_END> +//********************************************************************** + +//---------------------------------------------------------------------------- + +#include "ConSplit.h" +#include "token.h" +#include <Protocol/SimplePointer.h> + +//---------------------------------------------------------------------------- +extern EFI_HII_KEYBOARD_LAYOUT *gKeyDescriptorList; +extern EFI_KEY_TOGGLE_STATE mCSToggleState; +EFI_SIMPLE_POINTER_MODE gSimplePointerMode = { + 0x10000, + 0x10000, + 0x10000, + FALSE, + FALSE +}; + +VOID ConnectInputDevices( + VOID +); + +//---------------------------------------------------------------------------- + +EFI_SIMPLE_TEXT_INPUT_PROTOCOL mCSSimpleInProtocol = { + CSInReset, + CSReadKeyStroke, + NULL + } ; + +EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL mCSSimpleInExProtocol = { + CSInResetEx, + CSReadKeyStrokeEx, + NULL, + CSInSetState, + CSInRegisterKeyNotify, + CSInUnRegisterKeyNotify + } ; + +AMI_EFIKEYCODE_PROTOCOL mCSKeycodeInProtocol = { + CSInResetEx, + CSReadEfiKey, + NULL, + CSInSetState, + CSInRegisterKeyNotify, + CSInUnRegisterKeyNotify + } ; + +EFI_SIMPLE_POINTER_PROTOCOL mCSSimplePointerProtocol = { + ConSplitterSimplePointerReset, + ConSplitterSimplePointerGetState, + ConSplitterSimplePointerWaitForInput, + &gSimplePointerMode +}; + +//---------------------------------------------------------------------------- + + +// <AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Name: ConSplitterSimplePointerReset +// +// Description: Resets the pointer device hardware. +// +// Input: +// *This - pointer to protocol instance. +// ExtendedVerification - Driver may perform diagnostics on reset. +// +// Output: +// EFI_SUCCESS - device was reset successfully +// EFI_ERROR - some of devices returned error +// +//---------------------------------------------------------------------------- +// <AMI_PHDR_END> + +EFI_STATUS ConSplitterSimplePointerReset ( + IN EFI_SIMPLE_POINTER_PROTOCOL *This, + IN BOOLEAN ExtendedVerification ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_STATUS TestStatus; + CON_SPLIT_SIMPLE_POINTER *ConSimplePointer = NULL; + + if (StdInLocked) + return EFI_ACCESS_DENIED; + + if (ConPointerList.pHead == NULL) + return EFI_DEVICE_ERROR; + + ConSimplePointer = OUTTER(ConPointerList.pHead, Link, CON_SPLIT_SIMPLE_POINTER); + + // we need to loop through all the registered simple pointer devices + // and call each of their Reset function + while (ConSimplePointer != NULL) { + TestStatus = ConSimplePointer->SimplePointer->Reset(ConSimplePointer->SimplePointer, ExtendedVerification); + ConSimplePointer = OUTTER( ConSimplePointer->Link.pNext, Link, CON_SPLIT_SIMPLE_POINTER ); + + if (EFI_ERROR(TestStatus)) + Status = TestStatus; + } + + return Status; +} + + +// <AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Name: ConSplitterSimplePointerGetState +// +// Description: Retrieves the current state of a pointer device. +// Reads the next keystroke from the input device. The WaitForKey Event can +// be used to test for existance of a keystroke via WaitForEvent () call. +// If the ConIn is password locked make it look like no keystroke is availible +// +// Input: +// This - Protocol instance pointer. +// State - A pointer to the state information on the pointer device. +// +// Output: +// EFI_SUCCESS - The keystroke information was returned. +// EFI_NOT_READY - There was no keystroke data availiable. +// EFI_DEVICE_ERROR - The keydtroke information was not returned due to +// hardware errors. +// +//---------------------------------------------------------------------------- +// <AMI_PHDR_END> + +EFI_STATUS ConSplitterSimplePointerGetState( + IN EFI_SIMPLE_POINTER_PROTOCOL *This, + IN OUT EFI_SIMPLE_POINTER_STATE *State ) +{ + EFI_STATUS Status; + EFI_SIMPLE_POINTER_STATE CurrentState; + CON_SPLIT_SIMPLE_POINTER *ConSimplePointer = NULL; + BOOLEAN EfiSuccessDetected = FALSE; + BOOLEAN EfiDeviceErrorDetected = FALSE; + BOOLEAN EfiNotReadyDetected = FALSE; + + if (StdInLocked) + return EFI_ACCESS_DENIED; + + if (ConPointerList.pHead == NULL) + return EFI_DEVICE_ERROR; + + ConSimplePointer = OUTTER( ConPointerList.pHead, Link, CON_SPLIT_SIMPLE_POINTER ); + + State->RelativeMovementX = 0; + State->RelativeMovementY = 0; + State->RelativeMovementZ = 0; + State->LeftButton = FALSE; + State->RightButton = FALSE; + + // we need to loop through all the registered simple pointer devices + while (ConSimplePointer != NULL) { + + Status = ConSimplePointer->SimplePointer->GetState(ConSimplePointer->SimplePointer, &CurrentState); + + if (!EFI_ERROR(Status)) { + + EfiSuccessDetected = TRUE; + + if (CurrentState.LeftButton) + State->LeftButton = TRUE; + + if (CurrentState.RightButton) + State->RightButton = TRUE; + + if ( CurrentState.RelativeMovementX != 0 && ConSimplePointer->SimplePointer->Mode->ResolutionX != 0 ) + State->RelativeMovementX += + (CurrentState.RelativeMovementX * (INT32)gSimplePointerMode.ResolutionX) / + (INT32)ConSimplePointer->SimplePointer->Mode->ResolutionX; + + if ( CurrentState.RelativeMovementY != 0 && ConSimplePointer->SimplePointer->Mode->ResolutionY != 0 ) + State->RelativeMovementY += + (CurrentState.RelativeMovementY * (INT32)gSimplePointerMode.ResolutionY) / + (INT32)ConSimplePointer->SimplePointer->Mode->ResolutionY; + + if ( CurrentState.RelativeMovementZ != 0 && ConSimplePointer->SimplePointer->Mode->ResolutionZ != 0 ) + State->RelativeMovementZ += + (CurrentState.RelativeMovementZ * (INT32)gSimplePointerMode.ResolutionZ) / + (INT32)ConSimplePointer->SimplePointer->Mode->ResolutionZ; + + } else if (Status == EFI_DEVICE_ERROR) { + EfiDeviceErrorDetected = TRUE; + } else { + EfiNotReadyDetected = TRUE; + } + + ConSimplePointer = OUTTER( ConSimplePointer->Link.pNext, Link, CON_SPLIT_SIMPLE_POINTER ); + } + + return (EfiSuccessDetected) ? EFI_SUCCESS : (EfiDeviceErrorDetected) ? EFI_DEVICE_ERROR : EFI_NOT_READY; +} + + +// <AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Name: ConSplitterSimplePointerWaitForInput +// +// Description: This is callback function for WaitForInputEvent to use with +// WaitForEvent() to wait for input from the pointer device. +// +// Input: +// Event - The Event assoicated with callback. +// Context - Context registered when Event was created. +// +// Output: VOID +// +//---------------------------------------------------------------------------- +// <AMI_PHDR_END> + +VOID ConSplitterSimplePointerWaitForInput( + IN EFI_EVENT Event, + IN VOID *Context ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_STATUS TestStatus; + CON_SPLIT_SIMPLE_POINTER *ConSimplePointer = NULL; + + if (StdInLocked) + return; + + if (ConPointerList.pHead == NULL) + return; + + ConSimplePointer = OUTTER( ConPointerList.pHead, Link, CON_SPLIT_SIMPLE_POINTER ); + + // loop through simple pointer events and check their events + // if one event has been signaled, signal my event and exit. + // we need to loop through all the registered simple pointer devices + while (ConSimplePointer != NULL) { + TestStatus = pBS->CheckEvent(ConSimplePointer->SimplePointer->WaitForInput); + ConSimplePointer = OUTTER( ConSimplePointer->Link.pNext, Link, CON_SPLIT_SIMPLE_POINTER ); + + if (!EFI_ERROR(TestStatus)) + pBS->SignalEvent(Event); + } + + return; +} + + +// <AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Name: CSInReset +// +// Description: +// This function resets the input device hardware. This routine is a part +// of SimpleTextIn protocol implementation. +// +// Input: +// IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This - pointer to protocol instance +// IN BOOLEAN EV - flag if Extended verification has to be performed +// +// Output: +// EFI_STATUS +// EFI_SUCCESS - device was reset successfully +// EFI_ERROR - some of devices returned error +// +// Modified: +// +// Referrals: +// +// Notes: +// +//---------------------------------------------------------------------------- +// <AMI_PHDR_END> + +EFI_STATUS CSInReset( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + IN BOOLEAN EV +) +{ + EFI_STATUS Status = EFI_SUCCESS, TestStatus; + CON_SPLIT_IN *SimpleIn; + + if (StdInLocked) return EFI_ACCESS_DENIED; + + if (ConInList.pHead == NULL) + return EFI_SUCCESS; + + SimpleIn = OUTTER(ConInList.pHead, Link, CON_SPLIT_IN); + + // we need to loop through all the registered simple text out devices + // and call each of their Reset function + while ( SimpleIn != NULL) + { + TestStatus = SimpleIn->SimpleIn->Reset(SimpleIn->SimpleIn, EV); + SimpleIn = OUTTER(SimpleIn->Link.pNext, Link, CON_SPLIT_IN); + + if (EFI_ERROR(TestStatus)) + Status = TestStatus; + } + + return Status; + +} + +// <AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Name: CSReadKeyStroke +// +// Description: +// This function reads the next keystroke from the input device. This +// routine is a part of SimpleTextIn protocol implementation +// +// Input: +// IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This - pointer to protocol instance +// OUT EFI_INPUT_KEY *Key - key pressed information +// +// Output: +// EFI_STATUS +// EFI_SUCCESS - Keystroke data successfully retrieved +// EFI_NOT_READY - There was no keystroke data available +// EFI_DEVICE_ERROR - The keystroke information was not returned +// due to hardware error +// +// Modified: +// +// Referrals: +// +// Notes: +// +//-------------------------------------------------------------------------- +// <AMI_PHDR_END> + +EFI_STATUS CSReadKeyStroke( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + OUT EFI_INPUT_KEY *Key +) +{ + EFI_STATUS Status; + AMI_EFI_KEY_DATA EfiKeyData; + + Status = CSReadEfiKey ( (AMI_EFIKEYCODE_PROTOCOL*) This, &EfiKeyData ); + if (Status == EFI_SUCCESS) { + // + // Check for the Partial Key. If found, SimpleTextIn ReadKeyStroke + // Should not return that Key has bee found. + // + if(EfiKeyData.Key.ScanCode == 00 && EfiKeyData.Key.UnicodeChar == 0 && + (EfiKeyData.KeyState.KeyToggleState & KEY_STATE_EXPOSED )) { + return EFI_NOT_READY; + } + *Key = EfiKeyData.Key; + return EFI_SUCCESS; + } + + return Status; +} + +// <AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Name: CSWaitForKey +// +// Description: +// This function is a callback for the EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey event +// Checks whether the new key is available and if so - signals the event +// +// Input: +// IN EFI_EVENT Event - event to signal +// IN VOID *Context - pointer to event specific context +// +// Output: +// VOID +// +// Modified: +// +// Referrals: +// +// Notes: +// +//-------------------------------------------------------------------------- +// <AMI_PHDR_END> + +VOID CSWaitForKey( + IN EFI_EVENT Event, + IN VOID *Context +) +{ + EFI_STATUS Status = EFI_SUCCESS, TestStatus; + CON_SPLIT_IN *SimpleIn; + + if (StdInLocked) return ; + if (ConInList.pHead == NULL) return; + +// loop through simple in events and check their events +// if one event has been signaled, signal my event and exit + + SimpleIn = OUTTER(ConInList.pHead, Link, CON_SPLIT_IN); + + // we need to loop through all the registered simple text out devices + // and call each of their Reset function + while ( SimpleIn != NULL) + { + TestStatus = pBS->CheckEvent(SimpleIn->SimpleIn->WaitForKey); + SimpleIn = OUTTER(SimpleIn->Link.pNext, Link, CON_SPLIT_IN); + + if (!EFI_ERROR(TestStatus)) + pBS->SignalEvent (Event); + } + + return; +} + +// <AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Name: CSInResetEx +// +// Description: +// This function resets the input device hardware. This routine is a part +// of SimpleTextInEx protocol implementation +// +// Input: +// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This - pointer to protocol instance +// IN BOOLEAN ExtendedVerification - flag if Extended verification has to be performed +// +// Output: +// EFI_STATUS +// EFI_SUCCESS - device was reset successfully +// EFI_ERROR - some of devices returned error +// +// Modified: +// +// Referrals: +// +// Notes: +// +//-------------------------------------------------------------------------- +// <AMI_PHDR_END> + +EFI_STATUS CSInResetEx( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN BOOLEAN ExtendedVerification ) +{ + return CSInReset(0, ExtendedVerification); +} + +// <AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Name: CSReadKeyStrokeEx +// +// Description: +// This function reads the next keystroke from the input device. This +// routine is a part of SimpleTextInEx protocol implementation +// +// Input: +// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This - pointer to protocol instance +// OUT EFI_KEY_DATA *KeyData - key pressed information +// +// Output: +// EFI_STATUS +// EFI_SUCCESS - Keystroke data successfully retrieved +// EFI_NOT_READY - There was no keystroke data available +// EFI_DEVICE_ERROR - The keystroke information was not returned +// due to hardware error +// +// Modified: +// +// Referrals: +// +// Notes: +// +//-------------------------------------------------------------------------- +// <AMI_PHDR_END> + +EFI_STATUS CSReadKeyStrokeEx ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + OUT EFI_KEY_DATA *KeyData +) +{ + EFI_STATUS Status; + AMI_EFI_KEY_DATA EfiKeyData; + + if(KeyData == NULL) { + return EFI_INVALID_PARAMETER; + } + Status = CSReadEfiKey ( (AMI_EFIKEYCODE_PROTOCOL*) This, &EfiKeyData ); + if (Status == EFI_SUCCESS) { + KeyData->Key = EfiKeyData.Key; + KeyData->KeyState = EfiKeyData.KeyState; + return EFI_SUCCESS; + } + + return Status; +} + +// <AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Name: CSReadEfiKey +// +// Description: +// This function reads the next keystroke from the input device. This +// routine is a part of AmiKeyCode protocol implementation +// +// Input: +// IN AMI_EFIKEYCODE_PROTOCOL *This - pointer to protocol instance +// OUT AMI_EFI_KEY_DATA *KeyData - key pressed information +// +// Output: +// EFI_STATUS +// EFI_SUCCESS - Keystroke data successfully retrieved +// EFI_NOT_READY - There was no keystroke data available +// EFI_DEVICE_ERROR - The keystroke information was not returned +// due to hardware error +// +// Modified: +// +// Referrals: +// +// Notes: +// +//-------------------------------------------------------------------------- +// <AMI_PHDR_END> + +EFI_STATUS CSReadEfiKey ( + IN AMI_EFIKEYCODE_PROTOCOL *This, + OUT AMI_EFI_KEY_DATA *KeyData +) +{ + AMI_EFI_KEY_DATA TempKey; + EFI_STATUS Status = EFI_NOT_READY; + CON_SPLIT_IN *SimpleIn; + + if (StdInLocked) return EFI_ACCESS_DENIED; + + ConnectInputDevices(); + + if (ConInList.pHead == NULL) return EFI_NOT_READY; + + SimpleIn = OUTTER(ConInList.pHead, Link, CON_SPLIT_IN); + + pBS->SetMem(KeyData, sizeof(AMI_EFI_KEY_DATA), 0); + + // we need to loop through all the registered EfiKey, SimpleInEx and + // SimpleIn devices and call each of their ReadKeyStroke function + while (SimpleIn != NULL) + { + if (SimpleIn->KeycodeInEx) { + Status = SimpleIn->KeycodeInEx->ReadEfikey(SimpleIn->KeycodeInEx, &TempKey); + } else if(SimpleIn->SimpleInEx != NULL) { + Status = SimpleIn->SimpleInEx->ReadKeyStrokeEx( + SimpleIn->SimpleInEx, (EFI_KEY_DATA*)&TempKey); + } else if(SimpleIn->SimpleIn != NULL) { + Status = SimpleIn->SimpleIn->ReadKeyStroke( + SimpleIn->SimpleIn, (EFI_INPUT_KEY*)&TempKey); + } + + // Check for the Toggle State change + if (!EFI_ERROR(Status) && (TempKey.KeyState.KeyToggleState & TOGGLE_STATE_VALID)) { + if ((TempKey.KeyState.KeyToggleState & ~KEY_STATE_EXPOSED ) != mCSToggleState) { + mCSToggleState = (TempKey.KeyState.KeyToggleState & ~KEY_STATE_EXPOSED); + CSInSetState ( (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL*) This, + &mCSToggleState ); + } + } + + if (!EFI_ERROR(Status)) { + *KeyData = TempKey; + break; + } + + SimpleIn = OUTTER(SimpleIn->Link.pNext, Link, CON_SPLIT_IN); + } +#if PAUSEKEY_SUPPORT + if (!EFI_ERROR(Status) && TempKey.EfiKey == EfiKeyPause) { + while(TRUE) { + Status = CSReadEfiKey ( This, &TempKey ); + if ((!EFI_ERROR(Status)) && (TempKey.EfiKey != EfiKeyPause) && (TempKey.EfiKey != 0x55)) { + break; + } + } + *KeyData = TempKey; + } +#endif + return Status; +} + +// <AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Name: CSInSetState +// +// Description: +// This function sets certain state for input device +// +// Input: +// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This - pointer to protocol instance +// IN EFI_KEY_TOGGLE_STATE *KeyToggleState - pointer to state to set +// +// Output: +// EFI_STATUS +// EFI_SUCCESS - Keystroke data successfully retrieved +// EFI_UNSUPPORTED - Given state not supported +// EFI_INVALID_PARAMETER - KeyToggleState is NULL +// EFI_DEVICE_ERROR - input device not found +// EFI_ACCESS_DENIED - input device is busy +// +// Modified: +// +// Referrals: +// +// Notes: +// +//-------------------------------------------------------------------------- +// <AMI_PHDR_END> + +EFI_STATUS CSInSetState ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_KEY_TOGGLE_STATE *KeyToggleState +) +{ + EFI_STATUS Status = EFI_SUCCESS; + CON_SPLIT_IN *SimpleIn; + + if (StdInLocked) return EFI_ACCESS_DENIED; + + if (ConInList.pHead == NULL) + return EFI_UNSUPPORTED; + + if(KeyToggleState == NULL ) { + return EFI_INVALID_PARAMETER; + } + + if (!(*KeyToggleState & TOGGLE_STATE_VALID) || + ((*KeyToggleState & (~(TOGGLE_STATE_VALID | KEY_STATE_EXPOSED | + SCROLL_LOCK_ACTIVE | NUM_LOCK_ACTIVE | CAPS_LOCK_ACTIVE)))) ) { + return EFI_UNSUPPORTED; + } + + mCSToggleState = *KeyToggleState; // Update global toggle state + + SimpleIn = OUTTER(ConInList.pHead, Link, CON_SPLIT_IN); + + // we need to loop through all the registered KeycodeInEx devices + // and call each of their SetState function + while ( SimpleIn != NULL ) + { + if (SimpleIn->SimpleInEx) { + SimpleIn->SimpleInEx->SetState(SimpleIn->SimpleInEx, KeyToggleState); + } + SimpleIn = OUTTER(SimpleIn->Link.pNext, Link, CON_SPLIT_IN); + } + + return Status; +} + +// <AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Name: CSInKeyNotificationFunction +// +// Description: +// +// Input: +// +// Output: +// +// Modified: +// +// Referrals: +// +// Notes: +// +//-------------------------------------------------------------------------- +// <AMI_PHDR_END> + +EFI_STATUS +CSInKeyNotificationFunction( + IN EFI_KEY_DATA *KeyData +) +{ + EFI_STATUS Status = EFI_SUCCESS; + DLINK *ListPtr; + UINTN Index = 0; + UINTN Count = 0; + EFI_KEY_NOTIFY_FUNCTION *NotifyFunctionList = NULL; + CON_SPLIT_IN_KEY_NOTIFY *CsInKeyNotify = NULL; + + if (StdInLocked) return EFI_ACCESS_DENIED; + + if (ConInKeyNotifyList.pHead == NULL) return EFI_DEVICE_ERROR; + + Status = pBS->AllocatePool(EfiBootServicesData, + ConInKeyNotifyList.Size * sizeof(EFI_KEY_NOTIFY_FUNCTION), + (VOID**)&NotifyFunctionList); + if (EFI_ERROR(Status)) { + return EFI_OUT_OF_RESOURCES; + } + + for (ListPtr = ConInKeyNotifyList.pHead; ListPtr != NULL; ListPtr = ListPtr->pNext) { + CsInKeyNotify = OUTTER(ListPtr, Link, CON_SPLIT_IN_KEY_NOTIFY); + + if (!MemCmp(&(CsInKeyNotify->KeyData), KeyData, sizeof(CsInKeyNotify->KeyData))) { + NotifyFunctionList[Count++] = CsInKeyNotify->KeyNotificationFunction; + } + } + + for (Index = 0; Index < Count; Index++) { + NotifyFunctionList[Index](&(CsInKeyNotify->KeyData)); + } + + pBS->FreePool(NotifyFunctionList); + + return EFI_SUCCESS; +} + +// <AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Name: CSInRegisterKeyNotify +// +// Description: +// This function registers a notification function for a particular +// keystroke of the input device +// +// Input: +// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This - pointer to protocol instance +// IN EFI_KEY_DATA *KeyData - key value +// IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction - notification function +// OUT EFI_HANDLE *NotifyHandle - returned registered handle +// +// Output: +// EFI_STATUS +// EFI_SUCCESS - notification function registered successfully +// EFI_INVALID_PARAMETER - KeyData/KeyNotificationFunction/NotifyHandle is NULL +// EFI_DEVICE_ERROR - input device not found +// EFI_ACCESS_DENIED - input device is busy +// +// Modified: +// +// Referrals: +// +// Notes: +// +//-------------------------------------------------------------------------- +// <AMI_PHDR_END> + +EFI_STATUS CSInRegisterKeyNotify( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_KEY_DATA *KeyData, + IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, + OUT EFI_HANDLE *NotifyHandle +) +{ + EFI_STATUS Status = EFI_SUCCESS; + DLINK *ListPtr = NULL; + CON_SPLIT_IN *ConIn = NULL; + CON_SPLIT_IN_KEY_NOTIFY *CsInKeyNotify = NULL; + CON_SPLIT_IN_KEY_NOTIFY_HANDLE *CsInNotifyHandle = NULL; + + if (StdInLocked) return EFI_ACCESS_DENIED; + + if(KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL ) { + return EFI_INVALID_PARAMETER; + } + + for (ListPtr = ConInKeyNotifyList.pHead; ListPtr != NULL; ListPtr = ListPtr->pNext) { + CsInKeyNotify = OUTTER(ListPtr, Link, CON_SPLIT_IN_KEY_NOTIFY); + + if ((!MemCmp(&CsInKeyNotify->KeyData, KeyData, sizeof(CsInKeyNotify->KeyData))) && + (CsInKeyNotify->KeyNotificationFunction == KeyNotificationFunction)) { + *NotifyHandle = (EFI_HANDLE)&(CsInKeyNotify->Link); + return EFI_SUCCESS; + } + + } + + Status = pBS->AllocatePool(EfiBootServicesData, + sizeof(CON_SPLIT_IN_KEY_NOTIFY), &CsInKeyNotify); + if (EFI_ERROR(Status)) { + return EFI_OUT_OF_RESOURCES; + } + + MemCpy(&(CsInKeyNotify->KeyData), KeyData, sizeof(CsInKeyNotify->KeyData)); + CsInKeyNotify->KeyNotificationFunction = KeyNotificationFunction; + DListAdd(&ConInKeyNotifyList, &(CsInKeyNotify->Link)); + DListInit(&(CsInKeyNotify->NotifyHandleList)); + // we need to loop through all the registered SimpleInEx + // and call each of their ReadKeyStroke function + for (ListPtr = ConInList.pHead; ListPtr != NULL; ListPtr = ListPtr->pNext) { + ConIn = OUTTER(ListPtr, Link, CON_SPLIT_IN); + + if (ConIn->SimpleInEx == NULL) { + continue; + } + + Status = pBS->AllocatePool(EfiBootServicesData, + sizeof(CON_SPLIT_IN_KEY_NOTIFY_HANDLE), &CsInNotifyHandle); + if (EFI_ERROR(Status)) { + break; + } + + CsInNotifyHandle->SimpleInEx = ConIn->SimpleInEx; + DListAdd(&(CsInKeyNotify->NotifyHandleList), &(CsInNotifyHandle->Link)); + + Status = ConIn->SimpleInEx->RegisterKeyNotify(ConIn->SimpleInEx, + KeyData, CSInKeyNotificationFunction, &(CsInNotifyHandle->NotifyHandle)); + if (EFI_ERROR(Status)) { + break; + } + } + + if (EFI_ERROR(Status)) { + for (ListPtr = CsInKeyNotify->NotifyHandleList.pHead; + ListPtr != NULL; ListPtr = ListPtr->pNext) { + CsInNotifyHandle = OUTTER(ListPtr, Link, CON_SPLIT_IN_KEY_NOTIFY_HANDLE); + + CsInNotifyHandle->SimpleInEx->UnregisterKeyNotify( + CsInNotifyHandle->SimpleInEx, CsInNotifyHandle->NotifyHandle); + + DListDelete(&(CsInKeyNotify->NotifyHandleList), ListPtr); + pBS->FreePool(CsInNotifyHandle); + } + + pBS->FreePool(CsInKeyNotify); + + return Status; + } + + *NotifyHandle = (EFI_HANDLE)&(CsInKeyNotify->Link); + + return Status; +} + +// <AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Name: CSInUnRegisterKeyNotify +// +// Description: +// This function unregisters a notification function with given handle +// +// Input: +// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This - pointer to protocol instance +// IN EFI_HANDLE NotificationHandle - handle to unregister +// +// Output: +// EFI_STATUS +// EFI_SUCCESS - notification function unregistered successfully +// EFI_INVALID_PARAMETER - NotificationHandle is NULL +// EFI_DEVICE_ERROR - input device not found +// EFI_ACCESS_DENIED - input device is busy +// +// Modified: +// +// Referrals: +// +// Notes: +// +//-------------------------------------------------------------------------- +// <AMI_PHDR_END> + +EFI_STATUS CSInUnRegisterKeyNotify( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_HANDLE NotificationHandle +) +{ + EFI_STATUS Status = EFI_SUCCESS; + DLINK *ListPtr = NULL; + DLINK *HandleLink = NULL; + CON_SPLIT_IN_KEY_NOTIFY *CsInKeyNotify = NULL; + CON_SPLIT_IN_KEY_NOTIFY_HANDLE *CsInNotifyHandle = NULL; + + if (StdInLocked) return EFI_ACCESS_DENIED; + + if (NotificationHandle == NULL ) { + return EFI_INVALID_PARAMETER; + } + + for (ListPtr = ConInKeyNotifyList.pHead; ListPtr != NULL; ListPtr = ListPtr->pNext) { + CsInKeyNotify = OUTTER(ListPtr, Link, CON_SPLIT_IN_KEY_NOTIFY); + + if (NotificationHandle == (EFI_HANDLE)&(CsInKeyNotify->Link)) { + DListDelete(&ConInKeyNotifyList, ListPtr); + break; + } + } + + if (ListPtr == NULL) { + return EFI_INVALID_PARAMETER; + } + + // we need to loop through all the registered SimpleInEx + // and call each of their ReadKeyStroke function + + for (HandleLink = CsInKeyNotify->NotifyHandleList.pHead; HandleLink != NULL; + HandleLink = HandleLink->pNext) { + CsInNotifyHandle = OUTTER(HandleLink, Link, CON_SPLIT_IN_KEY_NOTIFY_HANDLE); + + Status = CsInNotifyHandle->SimpleInEx->UnregisterKeyNotify( + CsInNotifyHandle->SimpleInEx, CsInNotifyHandle->NotifyHandle); + + DListDelete(&(CsInKeyNotify->NotifyHandleList), HandleLink); + Status = pBS->FreePool(CsInNotifyHandle); + } + + Status = pBS->FreePool(CsInKeyNotify); + + return Status; +} + + +#if FAST_BOOT_SUPPORT +#include <Protocol/FastBootProtocol.h> +static AMI_FAST_BOOT_PROTOCOL *AmiFbProtocol = NULL; + +VOID ConnectInputDevices( + VOID +) +{ + EFI_STATUS Status; + static Executed = FALSE; + + if(Executed) + return; + + if(AmiFbProtocol == NULL) { + Status = pBS->LocateProtocol(&AmiFastBootProtocolGuid, NULL, &AmiFbProtocol); + if(EFI_ERROR(Status)) { + AmiFbProtocol = NULL; + return; + } + } + + if(AmiFbProtocol->IsRuntime()) { + AmiFbProtocol->ConnectInputDevices(); + Executed = TRUE; + } +} + +#else //#if FAST_BOOT_SUPPORT +VOID ConnectInputDevices( + VOID +){return;} +#endif + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** |