3 Copyright (c) 2004 - 2005, 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.
18 Helper functions for USB Keyboard Driver
26 #include <Library/UsbLib.h>
28 // USB Key Code to Efi key mapping table
29 // Format:<efi scan code>, <unicode without shift>, <unicode with shift>
32 UINT8 KeyConvertionTable
[USB_KEYCODE_MAX_MAKE
][3] = {
33 { SCAN_NULL
, 'a', 'A' }, // 0x04
34 { SCAN_NULL
, 'b', 'B' }, // 0x05
35 { SCAN_NULL
, 'c', 'C' }, // 0x06
36 { SCAN_NULL
, 'd', 'D' }, // 0x07
37 { SCAN_NULL
, 'e', 'E' }, // 0x08
38 { SCAN_NULL
, 'f', 'F' }, // 0x09
39 { SCAN_NULL
, 'g', 'G' }, // 0x0A
40 { SCAN_NULL
, 'h', 'H' }, // 0x0B
41 { SCAN_NULL
, 'i', 'I' }, // 0x0C
42 { SCAN_NULL
, 'j', 'J' }, // 0x0D
43 { SCAN_NULL
, 'k', 'K' }, // 0x0E
44 { SCAN_NULL
, 'l', 'L' }, // 0x0F
45 { SCAN_NULL
, 'm', 'M' }, // 0x10
46 { SCAN_NULL
, 'n', 'N' }, // 0x11
47 { SCAN_NULL
, 'o', 'O' }, // 0x12
48 { SCAN_NULL
, 'p', 'P' }, // 0x13
49 { SCAN_NULL
, 'q', 'Q' }, // 0x14
50 { SCAN_NULL
, 'r', 'R' }, // 0x15
51 { SCAN_NULL
, 's', 'S' }, // 0x16
52 { SCAN_NULL
, 't', 'T' }, // 0x17
53 { SCAN_NULL
, 'u', 'U' }, // 0x18
54 { SCAN_NULL
, 'v', 'V' }, // 0x19
55 { SCAN_NULL
, 'w', 'W' }, // 0x1A
56 { SCAN_NULL
, 'x', 'X' }, // 0x1B
57 { SCAN_NULL
, 'y', 'Y' }, // 0x1C
58 { SCAN_NULL
, 'z', 'Z' }, // 0x1D
59 { SCAN_NULL
, '1', '!' }, // 0x1E
60 { SCAN_NULL
, '2', '@' }, // 0x1F
61 { SCAN_NULL
, '3', '#' }, // 0x20
62 { SCAN_NULL
, '4', '$' }, // 0x21
63 { SCAN_NULL
, '5', '%' }, // 0x22
64 { SCAN_NULL
, '6', '^' }, // 0x23
65 { SCAN_NULL
, '7', '&' }, // 0x24
66 { SCAN_NULL
, '8', '*' }, // 0x25
67 { SCAN_NULL
, '9', '(' }, // 0x26
68 { SCAN_NULL
, '0', ')' }, // 0x27
69 { SCAN_NULL
, 0x0d, 0x0d }, // 0x28 Enter
70 { SCAN_ESC
, 0x00, 0x00 }, // 0x29 Esc
71 { SCAN_NULL
, 0x08, 0x08 }, // 0x2A Backspace
72 { SCAN_NULL
, 0x09, 0x09 }, // 0x2B Tab
73 { SCAN_NULL
, ' ', ' ' }, // 0x2C Spacebar
74 { SCAN_NULL
, '-', '_' }, // 0x2D
75 { SCAN_NULL
, '=', '+' }, // 0x2E
76 { SCAN_NULL
, '[', '{' }, // 0x2F
77 { SCAN_NULL
, ']', '}' }, // 0x30
78 { SCAN_NULL
, '\\', '|' }, // 0x31
79 { SCAN_NULL
, '\\', '|' }, // 0x32 Keyboard US \ and |
80 { SCAN_NULL
, ';', ':' }, // 0x33
81 { SCAN_NULL
, '\'', '"' }, // 0x34
82 { SCAN_NULL
, '`', '~' }, // 0x35 Keyboard Grave Accent and Tlide
83 { SCAN_NULL
, ',', '<' }, // 0x36
84 { SCAN_NULL
, '.', '>' }, // 0x37
85 { SCAN_NULL
, '/', '?' }, // 0x38
86 { SCAN_NULL
, 0x00, 0x00 }, // 0x39 CapsLock
87 { SCAN_F1
, 0x00, 0x00 }, // 0x3A
88 { SCAN_F2
, 0x00, 0x00 }, // 0x3B
89 { SCAN_F3
, 0x00, 0x00 }, // 0x3C
90 { SCAN_F4
, 0x00, 0x00 }, // 0x3D
91 { SCAN_F5
, 0x00, 0x00 }, // 0x3E
92 { SCAN_F6
, 0x00, 0x00 }, // 0x3F
93 { SCAN_F7
, 0x00, 0x00 }, // 0x40
94 { SCAN_F8
, 0x00, 0x00 }, // 0x41
95 { SCAN_F9
, 0x00, 0x00 }, // 0x42
96 { SCAN_F10
, 0x00, 0x00 }, // 0x43
97 { SCAN_F11
, 0x00, 0x00 }, // 0x44 F11
98 { SCAN_F12
, 0x00, 0x00 }, // 0x45 F12
99 { SCAN_NULL
, 0x00, 0x00 }, // 0x46 PrintScreen
100 { SCAN_NULL
, 0x00, 0x00 }, // 0x47 Scroll Lock
101 { SCAN_NULL
, 0x00, 0x00 }, // 0x48 Pause
102 { SCAN_INSERT
, 0x00, 0x00 }, // 0x49
103 { SCAN_HOME
, 0x00, 0x00 }, // 0x4A
104 { SCAN_PAGE_UP
, 0x00, 0x00 }, // 0x4B
105 { SCAN_DELETE
, 0x00, 0x00 }, // 0x4C
106 { SCAN_END
, 0x00, 0x00 }, // 0x4D
107 { SCAN_PAGE_DOWN
, 0x00, 0x00 }, // 0x4E
108 { SCAN_RIGHT
, 0x00, 0x00 }, // 0x4F
109 { SCAN_LEFT
, 0x00, 0x00 }, // 0x50
110 { SCAN_DOWN
, 0x00, 0x00 }, // 0x51
111 { SCAN_UP
, 0x00, 0x00 }, // 0x52
112 { SCAN_NULL
, 0x00, 0x00 }, // 0x53 NumLock
113 { SCAN_NULL
, '/', '/' }, // 0x54
114 { SCAN_NULL
, '*', '*' }, // 0x55
115 { SCAN_NULL
, '-', '-' }, // 0x56
116 { SCAN_NULL
, '+', '+' }, // 0x57
117 { SCAN_NULL
, 0x0d, 0x0d }, // 0x58
118 { SCAN_END
, '1', '1' }, // 0x59
119 { SCAN_DOWN
, '2', '2' }, // 0x5A
120 { SCAN_PAGE_DOWN
, '3', '3' }, // 0x5B
121 { SCAN_LEFT
, '4', '4' }, // 0x5C
122 { SCAN_NULL
, '5', '5' }, // 0x5D
123 { SCAN_RIGHT
, '6', '6' }, // 0x5E
124 { SCAN_HOME
, '7', '7' }, // 0x5F
125 { SCAN_UP
, '8', '8' }, // 0x60
126 { SCAN_PAGE_UP
, '9', '9' }, // 0x61
127 { SCAN_INSERT
, '0', '0' }, // 0x62
128 { SCAN_DELETE
, '.', '.' }, // 0x63
129 { SCAN_NULL
, '\\', '|' }, // 0x64 Keyboard Non-US \ and |
130 { SCAN_NULL
, 0x00, 0x00 }, // 0x65 Keyboard Application
131 { SCAN_NULL
, 0x00, 0x00 }, // 0x66 Keyboard Power
132 { SCAN_NULL
, '=' , '=' }, // 0x67 Keypad =
133 { SCAN_F13
, 0x00, 0x00 }, // 0x68
134 { SCAN_F14
, 0x00, 0x00 }, // 0x69
135 { SCAN_F15
, 0x00, 0x00 }, // 0x6A
136 { SCAN_F16
, 0x00, 0x00 }, // 0x6B
137 { SCAN_F17
, 0x00, 0x00 }, // 0x6C
138 { SCAN_F18
, 0x00, 0x00 }, // 0x6D
139 { SCAN_F19
, 0x00, 0x00 }, // 0x6E
140 { SCAN_F20
, 0x00, 0x00 }, // 0x6F
141 { SCAN_F21
, 0x00, 0x00 }, // 0x70
142 { SCAN_F22
, 0x00, 0x00 }, // 0x71
143 { SCAN_F23
, 0x00, 0x00 }, // 0x72
144 { SCAN_F24
, 0x00, 0x00 }, // 0x73
145 { SCAN_MUTE
, 0x00, 0x00 }, // 0x7F
146 { SCAN_VOLUME_UP
, 0x00, 0x00 }, // 0x80
147 { SCAN_VOLUME_DOWN
, 0x00, 0x00 }, // 0x81
150 STATIC KB_MODIFIER KB_Mod
[8] = {
151 { MOD_CONTROL_L
, 0xe0 }, // 11100000
152 { MOD_CONTROL_R
, 0xe4 }, // 11100100
153 { MOD_SHIFT_L
, 0xe1 }, // 11100001
154 { MOD_SHIFT_R
, 0xe5 }, // 11100101
155 { MOD_ALT_L
, 0xe2 }, // 11100010
156 { MOD_ALT_R
, 0xe6 }, // 11100110
157 { MOD_WIN_L
, 0xe3 }, // 11100011
158 { MOD_WIN_R
, 0xe7 }, // 11100111
164 Uses USB I/O to check whether the device is a USB Keyboard device.
166 UsbIo: Points to a USB I/O protocol instance.
172 IN EFI_USB_IO_PROTOCOL
*UsbIo
176 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
179 // Get the Default interface descriptor, currently we
180 // assume it is interface 1
182 Status
= UsbIo
->UsbGetInterfaceDescriptor (
187 if (EFI_ERROR (Status
)) {
191 if (InterfaceDescriptor
.InterfaceClass
== CLASS_HID
&&
192 InterfaceDescriptor
.InterfaceSubClass
== SUBCLASS_BOOT
&&
193 InterfaceDescriptor
.InterfaceProtocol
== PROTOCOL_KEYBOARD
205 Initialize USB Keyboard device and all private data structures.
207 UsbKeyboardDevice The USB_KB_DEV instance.
209 @retval EFI_SUCCESS Success
210 @retval EFI_DEVICE_ERROR Hardware Error
215 IN USB_KB_DEV
*UsbKeyboardDevice
223 UINT32 TransferResult
;
225 KbdReportStatusCode (
226 UsbKeyboardDevice
->DevicePath
,
228 PcdGet32 (PcdStatusCodeValueKeyboardSelfTest
)
231 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
234 // default configurations
239 // Uses default configuration to configure the USB Keyboard device.
241 Status
= UsbSetConfiguration (
242 UsbKeyboardDevice
->UsbIo
,
243 (UINT16
) ConfigValue
,
246 if (EFI_ERROR (Status
)) {
248 // If configuration could not be set here, it means
249 // the keyboard interface has some errors and could
250 // not be initialized
252 KbdReportStatusCode (
253 UsbKeyboardDevice
->DevicePath
,
254 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
255 PcdGet32 (PcdStatusCodeValueKeyboardInterfaceError
)
258 return EFI_DEVICE_ERROR
;
261 UsbGetProtocolRequest (
262 UsbKeyboardDevice
->UsbIo
,
263 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
267 // Sets boot protocol for the USB Keyboard.
268 // This driver only supports boot protocol.
269 // !!BugBug: How about the device that does not support boot protocol?
271 if (Protocol
!= BOOT_PROTOCOL
) {
272 UsbSetProtocolRequest (
273 UsbKeyboardDevice
->UsbIo
,
274 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
279 // the duration is indefinite, so the endpoint will inhibit reporting forever,
280 // and only reporting when a change is detected in the report data.
284 // idle value for all report ID
288 // idle forever until there is a key pressed and released.
292 UsbKeyboardDevice
->UsbIo
,
293 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
298 UsbKeyboardDevice
->CtrlOn
= 0;
299 UsbKeyboardDevice
->AltOn
= 0;
300 UsbKeyboardDevice
->ShiftOn
= 0;
301 UsbKeyboardDevice
->NumLockOn
= 0;
302 UsbKeyboardDevice
->CapsOn
= 0;
303 UsbKeyboardDevice
->ScrollOn
= 0;
305 UsbKeyboardDevice
->LeftCtrlOn
= 0;
306 UsbKeyboardDevice
->LeftAltOn
= 0;
307 UsbKeyboardDevice
->LeftShiftOn
= 0;
308 UsbKeyboardDevice
->LeftLogoOn
= 0;
309 UsbKeyboardDevice
->RightCtrlOn
= 0;
310 UsbKeyboardDevice
->RightAltOn
= 0;
311 UsbKeyboardDevice
->RightShiftOn
= 0;
312 UsbKeyboardDevice
->RightLogoOn
= 0;
313 UsbKeyboardDevice
->MenuKeyOn
= 0;
314 UsbKeyboardDevice
->SysReqOn
= 0;
317 // Sync the initial state of lights
319 SetKeyLED (UsbKeyboardDevice
);
321 ZeroMem (UsbKeyboardDevice
->LastKeyCodeArray
, sizeof (UINT8
) * 8);
324 // Set a timer for repeat keys' generation.
326 if (UsbKeyboardDevice
->RepeatTimer
) {
327 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
328 UsbKeyboardDevice
->RepeatTimer
= 0;
331 Status
= gBS
->CreateEvent (
332 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
334 USBKeyboardRepeatHandler
,
336 &UsbKeyboardDevice
->RepeatTimer
339 if (UsbKeyboardDevice
->DelayedRecoveryEvent
) {
340 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
341 UsbKeyboardDevice
->DelayedRecoveryEvent
= 0;
344 Status
= gBS
->CreateEvent (
345 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
347 USBKeyboardRecoveryHandler
,
349 &UsbKeyboardDevice
->DelayedRecoveryEvent
357 Handler function for USB Keyboard's asynchronous interrupt transfer.
359 Data A pointer to a buffer that is filled with key data which is
360 retrieved via asynchronous interrupt transfer.
361 DataLength Indicates the size of the data buffer.
362 Context Pointing to USB_KB_DEV instance.
363 Result Indicates the result of the asynchronous interrupt transfer.
365 @retval EFI_SUCCESS Success
366 @retval EFI_DEVICE_ERROR Hardware Error
378 USB_KB_DEV
*UsbKeyboardDevice
;
379 EFI_USB_IO_PROTOCOL
*UsbIo
;
380 UINT8
*CurKeyCodeBuffer
;
381 UINT8
*OldKeyCodeBuffer
;
382 UINT8 CurModifierMap
;
383 UINT8 OldModifierMap
;
397 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
398 UsbIo
= UsbKeyboardDevice
->UsbIo
;
401 // Analyzes the Result and performs corresponding action.
403 if (Result
!= EFI_USB_NOERROR
) {
405 // Some errors happen during the process
407 KbdReportStatusCode (
408 UsbKeyboardDevice
->DevicePath
,
409 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
410 PcdGet32 (PcdStatusCodeValueKeyboardInputError
)
414 // stop the repeat key generation if any
416 UsbKeyboardDevice
->RepeatKey
= 0;
419 UsbKeyboardDevice
->RepeatTimer
,
424 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
425 UsbClearEndpointHalt (
427 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
433 // Delete & Submit this interrupt again
436 UsbIo
->UsbAsyncInterruptTransfer (
438 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
447 UsbKeyboardDevice
->DelayedRecoveryEvent
,
449 EFI_USB_INTERRUPT_DELAY
452 return EFI_DEVICE_ERROR
;
455 if (DataLength
== 0 || Data
== NULL
) {
459 CurKeyCodeBuffer
= (UINT8
*) Data
;
460 OldKeyCodeBuffer
= UsbKeyboardDevice
->LastKeyCodeArray
;
463 // checks for new key stroke.
464 // if no new key got, return immediately.
466 for (Index
= 0; Index
< 8; Index
++) {
467 if (OldKeyCodeBuffer
[Index
] != CurKeyCodeBuffer
[Index
]) {
477 // Parse the modifier key
479 CurModifierMap
= CurKeyCodeBuffer
[0];
480 OldModifierMap
= OldKeyCodeBuffer
[0];
483 // handle modifier key's pressing or releasing situation.
485 for (Index
= 0; Index
< 8; Index
++) {
487 if ((CurModifierMap
& KB_Mod
[Index
].Mask
) != (OldModifierMap
& KB_Mod
[Index
].Mask
)) {
489 // if current modifier key is up, then
490 // CurModifierMap & KB_Mod[Index].Mask = 0;
491 // otherwize it is a non-zero value.
492 // Inserts the pressed modifier key into key buffer.
494 Down
= (UINT8
) (CurModifierMap
& KB_Mod
[Index
].Mask
);
495 InsertKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), KB_Mod
[Index
].Key
, Down
);
500 // handle normal key's releasing situation
503 for (Index
= 2; Index
< 8; Index
++) {
505 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index
])) {
510 for (Index2
= 2; Index2
< 8; Index2
++) {
512 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index2
])) {
516 if (OldKeyCodeBuffer
[Index
] == CurKeyCodeBuffer
[Index2
]) {
524 &(UsbKeyboardDevice
->KeyboardBuffer
),
525 OldKeyCodeBuffer
[Index
],
529 // the original reapeat key is released.
531 if (OldKeyCodeBuffer
[Index
] == UsbKeyboardDevice
->RepeatKey
) {
532 UsbKeyboardDevice
->RepeatKey
= 0;
538 // original repeat key is released, cancel the repeat timer
540 if (UsbKeyboardDevice
->RepeatKey
== 0) {
542 UsbKeyboardDevice
->RepeatTimer
,
549 // handle normal key's pressing situation
552 for (Index
= 2; Index
< 8; Index
++) {
554 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index
])) {
559 for (Index2
= 2; Index2
< 8; Index2
++) {
561 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index2
])) {
565 if (CurKeyCodeBuffer
[Index
] == OldKeyCodeBuffer
[Index2
]) {
572 InsertKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), CurKeyCodeBuffer
[Index
], 1);
574 // NumLock pressed or CapsLock pressed
576 if (CurKeyCodeBuffer
[Index
] == 0x53 || CurKeyCodeBuffer
[Index
] == 0x39) {
577 UsbKeyboardDevice
->RepeatKey
= 0;
579 NewRepeatKey
= CurKeyCodeBuffer
[Index
];
581 // do not repeat the original repeated key
583 UsbKeyboardDevice
->RepeatKey
= 0;
589 // Update LastKeycodeArray[] buffer in the
590 // Usb Keyboard Device data structure.
592 for (Index
= 0; Index
< 8; Index
++) {
593 UsbKeyboardDevice
->LastKeyCodeArray
[Index
] = CurKeyCodeBuffer
[Index
];
597 // pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence
598 // and judge whether it will invoke reset event.
600 SavedTail
= UsbKeyboardDevice
->KeyboardBuffer
.bTail
;
601 Index
= UsbKeyboardDevice
->KeyboardBuffer
.bHead
;
602 while (Index
!= SavedTail
) {
603 RemoveKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), &UsbKey
);
605 switch (UsbKey
.KeyCode
) {
610 UsbKeyboardDevice
->CtrlOn
= 1;
612 UsbKeyboardDevice
->CtrlOn
= 0;
619 UsbKeyboardDevice
->AltOn
= 1;
621 UsbKeyboardDevice
->AltOn
= 0;
631 if (UsbKeyboardDevice
->CtrlOn
&& UsbKeyboardDevice
->AltOn
) {
632 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
642 // insert the key back to the buffer.
643 // so the key sequence will not be destroyed.
646 &(UsbKeyboardDevice
->KeyboardBuffer
),
650 Index
= UsbKeyboardDevice
->KeyboardBuffer
.bHead
;
654 // If have new key pressed, update the RepeatKey value, and set the
655 // timer to repeate delay timer
657 if (NewRepeatKey
!= 0) {
659 // sets trigger time to "Repeat Delay Time",
660 // to trigger the repeat timer when the key is hold long
664 UsbKeyboardDevice
->RepeatTimer
,
668 UsbKeyboardDevice
->RepeatKey
= NewRepeatKey
;
676 Retrieves a key character after parsing the raw data in keyboard buffer.
678 UsbKeyboardDevice The USB_KB_DEV instance.
679 KeyChar Points to the Key character after key parsing.
681 @retval EFI_SUCCESS Success
682 @retval EFI_NOT_READY Device is not ready
687 IN OUT USB_KB_DEV
*UsbKeyboardDevice
,
695 while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice
->KeyboardBuffer
)) {
697 // pops one raw data off.
699 RemoveKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), &UsbKey
);
702 switch (UsbKey
.KeyCode
) {
708 UsbKeyboardDevice
->LeftCtrlOn
= 0;
709 UsbKeyboardDevice
->CtrlOn
= 0;
712 UsbKeyboardDevice
->RightCtrlOn
= 0;
713 UsbKeyboardDevice
->CtrlOn
= 0;
720 UsbKeyboardDevice
->LeftShiftOn
= 0;
721 UsbKeyboardDevice
->ShiftOn
= 0;
724 UsbKeyboardDevice
->RightShiftOn
= 0;
725 UsbKeyboardDevice
->ShiftOn
= 0;
732 UsbKeyboardDevice
->LeftAltOn
= 0;
733 UsbKeyboardDevice
->AltOn
= 0;
736 UsbKeyboardDevice
->RightAltOn
= 0;
737 UsbKeyboardDevice
->AltOn
= 0;
744 UsbKeyboardDevice
->LeftLogoOn
= 0;
747 UsbKeyboardDevice
->RightLogoOn
= 0;
751 // Menu key (App/Apps) release
754 UsbKeyboardDevice
->MenuKeyOn
= 0;
761 UsbKeyboardDevice
->SysReqOn
= 0;
771 // Analyzes key pressing situation
773 switch (UsbKey
.KeyCode
) {
776 UsbKeyboardDevice
->LeftCtrlOn
= 1;
777 UsbKeyboardDevice
->CtrlOn
= 1;
781 UsbKeyboardDevice
->RightCtrlOn
= 1;
782 UsbKeyboardDevice
->CtrlOn
= 1;
790 UsbKeyboardDevice
->LeftShiftOn
= 1;
791 UsbKeyboardDevice
->ShiftOn
= 1;
795 UsbKeyboardDevice
->RightShiftOn
= 1;
796 UsbKeyboardDevice
->ShiftOn
= 1;
804 UsbKeyboardDevice
->LeftAltOn
= 1;
805 UsbKeyboardDevice
->AltOn
= 1;
809 UsbKeyboardDevice
->RightAltOn
= 1;
810 UsbKeyboardDevice
->AltOn
= 1;
818 UsbKeyboardDevice
->LeftLogoOn
= 1;
822 UsbKeyboardDevice
->RightLogoOn
= 1;
827 // Menu key (App/Apps) press
830 UsbKeyboardDevice
->MenuKeyOn
= 1;
838 UsbKeyboardDevice
->SysReqOn
= 1;
843 UsbKeyboardDevice
->NumLockOn
^= 1;
845 // Turn on the NumLock light on KB
847 SetKeyLED (UsbKeyboardDevice
);
852 UsbKeyboardDevice
->CapsOn
^= 1;
854 // Turn on the CapsLock light on KB
856 SetKeyLED (UsbKeyboardDevice
);
861 UsbKeyboardDevice
->ScrollOn
^= 1;
863 // Turn on the ScrollLock light on KB
865 SetKeyLED (UsbKeyboardDevice
);
870 // PrintScreen,Pause,Application,Power
871 // keys are not valid EFI key
875 // PrintScreen/SysRq key and Application key
876 // Should be handled by UEFI2.1 compliant code
894 // When encountered Del Key...
896 if (UsbKey
.KeyCode
== 0x4c || UsbKey
.KeyCode
== 0x63) {
897 if (UsbKeyboardDevice
->CtrlOn
&& UsbKeyboardDevice
->AltOn
) {
898 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
902 *KeyChar
= UsbKey
.KeyCode
;
906 return EFI_NOT_READY
;
913 Converts USB Keyboard code to EFI Scan Code.
915 UsbKeyboardDevice The USB_KB_DEV instance.
916 KeyChar Indicates the key code that will be interpreted.
917 Key A pointer to a buffer that is filled in with
918 the keystroke information for the key that
921 @retval EFI_NOT_READY Device is not ready
922 @retval EFI_SUCCESS Success
926 USBKeyCodeToEFIScanCode (
927 IN USB_KB_DEV
*UsbKeyboardDevice
,
929 OUT EFI_INPUT_KEY
*Key
934 if (!USBKBD_VALID_KEYCODE (KeyChar
)) {
935 return EFI_NOT_READY
;
939 // valid USB Key Code starts from 4
941 Index
= (UINT8
) (KeyChar
- 4);
943 if (Index
>= USB_KEYCODE_MAX_MAKE
) {
944 return EFI_NOT_READY
;
948 // Undefined entries from 0x74 to 0x7E
950 if (KeyChar
> USB_KEYCODE_MAX_MAKE
) {
951 Index
= (UINT8
) (Index
- 11);
954 Key
->ScanCode
= KeyConvertionTable
[Index
][0];
956 if (UsbKeyboardDevice
->ShiftOn
) {
958 Key
->UnicodeChar
= KeyConvertionTable
[Index
][2];
960 // Need not return associated shift state if a class of printable characters that
961 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
963 if (Key
->UnicodeChar
>= 'A' && Key
->UnicodeChar
<= 'Z') {
964 UsbKeyboardDevice
->LeftShiftOn
= 0;
965 UsbKeyboardDevice
->RightShiftOn
= 0;
970 Key
->UnicodeChar
= KeyConvertionTable
[Index
][1];
973 if (UsbKeyboardDevice
->CapsOn
) {
975 if (Key
->UnicodeChar
>= 'a' && Key
->UnicodeChar
<= 'z') {
977 Key
->UnicodeChar
= KeyConvertionTable
[Index
][2];
979 } else if (Key
->UnicodeChar
>= 'A' && Key
->UnicodeChar
<= 'Z') {
981 Key
->UnicodeChar
= KeyConvertionTable
[Index
][1];
986 // Translate the CTRL-Alpha characters to their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
988 if (UsbKeyboardDevice
->CtrlOn
) {
989 if (Key
->UnicodeChar
>= 'a' && Key
->UnicodeChar
<= 'z') {
990 Key
->UnicodeChar
= (UINT16
) (Key
->UnicodeChar
- 'a' + 1);
991 } else if (Key
->UnicodeChar
>= 'A' && Key
->UnicodeChar
<= 'Z') {
992 Key
->UnicodeChar
= (UINT16
) (Key
->UnicodeChar
- 'A' + 1);
997 if (KeyChar
>= 0x59 && KeyChar
<= 0x63) {
999 if (UsbKeyboardDevice
->NumLockOn
&& !UsbKeyboardDevice
->ShiftOn
) {
1001 Key
->ScanCode
= SCAN_NULL
;
1005 Key
->UnicodeChar
= 0x00;
1009 if (Key
->UnicodeChar
== 0 && Key
->ScanCode
== SCAN_NULL
) {
1010 return EFI_NOT_READY
;
1015 // Save Shift/Toggle state
1017 if (UsbKeyboardDevice
->LeftCtrlOn
== 1) {
1018 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_LEFT_CONTROL_PRESSED
;
1020 if (UsbKeyboardDevice
->RightCtrlOn
== 1) {
1021 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_RIGHT_CONTROL_PRESSED
;
1023 if (UsbKeyboardDevice
->LeftAltOn
== 1) {
1024 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_LEFT_ALT_PRESSED
;
1026 if (UsbKeyboardDevice
->RightAltOn
== 1) {
1027 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_RIGHT_ALT_PRESSED
;
1029 if (UsbKeyboardDevice
->LeftShiftOn
== 1) {
1030 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_LEFT_SHIFT_PRESSED
;
1032 if (UsbKeyboardDevice
->RightShiftOn
== 1) {
1033 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_RIGHT_SHIFT_PRESSED
;
1035 if (UsbKeyboardDevice
->LeftLogoOn
== 1) {
1036 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_LEFT_LOGO_PRESSED
;
1038 if (UsbKeyboardDevice
->RightLogoOn
== 1) {
1039 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_RIGHT_LOGO_PRESSED
;
1041 if (UsbKeyboardDevice
->MenuKeyOn
== 1) {
1042 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_MENU_KEY_PRESSED
;
1044 if (UsbKeyboardDevice
->SysReqOn
== 1) {
1045 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_SYS_REQ_PRESSED
;
1048 if (UsbKeyboardDevice
->ScrollOn
== 1) {
1049 UsbKeyboardDevice
->KeyState
.KeyToggleState
|= EFI_SCROLL_LOCK_ACTIVE
;
1051 if (UsbKeyboardDevice
->NumLockOn
== 1) {
1052 UsbKeyboardDevice
->KeyState
.KeyToggleState
|= EFI_NUM_LOCK_ACTIVE
;
1054 if (UsbKeyboardDevice
->CapsOn
== 1) {
1055 UsbKeyboardDevice
->KeyState
.KeyToggleState
|= EFI_CAPS_LOCK_ACTIVE
;
1065 Resets USB Keyboard Buffer.
1067 @param KeyboardBuffer Points to the USB Keyboard Buffer.
1069 @retval EFI_SUCCESS Success
1074 IN OUT USB_KB_BUFFER
*KeyboardBuffer
1077 ZeroMem (KeyboardBuffer
, sizeof (USB_KB_BUFFER
));
1079 KeyboardBuffer
->bHead
= KeyboardBuffer
->bTail
;
1086 Check whether USB Keyboard buffer is empty.
1088 @param KeyboardBuffer USB Keyboard Buffer.
1093 IsUSBKeyboardBufferEmpty (
1094 IN USB_KB_BUFFER
*KeyboardBuffer
1098 // meet FIFO empty condition
1100 return (BOOLEAN
) (KeyboardBuffer
->bHead
== KeyboardBuffer
->bTail
);
1106 Check whether USB Keyboard buffer is full.
1108 @param KeyboardBuffer USB Keyboard Buffer.
1113 IsUSBKeyboardBufferFull (
1114 IN USB_KB_BUFFER
*KeyboardBuffer
1117 return (BOOLEAN
)(((KeyboardBuffer
->bTail
+ 1) % (MAX_KEY_ALLOWED
+ 1)) ==
1118 KeyboardBuffer
->bHead
);
1124 Inserts a key code into keyboard buffer.
1126 @param KeyboardBuffer Points to the USB Keyboard Buffer.
1128 @param Down Special key
1130 @retval EFI_SUCCESS Success
1135 IN OUT USB_KB_BUFFER
*KeyboardBuffer
,
1143 // if keyboard buffer is full, throw the
1144 // first key out of the keyboard buffer.
1146 if (IsUSBKeyboardBufferFull (KeyboardBuffer
)) {
1147 RemoveKeyCode (KeyboardBuffer
, &UsbKey
);
1150 KeyboardBuffer
->buffer
[KeyboardBuffer
->bTail
].KeyCode
= Key
;
1151 KeyboardBuffer
->buffer
[KeyboardBuffer
->bTail
].Down
= Down
;
1154 // adjust the tail pointer of the FIFO keyboard buffer.
1156 KeyboardBuffer
->bTail
= (UINT8
) ((KeyboardBuffer
->bTail
+ 1) % (MAX_KEY_ALLOWED
+ 1));
1163 Pops a key code off from keyboard buffer.
1165 @param KeyboardBuffer Points to the USB Keyboard Buffer.
1166 @param UsbKey Points to the buffer that contains a usb key code.
1168 @retval EFI_SUCCESS Success
1169 @retval EFI_DEVICE_ERROR Hardware Error
1174 IN OUT USB_KB_BUFFER
*KeyboardBuffer
,
1178 if (IsUSBKeyboardBufferEmpty (KeyboardBuffer
)) {
1179 return EFI_DEVICE_ERROR
;
1182 UsbKey
->KeyCode
= KeyboardBuffer
->buffer
[KeyboardBuffer
->bHead
].KeyCode
;
1183 UsbKey
->Down
= KeyboardBuffer
->buffer
[KeyboardBuffer
->bHead
].Down
;
1186 // adjust the head pointer of the FIFO keyboard buffer.
1188 KeyboardBuffer
->bHead
= (UINT8
) ((KeyboardBuffer
->bHead
+ 1) % (MAX_KEY_ALLOWED
+ 1));
1195 Sets USB Keyboard LED state.
1197 @param UsbKeyboardDevice The USB_KB_DEV instance.
1199 @retval EFI_SUCCESS Success
1204 IN USB_KB_DEV
*UsbKeyboardDevice
1211 // Set each field in Led map.
1213 Led
.NumLock
= (UINT8
) UsbKeyboardDevice
->NumLockOn
;
1214 Led
.CapsLock
= (UINT8
) UsbKeyboardDevice
->CapsOn
;
1215 Led
.ScrollLock
= (UINT8
) UsbKeyboardDevice
->ScrollOn
;
1220 // call Set Report Request to lighten the LED.
1222 UsbSetReportRequest (
1223 UsbKeyboardDevice
->UsbIo
,
1224 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
1236 Timer handler for Repeat Key timer.
1238 @param Event The Repeat Key event.
1239 @param Context Points to the USB_KB_DEV instance.
1245 USBKeyboardRepeatHandler (
1250 USB_KB_DEV
*UsbKeyboardDevice
;
1252 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1255 // Do nothing when there is no repeat key.
1257 if (UsbKeyboardDevice
->RepeatKey
!= 0) {
1259 // Inserts one Repeat key into keyboard buffer,
1262 &(UsbKeyboardDevice
->KeyboardBuffer
),
1263 UsbKeyboardDevice
->RepeatKey
,
1268 // set repeate rate for repeat key generation.
1271 UsbKeyboardDevice
->RepeatTimer
,
1281 Timer handler for Delayed Recovery timer.
1283 @param Event The Delayed Recovery event.
1284 @param Context Points to the USB_KB_DEV instance.
1290 USBKeyboardRecoveryHandler (
1296 USB_KB_DEV
*UsbKeyboardDevice
;
1297 EFI_USB_IO_PROTOCOL
*UsbIo
;
1300 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1302 UsbIo
= UsbKeyboardDevice
->UsbIo
;
1304 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
1306 UsbIo
->UsbAsyncInterruptTransfer (
1308 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1310 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,