2 Helper functions for USB Keyboard Driver.
4 Copyright (c) 2004 - 2008, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 // Default English keyboard layout
19 // Format:<efi key>, <unicode without shift>, <unicode with shift>, <Modifier>, <AffectedAttribute>
21 // According to Universal Serial Bus HID Usage Tables document ver 1.12,
22 // a Boot Keyboard should support the keycode range from 0x0 to 0x65 and 0xE0 to 0xE7.
23 // 0x0 to 0x3 are reserved for typical keyboard status or keyboard errors, so they are excluded.
25 UINT8 KeyboardLayoutTable
[NUMBER_OF_VALID_USB_KEYCODE
][5] = {
26 {EfiKeyC1
, 'a', 'A', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x04
27 {EfiKeyB5
, 'b', 'B', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x05
28 {EfiKeyB3
, 'c', 'C', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x06
29 {EfiKeyC3
, 'd', 'D', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x07
30 {EfiKeyD3
, 'e', 'E', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x08
31 {EfiKeyC4
, 'f', 'F', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x09
32 {EfiKeyC5
, 'g', 'G', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x0A
33 {EfiKeyC6
, 'h', 'H', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x0B
34 {EfiKeyD8
, 'i', 'I', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x0C
35 {EfiKeyC7
, 'j', 'J', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x0D
36 {EfiKeyC8
, 'k', 'K', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x0E
37 {EfiKeyC9
, 'l', 'L', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x0F
38 {EfiKeyB7
, 'm', 'M', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x10
39 {EfiKeyB6
, 'n', 'N', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x11
40 {EfiKeyD9
, 'o', 'O', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x12
41 {EfiKeyD10
, 'p', 'P', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x13
42 {EfiKeyD1
, 'q', 'Q', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x14
43 {EfiKeyD4
, 'r', 'R', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x15
44 {EfiKeyC2
, 's', 'S', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x16
45 {EfiKeyD5
, 't', 'T', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x17
46 {EfiKeyD7
, 'u', 'U', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x18
47 {EfiKeyB4
, 'v', 'V', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x19
48 {EfiKeyD2
, 'w', 'W', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x1A
49 {EfiKeyB2
, 'x', 'X', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x1B
50 {EfiKeyD6
, 'y', 'Y', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x1C
51 {EfiKeyB1
, 'z', 'Z', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x1D
52 {EfiKeyE1
, '1', '!', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x1E
53 {EfiKeyE2
, '2', '@', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x1F
54 {EfiKeyE3
, '3', '#', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x20
55 {EfiKeyE4
, '4', '$', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x21
56 {EfiKeyE5
, '5', '%', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x22
57 {EfiKeyE6
, '6', '^', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x23
58 {EfiKeyE7
, '7', '&', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x24
59 {EfiKeyE8
, '8', '*', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x25
60 {EfiKeyE9
, '9', '(', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x26
61 {EfiKeyE10
, '0', ')', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x27
62 {EfiKeyEnter
, 0x0d, 0x0d, EFI_NULL_MODIFIER
, 0}, // 0x28 Enter
63 {EfiKeyEsc
, 0x1b, 0x1b, EFI_NULL_MODIFIER
, 0}, // 0x29 Esc
64 {EfiKeyBackSpace
, 0x08, 0x08, EFI_NULL_MODIFIER
, 0}, // 0x2A Backspace
65 {EfiKeyTab
, 0x09, 0x09, EFI_NULL_MODIFIER
, 0}, // 0x2B Tab
66 {EfiKeySpaceBar
, ' ', ' ', EFI_NULL_MODIFIER
, 0}, // 0x2C Spacebar
67 {EfiKeyE11
, '-', '_', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x2D
68 {EfiKeyE12
, '=', '+', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x2E
69 {EfiKeyD11
, '[', '{', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x2F
70 {EfiKeyD12
, ']', '}', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x30
71 {EfiKeyD13
, '\\', '|', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x31
72 {EfiKeyC12
, '\\', '|', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x32 Keyboard Non-US # and ~
73 {EfiKeyC10
, ';', ':', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x33
74 {EfiKeyC11
, '\'', '"', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x34
75 {EfiKeyE0
, '`', '~', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x35 Keyboard Grave Accent and Tlide
76 {EfiKeyB8
, ',', '<', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x36
77 {EfiKeyB9
, '.', '>', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x37
78 {EfiKeyB10
, '/', '?', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x38
79 {EfiKeyCapsLock
, 0x00, 0x00, EFI_CAPS_LOCK_MODIFIER
, 0}, // 0x39 CapsLock
80 {EfiKeyF1
, 0x00, 0x00, EFI_FUNCTION_KEY_ONE_MODIFIER
, 0}, // 0x3A
81 {EfiKeyF2
, 0x00, 0x00, EFI_FUNCTION_KEY_TWO_MODIFIER
, 0}, // 0x3B
82 {EfiKeyF3
, 0x00, 0x00, EFI_FUNCTION_KEY_THREE_MODIFIER
, 0}, // 0x3C
83 {EfiKeyF4
, 0x00, 0x00, EFI_FUNCTION_KEY_FOUR_MODIFIER
, 0}, // 0x3D
84 {EfiKeyF5
, 0x00, 0x00, EFI_FUNCTION_KEY_FIVE_MODIFIER
, 0}, // 0x3E
85 {EfiKeyF6
, 0x00, 0x00, EFI_FUNCTION_KEY_SIX_MODIFIER
, 0}, // 0x3F
86 {EfiKeyF7
, 0x00, 0x00, EFI_FUNCTION_KEY_SEVEN_MODIFIER
, 0}, // 0x40
87 {EfiKeyF8
, 0x00, 0x00, EFI_FUNCTION_KEY_EIGHT_MODIFIER
, 0}, // 0x41
88 {EfiKeyF9
, 0x00, 0x00, EFI_FUNCTION_KEY_NINE_MODIFIER
, 0}, // 0x42
89 {EfiKeyF10
, 0x00, 0x00, EFI_FUNCTION_KEY_TEN_MODIFIER
, 0}, // 0x43
90 {EfiKeyF11
, 0x00, 0x00, EFI_FUNCTION_KEY_ELEVEN_MODIFIER
, 0}, // 0x44 F11
91 {EfiKeyF12
, 0x00, 0x00, EFI_FUNCTION_KEY_TWELVE_MODIFIER
, 0}, // 0x45 F12
92 {EfiKeyPrint
, 0x00, 0x00, EFI_PRINT_MODIFIER
, 0}, // 0x46 PrintScreen
93 {EfiKeySLck
, 0x00, 0x00, EFI_SCROLL_LOCK_MODIFIER
, 0}, // 0x47 Scroll Lock
94 {EfiKeyPause
, 0x00, 0x00, EFI_PAUSE_MODIFIER
, 0}, // 0x48 Pause
95 {EfiKeyIns
, 0x00, 0x00, EFI_INSERT_MODIFIER
, 0}, // 0x49
96 {EfiKeyHome
, 0x00, 0x00, EFI_HOME_MODIFIER
, 0}, // 0x4A
97 {EfiKeyPgUp
, 0x00, 0x00, EFI_PAGE_UP_MODIFIER
, 0}, // 0x4B
98 {EfiKeyDel
, 0x00, 0x00, EFI_DELETE_MODIFIER
, 0}, // 0x4C
99 {EfiKeyEnd
, 0x00, 0x00, EFI_END_MODIFIER
, 0}, // 0x4D
100 {EfiKeyPgDn
, 0x00, 0x00, EFI_PAGE_DOWN_MODIFIER
, 0}, // 0x4E
101 {EfiKeyRightArrow
, 0x00, 0x00, EFI_RIGHT_ARROW_MODIFIER
, 0}, // 0x4F
102 {EfiKeyLeftArrow
, 0x00, 0x00, EFI_LEFT_ARROW_MODIFIER
, 0}, // 0x50
103 {EfiKeyDownArrow
, 0x00, 0x00, EFI_DOWN_ARROW_MODIFIER
, 0}, // 0x51
104 {EfiKeyUpArrow
, 0x00, 0x00, EFI_UP_ARROW_MODIFIER
, 0}, // 0x52
105 {EfiKeyNLck
, 0x00, 0x00, EFI_NUM_LOCK_MODIFIER
, 0}, // 0x53 NumLock
106 {EfiKeySlash
, '/', '/', EFI_NULL_MODIFIER
, 0}, // 0x54
107 {EfiKeyAsterisk
, '*', '*', EFI_NULL_MODIFIER
, 0}, // 0x55
108 {EfiKeyMinus
, '-', '-', EFI_NULL_MODIFIER
, 0}, // 0x56
109 {EfiKeyPlus
, '+', '+', EFI_NULL_MODIFIER
, 0}, // 0x57
110 {EfiKeyEnter
, 0x0d, 0x0d, EFI_NULL_MODIFIER
, 0}, // 0x58
111 {EfiKeyOne
, '1', '1', EFI_END_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x59
112 {EfiKeyTwo
, '2', '2', EFI_DOWN_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x5A
113 {EfiKeyThree
, '3', '3', EFI_PAGE_DOWN_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x5B
114 {EfiKeyFour
, '4', '4', EFI_LEFT_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x5C
115 {EfiKeyFive
, '5', '5', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x5D
116 {EfiKeySix
, '6', '6', EFI_RIGHT_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x5E
117 {EfiKeySeven
, '7', '7', EFI_HOME_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x5F
118 {EfiKeyEight
, '8', '8', EFI_UP_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x60
119 {EfiKeyNine
, '9', '9', EFI_PAGE_UP_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x61
120 {EfiKeyZero
, '0', '0', EFI_INSERT_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x62
121 {EfiKeyPeriod
, '.', '.', EFI_DELETE_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x63
122 {EfiKeyB0
, '\\', '|', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x64 Keyboard Non-US \ and |
123 {EfiKeyA4
, 0x00, 0x00, EFI_MENU_MODIFIER
, 0}, // 0x65 Keyboard Application
125 {EfiKeyLCtrl
, 0, 0, EFI_LEFT_CONTROL_MODIFIER
, 0}, // 0xe0
126 {EfiKeyLShift
, 0, 0, EFI_LEFT_SHIFT_MODIFIER
, 0}, // 0xe1
127 {EfiKeyLAlt
, 0, 0, EFI_LEFT_ALT_MODIFIER
, 0}, // 0xe2
128 {EfiKeyA0
, 0, 0, EFI_LEFT_LOGO_MODIFIER
, 0}, // 0xe3
129 {EfiKeyRCtrl
, 0, 0, EFI_RIGHT_CONTROL_MODIFIER
, 0}, // 0xe4
130 {EfiKeyRShift
, 0, 0, EFI_RIGHT_SHIFT_MODIFIER
, 0}, // 0xe5
131 {EfiKeyA2
, 0, 0, EFI_RIGHT_ALT_MODIFIER
, 0}, // 0xe6
132 {EfiKeyA3
, 0, 0, EFI_RIGHT_LOGO_MODIFIER
, 0}, // 0xe7
136 // EFI_KEY to USB Keycode convertion table
137 // EFI_KEY is defined in UEFI spec.
138 // USB Keycode is defined in USB HID Firmware spec.
140 UINT8 EfiKeyToUsbKeyCodeConvertionTable
[] = {
144 0x2c, // EfiKeySpaceBar
149 0x50, // EfiKeyLeftArrow
150 0x51, // EfiKeyDownArrow
151 0x4F, // EfiKeyRightArrow
153 0x63, // EfiKeyPeriod
155 0xe1, // EfiKeyLShift
167 0xe5, // EfiKeyRShift
168 0x52, // EfiKeyUpArrow
172 0x39, // EfiKeyCapsLock
222 0x2A, // EfiKeyBackSpace
228 0x55, // EfiKeyAsterisk
249 // Keyboard modifier value to EFI Scan Code convertion table
250 // EFI Scan Code and the modifier values are defined in UEFI spec.
252 UINT8 ModifierValueToEfiScanCodeConvertionTable
[] = {
253 SCAN_NULL
, // EFI_NULL_MODIFIER
254 SCAN_NULL
, // EFI_LEFT_CONTROL_MODIFIER
255 SCAN_NULL
, // EFI_RIGHT_CONTROL_MODIFIER
256 SCAN_NULL
, // EFI_LEFT_ALT_MODIFIER
257 SCAN_NULL
, // EFI_RIGHT_ALT_MODIFIER
258 SCAN_NULL
, // EFI_ALT_GR_MODIFIER
259 SCAN_INSERT
, // EFI_INSERT_MODIFIER
260 SCAN_DELETE
, // EFI_DELETE_MODIFIER
261 SCAN_PAGE_DOWN
, // EFI_PAGE_DOWN_MODIFIER
262 SCAN_PAGE_UP
, // EFI_PAGE_UP_MODIFIER
263 SCAN_HOME
, // EFI_HOME_MODIFIER
264 SCAN_END
, // EFI_END_MODIFIER
265 SCAN_NULL
, // EFI_LEFT_SHIFT_MODIFIER
266 SCAN_NULL
, // EFI_RIGHT_SHIFT_MODIFIER
267 SCAN_NULL
, // EFI_CAPS_LOCK_MODIFIER
268 SCAN_NULL
, // EFI_NUM_LOCK_MODIFIER
269 SCAN_LEFT
, // EFI_LEFT_ARROW_MODIFIER
270 SCAN_RIGHT
, // EFI_RIGHT_ARROW_MODIFIER
271 SCAN_DOWN
, // EFI_DOWN_ARROW_MODIFIER
272 SCAN_UP
, // EFI_UP_ARROW_MODIFIER
273 SCAN_NULL
, // EFI_NS_KEY_MODIFIER
274 SCAN_NULL
, // EFI_NS_KEY_DEPENDENCY_MODIFIER
275 SCAN_F1
, // EFI_FUNCTION_KEY_ONE_MODIFIER
276 SCAN_F2
, // EFI_FUNCTION_KEY_TWO_MODIFIER
277 SCAN_F3
, // EFI_FUNCTION_KEY_THREE_MODIFIER
278 SCAN_F4
, // EFI_FUNCTION_KEY_FOUR_MODIFIER
279 SCAN_F5
, // EFI_FUNCTION_KEY_FIVE_MODIFIER
280 SCAN_F6
, // EFI_FUNCTION_KEY_SIX_MODIFIER
281 SCAN_F7
, // EFI_FUNCTION_KEY_SEVEN_MODIFIER
282 SCAN_F8
, // EFI_FUNCTION_KEY_EIGHT_MODIFIER
283 SCAN_F9
, // EFI_FUNCTION_KEY_NINE_MODIFIER
284 SCAN_F10
, // EFI_FUNCTION_KEY_TEN_MODIFIER
285 SCAN_F11
, // EFI_FUNCTION_KEY_ELEVEN_MODIFIER
286 SCAN_F12
, // EFI_FUNCTION_KEY_TWELVE_MODIFIER
289 EFI_GUID mKeyboardLayoutEventGuid
= EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
;
292 Initialize Key Convertion Table by using default keyboard layout.
294 @param UsbKeyboardDevice The USB_KB_DEV instance.
299 LoadDefaultKeyboardLayout (
300 IN OUT USB_KB_DEV
*UsbKeyboardDevice
304 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
307 // Construct KeyConvertionTable by default keyboard layout
309 KeyDescriptor
= &UsbKeyboardDevice
->KeyConvertionTable
[0];
311 for (Index
= 0; Index
< (NUMBER_OF_VALID_USB_KEYCODE
); Index
++) {
312 KeyDescriptor
->Key
= (EFI_KEY
) KeyboardLayoutTable
[Index
][0];
313 KeyDescriptor
->Unicode
= KeyboardLayoutTable
[Index
][1];
314 KeyDescriptor
->ShiftedUnicode
= KeyboardLayoutTable
[Index
][2];
315 KeyDescriptor
->AltGrUnicode
= 0;
316 KeyDescriptor
->ShiftedAltGrUnicode
= 0;
317 KeyDescriptor
->Modifier
= KeyboardLayoutTable
[Index
][3];
318 KeyDescriptor
->AffectedAttribute
= KeyboardLayoutTable
[Index
][4];
325 Uses USB I/O to check whether the device is a USB keyboard device.
327 @param UsbIo Pointer to a USB I/O protocol instance.
329 @retval TRUE Device is a USB keyboard device.
330 @retval FALSE Device is a not USB keyboard device.
336 IN EFI_USB_IO_PROTOCOL
*UsbIo
340 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
343 // Get the default interface descriptor
345 Status
= UsbIo
->UsbGetInterfaceDescriptor (
350 if (EFI_ERROR (Status
)) {
354 if (InterfaceDescriptor
.InterfaceClass
== CLASS_HID
&&
355 InterfaceDescriptor
.InterfaceSubClass
== SUBCLASS_BOOT
&&
356 InterfaceDescriptor
.InterfaceProtocol
== PROTOCOL_KEYBOARD
365 Get current keyboard layout from HII database.
367 @return Pointer to HII Keyboard Layout.
368 NULL means failure occurred while trying to get keyboard layout.
371 EFI_HII_KEYBOARD_LAYOUT
*
373 GetCurrentKeyboardLayout (
378 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
379 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
383 // Locate HII Database Protocol
385 Status
= gBS
->LocateProtocol (
386 &gEfiHiiDatabaseProtocolGuid
,
388 (VOID
**) &HiiDatabase
390 if (EFI_ERROR (Status
)) {
395 // Get current keyboard layout from HII database
398 KeyboardLayout
= NULL
;
399 Status
= HiiDatabase
->GetKeyboardLayout (
405 if (Status
== EFI_BUFFER_TOO_SMALL
) {
406 KeyboardLayout
= AllocatePool (Length
);
407 ASSERT (KeyboardLayout
!= NULL
);
409 Status
= HiiDatabase
->GetKeyboardLayout (
415 if (EFI_ERROR (Status
)) {
416 gBS
->FreePool (KeyboardLayout
);
417 KeyboardLayout
= NULL
;
421 return KeyboardLayout
;
425 Find Key Descriptor in Key Convertion Table given its USB keycode.
427 @param UsbKeyboardDevice The USB_KB_DEV instance.
428 @param KeyCode USB Keycode.
430 @return The Key Descriptor in Key Convertion Table.
431 NULL means not found.
437 IN USB_KB_DEV
*UsbKeyboardDevice
,
444 // Make sure KeyCode is in the range of [0x4, 0x65] or [0xe0, 0xe7]
446 if ((!USBKBD_VALID_KEYCODE (KeyCode
)) || ((KeyCode
> 0x65) && (KeyCode
< 0xe0)) || (KeyCode
> 0xe7)) {
451 // Calculate the index of Key Descriptor in Key Convertion Table
453 if (KeyCode
<= 0x65) {
454 Index
= (UINT8
) (KeyCode
- 4);
456 Index
= (UINT8
) (KeyCode
- 0xe0 + NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE
);
459 return &UsbKeyboardDevice
->KeyConvertionTable
[Index
];
463 Find Non-Spacing key for given Key descriptor.
465 @param UsbKeyboardDevice The USB_KB_DEV instance.
466 @param KeyDescriptor Key descriptor.
468 @return The Non-Spacing key corresponding to KeyDescriptor
469 NULL means not found.
475 IN USB_KB_DEV
*UsbKeyboardDevice
,
476 IN EFI_KEY_DESCRIPTOR
*KeyDescriptor
480 USB_NS_KEY
*UsbNsKey
;
482 Link
= GetFirstNode (&UsbKeyboardDevice
->NsKeyList
);
483 while (!IsNull (&UsbKeyboardDevice
->NsKeyList
, Link
)) {
484 UsbNsKey
= USB_NS_KEY_FORM_FROM_LINK (Link
);
486 if (UsbNsKey
->NsKey
[0].Key
== KeyDescriptor
->Key
) {
490 Link
= GetNextNode (&UsbKeyboardDevice
->NsKeyList
, Link
);
497 Find physical key definition for a given key descriptor.
499 For a specified non-spacing key, there are a list of physical
500 keys following it. This function traverses the list of
501 physical keys and tries to find the physical key matching
504 @param UsbNsKey The non-spacing key information.
505 @param KeyDescriptor The key descriptor.
507 @return The physical key definition.
508 If no physical key is found, parameter KeyDescriptor is returned.
514 IN USB_NS_KEY
*UsbNsKey
,
515 IN EFI_KEY_DESCRIPTOR
*KeyDescriptor
519 EFI_KEY_DESCRIPTOR
*PhysicalKey
;
521 PhysicalKey
= &UsbNsKey
->NsKey
[1];
522 for (Index
= 0; Index
< UsbNsKey
->KeyCount
; Index
++) {
523 if (KeyDescriptor
->Key
== PhysicalKey
->Key
) {
531 // No children definition matched, return original key
533 return KeyDescriptor
;
537 The notification function for EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID.
539 This function is registered to event of EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
540 group type, which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
541 It tries to get curent keyboard layout from HII database.
543 @param Event Event being signaled.
544 @param Context Points to USB_KB_DEV instance.
549 SetKeyboardLayoutEvent (
554 USB_KB_DEV
*UsbKeyboardDevice
;
555 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
556 EFI_KEY_DESCRIPTOR TempKey
;
557 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
558 EFI_KEY_DESCRIPTOR
*TableEntry
;
559 EFI_KEY_DESCRIPTOR
*NsKey
;
560 USB_NS_KEY
*UsbNsKey
;
566 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
569 // Try to get current keyboard layout from HII database
571 KeyboardLayout
= GetCurrentKeyboardLayout ();
572 if (KeyboardLayout
== NULL
) {
577 // Re-allocate resource for KeyConvertionTable
579 ReleaseKeyboardLayoutResources (UsbKeyboardDevice
);
580 UsbKeyboardDevice
->KeyConvertionTable
= AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE
) * sizeof (EFI_KEY_DESCRIPTOR
));
581 ASSERT (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
);
584 // Traverse the list of key descriptors following the header of EFI_HII_KEYBOARD_LAYOUT
586 KeyDescriptor
= (EFI_KEY_DESCRIPTOR
*) (((UINT8
*) KeyboardLayout
) + sizeof (EFI_HII_KEYBOARD_LAYOUT
));
587 for (Index
= 0; Index
< KeyboardLayout
->DescriptorCount
; Index
++) {
589 // Copy from HII keyboard layout package binary for alignment
591 CopyMem (&TempKey
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
594 // Fill the key into KeyConvertionTable, whose index is calculated from USB keycode.
596 KeyCode
= EfiKeyToUsbKeyCodeConvertionTable
[(UINT8
) (TempKey
.Key
)];
597 TableEntry
= GetKeyDescriptor (UsbKeyboardDevice
, KeyCode
);
598 CopyMem (TableEntry
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
601 // For non-spacing key, create the list with a non-spacing key followed by physical keys.
603 if (TempKey
.Modifier
== EFI_NS_KEY_MODIFIER
) {
604 UsbNsKey
= AllocatePool (sizeof (USB_NS_KEY
));
605 ASSERT (UsbNsKey
!= NULL
);
608 // Search for sequential children physical key definitions
611 NsKey
= KeyDescriptor
+ 1;
612 for (Index2
= Index
+ 1; Index2
< KeyboardLayout
->DescriptorCount
; Index2
++) {
613 CopyMem (&TempKey
, NsKey
, sizeof (EFI_KEY_DESCRIPTOR
));
614 if (TempKey
.Modifier
& EFI_NS_KEY_DEPENDENCY_MODIFIER
) {
622 UsbNsKey
->Signature
= USB_NS_KEY_SIGNATURE
;
623 UsbNsKey
->KeyCount
= KeyCount
;
624 UsbNsKey
->NsKey
= AllocateCopyPool (
625 (KeyCount
+ 1) * sizeof (EFI_KEY_DESCRIPTOR
),
628 InsertTailList (&UsbKeyboardDevice
->NsKeyList
, &UsbNsKey
->Link
);
631 // Skip over the child physical keys
634 KeyDescriptor
+= KeyCount
;
641 // There are two EfiKeyEnter, duplicate its key descriptor
643 TableEntry
= GetKeyDescriptor (UsbKeyboardDevice
, 0x58);
644 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, 0x28);
645 CopyMem (TableEntry
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
647 gBS
->FreePool (KeyboardLayout
);
651 Destroy resources for keyboard layout.
653 @param UsbKeyboardDevice The USB_KB_DEV instance.
658 ReleaseKeyboardLayoutResources (
659 IN OUT USB_KB_DEV
*UsbKeyboardDevice
662 USB_NS_KEY
*UsbNsKey
;
665 if (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
) {
666 FreePool (UsbKeyboardDevice
->KeyConvertionTable
);
668 UsbKeyboardDevice
->KeyConvertionTable
= NULL
;
670 while (!IsListEmpty (&UsbKeyboardDevice
->NsKeyList
)) {
671 Link
= GetFirstNode (&UsbKeyboardDevice
->NsKeyList
);
672 UsbNsKey
= USB_NS_KEY_FORM_FROM_LINK (Link
);
673 RemoveEntryList (&UsbNsKey
->Link
);
675 FreePool (UsbNsKey
->NsKey
);
681 Initialize USB keyboard layout.
683 This function initializes Key Convertion Table for the USB keyboard device.
684 It first tries to retrieve layout from HII database. If failed and default
685 layout is enabled, then it just uses the default layout.
687 @param UsbKeyboardDevice The USB_KB_DEV instance.
689 @retval EFI_SUCCESS Initialization succeeded.
690 @retval EFI_NOT_READY Keyboard layout cannot be retrieve from HII
691 database, and default layout is disabled.
692 @retval Other Fail to register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group.
698 OUT USB_KB_DEV
*UsbKeyboardDevice
701 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
704 UsbKeyboardDevice
->KeyConvertionTable
= AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE
) * sizeof (EFI_KEY_DESCRIPTOR
));
705 ASSERT (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
);
707 InitializeListHead (&UsbKeyboardDevice
->NsKeyList
);
708 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
709 UsbKeyboardDevice
->KeyboardLayoutEvent
= NULL
;
712 // Register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group,
713 // which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
715 Status
= gBS
->CreateEventEx (
718 SetKeyboardLayoutEvent
,
720 &mKeyboardLayoutEventGuid
,
721 &UsbKeyboardDevice
->KeyboardLayoutEvent
723 if (EFI_ERROR (Status
)) {
727 KeyboardLayout
= GetCurrentKeyboardLayout ();
728 if (KeyboardLayout
!= NULL
) {
730 // If current keyboard layout is successfully retrieved from HII database,
731 // force to initialize the keyboard layout.
733 gBS
->SignalEvent (UsbKeyboardDevice
->KeyboardLayoutEvent
);
735 if (FeaturePcdGet (PcdDisableDefaultKeyboardLayoutInUsbKbDriver
)) {
737 // If no keyboard layout can be retrieved from HII database, and default layout
738 // is disabled, then return EFI_NOT_READY.
740 return EFI_NOT_READY
;
743 // If no keyboard layout can be retrieved from HII database, and default layout
744 // is enabled, then load the default keyboard layout.
746 LoadDefaultKeyboardLayout (UsbKeyboardDevice
);
754 Initialize USB keyboard device and all private data structures.
756 @param UsbKeyboardDevice The USB_KB_DEV instance.
758 @retval EFI_SUCCESS Initialization is successful.
759 @retval EFI_DEVICE_ERROR Keyboard initialization failed.
765 IN OUT USB_KB_DEV
*UsbKeyboardDevice
773 UINT32 TransferResult
;
775 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
777 PcdGet32 (PcdStatusCodeValueKeyboardSelfTest
),
778 UsbKeyboardDevice
->DevicePath
781 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
784 // Uses default configuration to configure the USB keyboard device.
787 Status
= UsbSetConfiguration (
788 UsbKeyboardDevice
->UsbIo
,
789 (UINT16
) ConfigValue
,
792 if (EFI_ERROR (Status
)) {
794 // If configuration could not be set here, it means
795 // the keyboard interface has some errors and could
796 // not be initialized
798 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
799 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
800 PcdGet32 (PcdStatusCodeValueKeyboardInterfaceError
),
801 UsbKeyboardDevice
->DevicePath
804 return EFI_DEVICE_ERROR
;
807 UsbGetProtocolRequest (
808 UsbKeyboardDevice
->UsbIo
,
809 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
813 // Set boot protocol for the USB Keyboard.
814 // This driver only supports boot protocol.
815 // The device that does not support boot protocol is not supported.
817 if (Protocol
!= BOOT_PROTOCOL
) {
818 UsbSetProtocolRequest (
819 UsbKeyboardDevice
->UsbIo
,
820 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
826 // ReportId is zero, which means the idle rate applies to all input reports.
830 // Duration is zero, which means the duration is infinite.
831 // so the endpoint will inhibit reporting forever,
832 // and only reporting when a change is detected in the report data.
836 UsbKeyboardDevice
->UsbIo
,
837 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
842 UsbKeyboardDevice
->CtrlOn
= FALSE
;
843 UsbKeyboardDevice
->AltOn
= FALSE
;
844 UsbKeyboardDevice
->ShiftOn
= FALSE
;
845 UsbKeyboardDevice
->NumLockOn
= FALSE
;
846 UsbKeyboardDevice
->CapsOn
= FALSE
;
847 UsbKeyboardDevice
->ScrollOn
= FALSE
;
849 UsbKeyboardDevice
->LeftCtrlOn
= FALSE
;
850 UsbKeyboardDevice
->LeftAltOn
= FALSE
;
851 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
852 UsbKeyboardDevice
->LeftLogoOn
= FALSE
;
853 UsbKeyboardDevice
->RightCtrlOn
= FALSE
;
854 UsbKeyboardDevice
->RightAltOn
= FALSE
;
855 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
856 UsbKeyboardDevice
->RightLogoOn
= FALSE
;
857 UsbKeyboardDevice
->MenuKeyOn
= FALSE
;
858 UsbKeyboardDevice
->SysReqOn
= FALSE
;
860 UsbKeyboardDevice
->AltGrOn
= FALSE
;
862 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
865 // Sync the initial state of lights on keyboard.
867 SetKeyLED (UsbKeyboardDevice
);
869 ZeroMem (UsbKeyboardDevice
->LastKeyCodeArray
, sizeof (UINT8
) * 8);
872 // Set a timer for repeat keys' generation.
874 if (UsbKeyboardDevice
->RepeatTimer
!= NULL
) {
875 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
876 UsbKeyboardDevice
->RepeatTimer
= NULL
;
879 Status
= gBS
->CreateEvent (
880 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
882 USBKeyboardRepeatHandler
,
884 &UsbKeyboardDevice
->RepeatTimer
887 if (UsbKeyboardDevice
->DelayedRecoveryEvent
!= NULL
) {
888 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
889 UsbKeyboardDevice
->DelayedRecoveryEvent
= NULL
;
892 Status
= gBS
->CreateEvent (
893 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
895 USBKeyboardRecoveryHandler
,
897 &UsbKeyboardDevice
->DelayedRecoveryEvent
905 Handler function for USB keyboard's asynchronous interrupt transfer.
907 This function is the handler function for USB keyboard's asynchronous interrupt transfer
908 to manage the keyboard. It parses the USB keyboard input report, and inserts data to
909 keyboard buffer according to state of modifer keys and normal keys. Timer for repeat key
910 is also set accordingly.
912 @param Data A pointer to a buffer that is filled with key data which is
913 retrieved via asynchronous interrupt transfer.
914 @param DataLength Indicates the size of the data buffer.
915 @param Context Pointing to USB_KB_DEV instance.
916 @param Result Indicates the result of the asynchronous interrupt transfer.
918 @retval EFI_SUCCESS Asynchronous interrupt transfer is handled successfully.
919 @retval EFI_DEVICE_ERROR Hardware error occurs.
931 USB_KB_DEV
*UsbKeyboardDevice
;
932 EFI_USB_IO_PROTOCOL
*UsbIo
;
933 UINT8
*CurKeyCodeBuffer
;
934 UINT8
*OldKeyCodeBuffer
;
935 UINT8 CurModifierMap
;
936 UINT8 OldModifierMap
;
947 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
949 ASSERT (Context
!= NULL
);
952 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
953 UsbIo
= UsbKeyboardDevice
->UsbIo
;
956 // Analyzes Result and performs corresponding action.
958 if (Result
!= EFI_USB_NOERROR
) {
960 // Some errors happen during the process
962 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
963 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
964 PcdGet32 (PcdStatusCodeValueKeyboardInputError
),
965 UsbKeyboardDevice
->DevicePath
969 // Stop the repeat key generation if any
971 UsbKeyboardDevice
->RepeatKey
= 0;
974 UsbKeyboardDevice
->RepeatTimer
,
979 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
980 UsbClearEndpointHalt (
982 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
988 // Delete & Submit this interrupt again
989 // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt.
991 UsbIo
->UsbAsyncInterruptTransfer (
993 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1001 // EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling.
1004 UsbKeyboardDevice
->DelayedRecoveryEvent
,
1006 EFI_USB_INTERRUPT_DELAY
1009 return EFI_DEVICE_ERROR
;
1013 // If no error and no data, just return EFI_SUCCESS.
1015 if (DataLength
== 0 || Data
== NULL
) {
1020 // Following code checks current keyboard input report against old key code buffer.
1021 // According to USB HID Firmware Specification, the report consists of 8 bytes.
1022 // Byte 0 is map of Modifier keys.
1023 // Byte 1 is reserved.
1024 // Bytes 2 to 7 are keycodes.
1026 CurKeyCodeBuffer
= (UINT8
*) Data
;
1027 OldKeyCodeBuffer
= UsbKeyboardDevice
->LastKeyCodeArray
;
1030 // Checks for new key stroke.
1032 for (Index
= 0; Index
< 8; Index
++) {
1033 if (OldKeyCodeBuffer
[Index
] != CurKeyCodeBuffer
[Index
]) {
1039 // If no new key, return EFI_SUCCESS immediately.
1046 // Parse the modifier key, which is the first byte of keyboard input report.
1048 CurModifierMap
= CurKeyCodeBuffer
[0];
1049 OldModifierMap
= OldKeyCodeBuffer
[0];
1052 // Handle modifier key's pressing or releasing situation.
1053 // According to USB HID Firmware spec, Byte 0 uses folloing map of Modifier keys:
1054 // Bit0: Left Control, Keycode: 0xe0
1055 // Bit1: Left Shift, Keycode: 0xe1
1056 // Bit2: Left Alt, Keycode: 0xe2
1057 // Bit3: Left GUI, Keycode: 0xe3
1058 // Bit4: Right Control, Keycode: 0xe4
1059 // Bit5: Right Shift, Keycode: 0xe5
1060 // Bit6: Right Alt, Keycode: 0xe6
1061 // Bit7: Right GUI, Keycode: 0xe7
1063 for (Index
= 0; Index
< 8; Index
++) {
1064 Mask
= (UINT8
) (1 << Index
);
1065 if ((CurModifierMap
& Mask
) != (OldModifierMap
& Mask
)) {
1067 // If current modifier key is up, then CurModifierMap & Mask = 0;
1068 // otherwise it is a non-zero value.
1069 // Insert the changed modifier key into key buffer.
1071 Down
= (BOOLEAN
) ((CurModifierMap
& Mask
) != 0);
1072 InsertKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), (UINT8
) (0xe0 + Index
), Down
);
1077 // Handle normal key's releasing situation
1078 // Bytes 2 to 7 are for normal keycodes
1081 for (Index
= 2; Index
< 8; Index
++) {
1083 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index
])) {
1087 // For any key in old keycode buffer, if it is not in current keycode buffer,
1088 // then it is released. Otherwise, it is not released.
1091 for (Index2
= 2; Index2
< 8; Index2
++) {
1093 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index2
])) {
1097 if (OldKeyCodeBuffer
[Index
] == CurKeyCodeBuffer
[Index2
]) {
1105 &(UsbKeyboardDevice
->KeyboardBuffer
),
1106 OldKeyCodeBuffer
[Index
],
1110 // The original repeat key is released.
1112 if (OldKeyCodeBuffer
[Index
] == UsbKeyboardDevice
->RepeatKey
) {
1113 UsbKeyboardDevice
->RepeatKey
= 0;
1119 // If original repeat key is released, cancel the repeat timer
1121 if (UsbKeyboardDevice
->RepeatKey
== 0) {
1123 UsbKeyboardDevice
->RepeatTimer
,
1130 // Handle normal key's pressing situation
1133 for (Index
= 2; Index
< 8; Index
++) {
1135 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index
])) {
1139 // For any key in current keycode buffer, if it is not in old keycode buffer,
1140 // then it is pressed. Otherwise, it is not pressed.
1143 for (Index2
= 2; Index2
< 8; Index2
++) {
1145 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index2
])) {
1149 if (CurKeyCodeBuffer
[Index
] == OldKeyCodeBuffer
[Index2
]) {
1156 InsertKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), CurKeyCodeBuffer
[Index
], TRUE
);
1159 // Handle repeat key
1161 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, CurKeyCodeBuffer
[Index
]);
1162 if (KeyDescriptor
->Modifier
== EFI_NUM_LOCK_MODIFIER
|| KeyDescriptor
->Modifier
== EFI_CAPS_LOCK_MODIFIER
) {
1164 // For NumLock or CapsLock pressed, there is no need to handle repeat key for them.
1166 UsbKeyboardDevice
->RepeatKey
= 0;
1169 // Prepare new repeat key, and clear the original one.
1171 NewRepeatKey
= CurKeyCodeBuffer
[Index
];
1172 UsbKeyboardDevice
->RepeatKey
= 0;
1178 // Update LastKeycodeArray buffer in the UsbKeyboardDevice data structure.
1180 for (Index
= 0; Index
< 8; Index
++) {
1181 UsbKeyboardDevice
->LastKeyCodeArray
[Index
] = CurKeyCodeBuffer
[Index
];
1185 // Pre-process KeyboardBuffer to check if Ctrl + Alt + Del is pressed.
1187 SavedTail
= UsbKeyboardDevice
->KeyboardBuffer
.BufferTail
;
1188 Index
= UsbKeyboardDevice
->KeyboardBuffer
.BufferHead
;
1189 while (Index
!= SavedTail
) {
1190 RemoveKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), &UsbKey
);
1192 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, UsbKey
.KeyCode
);
1194 switch (KeyDescriptor
->Modifier
) {
1196 case EFI_LEFT_CONTROL_MODIFIER
:
1197 case EFI_RIGHT_CONTROL_MODIFIER
:
1199 UsbKeyboardDevice
->CtrlOn
= TRUE
;
1201 UsbKeyboardDevice
->CtrlOn
= FALSE
;
1205 case EFI_LEFT_ALT_MODIFIER
:
1206 case EFI_RIGHT_ALT_MODIFIER
:
1208 UsbKeyboardDevice
->AltOn
= TRUE
;
1210 UsbKeyboardDevice
->AltOn
= FALSE
;
1214 case EFI_ALT_GR_MODIFIER
:
1216 UsbKeyboardDevice
->AltGrOn
= TRUE
;
1218 UsbKeyboardDevice
->AltGrOn
= FALSE
;
1223 // For Del Key, check if Ctrl + Alt + Del occurs for reset.
1225 case EFI_DELETE_MODIFIER
:
1227 if ((UsbKeyboardDevice
->CtrlOn
) && (UsbKeyboardDevice
->AltOn
)) {
1228 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1238 // Insert the key back to the buffer,
1239 // so the key sequence will not be destroyed.
1242 &(UsbKeyboardDevice
->KeyboardBuffer
),
1246 Index
= UsbKeyboardDevice
->KeyboardBuffer
.BufferHead
;
1250 // If there is new key pressed, update the RepeatKey value, and set the
1251 // timer to repeate delay timer
1253 if (NewRepeatKey
!= 0) {
1255 // Sets trigger time to "Repeat Delay Time",
1256 // to trigger the repeat timer when the key is hold long
1260 UsbKeyboardDevice
->RepeatTimer
,
1264 UsbKeyboardDevice
->RepeatKey
= NewRepeatKey
;
1272 Retrieves a USB keycode after parsing the raw data in keyboard buffer.
1274 This function parses keyboard buffer. It updates state of modifier key for
1275 USB_KB_DEV instancem, and returns keycode for output.
1277 @param UsbKeyboardDevice The USB_KB_DEV instance.
1278 @param KeyCode Pointer to the USB keycode for output.
1280 @retval EFI_SUCCESS Keycode successfully parsed.
1281 @retval EFI_NOT_READY Keyboard buffer is not ready for a valid keycode
1287 IN OUT USB_KB_DEV
*UsbKeyboardDevice
,
1292 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1296 while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice
->KeyboardBuffer
)) {
1298 // Pops one raw data off.
1300 RemoveKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), &UsbKey
);
1302 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, UsbKey
.KeyCode
);
1307 switch (KeyDescriptor
->Modifier
) {
1312 case EFI_LEFT_CONTROL_MODIFIER
:
1313 UsbKeyboardDevice
->LeftCtrlOn
= FALSE
;
1314 UsbKeyboardDevice
->CtrlOn
= FALSE
;
1316 case EFI_RIGHT_CONTROL_MODIFIER
:
1317 UsbKeyboardDevice
->RightCtrlOn
= FALSE
;
1318 UsbKeyboardDevice
->CtrlOn
= FALSE
;
1324 case EFI_LEFT_SHIFT_MODIFIER
:
1325 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
1326 UsbKeyboardDevice
->ShiftOn
= FALSE
;
1328 case EFI_RIGHT_SHIFT_MODIFIER
:
1329 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
1330 UsbKeyboardDevice
->ShiftOn
= FALSE
;
1336 case EFI_LEFT_ALT_MODIFIER
:
1337 UsbKeyboardDevice
->LeftAltOn
= FALSE
;
1338 UsbKeyboardDevice
->AltOn
= FALSE
;
1340 case EFI_RIGHT_ALT_MODIFIER
:
1341 UsbKeyboardDevice
->RightAltOn
= FALSE
;
1342 UsbKeyboardDevice
->AltOn
= FALSE
;
1346 // Left Logo release
1348 case EFI_LEFT_LOGO_MODIFIER
:
1349 UsbKeyboardDevice
->LeftLogoOn
= FALSE
;
1353 // Right Logo release
1355 case EFI_RIGHT_LOGO_MODIFIER
:
1356 UsbKeyboardDevice
->RightLogoOn
= FALSE
;
1362 case EFI_MENU_MODIFIER
:
1363 UsbKeyboardDevice
->MenuKeyOn
= FALSE
;
1369 case EFI_PRINT_MODIFIER
:
1370 case EFI_SYS_REQUEST_MODIFIER
:
1371 UsbKeyboardDevice
->SysReqOn
= FALSE
;
1377 case EFI_ALT_GR_MODIFIER
:
1378 UsbKeyboardDevice
->AltGrOn
= FALSE
;
1389 // Analyzes key pressing situation
1391 switch (KeyDescriptor
->Modifier
) {
1396 case EFI_LEFT_CONTROL_MODIFIER
:
1397 UsbKeyboardDevice
->LeftCtrlOn
= TRUE
;
1398 UsbKeyboardDevice
->CtrlOn
= TRUE
;
1401 case EFI_RIGHT_CONTROL_MODIFIER
:
1402 UsbKeyboardDevice
->RightCtrlOn
= TRUE
;
1403 UsbKeyboardDevice
->CtrlOn
= TRUE
;
1410 case EFI_LEFT_SHIFT_MODIFIER
:
1411 UsbKeyboardDevice
->LeftShiftOn
= TRUE
;
1412 UsbKeyboardDevice
->ShiftOn
= TRUE
;
1415 case EFI_RIGHT_SHIFT_MODIFIER
:
1416 UsbKeyboardDevice
->RightShiftOn
= TRUE
;
1417 UsbKeyboardDevice
->ShiftOn
= TRUE
;
1424 case EFI_LEFT_ALT_MODIFIER
:
1425 UsbKeyboardDevice
->LeftAltOn
= TRUE
;
1426 UsbKeyboardDevice
->AltOn
= TRUE
;
1429 case EFI_RIGHT_ALT_MODIFIER
:
1430 UsbKeyboardDevice
->RightAltOn
= TRUE
;
1431 UsbKeyboardDevice
->AltOn
= TRUE
;
1438 case EFI_LEFT_LOGO_MODIFIER
:
1439 UsbKeyboardDevice
->LeftLogoOn
= TRUE
;
1445 case EFI_RIGHT_LOGO_MODIFIER
:
1446 UsbKeyboardDevice
->RightLogoOn
= TRUE
;
1452 case EFI_MENU_MODIFIER
:
1453 UsbKeyboardDevice
->MenuKeyOn
= TRUE
;
1459 case EFI_PRINT_MODIFIER
:
1460 case EFI_SYS_REQUEST_MODIFIER
:
1461 UsbKeyboardDevice
->SysReqOn
= TRUE
;
1468 case EFI_ALT_GR_MODIFIER
:
1469 UsbKeyboardDevice
->AltGrOn
= TRUE
;
1472 case EFI_NUM_LOCK_MODIFIER
:
1476 UsbKeyboardDevice
->NumLockOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->NumLockOn
));
1477 SetKeyLED (UsbKeyboardDevice
);
1481 case EFI_CAPS_LOCK_MODIFIER
:
1485 UsbKeyboardDevice
->CapsOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->CapsOn
));
1486 SetKeyLED (UsbKeyboardDevice
);
1490 case EFI_SCROLL_LOCK_MODIFIER
:
1492 // Toggle ScrollLock
1494 UsbKeyboardDevice
->ScrollOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->ScrollOn
));
1495 SetKeyLED (UsbKeyboardDevice
);
1500 // F11, F12, PrintScreen, Pause/Break
1501 // could not be retrieved via SimpleTextInEx protocol
1503 case EFI_FUNCTION_KEY_ELEVEN_MODIFIER
:
1504 case EFI_FUNCTION_KEY_TWELVE_MODIFIER
:
1505 case EFI_PAUSE_MODIFIER
:
1506 case EFI_BREAK_MODIFIER
:
1518 // When encountering Ctrl + Alt + Del, then warm reset.
1520 if (KeyDescriptor
->Modifier
== EFI_DELETE_MODIFIER
) {
1521 if ((UsbKeyboardDevice
->CtrlOn
) && (UsbKeyboardDevice
->AltOn
)) {
1522 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1526 *KeyCode
= UsbKey
.KeyCode
;
1530 return EFI_NOT_READY
;
1535 Converts USB Keycode ranging from 0x4 to 0x65 to EFI_INPUT_KEY.
1537 @param UsbKeyboardDevice The USB_KB_DEV instance.
1538 @param KeyCode Indicates the key code that will be interpreted.
1539 @param Key A pointer to a buffer that is filled in with
1540 the keystroke information for the key that
1543 @retval EFI_SUCCESS Success.
1544 @retval EFI_INVALID_PARAMETER KeyCode is not in the range of 0x4 to 0x65.
1545 @retval EFI_INVALID_PARAMETER Translated EFI_INPUT_KEY has zero for both ScanCode and UnicodeChar.
1546 @retval EFI_NOT_READY KeyCode represents a dead key with EFI_NS_KEY_MODIFIER
1551 UsbKeyCodeToEfiInputKey (
1552 IN USB_KB_DEV
*UsbKeyboardDevice
,
1554 OUT EFI_INPUT_KEY
*Key
1557 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1560 // KeyCode must in the range of 0x4 to 0x65
1562 if (!USBKBD_VALID_KEYCODE (KeyCode
)) {
1563 return EFI_INVALID_PARAMETER
;
1565 if ((KeyCode
- 4) >= NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE
) {
1566 return EFI_INVALID_PARAMETER
;
1569 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, KeyCode
);
1571 if (KeyDescriptor
->Modifier
== EFI_NS_KEY_MODIFIER
) {
1573 // If this is a dead key with EFI_NS_KEY_MODIFIER, then record it and return.
1575 UsbKeyboardDevice
->CurrentNsKey
= FindUsbNsKey (UsbKeyboardDevice
, KeyDescriptor
);
1576 return EFI_NOT_READY
;
1579 if (UsbKeyboardDevice
->CurrentNsKey
!= NULL
) {
1581 // If this keystroke follows a non-spacing key, then find the descriptor for corresponding
1584 KeyDescriptor
= FindPhysicalKey (UsbKeyboardDevice
->CurrentNsKey
, KeyDescriptor
);
1585 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
1588 Key
->ScanCode
= ModifierValueToEfiScanCodeConvertionTable
[KeyDescriptor
->Modifier
];
1589 Key
->UnicodeChar
= KeyDescriptor
->Unicode
;
1591 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_STANDARD_SHIFT
)!= 0) {
1592 if (UsbKeyboardDevice
->ShiftOn
) {
1593 Key
->UnicodeChar
= KeyDescriptor
->ShiftedUnicode
;
1596 // Need not return associated shift state if a class of printable characters that
1597 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
1599 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_CAPS_LOCK
) != 0) {
1600 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
1601 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
1604 if (UsbKeyboardDevice
->AltGrOn
) {
1605 Key
->UnicodeChar
= KeyDescriptor
->ShiftedAltGrUnicode
;
1611 Key
->UnicodeChar
= KeyDescriptor
->Unicode
;
1613 if (UsbKeyboardDevice
->AltGrOn
) {
1614 Key
->UnicodeChar
= KeyDescriptor
->AltGrUnicode
;
1619 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_CAPS_LOCK
) != 0) {
1620 if (UsbKeyboardDevice
->CapsOn
) {
1621 if (Key
->UnicodeChar
== KeyDescriptor
->Unicode
) {
1622 Key
->UnicodeChar
= KeyDescriptor
->ShiftedUnicode
;
1623 } else if (Key
->UnicodeChar
== KeyDescriptor
->ShiftedUnicode
) {
1624 Key
->UnicodeChar
= KeyDescriptor
->Unicode
;
1630 // Translate the CTRL-Alpha characters to their corresponding control value
1631 // (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
1633 if (UsbKeyboardDevice
->CtrlOn
) {
1634 if (Key
->UnicodeChar
>= 'a' && Key
->UnicodeChar
<= 'z') {
1635 Key
->UnicodeChar
= (UINT8
) (Key
->UnicodeChar
- 'a' + 1);
1636 } else if (Key
->UnicodeChar
>= 'A' && Key
->UnicodeChar
<= 'Z') {
1637 Key
->UnicodeChar
= (UINT8
) (Key
->UnicodeChar
- 'A' + 1);
1641 if (KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_NUM_LOCK
) {
1643 // For key affected by NumLock, if NumLock is on and Shift is not pressed, then it means
1644 // normal key, instead of original control key. So the ScanCode should be cleaned.
1645 // Otherwise, it means control key, so preserve the EFI Scan Code and clear the unicode keycode.
1647 if ((UsbKeyboardDevice
->NumLockOn
) && (!(UsbKeyboardDevice
->ShiftOn
))) {
1648 Key
->ScanCode
= SCAN_NULL
;
1650 Key
->UnicodeChar
= 0x00;
1655 // Translate Unicode 0x1B (ESC) to EFI Scan Code
1657 if (Key
->UnicodeChar
== 0x1B && Key
->ScanCode
== SCAN_NULL
) {
1658 Key
->ScanCode
= SCAN_ESC
;
1659 Key
->UnicodeChar
= 0x00;
1663 // Not valid for key without both unicode key code and EFI Scan Code.
1665 if (Key
->UnicodeChar
== 0 && Key
->ScanCode
== SCAN_NULL
) {
1666 return EFI_NOT_READY
;
1671 // Save Shift/Toggle state
1673 if (UsbKeyboardDevice
->LeftCtrlOn
) {
1674 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_LEFT_CONTROL_PRESSED
;
1676 if (UsbKeyboardDevice
->RightCtrlOn
) {
1677 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_RIGHT_CONTROL_PRESSED
;
1679 if (UsbKeyboardDevice
->LeftAltOn
) {
1680 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_LEFT_ALT_PRESSED
;
1682 if (UsbKeyboardDevice
->RightAltOn
) {
1683 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_RIGHT_ALT_PRESSED
;
1685 if (UsbKeyboardDevice
->LeftShiftOn
) {
1686 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_LEFT_SHIFT_PRESSED
;
1688 if (UsbKeyboardDevice
->RightShiftOn
) {
1689 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_RIGHT_SHIFT_PRESSED
;
1691 if (UsbKeyboardDevice
->LeftLogoOn
) {
1692 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_LEFT_LOGO_PRESSED
;
1694 if (UsbKeyboardDevice
->RightLogoOn
) {
1695 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_RIGHT_LOGO_PRESSED
;
1697 if (UsbKeyboardDevice
->MenuKeyOn
) {
1698 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_MENU_KEY_PRESSED
;
1700 if (UsbKeyboardDevice
->SysReqOn
) {
1701 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_SYS_REQ_PRESSED
;
1704 if (UsbKeyboardDevice
->ScrollOn
) {
1705 UsbKeyboardDevice
->KeyState
.KeyToggleState
|= EFI_SCROLL_LOCK_ACTIVE
;
1707 if (UsbKeyboardDevice
->NumLockOn
) {
1708 UsbKeyboardDevice
->KeyState
.KeyToggleState
|= EFI_NUM_LOCK_ACTIVE
;
1710 if (UsbKeyboardDevice
->CapsOn
) {
1711 UsbKeyboardDevice
->KeyState
.KeyToggleState
|= EFI_CAPS_LOCK_ACTIVE
;
1720 Resets USB keyboard buffer.
1722 @param KeyboardBuffer Points to the USB keyboard buffer.
1728 OUT USB_KB_BUFFER
*KeyboardBuffer
1731 ZeroMem (KeyboardBuffer
, sizeof (USB_KB_BUFFER
));
1733 KeyboardBuffer
->BufferHead
= KeyboardBuffer
->BufferTail
;
1738 Check whether USB keyboard buffer is empty.
1740 @param KeyboardBuffer USB keyboard buffer
1742 @retval TRUE Keyboard buffer is empty.
1743 @retval FALSE Keyboard buffer is not empty.
1748 IsUSBKeyboardBufferEmpty (
1749 IN USB_KB_BUFFER
*KeyboardBuffer
1753 // Meet FIFO empty condition
1755 return (BOOLEAN
) (KeyboardBuffer
->BufferHead
== KeyboardBuffer
->BufferTail
);
1760 Check whether USB keyboard buffer is full.
1762 @param KeyboardBuffer USB keyboard buffer
1764 @retval TRUE Keyboard buffer is full.
1765 @retval FALSE Keyboard buffer is not full.
1770 IsUSBKeyboardBufferFull (
1771 IN USB_KB_BUFFER
*KeyboardBuffer
1774 return (BOOLEAN
)(((KeyboardBuffer
->BufferTail
+ 1) % (MAX_KEY_ALLOWED
+ 1)) == KeyboardBuffer
->BufferHead
);
1779 Inserts a keycode into keyboard buffer.
1781 @param KeyboardBuffer Points to the USB keyboard buffer.
1782 @param Key Keycode to insert.
1783 @param Down TRUE means key is pressed.
1784 FALSE means key is released.
1790 IN OUT USB_KB_BUFFER
*KeyboardBuffer
,
1798 // If keyboard buffer is full, throw the
1799 // first key out of the keyboard buffer.
1801 if (IsUSBKeyboardBufferFull (KeyboardBuffer
)) {
1802 RemoveKeyCode (KeyboardBuffer
, &UsbKey
);
1805 KeyboardBuffer
->Buffer
[KeyboardBuffer
->BufferTail
].KeyCode
= Key
;
1806 KeyboardBuffer
->Buffer
[KeyboardBuffer
->BufferTail
].Down
= Down
;
1809 // Adjust the tail pointer of the FIFO keyboard buffer.
1811 KeyboardBuffer
->BufferTail
= (UINT8
) ((KeyboardBuffer
->BufferTail
+ 1) % (MAX_KEY_ALLOWED
+ 1));
1816 Remove a keycode from keyboard buffer and return it.
1818 @param KeyboardBuffer Points to the USB keyboard buffer.
1819 @param UsbKey Points to the buffer that contains keycode for output.
1821 @retval EFI_SUCCESS Keycode successfully removed from keyboard buffer.
1822 @retval EFI_DEVICE_ERROR Keyboard buffer is empty.
1828 IN OUT USB_KB_BUFFER
*KeyboardBuffer
,
1832 if (IsUSBKeyboardBufferEmpty (KeyboardBuffer
)) {
1833 return EFI_DEVICE_ERROR
;
1836 UsbKey
->KeyCode
= KeyboardBuffer
->Buffer
[KeyboardBuffer
->BufferHead
].KeyCode
;
1837 UsbKey
->Down
= KeyboardBuffer
->Buffer
[KeyboardBuffer
->BufferHead
].Down
;
1840 // Adjust the head pointer of the FIFO keyboard buffer.
1842 KeyboardBuffer
->BufferHead
= (UINT8
) ((KeyboardBuffer
->BufferHead
+ 1) % (MAX_KEY_ALLOWED
+ 1));
1849 Sets USB keyboard LED state.
1851 @param UsbKeyboardDevice The USB_KB_DEV instance.
1857 IN USB_KB_DEV
*UsbKeyboardDevice
1864 // Set each field in Led map.
1866 Led
.NumLock
= (UINT8
) ((UsbKeyboardDevice
->NumLockOn
) ? 1 : 0);
1867 Led
.CapsLock
= (UINT8
) ((UsbKeyboardDevice
->CapsOn
) ? 1 : 0);
1868 Led
.ScrollLock
= (UINT8
) ((UsbKeyboardDevice
->ScrollOn
) ? 1 : 0);
1873 // Call Set_Report Request to lighten the LED.
1875 UsbSetReportRequest (
1876 UsbKeyboardDevice
->UsbIo
,
1877 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
1887 Handler for Repeat Key event.
1889 This function is the handler for Repeat Key event triggered
1891 After a repeatable key is pressed, the event would be triggered
1892 with interval of USBKBD_REPEAT_DELAY. Once the event is triggered,
1893 following trigger will come with interval of USBKBD_REPEAT_RATE.
1895 @param Event The Repeat Key event.
1896 @param Context Points to the USB_KB_DEV instance.
1901 USBKeyboardRepeatHandler (
1906 USB_KB_DEV
*UsbKeyboardDevice
;
1908 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1911 // Do nothing when there is no repeat key.
1913 if (UsbKeyboardDevice
->RepeatKey
!= 0) {
1915 // Inserts the repeat key into keyboard buffer,
1918 &(UsbKeyboardDevice
->KeyboardBuffer
),
1919 UsbKeyboardDevice
->RepeatKey
,
1924 // Set repeate rate for next repeat key generation.
1927 UsbKeyboardDevice
->RepeatTimer
,
1936 Handler for Delayed Recovery event.
1938 This function is the handler for Delayed Recovery event triggered
1940 After a device error occurs, the event would be triggered
1941 with interval of EFI_USB_INTERRUPT_DELAY. EFI_USB_INTERRUPT_DELAY
1942 is defined in USB standard for error handling.
1944 @param Event The Delayed Recovery event.
1945 @param Context Points to the USB_KB_DEV instance.
1950 USBKeyboardRecoveryHandler (
1956 USB_KB_DEV
*UsbKeyboardDevice
;
1957 EFI_USB_IO_PROTOCOL
*UsbIo
;
1960 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1962 UsbIo
= UsbKeyboardDevice
->UsbIo
;
1964 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
1967 // Re-submit Asynchronous Interrupt Transfer for recovery.
1969 UsbIo
->UsbAsyncInterruptTransfer (
1971 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1973 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,