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 =
135 STATIC KB_MODIFIER KB_Mod
[8] = {
136 { MOD_CONTROL_L
, 0xe0 }, // 11100000
137 { MOD_CONTROL_R
, 0xe4 }, // 11100100
138 { MOD_SHIFT_L
, 0xe1 }, // 11100001
139 { MOD_SHIFT_R
, 0xe5 }, // 11100101
140 { MOD_ALT_L
, 0xe2 }, // 11100010
141 { MOD_ALT_R
, 0xe6 }, // 11100110
142 { MOD_WIN_L
, 0xe3 }, // 11100011
143 { MOD_WIN_R
, 0xe7 } // 11100111
149 Uses USB I/O to check whether the device is a USB Keyboard device.
151 UsbIo: Points to a USB I/O protocol instance.
157 IN EFI_USB_IO_PROTOCOL
*UsbIo
161 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
164 // Get the Default interface descriptor, currently we
165 // assume it is interface 1
167 Status
= UsbIo
->UsbGetInterfaceDescriptor (
172 if (EFI_ERROR (Status
)) {
176 if (InterfaceDescriptor
.InterfaceClass
== CLASS_HID
&&
177 InterfaceDescriptor
.InterfaceSubClass
== SUBCLASS_BOOT
&&
178 InterfaceDescriptor
.InterfaceProtocol
== PROTOCOL_KEYBOARD
190 Initialize USB Keyboard device and all private data structures.
192 UsbKeyboardDevice The USB_KB_DEV instance.
194 @retval EFI_SUCCESS Success
195 @retval EFI_DEVICE_ERROR Hardware Error
200 IN USB_KB_DEV
*UsbKeyboardDevice
208 UINT32 TransferResult
;
210 KbdReportStatusCode (
211 UsbKeyboardDevice
->DevicePath
,
213 PcdGet32 (PcdStatusCodeValueKeyboardSelfTest
)
216 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
219 // default configurations
224 // Uses default configuration to configure the USB Keyboard device.
226 Status
= UsbSetConfiguration (
227 UsbKeyboardDevice
->UsbIo
,
228 (UINT16
) ConfigValue
,
231 if (EFI_ERROR (Status
)) {
233 // If configuration could not be set here, it means
234 // the keyboard interface has some errors and could
235 // not be initialized
237 KbdReportStatusCode (
238 UsbKeyboardDevice
->DevicePath
,
239 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
240 PcdGet32 (PcdStatusCodeValueKeyboardInterfaceError
)
243 return EFI_DEVICE_ERROR
;
246 UsbGetProtocolRequest (
247 UsbKeyboardDevice
->UsbIo
,
248 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
252 // Sets boot protocol for the USB Keyboard.
253 // This driver only supports boot protocol.
254 // !!BugBug: How about the device that does not support boot protocol?
256 if (Protocol
!= BOOT_PROTOCOL
) {
257 UsbSetProtocolRequest (
258 UsbKeyboardDevice
->UsbIo
,
259 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
264 // the duration is indefinite, so the endpoint will inhibit reporting forever,
265 // and only reporting when a change is detected in the report data.
269 // idle value for all report ID
273 // idle forever until there is a key pressed and released.
277 UsbKeyboardDevice
->UsbIo
,
278 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
283 UsbKeyboardDevice
->CtrlOn
= 0;
284 UsbKeyboardDevice
->AltOn
= 0;
285 UsbKeyboardDevice
->ShiftOn
= 0;
286 UsbKeyboardDevice
->NumLockOn
= 0;
287 UsbKeyboardDevice
->CapsOn
= 0;
288 UsbKeyboardDevice
->ScrollOn
= 0;
291 // Sync the initial state of lights
293 SetKeyLED (UsbKeyboardDevice
);
295 ZeroMem (UsbKeyboardDevice
->LastKeyCodeArray
, sizeof (UINT8
) * 8);
298 // Set a timer for repeat keys' generation.
300 if (UsbKeyboardDevice
->RepeatTimer
) {
301 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
302 UsbKeyboardDevice
->RepeatTimer
= 0;
305 Status
= gBS
->CreateEvent (
306 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
308 USBKeyboardRepeatHandler
,
310 &UsbKeyboardDevice
->RepeatTimer
313 if (UsbKeyboardDevice
->DelayedRecoveryEvent
) {
314 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
315 UsbKeyboardDevice
->DelayedRecoveryEvent
= 0;
318 Status
= gBS
->CreateEvent (
319 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
321 USBKeyboardRecoveryHandler
,
323 &UsbKeyboardDevice
->DelayedRecoveryEvent
331 Handler function for USB Keyboard's asynchronous interrupt transfer.
333 Data A pointer to a buffer that is filled with key data which is
334 retrieved via asynchronous interrupt transfer.
335 DataLength Indicates the size of the data buffer.
336 Context Pointing to USB_KB_DEV instance.
337 Result Indicates the result of the asynchronous interrupt transfer.
339 @retval EFI_SUCCESS Success
340 @retval EFI_DEVICE_ERROR Hardware Error
352 USB_KB_DEV
*UsbKeyboardDevice
;
353 EFI_USB_IO_PROTOCOL
*UsbIo
;
354 UINT8
*CurKeyCodeBuffer
;
355 UINT8
*OldKeyCodeBuffer
;
356 UINT8 CurModifierMap
;
357 UINT8 OldModifierMap
;
371 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
372 UsbIo
= UsbKeyboardDevice
->UsbIo
;
375 // Analyzes the Result and performs corresponding action.
377 if (Result
!= EFI_USB_NOERROR
) {
379 // Some errors happen during the process
381 KbdReportStatusCode (
382 UsbKeyboardDevice
->DevicePath
,
383 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
384 PcdGet32 (PcdStatusCodeValueKeyboardInputError
)
388 // stop the repeat key generation if any
390 UsbKeyboardDevice
->RepeatKey
= 0;
393 UsbKeyboardDevice
->RepeatTimer
,
398 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
399 UsbClearEndpointHalt (
401 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
407 // Delete & Submit this interrupt again
410 UsbIo
->UsbAsyncInterruptTransfer (
412 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
421 UsbKeyboardDevice
->DelayedRecoveryEvent
,
423 EFI_USB_INTERRUPT_DELAY
426 return EFI_DEVICE_ERROR
;
429 if (DataLength
== 0 || Data
== NULL
) {
433 CurKeyCodeBuffer
= (UINT8
*) Data
;
434 OldKeyCodeBuffer
= UsbKeyboardDevice
->LastKeyCodeArray
;
437 // checks for new key stroke.
438 // if no new key got, return immediately.
440 for (Index
= 0; Index
< 8; Index
++) {
441 if (OldKeyCodeBuffer
[Index
] != CurKeyCodeBuffer
[Index
]) {
451 // Parse the modifier key
453 CurModifierMap
= CurKeyCodeBuffer
[0];
454 OldModifierMap
= OldKeyCodeBuffer
[0];
457 // handle modifier key's pressing or releasing situation.
459 for (Index
= 0; Index
< 8; Index
++) {
461 if ((CurModifierMap
& KB_Mod
[Index
].Mask
) != (OldModifierMap
& KB_Mod
[Index
].Mask
)) {
463 // if current modifier key is up, then
464 // CurModifierMap & KB_Mod[Index].Mask = 0;
465 // otherwize it is a non-zero value.
466 // Inserts the pressed modifier key into key buffer.
468 Down
= (UINT8
) (CurModifierMap
& KB_Mod
[Index
].Mask
);
469 InsertKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), KB_Mod
[Index
].Key
, Down
);
474 // handle normal key's releasing situation
477 for (Index
= 2; Index
< 8; Index
++) {
479 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index
])) {
484 for (Index2
= 2; Index2
< 8; Index2
++) {
486 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index2
])) {
490 if (OldKeyCodeBuffer
[Index
] == CurKeyCodeBuffer
[Index2
]) {
498 &(UsbKeyboardDevice
->KeyboardBuffer
),
499 OldKeyCodeBuffer
[Index
],
503 // the original reapeat key is released.
505 if (OldKeyCodeBuffer
[Index
] == UsbKeyboardDevice
->RepeatKey
) {
506 UsbKeyboardDevice
->RepeatKey
= 0;
512 // original repeat key is released, cancel the repeat timer
514 if (UsbKeyboardDevice
->RepeatKey
== 0) {
516 UsbKeyboardDevice
->RepeatTimer
,
523 // handle normal key's pressing situation
526 for (Index
= 2; Index
< 8; Index
++) {
528 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index
])) {
533 for (Index2
= 2; Index2
< 8; Index2
++) {
535 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index2
])) {
539 if (CurKeyCodeBuffer
[Index
] == OldKeyCodeBuffer
[Index2
]) {
546 InsertKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), CurKeyCodeBuffer
[Index
], 1);
548 // NumLock pressed or CapsLock pressed
550 if (CurKeyCodeBuffer
[Index
] == 0x53 || CurKeyCodeBuffer
[Index
] == 0x39) {
551 UsbKeyboardDevice
->RepeatKey
= 0;
553 NewRepeatKey
= CurKeyCodeBuffer
[Index
];
555 // do not repeat the original repeated key
557 UsbKeyboardDevice
->RepeatKey
= 0;
563 // Update LastKeycodeArray[] buffer in the
564 // Usb Keyboard Device data structure.
566 for (Index
= 0; Index
< 8; Index
++) {
567 UsbKeyboardDevice
->LastKeyCodeArray
[Index
] = CurKeyCodeBuffer
[Index
];
571 // pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence
572 // and judge whether it will invoke reset event.
574 SavedTail
= UsbKeyboardDevice
->KeyboardBuffer
.bTail
;
575 Index
= UsbKeyboardDevice
->KeyboardBuffer
.bHead
;
576 while (Index
!= SavedTail
) {
577 RemoveKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), &UsbKey
);
579 switch (UsbKey
.KeyCode
) {
584 UsbKeyboardDevice
->CtrlOn
= 1;
586 UsbKeyboardDevice
->CtrlOn
= 0;
593 UsbKeyboardDevice
->AltOn
= 1;
595 UsbKeyboardDevice
->AltOn
= 0;
605 if (UsbKeyboardDevice
->CtrlOn
&& UsbKeyboardDevice
->AltOn
) {
606 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
616 // insert the key back to the buffer.
617 // so the key sequence will not be destroyed.
620 &(UsbKeyboardDevice
->KeyboardBuffer
),
624 Index
= UsbKeyboardDevice
->KeyboardBuffer
.bHead
;
628 // If have new key pressed, update the RepeatKey value, and set the
629 // timer to repeate delay timer
631 if (NewRepeatKey
!= 0) {
633 // sets trigger time to "Repeat Delay Time",
634 // to trigger the repeat timer when the key is hold long
638 UsbKeyboardDevice
->RepeatTimer
,
642 UsbKeyboardDevice
->RepeatKey
= NewRepeatKey
;
650 Retrieves a key character after parsing the raw data in keyboard buffer.
652 UsbKeyboardDevice The USB_KB_DEV instance.
653 KeyChar Points to the Key character after key parsing.
655 @retval EFI_SUCCESS Success
656 @retval EFI_NOT_READY Device is not ready
661 IN OUT USB_KB_DEV
*UsbKeyboardDevice
,
669 while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice
->KeyboardBuffer
)) {
671 // pops one raw data off.
673 RemoveKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), &UsbKey
);
676 switch (UsbKey
.KeyCode
) {
680 UsbKeyboardDevice
->CtrlOn
= 0;
685 UsbKeyboardDevice
->ShiftOn
= 0;
690 UsbKeyboardDevice
->AltOn
= 0;
701 // Analyzes key pressing situation
703 switch (UsbKey
.KeyCode
) {
707 UsbKeyboardDevice
->CtrlOn
= 1;
713 UsbKeyboardDevice
->ShiftOn
= 1;
719 UsbKeyboardDevice
->AltOn
= 1;
729 UsbKeyboardDevice
->NumLockOn
^= 1;
731 // Turn on the NumLock light on KB
733 SetKeyLED (UsbKeyboardDevice
);
738 UsbKeyboardDevice
->CapsOn
^= 1;
740 // Turn on the CapsLock light on KB
742 SetKeyLED (UsbKeyboardDevice
);
747 UsbKeyboardDevice
->ScrollOn
^= 1;
749 // Turn on the ScrollLock light on KB
751 SetKeyLED (UsbKeyboardDevice
);
756 // PrintScreen,Pause,Application,Power
757 // keys are not valid EFI key
784 // When encountered Del Key...
786 if (UsbKey
.KeyCode
== 0x4c || UsbKey
.KeyCode
== 0x63) {
787 if (UsbKeyboardDevice
->CtrlOn
&& UsbKeyboardDevice
->AltOn
) {
788 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
792 *KeyChar
= UsbKey
.KeyCode
;
796 return EFI_NOT_READY
;
803 Converts USB Keyboard code to EFI Scan Code.
805 UsbKeyboardDevice The USB_KB_DEV instance.
806 KeyChar Indicates the key code that will be interpreted.
807 Key A pointer to a buffer that is filled in with
808 the keystroke information for the key that
811 @retval EFI_NOT_READY Device is not ready
812 @retval EFI_SUCCESS Success
816 USBKeyCodeToEFIScanCode (
817 IN USB_KB_DEV
*UsbKeyboardDevice
,
819 OUT EFI_INPUT_KEY
*Key
824 if (!USBKBD_VALID_KEYCODE (KeyChar
)) {
825 return EFI_NOT_READY
;
829 // valid USB Key Code starts from 4
831 Index
= (UINT8
) (KeyChar
- 4);
833 if (Index
>= USB_KEYCODE_MAX_MAKE
) {
834 return EFI_NOT_READY
;
837 Key
->ScanCode
= KeyConvertionTable
[Index
][0];
839 if (UsbKeyboardDevice
->ShiftOn
) {
841 Key
->UnicodeChar
= KeyConvertionTable
[Index
][2];
845 Key
->UnicodeChar
= KeyConvertionTable
[Index
][1];
848 if (UsbKeyboardDevice
->CapsOn
) {
850 if (Key
->UnicodeChar
>= 'a' && Key
->UnicodeChar
<= 'z') {
852 Key
->UnicodeChar
= KeyConvertionTable
[Index
][2];
854 } else if (Key
->UnicodeChar
>= 'A' && Key
->UnicodeChar
<= 'Z') {
856 Key
->UnicodeChar
= KeyConvertionTable
[Index
][1];
861 if (KeyChar
>= 0x59 && KeyChar
<= 0x63) {
863 if (UsbKeyboardDevice
->NumLockOn
&& !UsbKeyboardDevice
->ShiftOn
) {
865 Key
->ScanCode
= SCAN_NULL
;
869 Key
->UnicodeChar
= 0x00;
873 if (Key
->UnicodeChar
== 0 && Key
->ScanCode
== SCAN_NULL
) {
874 return EFI_NOT_READY
;
884 Resets USB Keyboard Buffer.
886 @param KeyboardBuffer Points to the USB Keyboard Buffer.
888 @retval EFI_SUCCESS Success
893 IN OUT USB_KB_BUFFER
*KeyboardBuffer
896 ZeroMem (KeyboardBuffer
, sizeof (USB_KB_BUFFER
));
898 KeyboardBuffer
->bHead
= KeyboardBuffer
->bTail
;
905 Check whether USB Keyboard buffer is empty.
907 @param KeyboardBuffer USB Keyboard Buffer.
912 IsUSBKeyboardBufferEmpty (
913 IN USB_KB_BUFFER
*KeyboardBuffer
917 // meet FIFO empty condition
919 return (BOOLEAN
) (KeyboardBuffer
->bHead
== KeyboardBuffer
->bTail
);
925 Check whether USB Keyboard buffer is full.
927 @param KeyboardBuffer USB Keyboard Buffer.
932 IsUSBKeyboardBufferFull (
933 IN USB_KB_BUFFER
*KeyboardBuffer
936 return (BOOLEAN
)(((KeyboardBuffer
->bTail
+ 1) % (MAX_KEY_ALLOWED
+ 1)) ==
937 KeyboardBuffer
->bHead
);
943 Inserts a key code into keyboard buffer.
945 @param KeyboardBuffer Points to the USB Keyboard Buffer.
947 @param Down Special key
949 @retval EFI_SUCCESS Success
954 IN OUT USB_KB_BUFFER
*KeyboardBuffer
,
962 // if keyboard buffer is full, throw the
963 // first key out of the keyboard buffer.
965 if (IsUSBKeyboardBufferFull (KeyboardBuffer
)) {
966 RemoveKeyCode (KeyboardBuffer
, &UsbKey
);
969 KeyboardBuffer
->buffer
[KeyboardBuffer
->bTail
].KeyCode
= Key
;
970 KeyboardBuffer
->buffer
[KeyboardBuffer
->bTail
].Down
= Down
;
973 // adjust the tail pointer of the FIFO keyboard buffer.
975 KeyboardBuffer
->bTail
= (UINT8
) ((KeyboardBuffer
->bTail
+ 1) % (MAX_KEY_ALLOWED
+ 1));
982 Pops a key code off from keyboard buffer.
984 @param KeyboardBuffer Points to the USB Keyboard Buffer.
985 @param UsbKey Points to the buffer that contains a usb key code.
987 @retval EFI_SUCCESS Success
988 @retval EFI_DEVICE_ERROR Hardware Error
993 IN OUT USB_KB_BUFFER
*KeyboardBuffer
,
997 if (IsUSBKeyboardBufferEmpty (KeyboardBuffer
)) {
998 return EFI_DEVICE_ERROR
;
1001 UsbKey
->KeyCode
= KeyboardBuffer
->buffer
[KeyboardBuffer
->bHead
].KeyCode
;
1002 UsbKey
->Down
= KeyboardBuffer
->buffer
[KeyboardBuffer
->bHead
].Down
;
1005 // adjust the head pointer of the FIFO keyboard buffer.
1007 KeyboardBuffer
->bHead
= (UINT8
) ((KeyboardBuffer
->bHead
+ 1) % (MAX_KEY_ALLOWED
+ 1));
1014 Sets USB Keyboard LED state.
1016 @param UsbKeyboardDevice The USB_KB_DEV instance.
1018 @retval EFI_SUCCESS Success
1023 IN USB_KB_DEV
*UsbKeyboardDevice
1030 // Set each field in Led map.
1032 Led
.NumLock
= (UINT8
) UsbKeyboardDevice
->NumLockOn
;
1033 Led
.CapsLock
= (UINT8
) UsbKeyboardDevice
->CapsOn
;
1034 Led
.ScrollLock
= (UINT8
) UsbKeyboardDevice
->ScrollOn
;
1039 // call Set Report Request to lighten the LED.
1041 UsbSetReportRequest (
1042 UsbKeyboardDevice
->UsbIo
,
1043 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
1055 Timer handler for Repeat Key timer.
1057 @param Event The Repeat Key event.
1058 @param Context Points to the USB_KB_DEV instance.
1064 USBKeyboardRepeatHandler (
1069 USB_KB_DEV
*UsbKeyboardDevice
;
1071 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1074 // Do nothing when there is no repeat key.
1076 if (UsbKeyboardDevice
->RepeatKey
!= 0) {
1078 // Inserts one Repeat key into keyboard buffer,
1081 &(UsbKeyboardDevice
->KeyboardBuffer
),
1082 UsbKeyboardDevice
->RepeatKey
,
1087 // set repeate rate for repeat key generation.
1090 UsbKeyboardDevice
->RepeatTimer
,
1100 Timer handler for Delayed Recovery timer.
1102 @param Event The Delayed Recovery event.
1103 @param Context Points to the USB_KB_DEV instance.
1109 USBKeyboardRecoveryHandler (
1115 USB_KB_DEV
*UsbKeyboardDevice
;
1116 EFI_USB_IO_PROTOCOL
*UsbIo
;
1119 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1121 UsbIo
= UsbKeyboardDevice
->UsbIo
;
1123 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
1125 UsbIo
->UsbAsyncInterruptTransfer (
1127 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1129 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,