3 Copyright (c) 2004 - 2008, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
30 // Driver model protocol interface
34 USBKeyboardDriverBindingEntryPoint (
35 IN EFI_HANDLE ImageHandle
,
36 IN EFI_SYSTEM_TABLE
*SystemTable
41 USBKeyboardDriverBindingSupported (
42 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
43 IN EFI_HANDLE Controller
,
44 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
49 USBKeyboardDriverBindingStart (
50 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
51 IN EFI_HANDLE Controller
,
52 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
57 USBKeyboardDriverBindingStop (
58 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
59 IN EFI_HANDLE Controller
,
60 IN UINTN NumberOfChildren
,
61 IN EFI_HANDLE
*ChildHandleBuffer
65 // Simple Text In Protocol Interface
71 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
72 IN BOOLEAN ExtendedVerification
78 USBKeyboardReadKeyStroke (
79 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
80 OUT EFI_INPUT_KEY
*Key
86 USBKeyboardWaitForKey (
96 USBKeyboardCheckForKey (
97 IN USB_KB_DEV
*UsbKeyboardDevice
100 EFI_GUID gEfiUsbKeyboardDriverGuid
= {
101 0xa05f5f78, 0xfb3, 0x4d10, {0x90, 0x90, 0xac, 0x4, 0x6e, 0xeb, 0x7c, 0x3c}
106 IN OUT LIST_ENTRY
*ListHead
111 IN EFI_KEY_DATA
*RegsiteredData
,
112 IN EFI_KEY_DATA
*InputData
117 // USB Keyboard Driver Global Variables
119 EFI_DRIVER_BINDING_PROTOCOL gUsbKeyboardDriverBinding
= {
120 USBKeyboardDriverBindingSupported
,
121 USBKeyboardDriverBindingStart
,
122 USBKeyboardDriverBindingStop
,
130 USBKeyboardDriverBindingEntryPoint (
131 IN EFI_HANDLE ImageHandle
,
132 IN EFI_SYSTEM_TABLE
*SystemTable
140 ImageHandle - EFI_HANDLE
141 SystemTable - EFI_SYSTEM_TABLE
147 return EfiLibInstallDriverBindingComponentName2 (
150 &gUsbKeyboardDriverBinding
,
152 &gUsbKeyboardComponentName
,
153 &gUsbKeyboardComponentName2
162 @param This EFI_DRIVER_BINDING_PROTOCOL
163 @param Controller Controller handle
164 @param RemainingDevicePath EFI_DEVICE_PATH_PROTOCOL
170 USBKeyboardDriverBindingSupported (
171 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
172 IN EFI_HANDLE Controller
,
173 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
176 EFI_STATUS OpenStatus
;
177 EFI_USB_IO_PROTOCOL
*UsbIo
;
181 // Check if USB_IO protocol is attached on the controller handle.
183 OpenStatus
= gBS
->OpenProtocol (
185 &gEfiUsbIoProtocolGuid
,
187 This
->DriverBindingHandle
,
189 EFI_OPEN_PROTOCOL_BY_DRIVER
191 if (EFI_ERROR (OpenStatus
)) {
196 // Use the USB I/O protocol interface to check whether the Controller is
197 // the Keyboard controller that can be managed by this driver.
199 Status
= EFI_SUCCESS
;
201 if (!IsUSBKeyboard (UsbIo
)) {
202 Status
= EFI_UNSUPPORTED
;
207 &gEfiUsbIoProtocolGuid
,
208 This
->DriverBindingHandle
,
219 @param This EFI_DRIVER_BINDING_PROTOCOL
220 @param Controller Controller handle
221 @param RemainingDevicePath EFI_DEVICE_PATH_PROTOCOL
223 @retval EFI_SUCCESS Success
224 @retval EFI_OUT_OF_RESOURCES Can't allocate memory
225 @retval EFI_UNSUPPORTED The Start routine fail
230 USBKeyboardDriverBindingStart (
231 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
232 IN EFI_HANDLE Controller
,
233 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
237 EFI_USB_IO_PROTOCOL
*UsbIo
;
238 USB_KB_DEV
*UsbKeyboardDevice
;
239 UINT8 EndpointNumber
;
240 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
243 UINT8 PollingInterval
;
247 UsbKeyboardDevice
= NULL
;
251 // Open USB_IO Protocol
253 Status
= gBS
->OpenProtocol (
255 &gEfiUsbIoProtocolGuid
,
257 This
->DriverBindingHandle
,
259 EFI_OPEN_PROTOCOL_BY_DRIVER
261 if (EFI_ERROR (Status
)) {
265 UsbKeyboardDevice
= AllocateZeroPool (sizeof (USB_KB_DEV
));
266 if (UsbKeyboardDevice
== NULL
) {
269 &gEfiUsbIoProtocolGuid
,
270 This
->DriverBindingHandle
,
273 return EFI_OUT_OF_RESOURCES
;
276 // Get the Device Path Protocol on Controller's handle
278 Status
= gBS
->OpenProtocol (
280 &gEfiDevicePathProtocolGuid
,
281 (VOID
**) &UsbKeyboardDevice
->DevicePath
,
282 This
->DriverBindingHandle
,
284 EFI_OPEN_PROTOCOL_GET_PROTOCOL
287 if (EFI_ERROR (Status
)) {
288 gBS
->FreePool (UsbKeyboardDevice
);
291 &gEfiUsbIoProtocolGuid
,
292 This
->DriverBindingHandle
,
298 // Report that the usb keyboard is being enabled
300 KbdReportStatusCode (
301 UsbKeyboardDevice
->DevicePath
,
303 PcdGet32 (PcdStatusCodeValueKeyboardEnable
)
307 // This is pretty close to keyboard detection, so log progress
309 KbdReportStatusCode (
310 UsbKeyboardDevice
->DevicePath
,
312 PcdGet32 (PcdStatusCodeValueKeyboardPresenceDetect
)
316 // Initialize UsbKeyboardDevice
318 UsbKeyboardDevice
->UsbIo
= UsbIo
;
321 // Get interface & endpoint descriptor
323 UsbIo
->UsbGetInterfaceDescriptor (
325 &UsbKeyboardDevice
->InterfaceDescriptor
328 EndpointNumber
= UsbKeyboardDevice
->InterfaceDescriptor
.NumEndpoints
;
330 for (Index
= 0; Index
< EndpointNumber
; Index
++) {
332 UsbIo
->UsbGetEndpointDescriptor (
338 if ((EndpointDescriptor
.Attributes
& 0x03) == 0x03) {
340 // We only care interrupt endpoint here
342 CopyMem(&UsbKeyboardDevice
->IntEndpointDescriptor
, &EndpointDescriptor
, sizeof(EndpointDescriptor
));
349 // No interrupt endpoint found, then return unsupported.
351 gBS
->FreePool (UsbKeyboardDevice
);
354 &gEfiUsbIoProtocolGuid
,
355 This
->DriverBindingHandle
,
358 return EFI_UNSUPPORTED
;
361 UsbKeyboardDevice
->Signature
= USB_KB_DEV_SIGNATURE
;
362 UsbKeyboardDevice
->SimpleInput
.Reset
= USBKeyboardReset
;
363 UsbKeyboardDevice
->SimpleInput
.ReadKeyStroke
= USBKeyboardReadKeyStroke
;
365 UsbKeyboardDevice
->SimpleInputEx
.Reset
= USBKeyboardResetEx
;
366 UsbKeyboardDevice
->SimpleInputEx
.ReadKeyStrokeEx
= USBKeyboardReadKeyStrokeEx
;
367 UsbKeyboardDevice
->SimpleInputEx
.SetState
= USBKeyboardSetState
;
368 UsbKeyboardDevice
->SimpleInputEx
.RegisterKeyNotify
= USBKeyboardRegisterKeyNotify
;
369 UsbKeyboardDevice
->SimpleInputEx
.UnregisterKeyNotify
= USBKeyboardUnregisterKeyNotify
;
371 InitializeListHead (&UsbKeyboardDevice
->NotifyList
);
373 Status
= gBS
->CreateEvent (
376 USBKeyboardWaitForKey
,
378 &(UsbKeyboardDevice
->SimpleInputEx
.WaitForKeyEx
)
381 if (EFI_ERROR (Status
)) {
385 Status
= InitKeyboardLayout (UsbKeyboardDevice
);
386 if (EFI_ERROR (Status
)) {
390 Status
= gBS
->CreateEvent (
393 USBKeyboardWaitForKey
,
395 &(UsbKeyboardDevice
->SimpleInput
.WaitForKey
)
398 if (EFI_ERROR (Status
)) {
399 gBS
->FreePool (UsbKeyboardDevice
);
402 &gEfiUsbIoProtocolGuid
,
403 This
->DriverBindingHandle
,
410 // Install simple txt in protocol interface
411 // for the usb keyboard device.
412 // Usb keyboard is a hot plug device, and expected to work immediately
413 // when plugging into system, so a HotPlugDeviceGuid is installed onto
414 // the usb keyboard device handle, to distinguish it from other conventional
417 Status
= gBS
->InstallMultipleProtocolInterfaces (
419 &gEfiSimpleTextInProtocolGuid
,
420 &UsbKeyboardDevice
->SimpleInput
,
421 &gEfiSimpleTextInputExProtocolGuid
,
422 &UsbKeyboardDevice
->SimpleInputEx
,
423 &gEfiHotPlugDeviceGuid
,
427 if (EFI_ERROR (Status
)) {
428 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
429 gBS
->FreePool (UsbKeyboardDevice
);
432 &gEfiUsbIoProtocolGuid
,
433 This
->DriverBindingHandle
,
440 // Reset USB Keyboard Device
442 Status
= UsbKeyboardDevice
->SimpleInput
.Reset (
443 &UsbKeyboardDevice
->SimpleInput
,
446 if (EFI_ERROR (Status
)) {
447 gBS
->UninstallMultipleProtocolInterfaces (
449 &gEfiSimpleTextInProtocolGuid
,
450 &UsbKeyboardDevice
->SimpleInput
,
451 &gEfiSimpleTextInputExProtocolGuid
,
452 &UsbKeyboardDevice
->SimpleInputEx
,
453 &gEfiHotPlugDeviceGuid
,
457 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
458 gBS
->FreePool (UsbKeyboardDevice
);
461 &gEfiUsbIoProtocolGuid
,
462 This
->DriverBindingHandle
,
468 // submit async interrupt transfer
470 EndpointAddr
= UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
;
471 PollingInterval
= UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
;
472 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
474 Status
= UsbIo
->UsbAsyncInterruptTransfer (
484 if (EFI_ERROR (Status
)) {
486 gBS
->UninstallMultipleProtocolInterfaces (
488 &gEfiSimpleTextInProtocolGuid
,
489 &UsbKeyboardDevice
->SimpleInput
,
490 &gEfiSimpleTextInputExProtocolGuid
,
491 &UsbKeyboardDevice
->SimpleInputEx
,
492 &gEfiHotPlugDeviceGuid
,
496 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
497 gBS
->FreePool (UsbKeyboardDevice
);
500 &gEfiUsbIoProtocolGuid
,
501 This
->DriverBindingHandle
,
507 UsbKeyboardDevice
->ControllerNameTable
= NULL
;
510 gUsbKeyboardComponentName
.SupportedLanguages
,
511 &UsbKeyboardDevice
->ControllerNameTable
,
512 L
"Generic Usb Keyboard",
517 gUsbKeyboardComponentName2
.SupportedLanguages
,
518 &UsbKeyboardDevice
->ControllerNameTable
,
519 L
"Generic Usb Keyboard",
527 if (UsbKeyboardDevice
!= NULL
) {
528 if (UsbKeyboardDevice
->SimpleInput
.WaitForKey
!= NULL
) {
529 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
531 if (UsbKeyboardDevice
->SimpleInputEx
.WaitForKeyEx
!= NULL
) {
532 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInputEx
.WaitForKeyEx
);
534 KbdFreeNotifyList (&UsbKeyboardDevice
->NotifyList
);
535 gBS
->FreePool (UsbKeyboardDevice
);
536 UsbKeyboardDevice
= NULL
;
540 &gEfiUsbIoProtocolGuid
,
541 This
->DriverBindingHandle
,
553 @param This EFI_DRIVER_BINDING_PROTOCOL
554 @param Controller Controller handle
555 @param NumberOfChildren Child handle number
556 @param ChildHandleBuffer Child handle buffer
558 @retval EFI_SUCCESS Success
559 @retval EFI_UNSUPPORTED Can't support
564 USBKeyboardDriverBindingStop (
565 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
566 IN EFI_HANDLE Controller
,
567 IN UINTN NumberOfChildren
,
568 IN EFI_HANDLE
*ChildHandleBuffer
572 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*SimpleInput
;
573 USB_KB_DEV
*UsbKeyboardDevice
;
575 Status
= gBS
->OpenProtocol (
577 &gEfiSimpleTextInProtocolGuid
,
578 (VOID
**) &SimpleInput
,
579 This
->DriverBindingHandle
,
581 EFI_OPEN_PROTOCOL_GET_PROTOCOL
583 if (EFI_ERROR (Status
)) {
584 return EFI_UNSUPPORTED
;
586 Status
= gBS
->OpenProtocol (
588 &gEfiSimpleTextInputExProtocolGuid
,
590 This
->DriverBindingHandle
,
592 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
594 if (EFI_ERROR (Status
)) {
595 return EFI_UNSUPPORTED
;
598 // Get USB_KB_DEV instance.
600 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (SimpleInput
);
604 &gEfiSimpleTextInProtocolGuid
,
605 This
->DriverBindingHandle
,
610 // Uninstall the Asyn Interrupt Transfer from this device
611 // will disable the key data input from this device
613 KbdReportStatusCode (
614 UsbKeyboardDevice
->DevicePath
,
616 PcdGet32 (PcdStatusCodeValueKeyboardDisable
)
620 // Destroy asynchronous interrupt transfer
622 UsbKeyboardDevice
->UsbIo
->UsbAsyncInterruptTransfer (
623 UsbKeyboardDevice
->UsbIo
,
624 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
626 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,
634 &gEfiUsbIoProtocolGuid
,
635 This
->DriverBindingHandle
,
639 Status
= gBS
->UninstallMultipleProtocolInterfaces (
641 &gEfiSimpleTextInProtocolGuid
,
642 &UsbKeyboardDevice
->SimpleInput
,
643 &gEfiSimpleTextInputExProtocolGuid
,
644 &UsbKeyboardDevice
->SimpleInputEx
,
645 &gEfiHotPlugDeviceGuid
,
650 // free all the resources.
652 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
653 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
654 gBS
->CloseEvent ((UsbKeyboardDevice
->SimpleInput
).WaitForKey
);
655 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInputEx
.WaitForKeyEx
);
656 KbdFreeNotifyList (&UsbKeyboardDevice
->NotifyList
);
658 ReleaseKeyboardLayoutResources (UsbKeyboardDevice
);
659 gBS
->CloseEvent (UsbKeyboardDevice
->KeyboardLayoutEvent
);
661 if (UsbKeyboardDevice
->ControllerNameTable
!= NULL
) {
662 FreeUnicodeStringTable (UsbKeyboardDevice
->ControllerNameTable
);
665 gBS
->FreePool (UsbKeyboardDevice
);
673 USBKeyboardReadKeyStrokeWorker (
674 IN USB_KB_DEV
*UsbKeyboardDevice
,
675 OUT EFI_KEY_DATA
*KeyData
680 Reads the next keystroke from the input device. The WaitForKey Event can
681 be used to test for existance of a keystroke via WaitForEvent () call.
684 UsbKeyboardDevice - Usb keyboard private structure.
685 KeyData - A pointer to a buffer that is filled in with the keystroke
686 state data for the key that was pressed.
689 EFI_SUCCESS - The keystroke information was returned.
690 EFI_NOT_READY - There was no keystroke data availiable.
691 EFI_DEVICE_ERROR - The keystroke information was not returned due to
693 EFI_INVALID_PARAMETER - KeyData is NULL.
701 KEYBOARD_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
702 EFI_KEY_DATA OriginalKeyData
;
704 if (KeyData
== NULL
) {
705 return EFI_INVALID_PARAMETER
;
709 // if there is no saved ASCII byte, fetch it
710 // by calling USBKeyboardCheckForKey().
712 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
713 Status
= USBKeyboardCheckForKey (UsbKeyboardDevice
);
714 if (EFI_ERROR (Status
)) {
719 KeyData
->Key
.UnicodeChar
= 0;
720 KeyData
->Key
.ScanCode
= SCAN_NULL
;
722 KeyChar
= UsbKeyboardDevice
->CurKeyChar
;
724 UsbKeyboardDevice
->CurKeyChar
= 0;
727 // Translate saved ASCII byte into EFI_INPUT_KEY
729 Status
= USBKeyCodeToEFIScanCode (UsbKeyboardDevice
, KeyChar
, &KeyData
->Key
);
730 if (EFI_ERROR (Status
)) {
734 CopyMem (&KeyData
->KeyState
, &UsbKeyboardDevice
->KeyState
, sizeof (KeyData
->KeyState
));
736 UsbKeyboardDevice
->KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
;
737 UsbKeyboardDevice
->KeyState
.KeyToggleState
= EFI_TOGGLE_STATE_VALID
;
740 //Switch the control value to their original characters. In USBKeyCodeToEFIScanCode() the CTRL-Alpha characters have been switched to
741 // their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A), here switch them back for notification function.
743 CopyMem (&OriginalKeyData
, KeyData
, sizeof (EFI_KEY_DATA
));
744 if (UsbKeyboardDevice
->CtrlOn
) {
745 if (OriginalKeyData
.Key
.UnicodeChar
>= 0x01 && OriginalKeyData
.Key
.UnicodeChar
<= 0x1A) {
746 if (UsbKeyboardDevice
->CapsOn
) {
747 OriginalKeyData
.Key
.UnicodeChar
= (CHAR16
)(OriginalKeyData
.Key
.UnicodeChar
+ 'A' - 1);
749 OriginalKeyData
.Key
.UnicodeChar
= (CHAR16
)(OriginalKeyData
.Key
.UnicodeChar
+ 'a' - 1);
755 // Invoke notification functions if exist
757 for (Link
= UsbKeyboardDevice
->NotifyList
.ForwardLink
; Link
!= &UsbKeyboardDevice
->NotifyList
; Link
= Link
->ForwardLink
) {
760 KEYBOARD_CONSOLE_IN_EX_NOTIFY
,
762 USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
764 if (IsKeyRegistered (&CurrentNotify
->KeyData
, &OriginalKeyData
)) {
765 CurrentNotify
->KeyNotificationFn (&OriginalKeyData
);
775 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
776 IN BOOLEAN ExtendedVerification
780 USB_KB_DEV
*UsbKeyboardDevice
;
782 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
784 KbdReportStatusCode (
785 UsbKeyboardDevice
->DevicePath
,
787 PcdGet32 (PcdStatusCodeValueKeyboardReset
)
791 // Non Exhaustive reset:
792 // only reset private data structures.
794 if (!ExtendedVerification
) {
796 // Clear the key buffer of this Usb keyboard
798 KbdReportStatusCode (
799 UsbKeyboardDevice
->DevicePath
,
801 PcdGet32 (PcdStatusCodeValueKeyboardClearBuffer
)
804 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
805 UsbKeyboardDevice
->CurKeyChar
= 0;
812 Status
= InitUSBKeyboard (UsbKeyboardDevice
);
813 UsbKeyboardDevice
->CurKeyChar
= 0;
814 if (EFI_ERROR (Status
)) {
815 return EFI_DEVICE_ERROR
;
823 Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke() function.
825 This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.
826 Key A pointer to a buffer that is filled in with the keystroke
827 information for the key that was pressed.
829 @retval EFI_SUCCESS Success
835 USBKeyboardReadKeyStroke (
836 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
837 OUT EFI_INPUT_KEY
*Key
840 USB_KB_DEV
*UsbKeyboardDevice
;
842 EFI_KEY_DATA KeyData
;
844 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
846 Status
= USBKeyboardReadKeyStrokeWorker (UsbKeyboardDevice
, &KeyData
);
847 if (EFI_ERROR (Status
)) {
851 CopyMem (Key
, &KeyData
.Key
, sizeof (EFI_INPUT_KEY
));
859 Handler function for WaitForKey event.
861 Event Event to be signaled when a key is pressed.
862 Context Points to USB_KB_DEV instance.
870 USBKeyboardWaitForKey (
875 USB_KB_DEV
*UsbKeyboardDevice
;
877 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
879 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
881 if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice
))) {
886 // If has key pending, signal the event.
888 gBS
->SignalEvent (Event
);
894 Check whether there is key pending.
896 UsbKeyboardDevice The USB_KB_DEV instance.
898 @retval EFI_SUCCESS Success
903 USBKeyboardCheckForKey (
904 IN USB_KB_DEV
*UsbKeyboardDevice
911 // Fetch raw data from the USB keyboard input,
912 // and translate it into ASCII data.
914 Status
= USBParseKey (UsbKeyboardDevice
, &KeyChar
);
915 if (EFI_ERROR (Status
)) {
919 UsbKeyboardDevice
->CurKeyChar
= KeyChar
;
925 Report Status Code in Usb Bot Driver
927 @param DevicePath Use this to get Device Path
928 @param CodeType Status Code Type
929 @param CodeValue Status Code Value
935 KbdReportStatusCode (
936 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
937 IN EFI_STATUS_CODE_TYPE CodeType
,
938 IN EFI_STATUS_CODE_VALUE Value
942 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
951 IN OUT LIST_ENTRY
*ListHead
959 ListHead - The list head
963 EFI_SUCCESS - Free the notify list successfully
964 EFI_INVALID_PARAMETER - ListHead is invalid.
968 KEYBOARD_CONSOLE_IN_EX_NOTIFY
*NotifyNode
;
970 if (ListHead
== NULL
) {
971 return EFI_INVALID_PARAMETER
;
973 while (!IsListEmpty (ListHead
)) {
975 ListHead
->ForwardLink
,
976 KEYBOARD_CONSOLE_IN_EX_NOTIFY
,
978 USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
980 RemoveEntryList (ListHead
->ForwardLink
);
981 gBS
->FreePool (NotifyNode
);
990 IN EFI_KEY_DATA
*RegsiteredData
,
991 IN EFI_KEY_DATA
*InputData
999 RegsiteredData - A pointer to a buffer that is filled in with the keystroke
1000 state data for the key that was registered.
1001 InputData - A pointer to a buffer that is filled in with the keystroke
1002 state data for the key that was pressed.
1005 TRUE - Key be pressed matches a registered key.
1006 FLASE - Match failed.
1010 ASSERT (RegsiteredData
!= NULL
&& InputData
!= NULL
);
1012 if ((RegsiteredData
->Key
.ScanCode
!= InputData
->Key
.ScanCode
) ||
1013 (RegsiteredData
->Key
.UnicodeChar
!= InputData
->Key
.UnicodeChar
)) {
1018 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
1020 if (RegsiteredData
->KeyState
.KeyShiftState
!= 0 &&
1021 RegsiteredData
->KeyState
.KeyShiftState
!= InputData
->KeyState
.KeyShiftState
) {
1024 if (RegsiteredData
->KeyState
.KeyToggleState
!= 0 &&
1025 RegsiteredData
->KeyState
.KeyToggleState
!= InputData
->KeyState
.KeyToggleState
) {
1034 // Simple Text Input Ex protocol functions
1038 USBKeyboardResetEx (
1039 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
1040 IN BOOLEAN ExtendedVerification
1044 Routine Description:
1045 Reset the input device and optionaly run diagnostics
1048 This - Protocol instance pointer.
1049 ExtendedVerification - Driver may perform diagnostics on reset.
1052 EFI_SUCCESS - The device was reset.
1053 EFI_DEVICE_ERROR - The device is not functioning properly and could
1059 USB_KB_DEV
*UsbKeyboardDevice
;
1063 UsbKeyboardDevice
= TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This
);
1065 Status
= UsbKeyboardDevice
->SimpleInput
.Reset (&UsbKeyboardDevice
->SimpleInput
, ExtendedVerification
);
1066 if (EFI_ERROR (Status
)) {
1067 return EFI_DEVICE_ERROR
;
1070 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1071 UsbKeyboardDevice
->KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
;
1072 UsbKeyboardDevice
->KeyState
.KeyToggleState
= EFI_TOGGLE_STATE_VALID
;
1073 gBS
->RestoreTPL (OldTpl
);
1081 USBKeyboardReadKeyStrokeEx (
1082 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
1083 OUT EFI_KEY_DATA
*KeyData
1087 Routine Description:
1088 Reads the next keystroke from the input device. The WaitForKey Event can
1089 be used to test for existance of a keystroke via WaitForEvent () call.
1092 This - Protocol instance pointer.
1093 KeyData - A pointer to a buffer that is filled in with the keystroke
1094 state data for the key that was pressed.
1097 EFI_SUCCESS - The keystroke information was returned.
1098 EFI_NOT_READY - There was no keystroke data availiable.
1099 EFI_DEVICE_ERROR - The keystroke information was not returned due to
1101 EFI_INVALID_PARAMETER - KeyData is NULL.
1105 USB_KB_DEV
*UsbKeyboardDevice
;
1107 if (KeyData
== NULL
) {
1108 return EFI_INVALID_PARAMETER
;
1111 UsbKeyboardDevice
= TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This
);
1113 return USBKeyboardReadKeyStrokeWorker (UsbKeyboardDevice
, KeyData
);
1119 USBKeyboardSetState (
1120 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
1121 IN EFI_KEY_TOGGLE_STATE
*KeyToggleState
1125 Routine Description:
1126 Set certain state for the input device.
1129 This - Protocol instance pointer.
1130 KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the
1131 state for the input device.
1134 EFI_SUCCESS - The device state was set successfully.
1135 EFI_DEVICE_ERROR - The device is not functioning correctly and could
1136 not have the setting adjusted.
1137 EFI_UNSUPPORTED - The device does not have the ability to set its state.
1138 EFI_INVALID_PARAMETER - KeyToggleState is NULL.
1142 USB_KB_DEV
*UsbKeyboardDevice
;
1144 if (KeyToggleState
== NULL
) {
1145 return EFI_INVALID_PARAMETER
;
1148 UsbKeyboardDevice
= TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This
);
1150 if (((UsbKeyboardDevice
->KeyState
.KeyToggleState
& EFI_TOGGLE_STATE_VALID
) != EFI_TOGGLE_STATE_VALID
) ||
1151 ((*KeyToggleState
& EFI_TOGGLE_STATE_VALID
) != EFI_TOGGLE_STATE_VALID
)) {
1152 return EFI_UNSUPPORTED
;
1156 // Update the status light
1159 UsbKeyboardDevice
->ScrollOn
= 0;
1160 UsbKeyboardDevice
->NumLockOn
= 0;
1161 UsbKeyboardDevice
->CapsOn
= 0;
1163 if ((*KeyToggleState
& EFI_SCROLL_LOCK_ACTIVE
) == EFI_SCROLL_LOCK_ACTIVE
) {
1164 UsbKeyboardDevice
->ScrollOn
= 1;
1166 if ((*KeyToggleState
& EFI_NUM_LOCK_ACTIVE
) == EFI_NUM_LOCK_ACTIVE
) {
1167 UsbKeyboardDevice
->NumLockOn
= 1;
1169 if ((*KeyToggleState
& EFI_CAPS_LOCK_ACTIVE
) == EFI_CAPS_LOCK_ACTIVE
) {
1170 UsbKeyboardDevice
->CapsOn
= 1;
1173 SetKeyLED (UsbKeyboardDevice
);
1175 UsbKeyboardDevice
->KeyState
.KeyToggleState
= *KeyToggleState
;
1183 USBKeyboardRegisterKeyNotify (
1184 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
1185 IN EFI_KEY_DATA
*KeyData
,
1186 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction
,
1187 OUT EFI_HANDLE
*NotifyHandle
1191 Routine Description:
1192 Register a notification function for a particular keystroke for the input device.
1195 This - Protocol instance pointer.
1196 KeyData - A pointer to a buffer that is filled in with the keystroke
1197 information data for the key that was pressed.
1198 KeyNotificationFunction - Points to the function to be called when the key
1199 sequence is typed specified by KeyData.
1200 NotifyHandle - Points to the unique handle assigned to the registered notification.
1203 EFI_SUCCESS - The notification function was registered successfully.
1204 EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures.
1205 EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.
1209 USB_KB_DEV
*UsbKeyboardDevice
;
1211 KEYBOARD_CONSOLE_IN_EX_NOTIFY
*NewNotify
;
1213 KEYBOARD_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
1215 if (KeyData
== NULL
|| NotifyHandle
== NULL
|| KeyNotificationFunction
== NULL
) {
1216 return EFI_INVALID_PARAMETER
;
1219 UsbKeyboardDevice
= TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This
);
1222 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
1224 for (Link
= UsbKeyboardDevice
->NotifyList
.ForwardLink
; Link
!= &UsbKeyboardDevice
->NotifyList
; Link
= Link
->ForwardLink
) {
1225 CurrentNotify
= CR (
1227 KEYBOARD_CONSOLE_IN_EX_NOTIFY
,
1229 USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
1231 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
1232 if (CurrentNotify
->KeyNotificationFn
== KeyNotificationFunction
) {
1233 *NotifyHandle
= CurrentNotify
->NotifyHandle
;
1240 // Allocate resource to save the notification function
1242 NewNotify
= (KEYBOARD_CONSOLE_IN_EX_NOTIFY
*) AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_EX_NOTIFY
));
1243 if (NewNotify
== NULL
) {
1244 return EFI_OUT_OF_RESOURCES
;
1247 NewNotify
->Signature
= USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
;
1248 NewNotify
->KeyNotificationFn
= KeyNotificationFunction
;
1249 CopyMem (&NewNotify
->KeyData
, KeyData
, sizeof (EFI_KEY_DATA
));
1250 InsertTailList (&UsbKeyboardDevice
->NotifyList
, &NewNotify
->NotifyEntry
);
1253 // Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE
1255 Status
= gBS
->InstallMultipleProtocolInterfaces (
1256 &NewNotify
->NotifyHandle
,
1257 &gSimpleTextInExNotifyGuid
,
1261 ASSERT_EFI_ERROR (Status
);
1263 *NotifyHandle
= NewNotify
->NotifyHandle
;
1271 USBKeyboardUnregisterKeyNotify (
1272 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
1273 IN EFI_HANDLE NotificationHandle
1277 Routine Description:
1278 Remove a registered notification function from a particular keystroke.
1281 This - Protocol instance pointer.
1282 NotificationHandle - The handle of the notification function being unregistered.
1285 EFI_SUCCESS - The notification function was unregistered successfully.
1286 EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
1287 EFI_NOT_FOUND - Can not find the matching entry in database.
1291 USB_KB_DEV
*UsbKeyboardDevice
;
1293 KEYBOARD_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
1296 if (NotificationHandle
== NULL
) {
1297 return EFI_INVALID_PARAMETER
;
1300 UsbKeyboardDevice
= TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This
);
1302 Status
= gBS
->OpenProtocol (
1304 &gSimpleTextInExNotifyGuid
,
1308 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
1310 if (EFI_ERROR (Status
)) {
1311 return EFI_INVALID_PARAMETER
;
1314 for (Link
= UsbKeyboardDevice
->NotifyList
.ForwardLink
; Link
!= &UsbKeyboardDevice
->NotifyList
; Link
= Link
->ForwardLink
) {
1315 CurrentNotify
= CR (
1317 KEYBOARD_CONSOLE_IN_EX_NOTIFY
,
1319 USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
1321 if (CurrentNotify
->NotifyHandle
== NotificationHandle
) {
1323 // Remove the notification function from NotifyList and free resources
1325 RemoveEntryList (&CurrentNotify
->NotifyEntry
);
1326 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1327 CurrentNotify
->NotifyHandle
,
1328 &gSimpleTextInExNotifyGuid
,
1332 ASSERT_EFI_ERROR (Status
);
1333 gBS
->FreePool (CurrentNotify
);
1338 return EFI_NOT_FOUND
;