3 Copyright (c) 2006, 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
27 // USB Key Code to Efi key mapping table
28 // Format:<efi scan code>, <unicode without shift>, <unicode with shift>
31 UINT8 KeyConvertionTable
[USB_KEYCODE_MAX_MAKE
][3] = {
32 { SCAN_NULL
, 'a', 'A' }, // 0x04
33 { SCAN_NULL
, 'b', 'B' }, // 0x05
34 { SCAN_NULL
, 'c', 'C' }, // 0x06
35 { SCAN_NULL
, 'd', 'D' }, // 0x07
36 { SCAN_NULL
, 'e', 'E' }, // 0x08
37 { SCAN_NULL
, 'f', 'F' }, // 0x09
38 { SCAN_NULL
, 'g', 'G' }, // 0x0A
39 { SCAN_NULL
, 'h', 'H' }, // 0x0B
40 { SCAN_NULL
, 'i', 'I' }, // 0x0C
41 { SCAN_NULL
, 'j', 'J' }, // 0x0D
42 { SCAN_NULL
, 'k', 'K' }, // 0x0E
43 { SCAN_NULL
, 'l', 'L' }, // 0x0F
44 { SCAN_NULL
, 'm', 'M' }, // 0x10
45 { SCAN_NULL
, 'n', 'N' }, // 0x11
46 { SCAN_NULL
, 'o', 'O' }, // 0x12
47 { SCAN_NULL
, 'p', 'P' }, // 0x13
48 { SCAN_NULL
, 'q', 'Q' }, // 0x14
49 { SCAN_NULL
, 'r', 'R' }, // 0x15
50 { SCAN_NULL
, 's', 'S' }, // 0x16
51 { SCAN_NULL
, 't', 'T' }, // 0x17
52 { SCAN_NULL
, 'u', 'U' }, // 0x18
53 { SCAN_NULL
, 'v', 'V' }, // 0x19
54 { SCAN_NULL
, 'w', 'W' }, // 0x1A
55 { SCAN_NULL
, 'x', 'X' }, // 0x1B
56 { SCAN_NULL
, 'y', 'Y' }, // 0x1C
57 { SCAN_NULL
, 'z', 'Z' }, // 0x1D
58 { SCAN_NULL
, '1', '!' }, // 0x1E
59 { SCAN_NULL
, '2', '@' }, // 0x1F
60 { SCAN_NULL
, '3', '#' }, // 0x20
61 { SCAN_NULL
, '4', '$' }, // 0x21
62 { SCAN_NULL
, '5', '%' }, // 0x22
63 { SCAN_NULL
, '6', '^' }, // 0x23
64 { SCAN_NULL
, '7', '&' }, // 0x24
65 { SCAN_NULL
, '8', '*' }, // 0x25
66 { SCAN_NULL
, '9', '(' }, // 0x26
67 { SCAN_NULL
, '0', ')' }, // 0x27
68 { SCAN_NULL
, 0x0d, 0x0d }, // 0x28 Enter
69 { SCAN_ESC
, 0x00, 0x00 }, // 0x29 Esc
70 { SCAN_NULL
, 0x08, 0x08 }, // 0x2A Backspace
71 { SCAN_NULL
, 0x09, 0x09 }, // 0x2B Tab
72 { SCAN_NULL
, ' ', ' ' }, // 0x2C Spacebar
73 { SCAN_NULL
, '-', '_' }, // 0x2D
74 { SCAN_NULL
, '=', '+' }, // 0x2E
75 { SCAN_NULL
, '[', '{' }, // 0x2F
76 { SCAN_NULL
, ']', '}' }, // 0x30
77 { SCAN_NULL
, '\\', '|' }, // 0x31
78 { SCAN_NULL
, '\\', '|' }, // 0x32 Keyboard US \ and |
79 { SCAN_NULL
, ';', ':' }, // 0x33
80 { SCAN_NULL
, '\'', '"' }, // 0x34
81 { SCAN_NULL
, '`', '~' }, // 0x35 Keyboard Grave Accent and Tlide
82 { SCAN_NULL
, ',', '<' }, // 0x36
83 { SCAN_NULL
, '.', '>' }, // 0x37
84 { SCAN_NULL
, '/', '?' }, // 0x38
85 { SCAN_NULL
, 0x00, 0x00 }, // 0x39 CapsLock
86 { SCAN_F1
, 0x00, 0x00 }, // 0x3A
87 { SCAN_F2
, 0x00, 0x00 }, // 0x3B
88 { SCAN_F3
, 0x00, 0x00 }, // 0x3C
89 { SCAN_F4
, 0x00, 0x00 }, // 0x3D
90 { SCAN_F5
, 0x00, 0x00 }, // 0x3E
91 { SCAN_F6
, 0x00, 0x00 }, // 0x3F
92 { SCAN_F7
, 0x00, 0x00 }, // 0x40
93 { SCAN_F8
, 0x00, 0x00 }, // 0x41
94 { SCAN_F9
, 0x00, 0x00 }, // 0x42
95 { SCAN_F10
, 0x00, 0x00 }, // 0x43
96 { SCAN_NULL
, 0x00, 0x00 }, // 0x44 F11
97 { SCAN_NULL
, 0x00, 0x00 }, // 0x45 F12
98 { SCAN_NULL
, 0x00, 0x00 }, // 0x46 PrintScreen
99 { SCAN_NULL
, 0x00, 0x00 }, // 0x47 Scroll Lock
100 { SCAN_NULL
, 0x00, 0x00 }, // 0x48 Pause
101 { SCAN_INSERT
, 0x00, 0x00 }, // 0x49
102 { SCAN_HOME
, 0x00, 0x00 }, // 0x4A
103 { SCAN_PAGE_UP
, 0x00, 0x00 }, // 0x4B
104 { SCAN_DELETE
, 0x00, 0x00 }, // 0x4C
105 { SCAN_END
, 0x00, 0x00 }, // 0x4D
106 { SCAN_PAGE_DOWN
, 0x00, 0x00 }, // 0x4E
107 { SCAN_RIGHT
, 0x00, 0x00 }, // 0x4F
108 { SCAN_LEFT
, 0x00, 0x00 }, // 0x50
109 { SCAN_DOWN
, 0x00, 0x00 }, // 0x51
110 { SCAN_UP
, 0x00, 0x00 }, // 0x52
111 { SCAN_NULL
, 0x00, 0x00 }, // 0x53 NumLock
112 { SCAN_NULL
, '/', '/' }, // 0x54
113 { SCAN_NULL
, '*', '*' }, // 0x55
114 { SCAN_NULL
, '-', '-' }, // 0x56
115 { SCAN_NULL
, '+', '+' }, // 0x57
116 { SCAN_NULL
, 0x0d, 0x0d }, // 0x58
117 { SCAN_END
, '1', '1' }, // 0x59
118 { SCAN_DOWN
, '2', '2' }, // 0x5A
119 { SCAN_PAGE_DOWN
, '3', '3' }, // 0x5B
120 { SCAN_LEFT
, '4', '4' }, // 0x5C
121 { SCAN_NULL
, '5', '5' }, // 0x5D
122 { SCAN_RIGHT
, '6', '6' }, // 0x5E
123 { SCAN_HOME
, '7', '7' }, // 0x5F
124 { SCAN_UP
, '8', '8' }, // 0x60
125 { SCAN_PAGE_UP
, '9', '9' }, // 0x61
126 { SCAN_INSERT
, '0', '0' }, // 0x62
127 { SCAN_DELETE
, '.', '.' }, // 0x63
128 { SCAN_NULL
, '\\', '|' }, // 0x64 Keyboard Non-US \ and |
129 { SCAN_NULL
, 0x00, 0x00 }, // 0x65 Keyboard Application
130 { SCAN_NULL
, 0x00, 0x00 }, // 0x66 Keyboard Power
131 { SCAN_NULL
, '=' , '=' } // 0x67 Keypad =
134 STATIC KB_MODIFIER KB_Mod
[8] = {
135 { MOD_CONTROL_L
, 0xe0 }, // 11100000
136 { MOD_CONTROL_R
, 0xe4 }, // 11100100
137 { MOD_SHIFT_L
, 0xe1 }, // 11100001
138 { MOD_SHIFT_R
, 0xe5 }, // 11100101
139 { MOD_ALT_L
, 0xe2 }, // 11100010
140 { MOD_ALT_R
, 0xe6 }, // 11100110
141 { MOD_WIN_L
, 0xe3 }, // 11100011
142 { MOD_WIN_R
, 0xe7 } // 11100111
148 IN EFI_USB_IO_PROTOCOL
*UsbIo
153 Uses USB I/O to check whether the device is a USB Keyboard device.
156 UsbIo: Points to a USB I/O protocol instance.
163 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
166 // Get the Default interface descriptor, currently we
167 // assume it is interface 1
169 Status
= UsbIo
->UsbGetInterfaceDescriptor (
174 if (EFI_ERROR (Status
)) {
178 if (InterfaceDescriptor
.InterfaceClass
== CLASS_HID
&&
179 InterfaceDescriptor
.InterfaceSubClass
== SUBCLASS_BOOT
&&
180 InterfaceDescriptor
.InterfaceProtocol
== PROTOCOL_KEYBOARD
192 IN USB_KB_DEV
*UsbKeyboardDevice
197 Initialize USB Keyboard device and all private data structures.
200 UsbKeyboardDevice The USB_KB_DEV instance.
203 EFI_SUCCESS - Success
204 EFI_DEVICE_ERROR - Hardware Error
212 UINT32 TransferResult
;
213 EFI_USB_IO_PROTOCOL
*UsbIo
;
215 UsbIo
= UsbKeyboardDevice
->UsbIo
;
217 KbdReportStatusCode (
218 UsbKeyboardDevice
->DevicePath
,
220 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_KEYBOARD_PC_SELF_TEST
)
223 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
226 // default configurations
231 // Uses default configuration to configure the USB Keyboard device.
233 Status
= UsbSetDeviceConfiguration (
234 UsbKeyboardDevice
->UsbIo
,
235 (UINT16
) ConfigValue
,
238 if (EFI_ERROR (Status
)) {
240 // If configuration could not be set here, it means
241 // the keyboard interface has some errors and could
242 // not be initialized
244 KbdReportStatusCode (
245 UsbKeyboardDevice
->DevicePath
,
246 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
247 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_INTERFACE_ERROR
)
250 return EFI_DEVICE_ERROR
;
253 UsbGetProtocolRequest (
254 UsbKeyboardDevice
->UsbIo
,
255 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
259 // Sets boot protocol for the USB Keyboard.
260 // This driver only supports boot protocol.
261 // !!BugBug: How about the device that does not support boot protocol?
263 if (Protocol
!= BOOT_PROTOCOL
) {
264 UsbSetProtocolRequest (
265 UsbKeyboardDevice
->UsbIo
,
266 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
271 // the duration is indefinite, so the endpoint will inhibit reporting forever,
272 // and only reporting when a change is detected in the report data.
276 // idle value for all report ID
280 // idle forever until there is a key pressed and released.
284 UsbKeyboardDevice
->UsbIo
,
285 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
290 UsbKeyboardDevice
->CtrlOn
= 0;
291 UsbKeyboardDevice
->AltOn
= 0;
292 UsbKeyboardDevice
->ShiftOn
= 0;
293 UsbKeyboardDevice
->NumLockOn
= 0;
294 UsbKeyboardDevice
->CapsOn
= 0;
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 EFI_EVENT_TIMER
| EFI_EVENT_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 EFI_EVENT_TIMER
| EFI_EVENT_NOTIFY_SIGNAL
,
321 USBKeyboardRecoveryHandler
,
323 &UsbKeyboardDevice
->DelayedRecoveryEvent
340 Handler function for USB Keyboard's asynchronous interrupt transfer.
343 Data A pointer to a buffer that is filled with key data which is
344 retrieved via asynchronous interrupt transfer.
345 DataLength Indicates the size of the data buffer.
346 Context Pointing to USB_KB_DEV instance.
347 Result Indicates the result of the asynchronous interrupt transfer.
350 EFI_SUCCESS - Success
351 EFI_DEVICE_ERROR - Hardware Error
354 USB_KB_DEV
*UsbKeyboardDevice
;
355 EFI_USB_IO_PROTOCOL
*UsbIo
;
356 UINT8
*CurKeyCodeBuffer
;
357 UINT8
*OldKeyCodeBuffer
;
358 UINT8 CurModifierMap
;
359 UINT8 OldModifierMap
;
375 DataPtr
= (UINT8
*) Data
;
376 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
377 UsbIo
= UsbKeyboardDevice
->UsbIo
;
380 // Analyzes the Result and performs corresponding action.
382 if (Result
!= EFI_USB_NOERROR
) {
384 // Some errors happen during the process
386 KbdReportStatusCode (
387 UsbKeyboardDevice
->DevicePath
,
388 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
389 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_INPUT_ERROR
)
393 // stop the repeat key generation if any
395 UsbKeyboardDevice
->RepeatKey
= 0;
398 UsbKeyboardDevice
->RepeatTimer
,
403 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
404 UsbClearEndpointHalt (
406 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
412 // Delete & Submit this interrupt again
415 Status
= UsbIo
->UsbAsyncInterruptTransfer (
417 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
426 UsbKeyboardDevice
->DelayedRecoveryEvent
,
428 EFI_USB_INTERRUPT_DELAY
431 return EFI_DEVICE_ERROR
;
434 if (DataLength
== 0 || Data
== NULL
) {
438 CurKeyCodeBuffer
= (UINT8
*) Data
;
439 OldKeyCodeBuffer
= UsbKeyboardDevice
->LastKeyCodeArray
;
442 // checks for new key stroke.
443 // if no new key got, return immediately.
445 for (Index
= 0; Index
< 8; Index
++) {
446 if (OldKeyCodeBuffer
[Index
] != CurKeyCodeBuffer
[Index
]) {
456 // Parse the modifier key
458 CurModifierMap
= CurKeyCodeBuffer
[0];
459 OldModifierMap
= OldKeyCodeBuffer
[0];
462 // handle modifier key's pressing or releasing situation.
464 for (Index
= 0; Index
< 8; Index
++) {
466 if ((CurModifierMap
& KB_Mod
[Index
].Mask
) != (OldModifierMap
& KB_Mod
[Index
].Mask
)) {
468 // if current modifier key is up, then
469 // CurModifierMap & KB_Mod[Index].Mask = 0;
470 // otherwize it is a non-zero value.
471 // Inserts the pressed modifier key into key buffer.
473 Down
= (UINT8
) (CurModifierMap
& KB_Mod
[Index
].Mask
);
474 InsertKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), KB_Mod
[Index
].Key
, Down
);
479 // handle normal key's releasing situation
482 for (Index
= 2; Index
< 8; Index
++) {
484 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index
])) {
489 for (Index2
= 2; Index2
< 8; Index2
++) {
491 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index2
])) {
495 if (OldKeyCodeBuffer
[Index
] == CurKeyCodeBuffer
[Index2
]) {
503 &(UsbKeyboardDevice
->KeyboardBuffer
),
504 OldKeyCodeBuffer
[Index
],
508 // the original reapeat key is released.
510 if (OldKeyCodeBuffer
[Index
] == UsbKeyboardDevice
->RepeatKey
) {
511 UsbKeyboardDevice
->RepeatKey
= 0;
517 // original repeat key is released, cancel the repeat timer
519 if (UsbKeyboardDevice
->RepeatKey
== 0) {
521 UsbKeyboardDevice
->RepeatTimer
,
528 // handle normal key's pressing situation
531 for (Index
= 2; Index
< 8; Index
++) {
533 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index
])) {
538 for (Index2
= 2; Index2
< 8; Index2
++) {
540 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index2
])) {
544 if (CurKeyCodeBuffer
[Index
] == OldKeyCodeBuffer
[Index2
]) {
551 InsertKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), CurKeyCodeBuffer
[Index
], 1);
553 // NumLock pressed or CapsLock pressed
555 if (CurKeyCodeBuffer
[Index
] == 0x53 || CurKeyCodeBuffer
[Index
] == 0x39) {
556 UsbKeyboardDevice
->RepeatKey
= 0;
558 NewRepeatKey
= CurKeyCodeBuffer
[Index
];
560 // do not repeat the original repeated key
562 UsbKeyboardDevice
->RepeatKey
= 0;
568 // Update LastKeycodeArray[] buffer in the
569 // Usb Keyboard Device data structure.
571 for (Index
= 0; Index
< 8; Index
++) {
572 UsbKeyboardDevice
->LastKeyCodeArray
[Index
] = CurKeyCodeBuffer
[Index
];
576 // pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence
577 // and judge whether it will invoke reset event.
579 SavedTail
= UsbKeyboardDevice
->KeyboardBuffer
.bTail
;
580 Index
= UsbKeyboardDevice
->KeyboardBuffer
.bHead
;
581 while (Index
!= SavedTail
) {
582 RemoveKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), &UsbKey
);
584 switch (UsbKey
.KeyCode
) {
589 UsbKeyboardDevice
->CtrlOn
= 1;
591 UsbKeyboardDevice
->CtrlOn
= 0;
598 UsbKeyboardDevice
->AltOn
= 1;
600 UsbKeyboardDevice
->AltOn
= 0;
610 if (UsbKeyboardDevice
->CtrlOn
&& UsbKeyboardDevice
->AltOn
) {
611 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
621 // insert the key back to the buffer.
622 // so the key sequence will not be destroyed.
625 &(UsbKeyboardDevice
->KeyboardBuffer
),
629 Index
= UsbKeyboardDevice
->KeyboardBuffer
.bHead
;
633 // If have new key pressed, update the RepeatKey value, and set the
634 // timer to repeate delay timer
636 if (NewRepeatKey
!= 0) {
638 // sets trigger time to "Repeat Delay Time",
639 // to trigger the repeat timer when the key is hold long
643 UsbKeyboardDevice
->RepeatTimer
,
647 UsbKeyboardDevice
->RepeatKey
= NewRepeatKey
;
655 IN OUT USB_KB_DEV
*UsbKeyboardDevice
,
661 Retrieves a key character after parsing the raw data in keyboard buffer.
664 UsbKeyboardDevice The USB_KB_DEV instance.
665 KeyChar Points to the Key character after key parsing.
668 EFI_SUCCESS - Success
669 EFI_NOT_READY - Device is not ready
676 while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice
->KeyboardBuffer
)) {
678 // pops one raw data off.
680 RemoveKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), &UsbKey
);
683 switch (UsbKey
.KeyCode
) {
687 UsbKeyboardDevice
->CtrlOn
= 0;
692 UsbKeyboardDevice
->ShiftOn
= 0;
697 UsbKeyboardDevice
->AltOn
= 0;
708 // Analyzes key pressing situation
710 switch (UsbKey
.KeyCode
) {
714 UsbKeyboardDevice
->CtrlOn
= 1;
720 UsbKeyboardDevice
->ShiftOn
= 1;
726 UsbKeyboardDevice
->AltOn
= 1;
736 UsbKeyboardDevice
->NumLockOn
^= 1;
737 SetKeyLED (UsbKeyboardDevice
);
742 UsbKeyboardDevice
->CapsOn
^= 1;
743 SetKeyLED (UsbKeyboardDevice
);
748 // F11,F12,PrintScreen,ScrollLock,Pause,Application,Power
749 // keys are not valid EFI key
765 // Turn on the ScrollLock light on KB
767 UsbKeyboardDevice
->ScrollOn
^= 1;
768 SetKeyLED (UsbKeyboardDevice
);
785 // When encountered Del Key...
787 if (UsbKey
.KeyCode
== 0x4c || UsbKey
.KeyCode
== 0x63) {
788 if (UsbKeyboardDevice
->CtrlOn
&& UsbKeyboardDevice
->AltOn
) {
789 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
793 *KeyChar
= UsbKey
.KeyCode
;
797 return EFI_NOT_READY
;
803 USBKeyCodeToEFIScanCode (
804 IN USB_KB_DEV
*UsbKeyboardDevice
,
806 OUT EFI_INPUT_KEY
*Key
811 Converts USB Keyboard code to EFI Scan Code.
814 UsbKeyboardDevice The USB_KB_DEV instance.
815 KeyChar Indicates the key code that will be interpreted.
816 Key A pointer to a buffer that is filled in with
817 the keystroke information for the key that
820 EFI_NOT_READY - Device is not ready
821 EFI_SUCCESS - Success
826 if (!USBKBD_VALID_KEYCODE (KeyChar
)) {
827 return EFI_NOT_READY
;
831 // valid USB Key Code starts from 4
833 Index
= (UINT8
) (KeyChar
- 4);
835 if (Index
>= USB_KEYCODE_MAX_MAKE
) {
836 return EFI_NOT_READY
;
839 Key
->ScanCode
= KeyConvertionTable
[Index
][0];
841 if (UsbKeyboardDevice
->ShiftOn
) {
843 Key
->UnicodeChar
= KeyConvertionTable
[Index
][2];
847 Key
->UnicodeChar
= KeyConvertionTable
[Index
][1];
850 if (UsbKeyboardDevice
->CapsOn
) {
852 if (Key
->UnicodeChar
>= 'a' && Key
->UnicodeChar
<= 'z') {
854 Key
->UnicodeChar
= KeyConvertionTable
[Index
][2];
856 } else if (Key
->UnicodeChar
>= 'A' && Key
->UnicodeChar
<= 'Z') {
858 Key
->UnicodeChar
= KeyConvertionTable
[Index
][1];
863 if (KeyChar
>= 0x59 && KeyChar
<= 0x63) {
865 if (UsbKeyboardDevice
->NumLockOn
&& !UsbKeyboardDevice
->ShiftOn
) {
867 Key
->ScanCode
= SCAN_NULL
;
871 Key
->UnicodeChar
= 0x00;
875 if (Key
->UnicodeChar
== 0 && Key
->ScanCode
== SCAN_NULL
) {
876 return EFI_NOT_READY
;
886 IN OUT USB_KB_BUFFER
*KeyboardBuffer
891 Resets USB Keyboard Buffer.
894 KeyboardBuffer - Points to the USB Keyboard Buffer.
897 EFI_SUCCESS - Success
900 ZeroMem (KeyboardBuffer
, sizeof (USB_KB_BUFFER
));
902 KeyboardBuffer
->bHead
= KeyboardBuffer
->bTail
;
908 IsUSBKeyboardBufferEmpty (
909 IN USB_KB_BUFFER
*KeyboardBuffer
914 Check whether USB Keyboard buffer is empty.
917 KeyboardBuffer - USB Keyboard Buffer.
924 // meet FIFO empty condition
926 return (BOOLEAN
) (KeyboardBuffer
->bHead
== KeyboardBuffer
->bTail
);
931 IsUSBKeyboardBufferFull (
932 IN USB_KB_BUFFER
*KeyboardBuffer
937 Check whether USB Keyboard buffer is full.
940 KeyboardBuffer - USB Keyboard Buffer.
946 return (BOOLEAN
)(((KeyboardBuffer
->bTail
+ 1) % (MAX_KEY_ALLOWED
+ 1)) ==
947 KeyboardBuffer
->bHead
);
953 IN OUT USB_KB_BUFFER
*KeyboardBuffer
,
960 Inserts a key code into keyboard buffer.
963 KeyboardBuffer - Points to the USB Keyboard Buffer.
967 EFI_SUCCESS - Success
973 // if keyboard buffer is full, throw the
974 // first key out of the keyboard buffer.
976 if (IsUSBKeyboardBufferFull (KeyboardBuffer
)) {
977 RemoveKeyCode (KeyboardBuffer
, &UsbKey
);
980 KeyboardBuffer
->buffer
[KeyboardBuffer
->bTail
].KeyCode
= Key
;
981 KeyboardBuffer
->buffer
[KeyboardBuffer
->bTail
].Down
= Down
;
984 // adjust the tail pointer of the FIFO keyboard buffer.
986 KeyboardBuffer
->bTail
= (UINT8
) ((KeyboardBuffer
->bTail
+ 1) % (MAX_KEY_ALLOWED
+ 1));
993 IN OUT USB_KB_BUFFER
*KeyboardBuffer
,
999 Pops a key code off from keyboard buffer.
1002 KeyboardBuffer - Points to the USB Keyboard Buffer.
1003 UsbKey - Points to the buffer that contains a usb key code.
1006 EFI_SUCCESS - Success
1007 EFI_DEVICE_ERROR - Hardware Error
1010 if (IsUSBKeyboardBufferEmpty (KeyboardBuffer
)) {
1011 return EFI_DEVICE_ERROR
;
1014 UsbKey
->KeyCode
= KeyboardBuffer
->buffer
[KeyboardBuffer
->bHead
].KeyCode
;
1015 UsbKey
->Down
= KeyboardBuffer
->buffer
[KeyboardBuffer
->bHead
].Down
;
1018 // adjust the head pointer of the FIFO keyboard buffer.
1020 KeyboardBuffer
->bHead
= (UINT8
) ((KeyboardBuffer
->bHead
+ 1) % (MAX_KEY_ALLOWED
+ 1));
1027 IN USB_KB_DEV
*UsbKeyboardDevice
1031 Routine Description:
1032 Sets USB Keyboard LED state.
1035 UsbKeyboardDevice - The USB_KB_DEV instance.
1038 EFI_SUCCESS - Success
1045 // Set each field in Led map.
1047 Led
.NumLock
= (UINT8
) UsbKeyboardDevice
->NumLockOn
;
1048 Led
.CapsLock
= (UINT8
) UsbKeyboardDevice
->CapsOn
;
1049 Led
.ScrollLock
= (UINT8
) UsbKeyboardDevice
->ScrollOn
;
1054 // call Set Report Request to lighten the LED.
1056 UsbSetReportRequest (
1057 UsbKeyboardDevice
->UsbIo
,
1058 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
1070 USBKeyboardRepeatHandler (
1076 Routine Description:
1077 Timer handler for Repeat Key timer.
1080 Event - The Repeat Key event.
1081 Context - Points to the USB_KB_DEV instance.
1087 USB_KB_DEV
*UsbKeyboardDevice
;
1089 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1092 // Do nothing when there is no repeat key.
1094 if (UsbKeyboardDevice
->RepeatKey
!= 0) {
1096 // Inserts one Repeat key into keyboard buffer,
1099 &(UsbKeyboardDevice
->KeyboardBuffer
),
1100 UsbKeyboardDevice
->RepeatKey
,
1105 // set repeate rate for repeat key generation.
1108 UsbKeyboardDevice
->RepeatTimer
,
1118 USBKeyboardRecoveryHandler (
1124 Routine Description:
1125 Timer handler for Delayed Recovery timer.
1128 Event - The Delayed Recovery event.
1129 Context - Points to the USB_KB_DEV instance.
1136 USB_KB_DEV
*UsbKeyboardDevice
;
1137 EFI_USB_IO_PROTOCOL
*UsbIo
;
1140 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1142 UsbIo
= UsbKeyboardDevice
->UsbIo
;
1144 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
1146 UsbIo
->UsbAsyncInterruptTransfer (
1148 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1150 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,