123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733 |
- /** @file
- Routines implements SIMPLE_TEXT_IN protocol's interfaces based on 8042 interfaces
- provided by Ps2KbdCtrller.c.
- Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "Ps2Keyboard.h"
- /**
- Check whether the EFI key buffer is empty.
- @param Queue Pointer to instance of EFI_KEY_QUEUE.
- @retval TRUE The EFI key buffer is empty.
- @retval FALSE The EFI key buffer isn't empty.
- **/
- BOOLEAN
- IsEfikeyBufEmpty (
- IN EFI_KEY_QUEUE *Queue
- )
- {
- return (BOOLEAN) (Queue->Head == Queue->Tail);
- }
- /**
- Read & remove one key data from the EFI key buffer.
- @param Queue Pointer to instance of EFI_KEY_QUEUE.
- @param KeyData Receive the key data.
- @retval EFI_SUCCESS The key data is popped successfully.
- @retval EFI_NOT_READY There is no key data available.
- **/
- EFI_STATUS
- PopEfikeyBufHead (
- IN EFI_KEY_QUEUE *Queue,
- OUT EFI_KEY_DATA *KeyData OPTIONAL
- )
- {
- if (IsEfikeyBufEmpty (Queue)) {
- return EFI_NOT_READY;
- }
- //
- // Retrieve and remove the values
- //
- if (KeyData != NULL) {
- CopyMem (KeyData, &Queue->Buffer[Queue->Head], sizeof (EFI_KEY_DATA));
- }
- Queue->Head = (Queue->Head + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;
- return EFI_SUCCESS;
- }
- /**
- Push one key data to the EFI key buffer.
- @param Queue Pointer to instance of EFI_KEY_QUEUE.
- @param KeyData The key data to push.
- **/
- VOID
- PushEfikeyBufTail (
- IN EFI_KEY_QUEUE *Queue,
- IN EFI_KEY_DATA *KeyData
- )
- {
- if ((Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT == Queue->Head) {
- //
- // If Queue is full, pop the one from head.
- //
- PopEfikeyBufHead (Queue, NULL);
- }
- CopyMem (&Queue->Buffer[Queue->Tail], KeyData, sizeof (EFI_KEY_DATA));
- Queue->Tail = (Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;
- }
- /**
- Judge whether is a registed key
- @param RegsiteredData A pointer to a buffer that is filled in with the keystroke
- state data for the key that was registered.
- @param InputData A pointer to a buffer that is filled in with the keystroke
- state data for the key that was pressed.
- @retval TRUE Key be pressed matches a registered key.
- @retval FLASE Match failed.
- **/
- BOOLEAN
- IsKeyRegistered (
- IN EFI_KEY_DATA *RegsiteredData,
- IN EFI_KEY_DATA *InputData
- )
- {
- ASSERT (RegsiteredData != NULL && InputData != NULL);
- if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
- (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {
- return FALSE;
- }
- //
- // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
- //
- if (RegsiteredData->KeyState.KeyShiftState != 0 &&
- RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {
- return FALSE;
- }
- if (RegsiteredData->KeyState.KeyToggleState != 0 &&
- RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {
- return FALSE;
- }
- return TRUE;
- }
- /**
- Reads the next keystroke from the input device. The WaitForKey Event can
- be used to test for existance of a keystroke via WaitForEvent () call.
- @param ConsoleInDev Ps2 Keyboard private structure
- @param KeyData A pointer to a buffer that is filled in with the keystroke
- state data for the key that was pressed.
- @retval EFI_SUCCESS The keystroke information was returned.
- @retval EFI_NOT_READY There was no keystroke data availiable.
- @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
- hardware errors.
- @retval EFI_INVALID_PARAMETER KeyData is NULL.
- **/
- EFI_STATUS
- KeyboardReadKeyStrokeWorker (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev,
- OUT EFI_KEY_DATA *KeyData
- )
- {
- EFI_STATUS Status;
- EFI_TPL OldTpl;
- if (KeyData == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // Enter critical section
- //
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
- KeyboardTimerHandler (NULL, ConsoleInDev);
- if (ConsoleInDev->KeyboardErr) {
- Status = EFI_DEVICE_ERROR;
- } else {
- Status = PopEfikeyBufHead (&ConsoleInDev->EfiKeyQueue, KeyData);
- if (Status == EFI_NOT_READY) {
- ZeroMem (&KeyData->Key, sizeof (KeyData->Key));
- InitializeKeyState (ConsoleInDev, &KeyData->KeyState);
- }
- }
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- /**
- Perform 8042 controller and keyboard initialization which implement SIMPLE_TEXT_IN.Reset()
- @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
- @param ExtendedVerification Indicate that the driver may perform a more
- exhaustive verification operation of the device during
- reset, now this par is ignored in this driver
- **/
- EFI_STATUS
- EFIAPI
- KeyboardEfiReset (
- IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
- IN BOOLEAN ExtendedVerification
- )
- {
- EFI_STATUS Status;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
- EFI_TPL OldTpl;
- ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
- if (ConsoleIn->KeyboardErr) {
- return EFI_DEVICE_ERROR;
- }
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET,
- ConsoleIn->DevicePath
- );
- //
- // Enter critical section
- //
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
- //
- // Call InitKeyboard to initialize the keyboard
- //
- Status = InitKeyboard (ConsoleIn, ExtendedVerification);
- if (EFI_ERROR (Status)) {
- //
- // Leave critical section and return
- //
- gBS->RestoreTPL (OldTpl);
- return EFI_DEVICE_ERROR;
- }
- //
- // Leave critical section and return
- //
- gBS->RestoreTPL (OldTpl);
- //
- // Report the status If a stuck key was detected
- //
- if (KeyReadStatusRegister (ConsoleIn) & 0x01) {
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_ERROR_CODE | EFI_ERROR_MINOR,
- EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_EC_STUCK_KEY,
- ConsoleIn->DevicePath
- );
- }
- //
- // Report the status If keyboard is locked
- //
- if ((KeyReadStatusRegister (ConsoleIn) & 0x10) == 0) {
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_ERROR_CODE | EFI_ERROR_MINOR,
- EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_EC_LOCKED,
- ConsoleIn->DevicePath
- );
- }
- return EFI_SUCCESS;
- }
- /**
- Retrieve key values for driver user which implement SIMPLE_TEXT_IN.ReadKeyStroke().
- @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
- @param Key The output buffer for key value
- @retval EFI_SUCCESS success to read key stroke
- **/
- EFI_STATUS
- EFIAPI
- KeyboardReadKeyStroke (
- IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
- OUT EFI_INPUT_KEY *Key
- )
- {
- EFI_STATUS Status;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
- EFI_KEY_DATA KeyData;
- ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
- //
- // Considering if the partial keystroke is enabled, there maybe a partial
- // keystroke in the queue, so here skip the partial keystroke and get the
- // next key from the queue
- //
- while (1) {
- //
- // If there is no pending key, then return.
- //
- Status = KeyboardReadKeyStrokeWorker (ConsoleIn, &KeyData);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // If it is partial keystroke, skip it.
- //
- if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {
- continue;
- }
- //
- // Translate the CTRL-Alpha characters to their corresponding control value
- // (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
- //
- if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {
- if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') {
- KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'a' + 1);
- } else if (KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') {
- KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'A' + 1);
- }
- }
- CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
- return EFI_SUCCESS;
- }
- }
- /**
- Event notification function for SIMPLE_TEXT_IN.WaitForKey event
- Signal the event if there is key available
- @param Event the event object
- @param Context waitting context
- **/
- VOID
- EFIAPI
- KeyboardWaitForKey (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- EFI_TPL OldTpl;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
- EFI_KEY_DATA KeyData;
- ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context;
- //
- // Enter critical section
- //
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
- KeyboardTimerHandler (NULL, ConsoleIn);
- if (!ConsoleIn->KeyboardErr) {
- //
- // WaitforKey doesn't suppor the partial key.
- // Considering if the partial keystroke is enabled, there maybe a partial
- // keystroke in the queue, so here skip the partial keystroke and get the
- // next key from the queue
- //
- while (!IsEfikeyBufEmpty (&ConsoleIn->EfiKeyQueue)) {
- CopyMem (
- &KeyData,
- &(ConsoleIn->EfiKeyQueue.Buffer[ConsoleIn->EfiKeyQueue.Head]),
- sizeof (EFI_KEY_DATA)
- );
- if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {
- PopEfikeyBufHead (&ConsoleIn->EfiKeyQueue, &KeyData);
- continue;
- }
- //
- // if there is pending value key, signal the event.
- //
- gBS->SignalEvent (Event);
- break;
- }
- }
- //
- // Leave critical section and return
- //
- gBS->RestoreTPL (OldTpl);
- }
- /**
- Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event
- Signal the event if there is key available
- @param Event event object
- @param Context waiting context
- **/
- VOID
- EFIAPI
- KeyboardWaitForKeyEx (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- KeyboardWaitForKey (Event, Context);
- }
- /**
- Reset the input device and optionaly run diagnostics
- @param This Protocol instance pointer.
- @param ExtendedVerification Driver may perform diagnostics on reset.
- @retval EFI_SUCCESS The device was reset.
- @retval EFI_DEVICE_ERROR The device is not functioning properly and could
- not be reset.
- **/
- EFI_STATUS
- EFIAPI
- KeyboardEfiResetEx (
- IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
- IN BOOLEAN ExtendedVerification
- )
- {
- KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
- ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
- return ConsoleInDev->ConIn.Reset (
- &ConsoleInDev->ConIn,
- ExtendedVerification
- );
- }
- /**
- Reads the next keystroke from the input device. The WaitForKey Event can
- be used to test for existance of a keystroke via WaitForEvent () call.
- @param This Protocol instance pointer.
- @param KeyData A pointer to a buffer that is filled in with the keystroke
- state data for the key that was pressed.
- @retval EFI_SUCCESS The keystroke information was returned.
- @retval EFI_NOT_READY There was no keystroke data availiable.
- @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
- hardware errors.
- @retval EFI_INVALID_PARAMETER KeyData is NULL.
- **/
- EFI_STATUS
- EFIAPI
- KeyboardReadKeyStrokeEx (
- IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
- OUT EFI_KEY_DATA *KeyData
- )
- {
- KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
- if (KeyData == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
- return KeyboardReadKeyStrokeWorker (ConsoleInDev, KeyData);
- }
- /**
- Set certain state for the input device.
- @param This Protocol instance pointer.
- @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
- state for the input device.
- @retval EFI_SUCCESS The device state was set successfully.
- @retval EFI_DEVICE_ERROR The device is not functioning correctly and could
- not have the setting adjusted.
- @retval EFI_UNSUPPORTED The device does not have the ability to set its state.
- @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
- **/
- EFI_STATUS
- EFIAPI
- KeyboardSetState (
- IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
- IN EFI_KEY_TOGGLE_STATE *KeyToggleState
- )
- {
- EFI_STATUS Status;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
- EFI_TPL OldTpl;
- if (KeyToggleState == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
- //
- // Enter critical section
- //
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
- if (ConsoleInDev->KeyboardErr) {
- Status = EFI_DEVICE_ERROR;
- goto Exit;
- }
- if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) {
- Status = EFI_UNSUPPORTED;
- goto Exit;
- }
- //
- // Update the status light
- //
- ConsoleInDev->ScrollLock = FALSE;
- ConsoleInDev->NumLock = FALSE;
- ConsoleInDev->CapsLock = FALSE;
- ConsoleInDev->IsSupportPartialKey = FALSE;
- if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {
- ConsoleInDev->ScrollLock = TRUE;
- }
- if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {
- ConsoleInDev->NumLock = TRUE;
- }
- if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {
- ConsoleInDev->CapsLock = TRUE;
- }
- if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) {
- ConsoleInDev->IsSupportPartialKey = TRUE;
- }
- Status = UpdateStatusLights (ConsoleInDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- }
- Exit:
- //
- // Leave critical section and return
- //
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- /**
- Register a notification function for a particular keystroke for the input device.
- @param This Protocol instance pointer.
- @param KeyData A pointer to a buffer that is filled in with the keystroke
- information data for the key that was pressed. If KeyData.Key,
- KeyData.KeyState.KeyToggleState and KeyData.KeyState.KeyShiftState are 0,
- then any incomplete keystroke will trigger a notification of the KeyNotificationFunction.
- @param KeyNotificationFunction Points to the function to be called when the key
- sequence is typed specified by KeyData. This notification function
- should be called at <=TPL_CALLBACK.
- @param NotifyHandle Points to the unique handle assigned to the registered notification.
- @retval EFI_SUCCESS The notification function was registered successfully.
- @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data structures.
- @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle or KeyNotificationFunction is NULL.
- **/
- EFI_STATUS
- EFIAPI
- KeyboardRegisterKeyNotify (
- IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
- IN EFI_KEY_DATA *KeyData,
- IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
- OUT VOID **NotifyHandle
- )
- {
- EFI_STATUS Status;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
- EFI_TPL OldTpl;
- LIST_ENTRY *Link;
- KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
- KEYBOARD_CONSOLE_IN_EX_NOTIFY *NewNotify;
- if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
- //
- // Enter critical section
- //
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
- //
- // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
- //
- for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) {
- CurrentNotify = CR (
- Link,
- KEYBOARD_CONSOLE_IN_EX_NOTIFY,
- NotifyEntry,
- KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
- );
- if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
- if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
- *NotifyHandle = CurrentNotify;
- Status = EFI_SUCCESS;
- goto Exit;
- }
- }
- }
- //
- // Allocate resource to save the notification function
- //
- NewNotify = (KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_EX_NOTIFY));
- if (NewNotify == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
- NewNotify->Signature = KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE;
- NewNotify->KeyNotificationFn = KeyNotificationFunction;
- CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));
- InsertTailList (&ConsoleInDev->NotifyList, &NewNotify->NotifyEntry);
- *NotifyHandle = NewNotify;
- Status = EFI_SUCCESS;
- Exit:
- //
- // Leave critical section and return
- //
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- /**
- Remove a registered notification function from a particular keystroke.
- @param This Protocol instance pointer.
- @param NotificationHandle The handle of the notification function being unregistered.
- @retval EFI_SUCCESS The notification function was unregistered successfully.
- @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
- **/
- EFI_STATUS
- EFIAPI
- KeyboardUnregisterKeyNotify (
- IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
- IN VOID *NotificationHandle
- )
- {
- EFI_STATUS Status;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
- EFI_TPL OldTpl;
- LIST_ENTRY *Link;
- KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
- if (NotificationHandle == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
- //
- // Enter critical section
- //
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
- for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) {
- CurrentNotify = CR (
- Link,
- KEYBOARD_CONSOLE_IN_EX_NOTIFY,
- NotifyEntry,
- KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
- );
- if (CurrentNotify == NotificationHandle) {
- //
- // Remove the notification function from NotifyList and free resources
- //
- RemoveEntryList (&CurrentNotify->NotifyEntry);
- gBS->FreePool (CurrentNotify);
- Status = EFI_SUCCESS;
- goto Exit;
- }
- }
- //
- // Can not find the specified Notification Handle
- //
- Status = EFI_INVALID_PARAMETER;
- Exit:
- //
- // Leave critical section and return
- //
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- /**
- Process key notify.
- @param Event Indicates the event that invoke this function.
- @param Context Indicates the calling context.
- **/
- VOID
- EFIAPI
- KeyNotifyProcessHandler (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- EFI_STATUS Status;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
- EFI_KEY_DATA KeyData;
- LIST_ENTRY *Link;
- LIST_ENTRY *NotifyList;
- KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
- EFI_TPL OldTpl;
- ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context;
- //
- // Invoke notification functions.
- //
- NotifyList = &ConsoleIn->NotifyList;
- while (TRUE) {
- //
- // Enter critical section
- //
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
- Status = PopEfikeyBufHead (&ConsoleIn->EfiKeyQueueForNotify, &KeyData);
- //
- // Leave critical section
- //
- gBS->RestoreTPL (OldTpl);
- if (EFI_ERROR (Status)) {
- break;
- }
- for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {
- CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
- if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
- CurrentNotify->KeyNotificationFn (&KeyData);
- }
- }
- }
- }
|