From 66aa04e4e3a0b84369cbb483a78c4113b619663a Mon Sep 17 00:00:00 2001 From: qhuang8 Date: Fri, 19 Oct 2007 02:35:29 +0000 Subject: Update to support EFI_SIMPLE_INPUT_EX protocol git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4178 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Bus/Usb/UsbKbDxe/efikey.c | 634 ++++++++++++++++++++++++++++++--- 1 file changed, 586 insertions(+), 48 deletions(-) (limited to 'MdeModulePkg/Bus/Usb/UsbKbDxe/efikey.c') diff --git a/MdeModulePkg/Bus/Usb/UsbKbDxe/efikey.c b/MdeModulePkg/Bus/Usb/UsbKbDxe/efikey.c index 62fec041c3..eee3827c23 100644 --- a/MdeModulePkg/Bus/Usb/UsbKbDxe/efikey.c +++ b/MdeModulePkg/Bus/Usb/UsbKbDxe/efikey.c @@ -100,6 +100,18 @@ USBKeyboardCheckForKey ( EFI_GUID gEfiUsbKeyboardDriverGuid = { 0xa05f5f78, 0xfb3, 0x4d10, {0x90, 0x90, 0xac, 0x4, 0x6e, 0xeb, 0x7c, 0x3c} }; +STATIC +EFI_STATUS +KbdFreeNotifyList ( + IN OUT LIST_ENTRY *ListHead + ); +STATIC +BOOLEAN +IsKeyRegistered ( + IN EFI_KEY_DATA *RegsiteredData, + IN EFI_KEY_DATA *InputData + ); + // // USB Keyboard Driver Global Variables @@ -349,6 +361,27 @@ USBKeyboardDriverBindingStart ( UsbKeyboardDevice->Signature = USB_KB_DEV_SIGNATURE; UsbKeyboardDevice->SimpleInput.Reset = USBKeyboardReset; UsbKeyboardDevice->SimpleInput.ReadKeyStroke = USBKeyboardReadKeyStroke; + + UsbKeyboardDevice->SimpleInputEx.Reset = USBKeyboardResetEx; + UsbKeyboardDevice->SimpleInputEx.ReadKeyStrokeEx = USBKeyboardReadKeyStrokeEx; + UsbKeyboardDevice->SimpleInputEx.SetState = USBKeyboardSetState; + UsbKeyboardDevice->SimpleInputEx.RegisterKeyNotify = USBKeyboardRegisterKeyNotify; + UsbKeyboardDevice->SimpleInputEx.UnregisterKeyNotify = USBKeyboardUnregisterKeyNotify; + + InitializeListHead (&UsbKeyboardDevice->NotifyList); + + Status = gBS->CreateEvent ( + EVT_NOTIFY_WAIT, + TPL_NOTIFY, + USBKeyboardWaitForKey, + UsbKeyboardDevice, + &(UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx) + ); + + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + Status = gBS->CreateEvent ( EVT_NOTIFY_WAIT, TPL_NOTIFY, @@ -380,6 +413,8 @@ USBKeyboardDriverBindingStart ( &Controller, &gEfiSimpleTextInProtocolGuid, &UsbKeyboardDevice->SimpleInput, + &gEfiSimpleTextInputExProtocolGuid, + &UsbKeyboardDevice->SimpleInputEx, &gEfiHotPlugDeviceGuid, NULL, NULL @@ -405,13 +440,15 @@ USBKeyboardDriverBindingStart ( ); if (EFI_ERROR (Status)) { gBS->UninstallMultipleProtocolInterfaces ( - Controller, - &gEfiSimpleTextInProtocolGuid, - &UsbKeyboardDevice->SimpleInput, - &gEfiHotPlugDeviceGuid, - NULL, - NULL - ); + Controller, + &gEfiSimpleTextInProtocolGuid, + &UsbKeyboardDevice->SimpleInput, + &gEfiSimpleTextInputExProtocolGuid, + &UsbKeyboardDevice->SimpleInputEx, + &gEfiHotPlugDeviceGuid, + NULL, + NULL + ); gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey); gBS->FreePool (UsbKeyboardDevice); gBS->CloseProtocol ( @@ -442,13 +479,15 @@ USBKeyboardDriverBindingStart ( if (EFI_ERROR (Status)) { gBS->UninstallMultipleProtocolInterfaces ( - Controller, - &gEfiSimpleTextInProtocolGuid, - &UsbKeyboardDevice->SimpleInput, - &gEfiHotPlugDeviceGuid, - NULL, - NULL - ); + Controller, + &gEfiSimpleTextInProtocolGuid, + &UsbKeyboardDevice->SimpleInput, + &gEfiSimpleTextInputExProtocolGuid, + &UsbKeyboardDevice->SimpleInputEx, + &gEfiHotPlugDeviceGuid, + NULL, + NULL + ); gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey); gBS->FreePool (UsbKeyboardDevice); gBS->CloseProtocol ( @@ -478,6 +517,27 @@ USBKeyboardDriverBindingStart ( return EFI_SUCCESS; + +ErrorExit: + if (UsbKeyboardDevice != NULL) { + if (UsbKeyboardDevice->SimpleInput.WaitForKey != NULL) { + gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey); + } + if (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx != NULL) { + gBS->CloseEvent (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx); + } + KbdFreeNotifyList (&UsbKeyboardDevice->NotifyList); + gBS->FreePool (UsbKeyboardDevice); + UsbKeyboardDevice = NULL; + } + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return Status; + } @@ -518,7 +578,17 @@ USBKeyboardDriverBindingStop ( if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } - + Status = gBS->OpenProtocol ( + Controller, + &gEfiSimpleTextInputExProtocolGuid, + NULL, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } // // Get USB_KB_DEV instance. // @@ -565,6 +635,8 @@ USBKeyboardDriverBindingStop ( Controller, &gEfiSimpleTextInProtocolGuid, &UsbKeyboardDevice->SimpleInput, + &gEfiSimpleTextInputExProtocolGuid, + &UsbKeyboardDevice->SimpleInputEx, &gEfiHotPlugDeviceGuid, NULL, NULL @@ -575,6 +647,8 @@ USBKeyboardDriverBindingStop ( gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer); gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent); gBS->CloseEvent ((UsbKeyboardDevice->SimpleInput).WaitForKey); + gBS->CloseEvent (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx); + KbdFreeNotifyList (&UsbKeyboardDevice->NotifyList); if (UsbKeyboardDevice->ControllerNameTable != NULL) { FreeUnicodeStringTable (UsbKeyboardDevice->ControllerNameTable); @@ -586,20 +660,107 @@ USBKeyboardDriverBindingStop ( } +STATIC +EFI_STATUS +USBKeyboardReadKeyStrokeWorker ( + IN USB_KB_DEV *UsbKeyboardDevice, + OUT EFI_KEY_DATA *KeyData + ) +/*++ + + Routine Description: + Reads the next keystroke from the input device. The WaitForKey Event can + be used to test for existance of a keystroke via WaitForEvent () call. + Arguments: + UsbKeyboardDevice - Usb keyboard private structure. + KeyData - A pointer to a buffer that is filled in with the keystroke + state data for the key that was pressed. -/** - Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset() function. + Returns: + EFI_SUCCESS - The keystroke information was returned. + EFI_NOT_READY - There was no keystroke data availiable. + EFI_DEVICE_ERROR - The keystroke information was not returned due to + hardware errors. + EFI_INVALID_PARAMETER - KeyData is NULL. - This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance. - ExtendedVerification - Indicates that the driver may perform a more exhaustive - verification operation of the device during reset. +--*/ +{ - @retval EFI_SUCCESS Success - @retval EFI_DEVICE_ERROR Hardware Error + EFI_STATUS Status; + UINT8 KeyChar; + LIST_ENTRY *Link; + KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; + EFI_KEY_DATA OriginalKeyData; -**/ + if (KeyData == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // if there is no saved ASCII byte, fetch it + // by calling USBKeyboardCheckForKey(). + // + if (UsbKeyboardDevice->CurKeyChar == 0) { + Status = USBKeyboardCheckForKey (UsbKeyboardDevice); + if (EFI_ERROR (Status)) { + return Status; + } + } + + KeyData->Key.UnicodeChar = 0; + KeyData->Key.ScanCode = SCAN_NULL; + + KeyChar = UsbKeyboardDevice->CurKeyChar; + + UsbKeyboardDevice->CurKeyChar = 0; + + // + // Translate saved ASCII byte into EFI_INPUT_KEY + // + Status = USBKeyCodeToEFIScanCode (UsbKeyboardDevice, KeyChar, &KeyData->Key); + if (EFI_ERROR (Status)) { + return Status; + } + + CopyMem (&KeyData->KeyState, &UsbKeyboardDevice->KeyState, sizeof (KeyData->KeyState)); + + UsbKeyboardDevice->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID; + UsbKeyboardDevice->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID; + + // + //Switch the control value to their original characters. In USBKeyCodeToEFIScanCode() the CTRL-Alpha characters have been switched to + // their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A), here switch them back for notification function. + // + CopyMem (&OriginalKeyData, KeyData, sizeof (EFI_KEY_DATA)); + if (UsbKeyboardDevice->CtrlOn) { + if (OriginalKeyData.Key.UnicodeChar >= 0x01 && OriginalKeyData.Key.UnicodeChar <= 0x1A) { + if (UsbKeyboardDevice->CapsOn) { + OriginalKeyData.Key.UnicodeChar = (CHAR16)(OriginalKeyData.Key.UnicodeChar + 'A' - 1); + } else { + OriginalKeyData.Key.UnicodeChar = (CHAR16)(OriginalKeyData.Key.UnicodeChar + 'a' - 1); + } + } + } + + // + // Invoke notification functions if exist + // + for (Link = UsbKeyboardDevice->NotifyList.ForwardLink; Link != &UsbKeyboardDevice->NotifyList; Link = Link->ForwardLink) { + CurrentNotify = CR ( + Link, + KEYBOARD_CONSOLE_IN_EX_NOTIFY, + NotifyEntry, + USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE + ); + if (IsKeyRegistered (&CurrentNotify->KeyData, &OriginalKeyData)) { + CurrentNotify->KeyNotificationFn (&OriginalKeyData); + } + } + + return EFI_SUCCESS; + +} EFI_STATUS EFIAPI USBKeyboardReset ( @@ -668,36 +829,20 @@ USBKeyboardReadKeyStroke ( OUT EFI_INPUT_KEY *Key ) { - USB_KB_DEV *UsbKeyboardDevice; - EFI_STATUS Status; - UINT8 KeyChar; + USB_KB_DEV *UsbKeyboardDevice; + EFI_STATUS Status; + EFI_KEY_DATA KeyData; UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This); - // - // if there is no saved ASCII byte, fetch it - // by calling USBKeyboardCheckForKey(). - // - if (UsbKeyboardDevice->CurKeyChar == 0) { - Status = USBKeyboardCheckForKey (UsbKeyboardDevice); - if (EFI_ERROR (Status)) { - return Status; - } + Status = USBKeyboardReadKeyStrokeWorker (UsbKeyboardDevice, &KeyData); + if (EFI_ERROR (Status)) { + return Status; } - Key->UnicodeChar = 0; - Key->ScanCode = SCAN_NULL; - - KeyChar = UsbKeyboardDevice->CurKeyChar; + CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY)); - UsbKeyboardDevice->CurKeyChar = 0; - - // - // Translate saved ASCII byte into EFI_INPUT_KEY - // - Status = USBKeyCodeToEFIScanCode (UsbKeyboardDevice, KeyChar, Key); - - return Status; + return EFI_SUCCESS; } @@ -792,3 +937,396 @@ KbdReportStatusCode ( DevicePath ); } +STATIC +EFI_STATUS +KbdFreeNotifyList ( + IN OUT LIST_ENTRY *ListHead + ) +/*++ + +Routine Description: + +Arguments: + + ListHead - The list head + +Returns: + + EFI_SUCCESS - Free the notify list successfully + EFI_INVALID_PARAMETER - ListHead is invalid. + +--*/ +{ + KEYBOARD_CONSOLE_IN_EX_NOTIFY *NotifyNode; + + if (ListHead == NULL) { + return EFI_INVALID_PARAMETER; + } + while (!IsListEmpty (ListHead)) { + NotifyNode = CR ( + ListHead->ForwardLink, + KEYBOARD_CONSOLE_IN_EX_NOTIFY, + NotifyEntry, + USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE + ); + RemoveEntryList (ListHead->ForwardLink); + gBS->FreePool (NotifyNode); + } + + return EFI_SUCCESS; +} + +STATIC +BOOLEAN +IsKeyRegistered ( + IN EFI_KEY_DATA *RegsiteredData, + IN EFI_KEY_DATA *InputData + ) +/*++ + +Routine Description: + +Arguments: + + RegsiteredData - A pointer to a buffer that is filled in with the keystroke + state data for the key that was registered. + InputData - A pointer to a buffer that is filled in with the keystroke + state data for the key that was pressed. + +Returns: + TRUE - Key be pressed matches a registered key. + FLASE - Match failed. + +--*/ +{ + 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; + +} + +// +// Simple Text Input Ex protocol functions +// +EFI_STATUS +EFIAPI +USBKeyboardResetEx ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +/*++ + + Routine Description: + Reset the input device and optionaly run diagnostics + + Arguments: + This - Protocol instance pointer. + ExtendedVerification - Driver may perform diagnostics on reset. + + Returns: + EFI_SUCCESS - The device was reset. + EFI_DEVICE_ERROR - The device is not functioning properly and could + not be reset. + +--*/ +{ + EFI_STATUS Status; + USB_KB_DEV *UsbKeyboardDevice; + EFI_TPL OldTpl; + + + UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This); + + Status = UsbKeyboardDevice->SimpleInput.Reset (&UsbKeyboardDevice->SimpleInput, ExtendedVerification); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + OldTpl = gBS->RaiseTPL (TPL_NOTIFY); + UsbKeyboardDevice->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID; + UsbKeyboardDevice->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID; + gBS->RestoreTPL (OldTpl); + + return EFI_SUCCESS; + +} + +EFI_STATUS +EFIAPI +USBKeyboardReadKeyStrokeEx ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + OUT EFI_KEY_DATA *KeyData + ) +/*++ + + Routine Description: + Reads the next keystroke from the input device. The WaitForKey Event can + be used to test for existance of a keystroke via WaitForEvent () call. + + Arguments: + This - Protocol instance pointer. + KeyData - A pointer to a buffer that is filled in with the keystroke + state data for the key that was pressed. + + Returns: + EFI_SUCCESS - The keystroke information was returned. + EFI_NOT_READY - There was no keystroke data availiable. + EFI_DEVICE_ERROR - The keystroke information was not returned due to + hardware errors. + EFI_INVALID_PARAMETER - KeyData is NULL. + +--*/ +{ + USB_KB_DEV *UsbKeyboardDevice; + + if (KeyData == NULL) { + return EFI_INVALID_PARAMETER; + } + + UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This); + + return USBKeyboardReadKeyStrokeWorker (UsbKeyboardDevice, KeyData); + +} + +EFI_STATUS +EFIAPI +USBKeyboardSetState ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_KEY_TOGGLE_STATE *KeyToggleState + ) +/*++ + + Routine Description: + Set certain state for the input device. + + Arguments: + This - Protocol instance pointer. + KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the + state for the input device. + + Returns: + EFI_SUCCESS - The device state was set successfully. + EFI_DEVICE_ERROR - The device is not functioning correctly and could + not have the setting adjusted. + EFI_UNSUPPORTED - The device does not have the ability to set its state. + EFI_INVALID_PARAMETER - KeyToggleState is NULL. + +--*/ +{ + USB_KB_DEV *UsbKeyboardDevice; + + if (KeyToggleState == NULL) { + return EFI_INVALID_PARAMETER; + } + + UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This); + + if (((UsbKeyboardDevice->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) || + ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID)) { + return EFI_UNSUPPORTED; + } + + // + // Update the status light + // + + UsbKeyboardDevice->ScrollOn = 0; + UsbKeyboardDevice->NumLockOn = 0; + UsbKeyboardDevice->CapsOn = 0; + + if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) { + UsbKeyboardDevice->ScrollOn = 1; + } + if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) { + UsbKeyboardDevice->NumLockOn = 1; + } + if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) { + UsbKeyboardDevice->CapsOn = 1; + } + + SetKeyLED (UsbKeyboardDevice); + + UsbKeyboardDevice->KeyState.KeyToggleState = *KeyToggleState; + + return EFI_SUCCESS; + +} + +EFI_STATUS +EFIAPI +USBKeyboardRegisterKeyNotify ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_KEY_DATA *KeyData, + IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, + OUT EFI_HANDLE *NotifyHandle + ) +/*++ + + Routine Description: + Register a notification function for a particular keystroke for the input device. + + Arguments: + This - Protocol instance pointer. + KeyData - A pointer to a buffer that is filled in with the keystroke + information data for the key that was pressed. + KeyNotificationFunction - Points to the function to be called when the key + sequence is typed specified by KeyData. + NotifyHandle - Points to the unique handle assigned to the registered notification. + + Returns: + EFI_SUCCESS - The notification function was registered successfully. + EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures. + EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL. + +--*/ +{ + USB_KB_DEV *UsbKeyboardDevice; + EFI_STATUS Status; + KEYBOARD_CONSOLE_IN_EX_NOTIFY *NewNotify; + LIST_ENTRY *Link; + KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; + + if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) { + return EFI_INVALID_PARAMETER; + } + + UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This); + + // + // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered. + // + for (Link = UsbKeyboardDevice->NotifyList.ForwardLink; Link != &UsbKeyboardDevice->NotifyList; Link = Link->ForwardLink) { + CurrentNotify = CR ( + Link, + KEYBOARD_CONSOLE_IN_EX_NOTIFY, + NotifyEntry, + USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE + ); + if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { + if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) { + *NotifyHandle = CurrentNotify->NotifyHandle; + return EFI_SUCCESS; + } + } + } + + // + // Allocate resource to save the notification function + // + NewNotify = (KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_EX_NOTIFY)); + if (NewNotify == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + NewNotify->Signature = USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE; + NewNotify->KeyNotificationFn = KeyNotificationFunction; + CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA)); + InsertTailList (&UsbKeyboardDevice->NotifyList, &NewNotify->NotifyEntry); + + // + // Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &NewNotify->NotifyHandle, + &gSimpleTextInExNotifyGuid, + NULL, + NULL + ); + ASSERT_EFI_ERROR (Status); + + *NotifyHandle = NewNotify->NotifyHandle; + + return EFI_SUCCESS; + +} + +EFI_STATUS +EFIAPI +USBKeyboardUnregisterKeyNotify ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_HANDLE NotificationHandle + ) +/*++ + + Routine Description: + Remove a registered notification function from a particular keystroke. + + Arguments: + This - Protocol instance pointer. + NotificationHandle - The handle of the notification function being unregistered. + + Returns: + EFI_SUCCESS - The notification function was unregistered successfully. + EFI_INVALID_PARAMETER - The NotificationHandle is invalid. + EFI_NOT_FOUND - Can not find the matching entry in database. + +--*/ +{ + USB_KB_DEV *UsbKeyboardDevice; + EFI_STATUS Status; + KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; + LIST_ENTRY *Link; + + if (NotificationHandle == NULL) { + return EFI_INVALID_PARAMETER; + } + + UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This); + + Status = gBS->OpenProtocol ( + NotificationHandle, + &gSimpleTextInExNotifyGuid, + NULL, + NULL, + NULL, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_INVALID_PARAMETER; + } + + for (Link = UsbKeyboardDevice->NotifyList.ForwardLink; Link != &UsbKeyboardDevice->NotifyList; Link = Link->ForwardLink) { + CurrentNotify = CR ( + Link, + KEYBOARD_CONSOLE_IN_EX_NOTIFY, + NotifyEntry, + USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE + ); + if (CurrentNotify->NotifyHandle == NotificationHandle) { + // + // Remove the notification function from NotifyList and free resources + // + RemoveEntryList (&CurrentNotify->NotifyEntry); + Status = gBS->UninstallMultipleProtocolInterfaces ( + CurrentNotify->NotifyHandle, + &gSimpleTextInExNotifyGuid, + NULL, + NULL + ); + ASSERT_EFI_ERROR (Status); + gBS->FreePool (CurrentNotify); + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + -- cgit v1.2.3