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
;
209 EFI_USB_IO_PROTOCOL
*UsbIo
;
211 UsbIo
= UsbKeyboardDevice
->UsbIo
;
213 KbdReportStatusCode (
214 UsbKeyboardDevice
->DevicePath
,
216 PcdGet32 (PcdStatusCodeValueKeyboardSelfTest
)
219 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
222 // default configurations
227 // Uses default configuration to configure the USB Keyboard device.
229 Status
= UsbSetConfiguration (
230 UsbKeyboardDevice
->UsbIo
,
231 (UINT16
) ConfigValue
,
234 if (EFI_ERROR (Status
)) {
236 // If configuration could not be set here, it means
237 // the keyboard interface has some errors and could
238 // not be initialized
240 KbdReportStatusCode (
241 UsbKeyboardDevice
->DevicePath
,
242 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
243 PcdGet32 (PcdStatusCodeValueKeyboardInterfaceError
)
246 return EFI_DEVICE_ERROR
;
249 UsbGetProtocolRequest (
250 UsbKeyboardDevice
->UsbIo
,
251 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
255 // Sets boot protocol for the USB Keyboard.
256 // This driver only supports boot protocol.
257 // !!BugBug: How about the device that does not support boot protocol?
259 if (Protocol
!= BOOT_PROTOCOL
) {
260 UsbSetProtocolRequest (
261 UsbKeyboardDevice
->UsbIo
,
262 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
267 // the duration is indefinite, so the endpoint will inhibit reporting forever,
268 // and only reporting when a change is detected in the report data.
272 // idle value for all report ID
276 // idle forever until there is a key pressed and released.
280 UsbKeyboardDevice
->UsbIo
,
281 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
286 UsbKeyboardDevice
->CtrlOn
= 0;
287 UsbKeyboardDevice
->AltOn
= 0;
288 UsbKeyboardDevice
->ShiftOn
= 0;
289 UsbKeyboardDevice
->NumLockOn
= 0;
290 UsbKeyboardDevice
->CapsOn
= 0;
291 UsbKeyboardDevice
->ScrollOn
= 0;
294 // Sync the initial state of lights
296 SetKeyLED (UsbKeyboardDevice
);
298 ZeroMem (UsbKeyboardDevice
->LastKeyCodeArray
, sizeof (UINT8
) * 8);
301 // Set a timer for repeat keys' generation.
303 if (UsbKeyboardDevice
->RepeatTimer
) {
304 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
305 UsbKeyboardDevice
->RepeatTimer
= 0;
308 Status
= gBS
->CreateEvent (
309 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
311 USBKeyboardRepeatHandler
,
313 &UsbKeyboardDevice
->RepeatTimer
316 if (UsbKeyboardDevice
->DelayedRecoveryEvent
) {
317 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
318 UsbKeyboardDevice
->DelayedRecoveryEvent
= 0;
321 Status
= gBS
->CreateEvent (
322 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
324 USBKeyboardRecoveryHandler
,
326 &UsbKeyboardDevice
->DelayedRecoveryEvent
334 Handler function for USB Keyboard's asynchronous interrupt transfer.
336 Data A pointer to a buffer that is filled with key data which is
337 retrieved via asynchronous interrupt transfer.
338 DataLength Indicates the size of the data buffer.
339 Context Pointing to USB_KB_DEV instance.
340 Result Indicates the result of the asynchronous interrupt transfer.
342 @retval EFI_SUCCESS Success
343 @retval EFI_DEVICE_ERROR Hardware Error
355 USB_KB_DEV
*UsbKeyboardDevice
;
356 EFI_USB_IO_PROTOCOL
*UsbIo
;
357 UINT8
*CurKeyCodeBuffer
;
358 UINT8
*OldKeyCodeBuffer
;
359 UINT8 CurModifierMap
;
360 UINT8 OldModifierMap
;
376 DataPtr
= (UINT8
*) Data
;
377 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
378 UsbIo
= UsbKeyboardDevice
->UsbIo
;
381 // Analyzes the Result and performs corresponding action.
383 if (Result
!= EFI_USB_NOERROR
) {
385 // Some errors happen during the process
387 KbdReportStatusCode (
388 UsbKeyboardDevice
->DevicePath
,
389 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
390 PcdGet32 (PcdStatusCodeValueKeyboardInputError
)
394 // stop the repeat key generation if any
396 UsbKeyboardDevice
->RepeatKey
= 0;
399 UsbKeyboardDevice
->RepeatTimer
,
404 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
405 UsbClearEndpointHalt (
407 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
413 // Delete & Submit this interrupt again
416 Status
= UsbIo
->UsbAsyncInterruptTransfer (
418 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
427 UsbKeyboardDevice
->DelayedRecoveryEvent
,
429 EFI_USB_INTERRUPT_DELAY
432 return EFI_DEVICE_ERROR
;
435 if (DataLength
== 0 || Data
== NULL
) {
439 CurKeyCodeBuffer
= (UINT8
*) Data
;
440 OldKeyCodeBuffer
= UsbKeyboardDevice
->LastKeyCodeArray
;
443 // checks for new key stroke.
444 // if no new key got, return immediately.
446 for (Index
= 0; Index
< 8; Index
++) {
447 if (OldKeyCodeBuffer
[Index
] != CurKeyCodeBuffer
[Index
]) {
457 // Parse the modifier key
459 CurModifierMap
= CurKeyCodeBuffer
[0];
460 OldModifierMap
= OldKeyCodeBuffer
[0];
463 // handle modifier key's pressing or releasing situation.
465 for (Index
= 0; Index
< 8; Index
++) {
467 if ((CurModifierMap
& KB_Mod
[Index
].Mask
) != (OldModifierMap
& KB_Mod
[Index
].Mask
)) {
469 // if current modifier key is up, then
470 // CurModifierMap & KB_Mod[Index].Mask = 0;
471 // otherwize it is a non-zero value.
472 // Inserts the pressed modifier key into key buffer.
474 Down
= (UINT8
) (CurModifierMap
& KB_Mod
[Index
].Mask
);
475 InsertKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), KB_Mod
[Index
].Key
, Down
);
480 // handle normal key's releasing situation
483 for (Index
= 2; Index
< 8; Index
++) {
485 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index
])) {
490 for (Index2
= 2; Index2
< 8; Index2
++) {
492 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index2
])) {
496 if (OldKeyCodeBuffer
[Index
] == CurKeyCodeBuffer
[Index2
]) {
504 &(UsbKeyboardDevice
->KeyboardBuffer
),
505 OldKeyCodeBuffer
[Index
],
509 // the original reapeat key is released.
511 if (OldKeyCodeBuffer
[Index
] == UsbKeyboardDevice
->RepeatKey
) {
512 UsbKeyboardDevice
->RepeatKey
= 0;
518 // original repeat key is released, cancel the repeat timer
520 if (UsbKeyboardDevice
->RepeatKey
== 0) {
522 UsbKeyboardDevice
->RepeatTimer
,
529 // handle normal key's pressing situation
532 for (Index
= 2; Index
< 8; Index
++) {
534 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index
])) {
539 for (Index2
= 2; Index2
< 8; Index2
++) {
541 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index2
])) {
545 if (CurKeyCodeBuffer
[Index
] == OldKeyCodeBuffer
[Index2
]) {
552 InsertKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), CurKeyCodeBuffer
[Index
], 1);
554 // NumLock pressed or CapsLock pressed
556 if (CurKeyCodeBuffer
[Index
] == 0x53 || CurKeyCodeBuffer
[Index
] == 0x39) {
557 UsbKeyboardDevice
->RepeatKey
= 0;
559 NewRepeatKey
= CurKeyCodeBuffer
[Index
];
561 // do not repeat the original repeated key
563 UsbKeyboardDevice
->RepeatKey
= 0;
569 // Update LastKeycodeArray[] buffer in the
570 // Usb Keyboard Device data structure.
572 for (Index
= 0; Index
< 8; Index
++) {
573 UsbKeyboardDevice
->LastKeyCodeArray
[Index
] = CurKeyCodeBuffer
[Index
];
577 // pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence
578 // and judge whether it will invoke reset event.
580 SavedTail
= UsbKeyboardDevice
->KeyboardBuffer
.bTail
;
581 Index
= UsbKeyboardDevice
->KeyboardBuffer
.bHead
;
582 while (Index
!= SavedTail
) {
583 RemoveKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), &UsbKey
);
585 switch (UsbKey
.KeyCode
) {
590 UsbKeyboardDevice
->CtrlOn
= 1;
592 UsbKeyboardDevice
->CtrlOn
= 0;
599 UsbKeyboardDevice
->AltOn
= 1;
601 UsbKeyboardDevice
->AltOn
= 0;
611 if (UsbKeyboardDevice
->CtrlOn
&& UsbKeyboardDevice
->AltOn
) {
612 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
622 // insert the key back to the buffer.
623 // so the key sequence will not be destroyed.
626 &(UsbKeyboardDevice
->KeyboardBuffer
),
630 Index
= UsbKeyboardDevice
->KeyboardBuffer
.bHead
;
634 // If have new key pressed, update the RepeatKey value, and set the
635 // timer to repeate delay timer
637 if (NewRepeatKey
!= 0) {
639 // sets trigger time to "Repeat Delay Time",
640 // to trigger the repeat timer when the key is hold long
644 UsbKeyboardDevice
->RepeatTimer
,
648 UsbKeyboardDevice
->RepeatKey
= NewRepeatKey
;
656 Retrieves a key character after parsing the raw data in keyboard buffer.
658 UsbKeyboardDevice The USB_KB_DEV instance.
659 KeyChar Points to the Key character after key parsing.
661 @retval EFI_SUCCESS Success
662 @retval EFI_NOT_READY Device is not ready
667 IN OUT USB_KB_DEV
*UsbKeyboardDevice
,
675 while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice
->KeyboardBuffer
)) {
677 // pops one raw data off.
679 RemoveKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), &UsbKey
);
682 switch (UsbKey
.KeyCode
) {
686 UsbKeyboardDevice
->CtrlOn
= 0;
691 UsbKeyboardDevice
->ShiftOn
= 0;
696 UsbKeyboardDevice
->AltOn
= 0;
707 // Analyzes key pressing situation
709 switch (UsbKey
.KeyCode
) {
713 UsbKeyboardDevice
->CtrlOn
= 1;
719 UsbKeyboardDevice
->ShiftOn
= 1;
725 UsbKeyboardDevice
->AltOn
= 1;
735 UsbKeyboardDevice
->NumLockOn
^= 1;
737 // Turn on the NumLock light on KB
739 SetKeyLED (UsbKeyboardDevice
);
744 UsbKeyboardDevice
->CapsOn
^= 1;
746 // Turn on the CapsLock light on KB
748 SetKeyLED (UsbKeyboardDevice
);
753 UsbKeyboardDevice
->ScrollOn
^= 1;
755 // Turn on the ScrollLock light on KB
757 SetKeyLED (UsbKeyboardDevice
);
762 // PrintScreen,Pause,Application,Power
763 // keys are not valid EFI key
790 // When encountered Del Key...
792 if (UsbKey
.KeyCode
== 0x4c || UsbKey
.KeyCode
== 0x63) {
793 if (UsbKeyboardDevice
->CtrlOn
&& UsbKeyboardDevice
->AltOn
) {
794 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
798 *KeyChar
= UsbKey
.KeyCode
;
802 return EFI_NOT_READY
;
809 Converts USB Keyboard code to EFI Scan Code.
811 UsbKeyboardDevice The USB_KB_DEV instance.
812 KeyChar Indicates the key code that will be interpreted.
813 Key A pointer to a buffer that is filled in with
814 the keystroke information for the key that
817 @retval EFI_NOT_READY Device is not ready
818 @retval EFI_SUCCESS Success
822 USBKeyCodeToEFIScanCode (
823 IN USB_KB_DEV
*UsbKeyboardDevice
,
825 OUT EFI_INPUT_KEY
*Key
830 if (!USBKBD_VALID_KEYCODE (KeyChar
)) {
831 return EFI_NOT_READY
;
835 // valid USB Key Code starts from 4
837 Index
= (UINT8
) (KeyChar
- 4);
839 if (Index
>= USB_KEYCODE_MAX_MAKE
) {
840 return EFI_NOT_READY
;
843 Key
->ScanCode
= KeyConvertionTable
[Index
][0];
845 if (UsbKeyboardDevice
->ShiftOn
) {
847 Key
->UnicodeChar
= KeyConvertionTable
[Index
][2];
851 Key
->UnicodeChar
= KeyConvertionTable
[Index
][1];
854 if (UsbKeyboardDevice
->CapsOn
) {
856 if (Key
->UnicodeChar
>= 'a' && Key
->UnicodeChar
<= 'z') {
858 Key
->UnicodeChar
= KeyConvertionTable
[Index
][2];
860 } else if (Key
->UnicodeChar
>= 'A' && Key
->UnicodeChar
<= 'Z') {
862 Key
->UnicodeChar
= KeyConvertionTable
[Index
][1];
867 if (KeyChar
>= 0x59 && KeyChar
<= 0x63) {
869 if (UsbKeyboardDevice
->NumLockOn
&& !UsbKeyboardDevice
->ShiftOn
) {
871 Key
->ScanCode
= SCAN_NULL
;
875 Key
->UnicodeChar
= 0x00;
879 if (Key
->UnicodeChar
== 0 && Key
->ScanCode
== SCAN_NULL
) {
880 return EFI_NOT_READY
;
890 Resets USB Keyboard Buffer.
892 @param KeyboardBuffer Points to the USB Keyboard Buffer.
894 @retval EFI_SUCCESS Success
899 IN OUT USB_KB_BUFFER
*KeyboardBuffer
902 ZeroMem (KeyboardBuffer
, sizeof (USB_KB_BUFFER
));
904 KeyboardBuffer
->bHead
= KeyboardBuffer
->bTail
;
911 Check whether USB Keyboard buffer is empty.
913 @param KeyboardBuffer USB Keyboard Buffer.
918 IsUSBKeyboardBufferEmpty (
919 IN USB_KB_BUFFER
*KeyboardBuffer
923 // meet FIFO empty condition
925 return (BOOLEAN
) (KeyboardBuffer
->bHead
== KeyboardBuffer
->bTail
);
931 Check whether USB Keyboard buffer is full.
933 @param KeyboardBuffer USB Keyboard Buffer.
938 IsUSBKeyboardBufferFull (
939 IN USB_KB_BUFFER
*KeyboardBuffer
942 return (BOOLEAN
)(((KeyboardBuffer
->bTail
+ 1) % (MAX_KEY_ALLOWED
+ 1)) ==
943 KeyboardBuffer
->bHead
);
949 Inserts a key code into keyboard buffer.
951 @param KeyboardBuffer Points to the USB Keyboard Buffer.
953 @param Down Special key
955 @retval EFI_SUCCESS Success
960 IN OUT USB_KB_BUFFER
*KeyboardBuffer
,
968 // if keyboard buffer is full, throw the
969 // first key out of the keyboard buffer.
971 if (IsUSBKeyboardBufferFull (KeyboardBuffer
)) {
972 RemoveKeyCode (KeyboardBuffer
, &UsbKey
);
975 KeyboardBuffer
->buffer
[KeyboardBuffer
->bTail
].KeyCode
= Key
;
976 KeyboardBuffer
->buffer
[KeyboardBuffer
->bTail
].Down
= Down
;
979 // adjust the tail pointer of the FIFO keyboard buffer.
981 KeyboardBuffer
->bTail
= (UINT8
) ((KeyboardBuffer
->bTail
+ 1) % (MAX_KEY_ALLOWED
+ 1));
988 Pops a key code off from keyboard buffer.
990 @param KeyboardBuffer Points to the USB Keyboard Buffer.
991 @param UsbKey Points to the buffer that contains a usb key code.
993 @retval EFI_SUCCESS Success
994 @retval EFI_DEVICE_ERROR Hardware Error
999 IN OUT USB_KB_BUFFER
*KeyboardBuffer
,
1003 if (IsUSBKeyboardBufferEmpty (KeyboardBuffer
)) {
1004 return EFI_DEVICE_ERROR
;
1007 UsbKey
->KeyCode
= KeyboardBuffer
->buffer
[KeyboardBuffer
->bHead
].KeyCode
;
1008 UsbKey
->Down
= KeyboardBuffer
->buffer
[KeyboardBuffer
->bHead
].Down
;
1011 // adjust the head pointer of the FIFO keyboard buffer.
1013 KeyboardBuffer
->bHead
= (UINT8
) ((KeyboardBuffer
->bHead
+ 1) % (MAX_KEY_ALLOWED
+ 1));
1020 Sets USB Keyboard LED state.
1022 @param UsbKeyboardDevice The USB_KB_DEV instance.
1024 @retval EFI_SUCCESS Success
1029 IN USB_KB_DEV
*UsbKeyboardDevice
1036 // Set each field in Led map.
1038 Led
.NumLock
= (UINT8
) UsbKeyboardDevice
->NumLockOn
;
1039 Led
.CapsLock
= (UINT8
) UsbKeyboardDevice
->CapsOn
;
1040 Led
.ScrollLock
= (UINT8
) UsbKeyboardDevice
->ScrollOn
;
1045 // call Set Report Request to lighten the LED.
1047 UsbSetReportRequest (
1048 UsbKeyboardDevice
->UsbIo
,
1049 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
1061 Timer handler for Repeat Key timer.
1063 @param Event The Repeat Key event.
1064 @param Context Points to the USB_KB_DEV instance.
1070 USBKeyboardRepeatHandler (
1075 USB_KB_DEV
*UsbKeyboardDevice
;
1077 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1080 // Do nothing when there is no repeat key.
1082 if (UsbKeyboardDevice
->RepeatKey
!= 0) {
1084 // Inserts one Repeat key into keyboard buffer,
1087 &(UsbKeyboardDevice
->KeyboardBuffer
),
1088 UsbKeyboardDevice
->RepeatKey
,
1093 // set repeate rate for repeat key generation.
1096 UsbKeyboardDevice
->RepeatTimer
,
1106 Timer handler for Delayed Recovery timer.
1108 @param Event The Delayed Recovery event.
1109 @param Context Points to the USB_KB_DEV instance.
1115 USBKeyboardRecoveryHandler (
1121 USB_KB_DEV
*UsbKeyboardDevice
;
1122 EFI_USB_IO_PROTOCOL
*UsbIo
;
1125 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1127 UsbIo
= UsbKeyboardDevice
->UsbIo
;
1129 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
1131 UsbIo
->UsbAsyncInterruptTransfer (
1133 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1135 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,