3 USB Keyboard Driver that includes the implementation of interface.
5 Copyright (c) 2004 - 2008, Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 The Usb Keyboard Driver Entry Point.
22 @param ImageHandle The driver image handle.
23 @param SystemTable The system table.
25 @return EFI_SUCCESS The component name protocol is installed.
26 @return Others Failed to install.
31 USBKeyboardDriverBindingEntryPoint (
32 IN EFI_HANDLE ImageHandle
,
33 IN EFI_SYSTEM_TABLE
*SystemTable
37 Check whether USB keyboard driver support this device.
39 @param This The USB keyboard driver binding protocol.
40 @param Controller The controller handle to check.
41 @param RemainingDevicePath The remaining device path.
43 @retval EFI_SUCCESS The driver supports this controller.
44 @retval EFI_UNSUPPORTED This device isn't supported.
48 USBKeyboardDriverBindingSupported (
49 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
50 IN EFI_HANDLE Controller
,
51 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
55 Start running driver on the controller.
57 @param This The USB keyboard driver binding instance.
58 @param Controller The controller to check.
59 @param RemainingDevicePath The remaining device patch.
61 @retval EFI_SUCCESS The controller is controlled by the usb keyboard driver.
62 @return Other The keyboard driver doesn't support this controller.
67 USBKeyboardDriverBindingStart (
68 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
69 IN EFI_HANDLE Controller
,
70 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
74 Stop handle the controller by this USB keyboard driver.
76 @param This The USB keyboard driver binding protocol.
77 @param Controller The controller to release.
78 @param NumberOfChildren The number of handles in ChildHandleBuffer.
79 @param ChildHandleBuffer The array of child handle.
81 @retval EFI_SUCCESS The controller or children are stopped.
82 @retval EFI_DEVICE_ERROR Failed to stop the driver.
87 USBKeyboardDriverBindingStop (
88 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
89 IN EFI_HANDLE Controller
,
90 IN UINTN NumberOfChildren
,
91 IN EFI_HANDLE
*ChildHandleBuffer
97 @param This The protocol instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
98 @param ExtendedVerification Whether completely reset keyboard or not.
100 @retval EFI_SUCCESS Reset keyboard successfully.
101 @retval EFI_DEVICE_ERROR Reset keyboard failed.
107 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
108 IN BOOLEAN ExtendedVerification
112 Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke() function.
114 @param This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.
115 @param Key A pointer to a buffer that is filled in with the keystroke
116 information for the key that was pressed.
118 @retval EFI_SUCCESS Read key stroke successfully.
119 @retval Other Read key stroke failed.
124 USBKeyboardReadKeyStroke (
125 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
126 OUT EFI_INPUT_KEY
*Key
130 Handler function for WaitForKey event.
132 @param Event Event to be signaled when a key is pressed.
133 @param Context Points to USB_KB_DEV instance.
139 USBKeyboardWaitForKey (
145 Check whether there is key pending.
147 @param UsbKeyboardDevice The USB_KB_DEV instance.
149 @retval EFI_SUCCESS Have key pending to read.
150 @retval Other Parse key failed.
155 USBKeyboardCheckForKey (
156 IN USB_KB_DEV
*UsbKeyboardDevice
159 EFI_GUID gEfiUsbKeyboardDriverGuid
= {
160 0xa05f5f78, 0xfb3, 0x4d10, {0x90, 0x90, 0xac, 0x4, 0x6e, 0xeb, 0x7c, 0x3c}
164 Free keyboard notify list.
166 @param ListHead The list head.
168 @retval EFI_SUCCESS Free the notify list successfully.
169 @retval EFI_INVALID_PARAMETER ListHead is invalid.
175 IN OUT LIST_ENTRY
*ListHead
179 Whether the pressed key matches a registered key or not.
181 @param RegsiteredData A pointer to a buffer that is filled in with the keystroke
182 state data for the key that was registered.
183 @param InputData A pointer to a buffer that is filled in with the keystroke
184 state data for the key that was pressed.
186 @retval TRUE Key pressed matches a registered key.
187 @retval FLASE Match failed.
193 IN EFI_KEY_DATA
*RegsiteredData
,
194 IN EFI_KEY_DATA
*InputData
199 // USB Keyboard Driver Global Variables
201 EFI_DRIVER_BINDING_PROTOCOL gUsbKeyboardDriverBinding
= {
202 USBKeyboardDriverBindingSupported
,
203 USBKeyboardDriverBindingStart
,
204 USBKeyboardDriverBindingStop
,
211 The Usb Keyboard Driver Entry Point.
213 @param ImageHandle The driver image handle.
214 @param SystemTable The system table.
216 @return EFI_SUCCESS The component name protocol is installed.
217 @return Others Failed to install.
222 USBKeyboardDriverBindingEntryPoint (
223 IN EFI_HANDLE ImageHandle
,
224 IN EFI_SYSTEM_TABLE
*SystemTable
227 return EfiLibInstallDriverBindingComponentName2 (
230 &gUsbKeyboardDriverBinding
,
232 &gUsbKeyboardComponentName
,
233 &gUsbKeyboardComponentName2
238 Check whether USB keyboard driver support this device.
240 @param This The USB keyboard driver binding protocol.
241 @param Controller The controller handle to check.
242 @param RemainingDevicePath The remaining device path.
244 @retval EFI_SUCCESS The driver supports this controller.
245 @retval EFI_UNSUPPORTED This device isn't supported.
249 USBKeyboardDriverBindingSupported (
250 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
251 IN EFI_HANDLE Controller
,
252 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
255 EFI_STATUS OpenStatus
;
256 EFI_USB_IO_PROTOCOL
*UsbIo
;
260 // Check if USB_IO protocol is attached on the controller handle.
262 OpenStatus
= gBS
->OpenProtocol (
264 &gEfiUsbIoProtocolGuid
,
266 This
->DriverBindingHandle
,
268 EFI_OPEN_PROTOCOL_BY_DRIVER
270 if (EFI_ERROR (OpenStatus
)) {
275 // Use the USB I/O protocol interface to check whether the Controller is
276 // the Keyboard controller that can be managed by this driver.
278 Status
= EFI_SUCCESS
;
280 if (!IsUSBKeyboard (UsbIo
)) {
281 Status
= EFI_UNSUPPORTED
;
286 &gEfiUsbIoProtocolGuid
,
287 This
->DriverBindingHandle
,
295 Start running driver on the controller.
297 @param This The USB keyboard driver binding instance.
298 @param Controller The controller to check.
299 @param RemainingDevicePath The remaining device patch.
301 @retval EFI_SUCCESS The controller is controlled by the usb keyboard driver.
302 @return Other The keyboard driver doesn't support this controller.
307 USBKeyboardDriverBindingStart (
308 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
309 IN EFI_HANDLE Controller
,
310 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
314 EFI_USB_IO_PROTOCOL
*UsbIo
;
315 USB_KB_DEV
*UsbKeyboardDevice
;
316 UINT8 EndpointNumber
;
317 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
320 UINT8 PollingInterval
;
324 UsbKeyboardDevice
= NULL
;
328 // Open USB_IO Protocol
330 Status
= gBS
->OpenProtocol (
332 &gEfiUsbIoProtocolGuid
,
334 This
->DriverBindingHandle
,
336 EFI_OPEN_PROTOCOL_BY_DRIVER
338 if (EFI_ERROR (Status
)) {
342 UsbKeyboardDevice
= AllocateZeroPool (sizeof (USB_KB_DEV
));
343 if (UsbKeyboardDevice
== NULL
) {
346 &gEfiUsbIoProtocolGuid
,
347 This
->DriverBindingHandle
,
350 return EFI_OUT_OF_RESOURCES
;
353 // Get the Device Path Protocol on Controller's handle
355 Status
= gBS
->OpenProtocol (
357 &gEfiDevicePathProtocolGuid
,
358 (VOID
**) &UsbKeyboardDevice
->DevicePath
,
359 This
->DriverBindingHandle
,
361 EFI_OPEN_PROTOCOL_GET_PROTOCOL
364 if (EFI_ERROR (Status
)) {
365 gBS
->FreePool (UsbKeyboardDevice
);
368 &gEfiUsbIoProtocolGuid
,
369 This
->DriverBindingHandle
,
375 // Report that the usb keyboard is being enabled
377 KbdReportStatusCode (
378 UsbKeyboardDevice
->DevicePath
,
380 PcdGet32 (PcdStatusCodeValueKeyboardEnable
)
384 // This is pretty close to keyboard detection, so log progress
386 KbdReportStatusCode (
387 UsbKeyboardDevice
->DevicePath
,
389 PcdGet32 (PcdStatusCodeValueKeyboardPresenceDetect
)
393 // Initialize UsbKeyboardDevice
395 UsbKeyboardDevice
->UsbIo
= UsbIo
;
398 // Get interface & endpoint descriptor
400 UsbIo
->UsbGetInterfaceDescriptor (
402 &UsbKeyboardDevice
->InterfaceDescriptor
405 EndpointNumber
= UsbKeyboardDevice
->InterfaceDescriptor
.NumEndpoints
;
407 for (Index
= 0; Index
< EndpointNumber
; Index
++) {
409 UsbIo
->UsbGetEndpointDescriptor (
415 if ((EndpointDescriptor
.Attributes
& 0x03) == 0x03) {
417 // We only care interrupt endpoint here
419 CopyMem(&UsbKeyboardDevice
->IntEndpointDescriptor
, &EndpointDescriptor
, sizeof(EndpointDescriptor
));
426 // No interrupt endpoint found, then return unsupported.
428 gBS
->FreePool (UsbKeyboardDevice
);
431 &gEfiUsbIoProtocolGuid
,
432 This
->DriverBindingHandle
,
435 return EFI_UNSUPPORTED
;
438 UsbKeyboardDevice
->Signature
= USB_KB_DEV_SIGNATURE
;
439 UsbKeyboardDevice
->SimpleInput
.Reset
= USBKeyboardReset
;
440 UsbKeyboardDevice
->SimpleInput
.ReadKeyStroke
= USBKeyboardReadKeyStroke
;
442 UsbKeyboardDevice
->SimpleInputEx
.Reset
= USBKeyboardResetEx
;
443 UsbKeyboardDevice
->SimpleInputEx
.ReadKeyStrokeEx
= USBKeyboardReadKeyStrokeEx
;
444 UsbKeyboardDevice
->SimpleInputEx
.SetState
= USBKeyboardSetState
;
445 UsbKeyboardDevice
->SimpleInputEx
.RegisterKeyNotify
= USBKeyboardRegisterKeyNotify
;
446 UsbKeyboardDevice
->SimpleInputEx
.UnregisterKeyNotify
= USBKeyboardUnregisterKeyNotify
;
448 InitializeListHead (&UsbKeyboardDevice
->NotifyList
);
450 Status
= gBS
->CreateEvent (
453 USBKeyboardWaitForKey
,
455 &(UsbKeyboardDevice
->SimpleInputEx
.WaitForKeyEx
)
458 if (EFI_ERROR (Status
)) {
462 Status
= InitKeyboardLayout (UsbKeyboardDevice
);
463 if (EFI_ERROR (Status
)) {
467 Status
= gBS
->CreateEvent (
470 USBKeyboardWaitForKey
,
472 &(UsbKeyboardDevice
->SimpleInput
.WaitForKey
)
475 if (EFI_ERROR (Status
)) {
476 gBS
->FreePool (UsbKeyboardDevice
);
479 &gEfiUsbIoProtocolGuid
,
480 This
->DriverBindingHandle
,
487 // Install simple txt in protocol interface
488 // for the usb keyboard device.
489 // Usb keyboard is a hot plug device, and expected to work immediately
490 // when plugging into system, so a HotPlugDeviceGuid is installed onto
491 // the usb keyboard device handle, to distinguish it from other conventional
494 Status
= gBS
->InstallMultipleProtocolInterfaces (
496 &gEfiSimpleTextInProtocolGuid
,
497 &UsbKeyboardDevice
->SimpleInput
,
498 &gEfiSimpleTextInputExProtocolGuid
,
499 &UsbKeyboardDevice
->SimpleInputEx
,
500 &gEfiHotPlugDeviceGuid
,
504 if (EFI_ERROR (Status
)) {
505 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
506 gBS
->FreePool (UsbKeyboardDevice
);
509 &gEfiUsbIoProtocolGuid
,
510 This
->DriverBindingHandle
,
517 // Reset USB Keyboard Device
519 Status
= UsbKeyboardDevice
->SimpleInput
.Reset (
520 &UsbKeyboardDevice
->SimpleInput
,
523 if (EFI_ERROR (Status
)) {
524 gBS
->UninstallMultipleProtocolInterfaces (
526 &gEfiSimpleTextInProtocolGuid
,
527 &UsbKeyboardDevice
->SimpleInput
,
528 &gEfiSimpleTextInputExProtocolGuid
,
529 &UsbKeyboardDevice
->SimpleInputEx
,
530 &gEfiHotPlugDeviceGuid
,
534 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
535 gBS
->FreePool (UsbKeyboardDevice
);
538 &gEfiUsbIoProtocolGuid
,
539 This
->DriverBindingHandle
,
545 // submit async interrupt transfer
547 EndpointAddr
= UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
;
548 PollingInterval
= UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
;
549 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
551 Status
= UsbIo
->UsbAsyncInterruptTransfer (
561 if (EFI_ERROR (Status
)) {
563 gBS
->UninstallMultipleProtocolInterfaces (
565 &gEfiSimpleTextInProtocolGuid
,
566 &UsbKeyboardDevice
->SimpleInput
,
567 &gEfiSimpleTextInputExProtocolGuid
,
568 &UsbKeyboardDevice
->SimpleInputEx
,
569 &gEfiHotPlugDeviceGuid
,
573 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
574 gBS
->FreePool (UsbKeyboardDevice
);
577 &gEfiUsbIoProtocolGuid
,
578 This
->DriverBindingHandle
,
584 UsbKeyboardDevice
->ControllerNameTable
= NULL
;
587 gUsbKeyboardComponentName
.SupportedLanguages
,
588 &UsbKeyboardDevice
->ControllerNameTable
,
589 L
"Generic Usb Keyboard",
594 gUsbKeyboardComponentName2
.SupportedLanguages
,
595 &UsbKeyboardDevice
->ControllerNameTable
,
596 L
"Generic Usb Keyboard",
604 if (UsbKeyboardDevice
!= NULL
) {
605 if (UsbKeyboardDevice
->SimpleInput
.WaitForKey
!= NULL
) {
606 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
608 if (UsbKeyboardDevice
->SimpleInputEx
.WaitForKeyEx
!= NULL
) {
609 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInputEx
.WaitForKeyEx
);
611 KbdFreeNotifyList (&UsbKeyboardDevice
->NotifyList
);
612 gBS
->FreePool (UsbKeyboardDevice
);
613 UsbKeyboardDevice
= NULL
;
617 &gEfiUsbIoProtocolGuid
,
618 This
->DriverBindingHandle
,
627 Stop handle the controller by this USB keyboard driver.
629 @param This The USB keyboard driver binding protocol.
630 @param Controller The controller to release.
631 @param NumberOfChildren The number of handles in ChildHandleBuffer.
632 @param ChildHandleBuffer The array of child handle.
634 @retval EFI_SUCCESS The controller or children are stopped.
635 @retval EFI_DEVICE_ERROR Failed to stop the driver.
640 USBKeyboardDriverBindingStop (
641 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
642 IN EFI_HANDLE Controller
,
643 IN UINTN NumberOfChildren
,
644 IN EFI_HANDLE
*ChildHandleBuffer
648 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*SimpleInput
;
649 USB_KB_DEV
*UsbKeyboardDevice
;
651 Status
= gBS
->OpenProtocol (
653 &gEfiSimpleTextInProtocolGuid
,
654 (VOID
**) &SimpleInput
,
655 This
->DriverBindingHandle
,
657 EFI_OPEN_PROTOCOL_GET_PROTOCOL
659 if (EFI_ERROR (Status
)) {
660 return EFI_UNSUPPORTED
;
662 Status
= gBS
->OpenProtocol (
664 &gEfiSimpleTextInputExProtocolGuid
,
666 This
->DriverBindingHandle
,
668 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
670 if (EFI_ERROR (Status
)) {
671 return EFI_UNSUPPORTED
;
674 // Get USB_KB_DEV instance.
676 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (SimpleInput
);
680 &gEfiSimpleTextInProtocolGuid
,
681 This
->DriverBindingHandle
,
686 // Uninstall the Asyn Interrupt Transfer from this device
687 // will disable the key data input from this device
689 KbdReportStatusCode (
690 UsbKeyboardDevice
->DevicePath
,
692 PcdGet32 (PcdStatusCodeValueKeyboardDisable
)
696 // Destroy asynchronous interrupt transfer
698 UsbKeyboardDevice
->UsbIo
->UsbAsyncInterruptTransfer (
699 UsbKeyboardDevice
->UsbIo
,
700 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
702 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,
710 &gEfiUsbIoProtocolGuid
,
711 This
->DriverBindingHandle
,
715 Status
= gBS
->UninstallMultipleProtocolInterfaces (
717 &gEfiSimpleTextInProtocolGuid
,
718 &UsbKeyboardDevice
->SimpleInput
,
719 &gEfiSimpleTextInputExProtocolGuid
,
720 &UsbKeyboardDevice
->SimpleInputEx
,
721 &gEfiHotPlugDeviceGuid
,
726 // free all the resources.
728 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
729 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
730 gBS
->CloseEvent ((UsbKeyboardDevice
->SimpleInput
).WaitForKey
);
731 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInputEx
.WaitForKeyEx
);
732 KbdFreeNotifyList (&UsbKeyboardDevice
->NotifyList
);
734 ReleaseKeyboardLayoutResources (UsbKeyboardDevice
);
735 gBS
->CloseEvent (UsbKeyboardDevice
->KeyboardLayoutEvent
);
737 if (UsbKeyboardDevice
->ControllerNameTable
!= NULL
) {
738 FreeUnicodeStringTable (UsbKeyboardDevice
->ControllerNameTable
);
741 gBS
->FreePool (UsbKeyboardDevice
);
748 Reads the next keystroke from the input device. The WaitForKey Event can
749 be used to test for existance of a keystroke via WaitForEvent () call.
751 @param UsbKeyboardDevice Usb keyboard's private structure.
752 @param KeyData A pointer to a buffer that is filled in with the keystroke
753 state data for the key that was pressed.
755 @return EFI_SUCCESS The keystroke information was returned.
756 @return EFI_NOT_READY There was no keystroke data availiable.
757 @return EFI_DEVICE_ERROR The keystroke information was not returned due to
759 @return EFI_INVALID_PARAMETER KeyData is NULL.
764 USBKeyboardReadKeyStrokeWorker (
765 IN USB_KB_DEV
*UsbKeyboardDevice
,
766 OUT EFI_KEY_DATA
*KeyData
773 KEYBOARD_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
774 EFI_KEY_DATA OriginalKeyData
;
776 if (KeyData
== NULL
) {
777 return EFI_INVALID_PARAMETER
;
781 // if there is no saved ASCII byte, fetch it
782 // by calling USBKeyboardCheckForKey().
784 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
785 Status
= USBKeyboardCheckForKey (UsbKeyboardDevice
);
786 if (EFI_ERROR (Status
)) {
791 KeyData
->Key
.UnicodeChar
= 0;
792 KeyData
->Key
.ScanCode
= SCAN_NULL
;
794 KeyChar
= UsbKeyboardDevice
->CurKeyChar
;
796 UsbKeyboardDevice
->CurKeyChar
= 0;
799 // Translate saved ASCII byte into EFI_INPUT_KEY
801 Status
= USBKeyCodeToEFIScanCode (UsbKeyboardDevice
, KeyChar
, &KeyData
->Key
);
802 if (EFI_ERROR (Status
)) {
806 CopyMem (&KeyData
->KeyState
, &UsbKeyboardDevice
->KeyState
, sizeof (KeyData
->KeyState
));
808 UsbKeyboardDevice
->KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
;
809 UsbKeyboardDevice
->KeyState
.KeyToggleState
= EFI_TOGGLE_STATE_VALID
;
812 //Switch the control value to their original characters. In USBKeyCodeToEFIScanCode() the CTRL-Alpha characters have been switched to
813 // their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A), here switch them back for notification function.
815 CopyMem (&OriginalKeyData
, KeyData
, sizeof (EFI_KEY_DATA
));
816 if (UsbKeyboardDevice
->CtrlOn
!= 0) {
817 if (OriginalKeyData
.Key
.UnicodeChar
>= 0x01 && OriginalKeyData
.Key
.UnicodeChar
<= 0x1A) {
818 if (UsbKeyboardDevice
->CapsOn
!= 0) {
819 OriginalKeyData
.Key
.UnicodeChar
= (CHAR16
)(OriginalKeyData
.Key
.UnicodeChar
+ 'A' - 1);
821 OriginalKeyData
.Key
.UnicodeChar
= (CHAR16
)(OriginalKeyData
.Key
.UnicodeChar
+ 'a' - 1);
827 // Invoke notification functions if exist
829 for (Link
= UsbKeyboardDevice
->NotifyList
.ForwardLink
; Link
!= &UsbKeyboardDevice
->NotifyList
; Link
= Link
->ForwardLink
) {
832 KEYBOARD_CONSOLE_IN_EX_NOTIFY
,
834 USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
836 if (IsKeyRegistered (&CurrentNotify
->KeyData
, &OriginalKeyData
)) {
837 CurrentNotify
->KeyNotificationFn (&OriginalKeyData
);
848 @param This The protocol instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
849 @param ExtendedVerification Whether completely reset keyboard or not.
851 @retval EFI_SUCCESS Reset keyboard successfully.
852 @retval EFI_DEVICE_ERROR Reset keyboard failed.
858 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
859 IN BOOLEAN ExtendedVerification
863 USB_KB_DEV
*UsbKeyboardDevice
;
865 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
867 KbdReportStatusCode (
868 UsbKeyboardDevice
->DevicePath
,
870 PcdGet32 (PcdStatusCodeValueKeyboardReset
)
874 // Non Exhaustive reset:
875 // only reset private data structures.
877 if (!ExtendedVerification
) {
879 // Clear the key buffer of this Usb keyboard
881 KbdReportStatusCode (
882 UsbKeyboardDevice
->DevicePath
,
884 PcdGet32 (PcdStatusCodeValueKeyboardClearBuffer
)
887 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
888 UsbKeyboardDevice
->CurKeyChar
= 0;
895 Status
= InitUSBKeyboard (UsbKeyboardDevice
);
896 UsbKeyboardDevice
->CurKeyChar
= 0;
897 if (EFI_ERROR (Status
)) {
898 return EFI_DEVICE_ERROR
;
906 Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke() function.
908 @param This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.
909 @param Key A pointer to a buffer that is filled in with the keystroke
910 information for the key that was pressed.
912 @retval EFI_SUCCESS Read key stroke successfully.
913 @retval Other Read key stroke failed.
918 USBKeyboardReadKeyStroke (
919 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
920 OUT EFI_INPUT_KEY
*Key
923 USB_KB_DEV
*UsbKeyboardDevice
;
925 EFI_KEY_DATA KeyData
;
927 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
929 Status
= USBKeyboardReadKeyStrokeWorker (UsbKeyboardDevice
, &KeyData
);
930 if (EFI_ERROR (Status
)) {
934 CopyMem (Key
, &KeyData
.Key
, sizeof (EFI_INPUT_KEY
));
942 Handler function for WaitForKey event.
944 @param Event Event to be signaled when a key is pressed.
945 @param Context Points to USB_KB_DEV instance.
951 USBKeyboardWaitForKey (
956 USB_KB_DEV
*UsbKeyboardDevice
;
958 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
960 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
962 if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice
))) {
967 // If has key pending, signal the event.
969 gBS
->SignalEvent (Event
);
974 Check whether there is key pending.
976 @param UsbKeyboardDevice The USB_KB_DEV instance.
978 @retval EFI_SUCCESS Have key pending to read.
979 @retval Other Parse key failed.
984 USBKeyboardCheckForKey (
985 IN USB_KB_DEV
*UsbKeyboardDevice
992 // Fetch raw data from the USB keyboard input,
993 // and translate it into ASCII data.
995 Status
= USBParseKey (UsbKeyboardDevice
, &KeyChar
);
996 if (EFI_ERROR (Status
)) {
1000 UsbKeyboardDevice
->CurKeyChar
= KeyChar
;
1005 Report Status Code in Usb Keyboard Driver.
1007 @param DevicePath Use this to get Device Path.
1008 @param CodeType Status Code Type.
1009 @param CodeValue Status Code Value.
1016 KbdReportStatusCode (
1017 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
1018 IN EFI_STATUS_CODE_TYPE CodeType
,
1019 IN EFI_STATUS_CODE_VALUE Value
1023 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1031 Free keyboard notify list.
1033 @param ListHead The list head.
1035 @retval EFI_SUCCESS Free the notify list successfully.
1036 @retval EFI_INVALID_PARAMETER ListHead is invalid.
1042 IN OUT LIST_ENTRY
*ListHead
1045 KEYBOARD_CONSOLE_IN_EX_NOTIFY
*NotifyNode
;
1047 if (ListHead
== NULL
) {
1048 return EFI_INVALID_PARAMETER
;
1050 while (!IsListEmpty (ListHead
)) {
1052 ListHead
->ForwardLink
,
1053 KEYBOARD_CONSOLE_IN_EX_NOTIFY
,
1055 USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
1057 RemoveEntryList (ListHead
->ForwardLink
);
1058 gBS
->FreePool (NotifyNode
);
1065 Whether the pressed key matches a registered key or not.
1067 @param RegsiteredData A pointer to a buffer that is filled in with the keystroke
1068 state data for the key that was registered.
1069 @param InputData A pointer to a buffer that is filled in with the keystroke
1070 state data for the key that was pressed.
1072 @retval TRUE Key pressed matches a registered key.
1073 @retval FLASE Match failed.
1079 IN EFI_KEY_DATA
*RegsiteredData
,
1080 IN EFI_KEY_DATA
*InputData
1083 ASSERT (RegsiteredData
!= NULL
&& InputData
!= NULL
);
1085 if ((RegsiteredData
->Key
.ScanCode
!= InputData
->Key
.ScanCode
) ||
1086 (RegsiteredData
->Key
.UnicodeChar
!= InputData
->Key
.UnicodeChar
)) {
1091 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
1093 if (RegsiteredData
->KeyState
.KeyShiftState
!= 0 &&
1094 RegsiteredData
->KeyState
.KeyShiftState
!= InputData
->KeyState
.KeyShiftState
) {
1097 if (RegsiteredData
->KeyState
.KeyToggleState
!= 0 &&
1098 RegsiteredData
->KeyState
.KeyToggleState
!= InputData
->KeyState
.KeyToggleState
) {
1107 // Simple Text Input Ex protocol functions
1110 The extension routine to reset the input device.
1112 @param This Protocol instance pointer.
1113 @param ExtendedVerification Driver may perform diagnostics on reset.
1115 @retval EFI_SUCCESS The device was reset.
1116 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
1122 USBKeyboardResetEx (
1123 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
1124 IN BOOLEAN ExtendedVerification
1128 USB_KB_DEV
*UsbKeyboardDevice
;
1132 UsbKeyboardDevice
= TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This
);
1134 Status
= UsbKeyboardDevice
->SimpleInput
.Reset (&UsbKeyboardDevice
->SimpleInput
, ExtendedVerification
);
1135 if (EFI_ERROR (Status
)) {
1136 return EFI_DEVICE_ERROR
;
1139 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1140 UsbKeyboardDevice
->KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
;
1141 UsbKeyboardDevice
->KeyState
.KeyToggleState
= EFI_TOGGLE_STATE_VALID
;
1142 gBS
->RestoreTPL (OldTpl
);
1149 Reads the next keystroke from the input device. The WaitForKey Event can
1150 be used to test for existance of a keystroke via WaitForEvent () call.
1152 @param This Protocol instance pointer.
1153 @param KeyData A pointer to a buffer that is filled in with the keystroke
1154 state data for the key that was pressed.
1156 @return EFI_SUCCESS The keystroke information was returned successfully.
1157 @retval EFI_INVALID_PARAMETER KeyData is NULL.
1158 @retval Other Read key stroke information failed.
1163 USBKeyboardReadKeyStrokeEx (
1164 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
1165 OUT EFI_KEY_DATA
*KeyData
1168 USB_KB_DEV
*UsbKeyboardDevice
;
1170 if (KeyData
== NULL
) {
1171 return EFI_INVALID_PARAMETER
;
1174 UsbKeyboardDevice
= TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This
);
1176 return USBKeyboardReadKeyStrokeWorker (UsbKeyboardDevice
, KeyData
);
1181 Set certain state for the input device.
1183 @param This Protocol instance pointer.
1184 @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
1185 state for the input device.
1187 @retval EFI_SUCCESS The device state was set successfully.
1188 @retval EFI_UNSUPPORTED The device does not have the ability to set its state.
1189 @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
1194 USBKeyboardSetState (
1195 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
1196 IN EFI_KEY_TOGGLE_STATE
*KeyToggleState
1199 USB_KB_DEV
*UsbKeyboardDevice
;
1201 if (KeyToggleState
== NULL
) {
1202 return EFI_INVALID_PARAMETER
;
1205 UsbKeyboardDevice
= TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This
);
1207 if (((UsbKeyboardDevice
->KeyState
.KeyToggleState
& EFI_TOGGLE_STATE_VALID
) != EFI_TOGGLE_STATE_VALID
) ||
1208 ((*KeyToggleState
& EFI_TOGGLE_STATE_VALID
) != EFI_TOGGLE_STATE_VALID
)) {
1209 return EFI_UNSUPPORTED
;
1213 // Update the status light
1216 UsbKeyboardDevice
->ScrollOn
= 0;
1217 UsbKeyboardDevice
->NumLockOn
= 0;
1218 UsbKeyboardDevice
->CapsOn
= 0;
1220 if ((*KeyToggleState
& EFI_SCROLL_LOCK_ACTIVE
) == EFI_SCROLL_LOCK_ACTIVE
) {
1221 UsbKeyboardDevice
->ScrollOn
= 1;
1223 if ((*KeyToggleState
& EFI_NUM_LOCK_ACTIVE
) == EFI_NUM_LOCK_ACTIVE
) {
1224 UsbKeyboardDevice
->NumLockOn
= 1;
1226 if ((*KeyToggleState
& EFI_CAPS_LOCK_ACTIVE
) == EFI_CAPS_LOCK_ACTIVE
) {
1227 UsbKeyboardDevice
->CapsOn
= 1;
1230 SetKeyLED (UsbKeyboardDevice
);
1232 UsbKeyboardDevice
->KeyState
.KeyToggleState
= *KeyToggleState
;
1239 Register a notification function for a particular keystroke for the input device.
1241 @param This Protocol instance pointer.
1242 @param KeyData A pointer to a buffer that is filled in with the keystroke
1243 information data for the key that was pressed.
1244 @param KeyNotificationFunction Points to the function to be called when the key
1245 sequence is typed specified by KeyData.
1246 @param NotifyHandle Points to the unique handle assigned to the registered notification.
1248 @retval EFI_SUCCESS The notification function was registered successfully.
1249 @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data structures.
1250 @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle is NULL.
1255 USBKeyboardRegisterKeyNotify (
1256 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
1257 IN EFI_KEY_DATA
*KeyData
,
1258 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction
,
1259 OUT EFI_HANDLE
*NotifyHandle
1262 USB_KB_DEV
*UsbKeyboardDevice
;
1264 KEYBOARD_CONSOLE_IN_EX_NOTIFY
*NewNotify
;
1266 KEYBOARD_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
1268 if (KeyData
== NULL
|| NotifyHandle
== NULL
|| KeyNotificationFunction
== NULL
) {
1269 return EFI_INVALID_PARAMETER
;
1272 UsbKeyboardDevice
= TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This
);
1275 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
1277 for (Link
= UsbKeyboardDevice
->NotifyList
.ForwardLink
; Link
!= &UsbKeyboardDevice
->NotifyList
; Link
= Link
->ForwardLink
) {
1278 CurrentNotify
= CR (
1280 KEYBOARD_CONSOLE_IN_EX_NOTIFY
,
1282 USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
1284 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
1285 if (CurrentNotify
->KeyNotificationFn
== KeyNotificationFunction
) {
1286 *NotifyHandle
= CurrentNotify
->NotifyHandle
;
1293 // Allocate resource to save the notification function
1295 NewNotify
= (KEYBOARD_CONSOLE_IN_EX_NOTIFY
*) AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_EX_NOTIFY
));
1296 if (NewNotify
== NULL
) {
1297 return EFI_OUT_OF_RESOURCES
;
1300 NewNotify
->Signature
= USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
;
1301 NewNotify
->KeyNotificationFn
= KeyNotificationFunction
;
1302 CopyMem (&NewNotify
->KeyData
, KeyData
, sizeof (EFI_KEY_DATA
));
1303 InsertTailList (&UsbKeyboardDevice
->NotifyList
, &NewNotify
->NotifyEntry
);
1306 // Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE
1308 Status
= gBS
->InstallMultipleProtocolInterfaces (
1309 &NewNotify
->NotifyHandle
,
1310 &gSimpleTextInExNotifyGuid
,
1314 ASSERT_EFI_ERROR (Status
);
1316 *NotifyHandle
= NewNotify
->NotifyHandle
;
1323 Remove a registered notification function from a particular keystroke.
1325 @param This Protocol instance pointer.
1326 @param NotificationHandle The handle of the notification function being unregistered.
1328 @retval EFI_SUCCESS The notification function was unregistered successfully.
1329 @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid or opening gSimpleTextInExNotifyGuid
1330 on NotificationHandle fails.
1331 @retval EFI_NOT_FOUND Can not find the matching entry in database.
1336 USBKeyboardUnregisterKeyNotify (
1337 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
1338 IN EFI_HANDLE NotificationHandle
1341 USB_KB_DEV
*UsbKeyboardDevice
;
1343 KEYBOARD_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
1346 if (NotificationHandle
== NULL
) {
1347 return EFI_INVALID_PARAMETER
;
1350 UsbKeyboardDevice
= TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This
);
1352 Status
= gBS
->OpenProtocol (
1354 &gSimpleTextInExNotifyGuid
,
1358 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
1360 if (EFI_ERROR (Status
)) {
1361 return EFI_INVALID_PARAMETER
;
1364 for (Link
= UsbKeyboardDevice
->NotifyList
.ForwardLink
; Link
!= &UsbKeyboardDevice
->NotifyList
; Link
= Link
->ForwardLink
) {
1365 CurrentNotify
= CR (
1367 KEYBOARD_CONSOLE_IN_EX_NOTIFY
,
1369 USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
1371 if (CurrentNotify
->NotifyHandle
== NotificationHandle
) {
1373 // Remove the notification function from NotifyList and free resources
1375 RemoveEntryList (&CurrentNotify
->NotifyEntry
);
1376 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1377 CurrentNotify
->NotifyHandle
,
1378 &gSimpleTextInExNotifyGuid
,
1382 ASSERT_EFI_ERROR (Status
);
1383 gBS
->FreePool (CurrentNotify
);
1388 return EFI_NOT_FOUND
;