2 Helper functions for USB Keyboard Driver.
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
11 USB_KEYBOARD_LAYOUT_PACK_BIN mUsbKeyboardLayoutBin
= {
12 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN
), // Binary size
15 // EFI_HII_PACKAGE_HEADER
18 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN
) - sizeof (UINT32
),
19 EFI_HII_PACKAGE_KEYBOARD_LAYOUT
22 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN
) - sizeof (UINT32
) - sizeof (EFI_HII_PACKAGE_HEADER
) - sizeof (UINT16
), // LayoutLength
23 USB_KEYBOARD_LAYOUT_KEY_GUID
, // KeyGuid
24 sizeof (UINT16
) + sizeof (EFI_GUID
) + sizeof (UINT32
) + sizeof (UINT8
) + (USB_KEYBOARD_KEY_COUNT
* sizeof (EFI_KEY_DESCRIPTOR
)), // LayoutDescriptorStringOffset
25 USB_KEYBOARD_KEY_COUNT
, // DescriptorCount
28 // EFI_KEY_DESCRIPTOR (total number is USB_KEYBOARD_KEY_COUNT)
30 {EfiKeyC1
, 'a', 'A', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
31 {EfiKeyB5
, 'b', 'B', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
32 {EfiKeyB3
, 'c', 'C', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
33 {EfiKeyC3
, 'd', 'D', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
34 {EfiKeyD3
, 'e', 'E', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
35 {EfiKeyC4
, 'f', 'F', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
36 {EfiKeyC5
, 'g', 'G', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
37 {EfiKeyC6
, 'h', 'H', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
38 {EfiKeyD8
, 'i', 'I', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
39 {EfiKeyC7
, 'j', 'J', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
40 {EfiKeyC8
, 'k', 'K', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
41 {EfiKeyC9
, 'l', 'L', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
42 {EfiKeyB7
, 'm', 'M', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
43 {EfiKeyB6
, 'n', 'N', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
44 {EfiKeyD9
, 'o', 'O', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
45 {EfiKeyD10
, 'p', 'P', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
46 {EfiKeyD1
, 'q', 'Q', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
47 {EfiKeyD4
, 'r', 'R', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
48 {EfiKeyC2
, 's', 'S', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
49 {EfiKeyD5
, 't', 'T', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
50 {EfiKeyD7
, 'u', 'U', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
51 {EfiKeyB4
, 'v', 'V', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
52 {EfiKeyD2
, 'w', 'W', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
53 {EfiKeyB2
, 'x', 'X', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
54 {EfiKeyD6
, 'y', 'Y', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
55 {EfiKeyB1
, 'z', 'Z', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
56 {EfiKeyE1
, '1', '!', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
57 {EfiKeyE2
, '2', '@', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
58 {EfiKeyE3
, '3', '#', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
59 {EfiKeyE4
, '4', '$', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
60 {EfiKeyE5
, '5', '%', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
61 {EfiKeyE6
, '6', '^', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
62 {EfiKeyE7
, '7', '&', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
63 {EfiKeyE8
, '8', '*', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
64 {EfiKeyE9
, '9', '(', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
65 {EfiKeyE10
, '0', ')', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
66 {EfiKeyEnter
, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER
, 0},
67 {EfiKeyEsc
, 0x1b, 0x1b, 0, 0, EFI_NULL_MODIFIER
, 0},
68 {EfiKeyBackSpace
, 0x08, 0x08, 0, 0, EFI_NULL_MODIFIER
, 0},
69 {EfiKeyTab
, 0x09, 0x09, 0, 0, EFI_NULL_MODIFIER
, 0},
70 {EfiKeySpaceBar
, ' ', ' ', 0, 0, EFI_NULL_MODIFIER
, 0},
71 {EfiKeyE11
, '-', '_', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
72 {EfiKeyE12
, '=', '+', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
73 {EfiKeyD11
, '[', '{', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
74 {EfiKeyD12
, ']', '}', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
75 {EfiKeyD13
, '\\', '|', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
76 {EfiKeyC12
, '\\', '|', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
77 {EfiKeyC10
, ';', ':', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
78 {EfiKeyC11
, '\'', '"', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
79 {EfiKeyE0
, '`', '~', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
80 {EfiKeyB8
, ',', '<', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
81 {EfiKeyB9
, '.', '>', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
82 {EfiKeyB10
, '/', '?', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
83 {EfiKeyCapsLock
, 0x00, 0x00, 0, 0, EFI_CAPS_LOCK_MODIFIER
, 0},
84 {EfiKeyF1
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ONE_MODIFIER
, 0},
85 {EfiKeyF2
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWO_MODIFIER
, 0},
86 {EfiKeyF3
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_THREE_MODIFIER
, 0},
87 {EfiKeyF4
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FOUR_MODIFIER
, 0},
88 {EfiKeyF5
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FIVE_MODIFIER
, 0},
89 {EfiKeyF6
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SIX_MODIFIER
, 0},
90 {EfiKeyF7
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SEVEN_MODIFIER
, 0},
91 {EfiKeyF8
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_EIGHT_MODIFIER
, 0},
92 {EfiKeyF9
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_NINE_MODIFIER
, 0},
93 {EfiKeyF10
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TEN_MODIFIER
, 0},
94 {EfiKeyF11
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ELEVEN_MODIFIER
, 0},
95 {EfiKeyF12
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWELVE_MODIFIER
, 0},
96 {EfiKeyPrint
, 0x00, 0x00, 0, 0, EFI_PRINT_MODIFIER
, 0},
97 {EfiKeySLck
, 0x00, 0x00, 0, 0, EFI_SCROLL_LOCK_MODIFIER
, 0},
98 {EfiKeyPause
, 0x00, 0x00, 0, 0, EFI_PAUSE_MODIFIER
, 0},
99 {EfiKeyIns
, 0x00, 0x00, 0, 0, EFI_INSERT_MODIFIER
, 0},
100 {EfiKeyHome
, 0x00, 0x00, 0, 0, EFI_HOME_MODIFIER
, 0},
101 {EfiKeyPgUp
, 0x00, 0x00, 0, 0, EFI_PAGE_UP_MODIFIER
, 0},
102 {EfiKeyDel
, 0x00, 0x00, 0, 0, EFI_DELETE_MODIFIER
, 0},
103 {EfiKeyEnd
, 0x00, 0x00, 0, 0, EFI_END_MODIFIER
, 0},
104 {EfiKeyPgDn
, 0x00, 0x00, 0, 0, EFI_PAGE_DOWN_MODIFIER
, 0},
105 {EfiKeyRightArrow
, 0x00, 0x00, 0, 0, EFI_RIGHT_ARROW_MODIFIER
, 0},
106 {EfiKeyLeftArrow
, 0x00, 0x00, 0, 0, EFI_LEFT_ARROW_MODIFIER
, 0},
107 {EfiKeyDownArrow
, 0x00, 0x00, 0, 0, EFI_DOWN_ARROW_MODIFIER
, 0},
108 {EfiKeyUpArrow
, 0x00, 0x00, 0, 0, EFI_UP_ARROW_MODIFIER
, 0},
109 {EfiKeyNLck
, 0x00, 0x00, 0, 0, EFI_NUM_LOCK_MODIFIER
, 0},
110 {EfiKeySlash
, '/', '/', 0, 0, EFI_NULL_MODIFIER
, 0},
111 {EfiKeyAsterisk
, '*', '*', 0, 0, EFI_NULL_MODIFIER
, 0},
112 {EfiKeyMinus
, '-', '-', 0, 0, EFI_NULL_MODIFIER
, 0},
113 {EfiKeyPlus
, '+', '+', 0, 0, EFI_NULL_MODIFIER
, 0},
114 {EfiKeyEnter
, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER
, 0},
115 {EfiKeyOne
, '1', '1', 0, 0, EFI_END_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
116 {EfiKeyTwo
, '2', '2', 0, 0, EFI_DOWN_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
117 {EfiKeyThree
, '3', '3', 0, 0, EFI_PAGE_DOWN_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
118 {EfiKeyFour
, '4', '4', 0, 0, EFI_LEFT_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
119 {EfiKeyFive
, '5', '5', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
120 {EfiKeySix
, '6', '6', 0, 0, EFI_RIGHT_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
121 {EfiKeySeven
, '7', '7', 0, 0, EFI_HOME_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
122 {EfiKeyEight
, '8', '8', 0, 0, EFI_UP_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
123 {EfiKeyNine
, '9', '9', 0, 0, EFI_PAGE_UP_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
124 {EfiKeyZero
, '0', '0', 0, 0, EFI_INSERT_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
125 {EfiKeyPeriod
, '.', '.', 0, 0, EFI_DELETE_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
126 {EfiKeyA4
, 0x00, 0x00, 0, 0, EFI_MENU_MODIFIER
, 0},
127 {EfiKeyLCtrl
, 0, 0, 0, 0, EFI_LEFT_CONTROL_MODIFIER
, 0},
128 {EfiKeyLShift
, 0, 0, 0, 0, EFI_LEFT_SHIFT_MODIFIER
, 0},
129 {EfiKeyLAlt
, 0, 0, 0, 0, EFI_LEFT_ALT_MODIFIER
, 0},
130 {EfiKeyA0
, 0, 0, 0, 0, EFI_LEFT_LOGO_MODIFIER
, 0},
131 {EfiKeyRCtrl
, 0, 0, 0, 0, EFI_RIGHT_CONTROL_MODIFIER
, 0},
132 {EfiKeyRShift
, 0, 0, 0, 0, EFI_RIGHT_SHIFT_MODIFIER
, 0},
133 {EfiKeyA2
, 0, 0, 0, 0, EFI_RIGHT_ALT_MODIFIER
, 0},
134 {EfiKeyA3
, 0, 0, 0, 0, EFI_RIGHT_LOGO_MODIFIER
, 0},
136 1, // DescriptionCount
137 {'e', 'n', '-', 'U', 'S'}, // RFC4646 language code
139 {'E', 'n', 'g', 'l', 'i', 's', 'h', ' ', 'K', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '\0'}, // DescriptionString[]
143 // EFI_KEY to USB Keycode conversion table
144 // EFI_KEY is defined in UEFI spec.
145 // USB Keycode is defined in USB HID Firmware spec.
147 UINT8 EfiKeyToUsbKeyCodeConvertionTable
[] = {
151 0x2c, // EfiKeySpaceBar
156 0x50, // EfiKeyLeftArrow
157 0x51, // EfiKeyDownArrow
158 0x4F, // EfiKeyRightArrow
160 0x63, // EfiKeyPeriod
162 0xe1, // EfiKeyLShift
174 0xe5, // EfiKeyRShift
175 0x52, // EfiKeyUpArrow
179 0x39, // EfiKeyCapsLock
229 0x2A, // EfiKeyBackSpace
235 0x55, // EfiKeyAsterisk
256 // Keyboard modifier value to EFI Scan Code convertion table
257 // EFI Scan Code and the modifier values are defined in UEFI spec.
259 UINT8 ModifierValueToEfiScanCodeConvertionTable
[] = {
260 SCAN_NULL
, // EFI_NULL_MODIFIER
261 SCAN_NULL
, // EFI_LEFT_CONTROL_MODIFIER
262 SCAN_NULL
, // EFI_RIGHT_CONTROL_MODIFIER
263 SCAN_NULL
, // EFI_LEFT_ALT_MODIFIER
264 SCAN_NULL
, // EFI_RIGHT_ALT_MODIFIER
265 SCAN_NULL
, // EFI_ALT_GR_MODIFIER
266 SCAN_INSERT
, // EFI_INSERT_MODIFIER
267 SCAN_DELETE
, // EFI_DELETE_MODIFIER
268 SCAN_PAGE_DOWN
, // EFI_PAGE_DOWN_MODIFIER
269 SCAN_PAGE_UP
, // EFI_PAGE_UP_MODIFIER
270 SCAN_HOME
, // EFI_HOME_MODIFIER
271 SCAN_END
, // EFI_END_MODIFIER
272 SCAN_NULL
, // EFI_LEFT_SHIFT_MODIFIER
273 SCAN_NULL
, // EFI_RIGHT_SHIFT_MODIFIER
274 SCAN_NULL
, // EFI_CAPS_LOCK_MODIFIER
275 SCAN_NULL
, // EFI_NUM_LOCK_MODIFIER
276 SCAN_LEFT
, // EFI_LEFT_ARROW_MODIFIER
277 SCAN_RIGHT
, // EFI_RIGHT_ARROW_MODIFIER
278 SCAN_DOWN
, // EFI_DOWN_ARROW_MODIFIER
279 SCAN_UP
, // EFI_UP_ARROW_MODIFIER
280 SCAN_NULL
, // EFI_NS_KEY_MODIFIER
281 SCAN_NULL
, // EFI_NS_KEY_DEPENDENCY_MODIFIER
282 SCAN_F1
, // EFI_FUNCTION_KEY_ONE_MODIFIER
283 SCAN_F2
, // EFI_FUNCTION_KEY_TWO_MODIFIER
284 SCAN_F3
, // EFI_FUNCTION_KEY_THREE_MODIFIER
285 SCAN_F4
, // EFI_FUNCTION_KEY_FOUR_MODIFIER
286 SCAN_F5
, // EFI_FUNCTION_KEY_FIVE_MODIFIER
287 SCAN_F6
, // EFI_FUNCTION_KEY_SIX_MODIFIER
288 SCAN_F7
, // EFI_FUNCTION_KEY_SEVEN_MODIFIER
289 SCAN_F8
, // EFI_FUNCTION_KEY_EIGHT_MODIFIER
290 SCAN_F9
, // EFI_FUNCTION_KEY_NINE_MODIFIER
291 SCAN_F10
, // EFI_FUNCTION_KEY_TEN_MODIFIER
292 SCAN_F11
, // EFI_FUNCTION_KEY_ELEVEN_MODIFIER
293 SCAN_F12
, // EFI_FUNCTION_KEY_TWELVE_MODIFIER
295 // For Partial Keystroke support
297 SCAN_NULL
, // EFI_PRINT_MODIFIER
298 SCAN_NULL
, // EFI_SYS_REQUEST_MODIFIER
299 SCAN_NULL
, // EFI_SCROLL_LOCK_MODIFIER
300 SCAN_PAUSE
, // EFI_PAUSE_MODIFIER
301 SCAN_NULL
, // EFI_BREAK_MODIFIER
302 SCAN_NULL
, // EFI_LEFT_LOGO_MODIFIER
303 SCAN_NULL
, // EFI_RIGHT_LOGO_MODIFER
304 SCAN_NULL
, // EFI_MENU_MODIFER
308 Initialize Key Convention Table by using default keyboard layout.
310 @param UsbKeyboardDevice The USB_KB_DEV instance.
312 @retval EFI_SUCCESS The default keyboard layout was installed successfully
313 @retval Others Failure to install default keyboard layout.
316 InstallDefaultKeyboardLayout (
317 IN OUT USB_KB_DEV
*UsbKeyboardDevice
321 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
322 EFI_HII_HANDLE HiiHandle
;
325 // Locate Hii database protocol
327 Status
= gBS
->LocateProtocol (
328 &gEfiHiiDatabaseProtocolGuid
,
330 (VOID
**) &HiiDatabase
332 if (EFI_ERROR (Status
)) {
337 // Install Keyboard Layout package to HII database
339 HiiHandle
= HiiAddPackages (
340 &gUsbKeyboardLayoutPackageGuid
,
341 UsbKeyboardDevice
->ControllerHandle
,
342 &mUsbKeyboardLayoutBin
,
345 if (HiiHandle
== NULL
) {
346 return EFI_OUT_OF_RESOURCES
;
350 // Set current keyboard layout
352 Status
= HiiDatabase
->SetKeyboardLayout (HiiDatabase
, &gUsbKeyboardLayoutKeyGuid
);
359 Uses USB I/O to check whether the device is a USB keyboard device.
361 @param UsbIo Pointer to a USB I/O protocol instance.
363 @retval TRUE Device is a USB keyboard device.
364 @retval FALSE Device is a not USB keyboard device.
369 IN EFI_USB_IO_PROTOCOL
*UsbIo
373 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
376 // Get the default interface descriptor
378 Status
= UsbIo
->UsbGetInterfaceDescriptor (
383 if (EFI_ERROR (Status
)) {
387 if (InterfaceDescriptor
.InterfaceClass
== CLASS_HID
&&
388 InterfaceDescriptor
.InterfaceSubClass
== SUBCLASS_BOOT
&&
389 InterfaceDescriptor
.InterfaceProtocol
== PROTOCOL_KEYBOARD
398 Get current keyboard layout from HII database.
400 @return Pointer to HII Keyboard Layout.
401 NULL means failure occurred while trying to get keyboard layout.
404 EFI_HII_KEYBOARD_LAYOUT
*
405 GetCurrentKeyboardLayout (
410 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
411 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
415 // Locate HII Database Protocol
417 Status
= gBS
->LocateProtocol (
418 &gEfiHiiDatabaseProtocolGuid
,
420 (VOID
**) &HiiDatabase
422 if (EFI_ERROR (Status
)) {
427 // Get current keyboard layout from HII database
430 KeyboardLayout
= NULL
;
431 Status
= HiiDatabase
->GetKeyboardLayout (
437 if (Status
== EFI_BUFFER_TOO_SMALL
) {
438 KeyboardLayout
= AllocatePool (Length
);
439 ASSERT (KeyboardLayout
!= NULL
);
441 Status
= HiiDatabase
->GetKeyboardLayout (
447 if (EFI_ERROR (Status
)) {
448 FreePool (KeyboardLayout
);
449 KeyboardLayout
= NULL
;
453 return KeyboardLayout
;
457 Find Key Descriptor in Key Convertion Table given its USB keycode.
459 @param UsbKeyboardDevice The USB_KB_DEV instance.
460 @param KeyCode USB Keycode.
462 @return The Key Descriptor in Key Convertion Table.
463 NULL means not found.
468 IN USB_KB_DEV
*UsbKeyboardDevice
,
475 // Make sure KeyCode is in the range of [0x4, 0x65] or [0xe0, 0xe7]
477 if ((!USBKBD_VALID_KEYCODE (KeyCode
)) || ((KeyCode
> 0x65) && (KeyCode
< 0xe0)) || (KeyCode
> 0xe7)) {
482 // Calculate the index of Key Descriptor in Key Convertion Table
484 if (KeyCode
<= 0x65) {
485 Index
= (UINT8
) (KeyCode
- 4);
487 Index
= (UINT8
) (KeyCode
- 0xe0 + NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE
);
490 return &UsbKeyboardDevice
->KeyConvertionTable
[Index
];
494 Find Non-Spacing key for given Key descriptor.
496 @param UsbKeyboardDevice The USB_KB_DEV instance.
497 @param KeyDescriptor Key descriptor.
499 @return The Non-Spacing key corresponding to KeyDescriptor
500 NULL means not found.
505 IN USB_KB_DEV
*UsbKeyboardDevice
,
506 IN EFI_KEY_DESCRIPTOR
*KeyDescriptor
510 LIST_ENTRY
*NsKeyList
;
511 USB_NS_KEY
*UsbNsKey
;
513 NsKeyList
= &UsbKeyboardDevice
->NsKeyList
;
514 Link
= GetFirstNode (NsKeyList
);
515 while (!IsNull (NsKeyList
, Link
)) {
516 UsbNsKey
= USB_NS_KEY_FORM_FROM_LINK (Link
);
518 if (UsbNsKey
->NsKey
[0].Key
== KeyDescriptor
->Key
) {
522 Link
= GetNextNode (NsKeyList
, Link
);
529 Find physical key definition for a given key descriptor.
531 For a specified non-spacing key, there are a list of physical
532 keys following it. This function traverses the list of
533 physical keys and tries to find the physical key matching
536 @param UsbNsKey The non-spacing key information.
537 @param KeyDescriptor The key descriptor.
539 @return The physical key definition.
540 If no physical key is found, parameter KeyDescriptor is returned.
545 IN USB_NS_KEY
*UsbNsKey
,
546 IN EFI_KEY_DESCRIPTOR
*KeyDescriptor
550 EFI_KEY_DESCRIPTOR
*PhysicalKey
;
552 PhysicalKey
= &UsbNsKey
->NsKey
[1];
553 for (Index
= 0; Index
< UsbNsKey
->KeyCount
; Index
++) {
554 if (KeyDescriptor
->Key
== PhysicalKey
->Key
) {
562 // No children definition matched, return original key
564 return KeyDescriptor
;
568 The notification function for EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID.
570 This function is registered to event of EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
571 group type, which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
572 It tries to get curent keyboard layout from HII database.
574 @param Event Event being signaled.
575 @param Context Points to USB_KB_DEV instance.
580 SetKeyboardLayoutEvent (
585 USB_KB_DEV
*UsbKeyboardDevice
;
586 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
587 EFI_KEY_DESCRIPTOR TempKey
;
588 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
589 EFI_KEY_DESCRIPTOR
*TableEntry
;
590 EFI_KEY_DESCRIPTOR
*NsKey
;
591 USB_NS_KEY
*UsbNsKey
;
597 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
598 if (UsbKeyboardDevice
->Signature
!= USB_KB_DEV_SIGNATURE
) {
603 // Try to get current keyboard layout from HII database
605 KeyboardLayout
= GetCurrentKeyboardLayout ();
606 if (KeyboardLayout
== NULL
) {
611 // Re-allocate resource for KeyConvertionTable
613 ReleaseKeyboardLayoutResources (UsbKeyboardDevice
);
614 UsbKeyboardDevice
->KeyConvertionTable
= AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE
) * sizeof (EFI_KEY_DESCRIPTOR
));
615 ASSERT (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
);
618 // Traverse the list of key descriptors following the header of EFI_HII_KEYBOARD_LAYOUT
620 KeyDescriptor
= (EFI_KEY_DESCRIPTOR
*) (((UINT8
*) KeyboardLayout
) + sizeof (EFI_HII_KEYBOARD_LAYOUT
));
621 for (Index
= 0; Index
< KeyboardLayout
->DescriptorCount
; Index
++) {
623 // Copy from HII keyboard layout package binary for alignment
625 CopyMem (&TempKey
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
628 // Fill the key into KeyConvertionTable, whose index is calculated from USB keycode.
630 KeyCode
= EfiKeyToUsbKeyCodeConvertionTable
[(UINT8
) (TempKey
.Key
)];
631 TableEntry
= GetKeyDescriptor (UsbKeyboardDevice
, KeyCode
);
632 if (TableEntry
== NULL
) {
633 ReleaseKeyboardLayoutResources (UsbKeyboardDevice
);
634 FreePool (KeyboardLayout
);
637 CopyMem (TableEntry
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
640 // For non-spacing key, create the list with a non-spacing key followed by physical keys.
642 if (TempKey
.Modifier
== EFI_NS_KEY_MODIFIER
) {
643 UsbNsKey
= AllocateZeroPool (sizeof (USB_NS_KEY
));
644 ASSERT (UsbNsKey
!= NULL
);
647 // Search for sequential children physical key definitions
650 NsKey
= KeyDescriptor
+ 1;
651 for (Index2
= (UINT8
) Index
+ 1; Index2
< KeyboardLayout
->DescriptorCount
; Index2
++) {
652 CopyMem (&TempKey
, NsKey
, sizeof (EFI_KEY_DESCRIPTOR
));
653 if (TempKey
.Modifier
== EFI_NS_KEY_DEPENDENCY_MODIFIER
) {
661 UsbNsKey
->Signature
= USB_NS_KEY_SIGNATURE
;
662 UsbNsKey
->KeyCount
= KeyCount
;
663 UsbNsKey
->NsKey
= AllocateCopyPool (
664 (KeyCount
+ 1) * sizeof (EFI_KEY_DESCRIPTOR
),
667 InsertTailList (&UsbKeyboardDevice
->NsKeyList
, &UsbNsKey
->Link
);
670 // Skip over the child physical keys
673 KeyDescriptor
+= KeyCount
;
680 // There are two EfiKeyEnter, duplicate its key descriptor
682 TableEntry
= GetKeyDescriptor (UsbKeyboardDevice
, 0x58);
683 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, 0x28);
684 CopyMem (TableEntry
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
686 FreePool (KeyboardLayout
);
690 Destroy resources for keyboard layout.
692 @param UsbKeyboardDevice The USB_KB_DEV instance.
696 ReleaseKeyboardLayoutResources (
697 IN OUT USB_KB_DEV
*UsbKeyboardDevice
700 USB_NS_KEY
*UsbNsKey
;
703 if (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
) {
704 FreePool (UsbKeyboardDevice
->KeyConvertionTable
);
706 UsbKeyboardDevice
->KeyConvertionTable
= NULL
;
708 while (!IsListEmpty (&UsbKeyboardDevice
->NsKeyList
)) {
709 Link
= GetFirstNode (&UsbKeyboardDevice
->NsKeyList
);
710 UsbNsKey
= USB_NS_KEY_FORM_FROM_LINK (Link
);
711 RemoveEntryList (&UsbNsKey
->Link
);
713 FreePool (UsbNsKey
->NsKey
);
719 Initialize USB keyboard layout.
721 This function initializes Key Convertion Table for the USB keyboard device.
722 It first tries to retrieve layout from HII database. If failed and default
723 layout is enabled, then it just uses the default layout.
725 @param UsbKeyboardDevice The USB_KB_DEV instance.
727 @retval EFI_SUCCESS Initialization succeeded.
728 @retval EFI_NOT_READY Keyboard layout cannot be retrieve from HII
729 database, and default layout is disabled.
730 @retval Other Fail to register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group.
735 OUT USB_KB_DEV
*UsbKeyboardDevice
738 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
741 UsbKeyboardDevice
->KeyConvertionTable
= AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE
) * sizeof (EFI_KEY_DESCRIPTOR
));
742 ASSERT (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
);
744 InitializeListHead (&UsbKeyboardDevice
->NsKeyList
);
745 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
746 UsbKeyboardDevice
->KeyboardLayoutEvent
= NULL
;
749 // Register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group,
750 // which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
752 Status
= gBS
->CreateEventEx (
755 SetKeyboardLayoutEvent
,
757 &gEfiHiiKeyBoardLayoutGuid
,
758 &UsbKeyboardDevice
->KeyboardLayoutEvent
760 if (EFI_ERROR (Status
)) {
764 KeyboardLayout
= GetCurrentKeyboardLayout ();
765 if (KeyboardLayout
!= NULL
) {
767 // If current keyboard layout is successfully retrieved from HII database,
768 // force to initialize the keyboard layout.
770 gBS
->SignalEvent (UsbKeyboardDevice
->KeyboardLayoutEvent
);
772 if (FeaturePcdGet (PcdDisableDefaultKeyboardLayoutInUsbKbDriver
)) {
774 // If no keyboard layout can be retrieved from HII database, and default layout
775 // is disabled, then return EFI_NOT_READY.
777 return EFI_NOT_READY
;
780 // If no keyboard layout can be retrieved from HII database, and default layout
781 // is enabled, then load the default keyboard layout.
783 InstallDefaultKeyboardLayout (UsbKeyboardDevice
);
791 Initialize USB keyboard device and all private data structures.
793 @param UsbKeyboardDevice The USB_KB_DEV instance.
795 @retval EFI_SUCCESS Initialization is successful.
796 @retval EFI_DEVICE_ERROR Keyboard initialization failed.
801 IN OUT USB_KB_DEV
*UsbKeyboardDevice
807 UINT32 TransferResult
;
809 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
811 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_KEYBOARD_PC_SELF_TEST
),
812 UsbKeyboardDevice
->DevicePath
815 InitQueue (&UsbKeyboardDevice
->UsbKeyQueue
, sizeof (USB_KEY
));
816 InitQueue (&UsbKeyboardDevice
->EfiKeyQueue
, sizeof (EFI_KEY_DATA
));
817 InitQueue (&UsbKeyboardDevice
->EfiKeyQueueForNotify
, sizeof (EFI_KEY_DATA
));
820 // Use the config out of the descriptor
821 // Assumed the first config is the correct one and this is not always the case
823 Status
= UsbGetConfiguration (
824 UsbKeyboardDevice
->UsbIo
,
828 if (EFI_ERROR (Status
)) {
831 // Uses default configuration to configure the USB Keyboard device.
833 Status
= UsbSetConfiguration (
834 UsbKeyboardDevice
->UsbIo
,
838 if (EFI_ERROR (Status
)) {
840 // If configuration could not be set here, it means
841 // the keyboard interface has some errors and could
842 // not be initialized
844 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
845 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
846 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_INTERFACE_ERROR
),
847 UsbKeyboardDevice
->DevicePath
850 return EFI_DEVICE_ERROR
;
854 UsbGetProtocolRequest (
855 UsbKeyboardDevice
->UsbIo
,
856 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
860 // Set boot protocol for the USB Keyboard.
861 // This driver only supports boot protocol.
863 if (Protocol
!= BOOT_PROTOCOL
) {
864 UsbSetProtocolRequest (
865 UsbKeyboardDevice
->UsbIo
,
866 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
871 UsbKeyboardDevice
->CtrlOn
= FALSE
;
872 UsbKeyboardDevice
->AltOn
= FALSE
;
873 UsbKeyboardDevice
->ShiftOn
= FALSE
;
874 UsbKeyboardDevice
->NumLockOn
= FALSE
;
875 UsbKeyboardDevice
->CapsOn
= FALSE
;
876 UsbKeyboardDevice
->ScrollOn
= FALSE
;
878 UsbKeyboardDevice
->LeftCtrlOn
= FALSE
;
879 UsbKeyboardDevice
->LeftAltOn
= FALSE
;
880 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
881 UsbKeyboardDevice
->LeftLogoOn
= FALSE
;
882 UsbKeyboardDevice
->RightCtrlOn
= FALSE
;
883 UsbKeyboardDevice
->RightAltOn
= FALSE
;
884 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
885 UsbKeyboardDevice
->RightLogoOn
= FALSE
;
886 UsbKeyboardDevice
->MenuKeyOn
= FALSE
;
887 UsbKeyboardDevice
->SysReqOn
= FALSE
;
889 UsbKeyboardDevice
->AltGrOn
= FALSE
;
891 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
894 // Sync the initial state of lights on keyboard.
896 SetKeyLED (UsbKeyboardDevice
);
898 ZeroMem (UsbKeyboardDevice
->LastKeyCodeArray
, sizeof (UINT8
) * 8);
901 // Create event for repeat keys' generation.
903 if (UsbKeyboardDevice
->RepeatTimer
!= NULL
) {
904 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
905 UsbKeyboardDevice
->RepeatTimer
= NULL
;
909 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
911 USBKeyboardRepeatHandler
,
913 &UsbKeyboardDevice
->RepeatTimer
917 // Create event for delayed recovery, which deals with device error.
919 if (UsbKeyboardDevice
->DelayedRecoveryEvent
!= NULL
) {
920 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
921 UsbKeyboardDevice
->DelayedRecoveryEvent
= NULL
;
925 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
927 USBKeyboardRecoveryHandler
,
929 &UsbKeyboardDevice
->DelayedRecoveryEvent
937 Handler function for USB keyboard's asynchronous interrupt transfer.
939 This function is the handler function for USB keyboard's asynchronous interrupt transfer
940 to manage the keyboard. It parses the USB keyboard input report, and inserts data to
941 keyboard buffer according to state of modifer keys and normal keys. Timer for repeat key
942 is also set accordingly.
944 @param Data A pointer to a buffer that is filled with key data which is
945 retrieved via asynchronous interrupt transfer.
946 @param DataLength Indicates the size of the data buffer.
947 @param Context Pointing to USB_KB_DEV instance.
948 @param Result Indicates the result of the asynchronous interrupt transfer.
950 @retval EFI_SUCCESS Asynchronous interrupt transfer is handled successfully.
951 @retval EFI_DEVICE_ERROR Hardware error occurs.
963 USB_KB_DEV
*UsbKeyboardDevice
;
964 EFI_USB_IO_PROTOCOL
*UsbIo
;
965 UINT8
*CurKeyCodeBuffer
;
966 UINT8
*OldKeyCodeBuffer
;
967 UINT8 CurModifierMap
;
968 UINT8 OldModifierMap
;
977 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
979 ASSERT (Context
!= NULL
);
982 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
983 UsbIo
= UsbKeyboardDevice
->UsbIo
;
986 // Analyzes Result and performs corresponding action.
988 if (Result
!= EFI_USB_NOERROR
) {
990 // Some errors happen during the process
992 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
993 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
994 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_INPUT_ERROR
),
995 UsbKeyboardDevice
->DevicePath
999 // Stop the repeat key generation if any
1001 UsbKeyboardDevice
->RepeatKey
= 0;
1004 UsbKeyboardDevice
->RepeatTimer
,
1009 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
1010 UsbClearEndpointHalt (
1012 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1018 // Delete & Submit this interrupt again
1019 // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt.
1021 UsbIo
->UsbAsyncInterruptTransfer (
1023 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1031 // EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling.
1034 UsbKeyboardDevice
->DelayedRecoveryEvent
,
1036 EFI_USB_INTERRUPT_DELAY
1039 return EFI_DEVICE_ERROR
;
1043 // If no error and no data, just return EFI_SUCCESS.
1045 if (DataLength
== 0 || Data
== NULL
) {
1050 // Following code checks current keyboard input report against old key code buffer.
1051 // According to USB HID Firmware Specification, the report consists of 8 bytes.
1052 // Byte 0 is map of Modifier keys.
1053 // Byte 1 is reserved.
1054 // Bytes 2 to 7 are keycodes.
1056 if (DataLength
< 8) {
1057 return EFI_DEVICE_ERROR
;
1060 CurKeyCodeBuffer
= (UINT8
*) Data
;
1061 OldKeyCodeBuffer
= UsbKeyboardDevice
->LastKeyCodeArray
;
1064 // Checks for new key stroke.
1066 for (Index
= 0; Index
< 8; Index
++) {
1067 if (OldKeyCodeBuffer
[Index
] != CurKeyCodeBuffer
[Index
]) {
1073 // If no new key, return EFI_SUCCESS immediately.
1080 // Parse the modifier key, which is the first byte of keyboard input report.
1082 CurModifierMap
= CurKeyCodeBuffer
[0];
1083 OldModifierMap
= OldKeyCodeBuffer
[0];
1086 // Handle modifier key's pressing or releasing situation.
1087 // According to USB HID Firmware spec, Byte 0 uses folloing map of Modifier keys:
1088 // Bit0: Left Control, Keycode: 0xe0
1089 // Bit1: Left Shift, Keycode: 0xe1
1090 // Bit2: Left Alt, Keycode: 0xe2
1091 // Bit3: Left GUI, Keycode: 0xe3
1092 // Bit4: Right Control, Keycode: 0xe4
1093 // Bit5: Right Shift, Keycode: 0xe5
1094 // Bit6: Right Alt, Keycode: 0xe6
1095 // Bit7: Right GUI, Keycode: 0xe7
1097 for (Index
= 0; Index
< 8; Index
++) {
1098 Mask
= (UINT8
) (1 << Index
);
1099 if ((CurModifierMap
& Mask
) != (OldModifierMap
& Mask
)) {
1101 // If current modifier key is up, then CurModifierMap & Mask = 0;
1102 // otherwise it is a non-zero value.
1103 // Insert the changed modifier key into key buffer.
1105 UsbKey
.KeyCode
= (UINT8
) (0xe0 + Index
);
1106 UsbKey
.Down
= (BOOLEAN
) ((CurModifierMap
& Mask
) != 0);
1107 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1112 // Handle normal key's releasing situation
1113 // Bytes 2 to 7 are for normal keycodes
1116 for (Index
= 2; Index
< 8; Index
++) {
1118 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index
])) {
1122 // For any key in old keycode buffer, if it is not in current keycode buffer,
1123 // then it is released. Otherwise, it is not released.
1126 for (Index2
= 2; Index2
< 8; Index2
++) {
1128 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index2
])) {
1132 if (OldKeyCodeBuffer
[Index
] == CurKeyCodeBuffer
[Index2
]) {
1139 UsbKey
.KeyCode
= OldKeyCodeBuffer
[Index
];
1140 UsbKey
.Down
= FALSE
;
1141 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1143 // The original repeat key is released.
1145 if (OldKeyCodeBuffer
[Index
] == UsbKeyboardDevice
->RepeatKey
) {
1146 UsbKeyboardDevice
->RepeatKey
= 0;
1152 // If original repeat key is released, cancel the repeat timer
1154 if (UsbKeyboardDevice
->RepeatKey
== 0) {
1156 UsbKeyboardDevice
->RepeatTimer
,
1163 // Handle normal key's pressing situation
1166 for (Index
= 2; Index
< 8; Index
++) {
1168 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index
])) {
1172 // For any key in current keycode buffer, if it is not in old keycode buffer,
1173 // then it is pressed. Otherwise, it is not pressed.
1176 for (Index2
= 2; Index2
< 8; Index2
++) {
1178 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index2
])) {
1182 if (CurKeyCodeBuffer
[Index
] == OldKeyCodeBuffer
[Index2
]) {
1189 UsbKey
.KeyCode
= CurKeyCodeBuffer
[Index
];
1191 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1194 // Handle repeat key
1196 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, CurKeyCodeBuffer
[Index
]);
1197 if (KeyDescriptor
== NULL
) {
1201 if (KeyDescriptor
->Modifier
== EFI_NUM_LOCK_MODIFIER
|| KeyDescriptor
->Modifier
== EFI_CAPS_LOCK_MODIFIER
) {
1203 // For NumLock or CapsLock pressed, there is no need to handle repeat key for them.
1205 UsbKeyboardDevice
->RepeatKey
= 0;
1208 // Prepare new repeat key, and clear the original one.
1210 NewRepeatKey
= CurKeyCodeBuffer
[Index
];
1211 UsbKeyboardDevice
->RepeatKey
= 0;
1217 // Update LastKeycodeArray buffer in the UsbKeyboardDevice data structure.
1219 for (Index
= 0; Index
< 8; Index
++) {
1220 UsbKeyboardDevice
->LastKeyCodeArray
[Index
] = CurKeyCodeBuffer
[Index
];
1224 // If there is new key pressed, update the RepeatKey value, and set the
1225 // timer to repeate delay timer
1227 if (NewRepeatKey
!= 0) {
1229 // Sets trigger time to "Repeat Delay Time",
1230 // to trigger the repeat timer when the key is hold long
1234 UsbKeyboardDevice
->RepeatTimer
,
1238 UsbKeyboardDevice
->RepeatKey
= NewRepeatKey
;
1246 Retrieves a USB keycode after parsing the raw data in keyboard buffer.
1248 This function parses keyboard buffer. It updates state of modifier key for
1249 USB_KB_DEV instancem, and returns keycode for output.
1251 @param UsbKeyboardDevice The USB_KB_DEV instance.
1252 @param KeyCode Pointer to the USB keycode for output.
1254 @retval EFI_SUCCESS Keycode successfully parsed.
1255 @retval EFI_NOT_READY Keyboard buffer is not ready for a valid keycode
1260 IN OUT USB_KB_DEV
*UsbKeyboardDevice
,
1265 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1269 while (!IsQueueEmpty (&UsbKeyboardDevice
->UsbKeyQueue
)) {
1271 // Pops one raw data off.
1273 Dequeue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1275 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, UsbKey
.KeyCode
);
1276 if (KeyDescriptor
== NULL
) {
1283 switch (KeyDescriptor
->Modifier
) {
1288 case EFI_LEFT_CONTROL_MODIFIER
:
1289 UsbKeyboardDevice
->LeftCtrlOn
= FALSE
;
1290 UsbKeyboardDevice
->CtrlOn
= FALSE
;
1292 case EFI_RIGHT_CONTROL_MODIFIER
:
1293 UsbKeyboardDevice
->RightCtrlOn
= FALSE
;
1294 UsbKeyboardDevice
->CtrlOn
= FALSE
;
1300 case EFI_LEFT_SHIFT_MODIFIER
:
1301 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
1302 UsbKeyboardDevice
->ShiftOn
= FALSE
;
1304 case EFI_RIGHT_SHIFT_MODIFIER
:
1305 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
1306 UsbKeyboardDevice
->ShiftOn
= FALSE
;
1312 case EFI_LEFT_ALT_MODIFIER
:
1313 UsbKeyboardDevice
->LeftAltOn
= FALSE
;
1314 UsbKeyboardDevice
->AltOn
= FALSE
;
1316 case EFI_RIGHT_ALT_MODIFIER
:
1317 UsbKeyboardDevice
->RightAltOn
= FALSE
;
1318 UsbKeyboardDevice
->AltOn
= FALSE
;
1322 // Left Logo release
1324 case EFI_LEFT_LOGO_MODIFIER
:
1325 UsbKeyboardDevice
->LeftLogoOn
= FALSE
;
1329 // Right Logo release
1331 case EFI_RIGHT_LOGO_MODIFIER
:
1332 UsbKeyboardDevice
->RightLogoOn
= FALSE
;
1338 case EFI_MENU_MODIFIER
:
1339 UsbKeyboardDevice
->MenuKeyOn
= FALSE
;
1345 case EFI_PRINT_MODIFIER
:
1346 case EFI_SYS_REQUEST_MODIFIER
:
1347 UsbKeyboardDevice
->SysReqOn
= FALSE
;
1353 case EFI_ALT_GR_MODIFIER
:
1354 UsbKeyboardDevice
->AltGrOn
= FALSE
;
1365 // Analyzes key pressing situation
1367 switch (KeyDescriptor
->Modifier
) {
1372 case EFI_LEFT_CONTROL_MODIFIER
:
1373 UsbKeyboardDevice
->LeftCtrlOn
= TRUE
;
1374 UsbKeyboardDevice
->CtrlOn
= TRUE
;
1376 case EFI_RIGHT_CONTROL_MODIFIER
:
1377 UsbKeyboardDevice
->RightCtrlOn
= TRUE
;
1378 UsbKeyboardDevice
->CtrlOn
= TRUE
;
1384 case EFI_LEFT_SHIFT_MODIFIER
:
1385 UsbKeyboardDevice
->LeftShiftOn
= TRUE
;
1386 UsbKeyboardDevice
->ShiftOn
= TRUE
;
1388 case EFI_RIGHT_SHIFT_MODIFIER
:
1389 UsbKeyboardDevice
->RightShiftOn
= TRUE
;
1390 UsbKeyboardDevice
->ShiftOn
= TRUE
;
1396 case EFI_LEFT_ALT_MODIFIER
:
1397 UsbKeyboardDevice
->LeftAltOn
= TRUE
;
1398 UsbKeyboardDevice
->AltOn
= TRUE
;
1400 case EFI_RIGHT_ALT_MODIFIER
:
1401 UsbKeyboardDevice
->RightAltOn
= TRUE
;
1402 UsbKeyboardDevice
->AltOn
= TRUE
;
1408 case EFI_LEFT_LOGO_MODIFIER
:
1409 UsbKeyboardDevice
->LeftLogoOn
= TRUE
;
1415 case EFI_RIGHT_LOGO_MODIFIER
:
1416 UsbKeyboardDevice
->RightLogoOn
= TRUE
;
1422 case EFI_MENU_MODIFIER
:
1423 UsbKeyboardDevice
->MenuKeyOn
= TRUE
;
1429 case EFI_PRINT_MODIFIER
:
1430 case EFI_SYS_REQUEST_MODIFIER
:
1431 UsbKeyboardDevice
->SysReqOn
= TRUE
;
1437 case EFI_ALT_GR_MODIFIER
:
1438 UsbKeyboardDevice
->AltGrOn
= TRUE
;
1441 case EFI_NUM_LOCK_MODIFIER
:
1445 UsbKeyboardDevice
->NumLockOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->NumLockOn
));
1446 SetKeyLED (UsbKeyboardDevice
);
1449 case EFI_CAPS_LOCK_MODIFIER
:
1453 UsbKeyboardDevice
->CapsOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->CapsOn
));
1454 SetKeyLED (UsbKeyboardDevice
);
1457 case EFI_SCROLL_LOCK_MODIFIER
:
1459 // Toggle ScrollLock
1461 UsbKeyboardDevice
->ScrollOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->ScrollOn
));
1462 SetKeyLED (UsbKeyboardDevice
);
1470 // When encountering Ctrl + Alt + Del, then warm reset.
1472 if (KeyDescriptor
->Modifier
== EFI_DELETE_MODIFIER
) {
1473 if ((UsbKeyboardDevice
->CtrlOn
) && (UsbKeyboardDevice
->AltOn
)) {
1474 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1478 *KeyCode
= UsbKey
.KeyCode
;
1482 return EFI_NOT_READY
;
1486 Initialize the key state.
1488 @param UsbKeyboardDevice The USB_KB_DEV instance.
1489 @param KeyState A pointer to receive the key state information.
1492 InitializeKeyState (
1493 IN USB_KB_DEV
*UsbKeyboardDevice
,
1494 OUT EFI_KEY_STATE
*KeyState
1497 KeyState
->KeyShiftState
= EFI_SHIFT_STATE_VALID
;
1498 KeyState
->KeyToggleState
= EFI_TOGGLE_STATE_VALID
;
1500 if (UsbKeyboardDevice
->LeftCtrlOn
) {
1501 KeyState
->KeyShiftState
|= EFI_LEFT_CONTROL_PRESSED
;
1503 if (UsbKeyboardDevice
->RightCtrlOn
) {
1504 KeyState
->KeyShiftState
|= EFI_RIGHT_CONTROL_PRESSED
;
1506 if (UsbKeyboardDevice
->LeftAltOn
) {
1507 KeyState
->KeyShiftState
|= EFI_LEFT_ALT_PRESSED
;
1509 if (UsbKeyboardDevice
->RightAltOn
) {
1510 KeyState
->KeyShiftState
|= EFI_RIGHT_ALT_PRESSED
;
1512 if (UsbKeyboardDevice
->LeftShiftOn
) {
1513 KeyState
->KeyShiftState
|= EFI_LEFT_SHIFT_PRESSED
;
1515 if (UsbKeyboardDevice
->RightShiftOn
) {
1516 KeyState
->KeyShiftState
|= EFI_RIGHT_SHIFT_PRESSED
;
1518 if (UsbKeyboardDevice
->LeftLogoOn
) {
1519 KeyState
->KeyShiftState
|= EFI_LEFT_LOGO_PRESSED
;
1521 if (UsbKeyboardDevice
->RightLogoOn
) {
1522 KeyState
->KeyShiftState
|= EFI_RIGHT_LOGO_PRESSED
;
1524 if (UsbKeyboardDevice
->MenuKeyOn
) {
1525 KeyState
->KeyShiftState
|= EFI_MENU_KEY_PRESSED
;
1527 if (UsbKeyboardDevice
->SysReqOn
) {
1528 KeyState
->KeyShiftState
|= EFI_SYS_REQ_PRESSED
;
1531 if (UsbKeyboardDevice
->ScrollOn
) {
1532 KeyState
->KeyToggleState
|= EFI_SCROLL_LOCK_ACTIVE
;
1534 if (UsbKeyboardDevice
->NumLockOn
) {
1535 KeyState
->KeyToggleState
|= EFI_NUM_LOCK_ACTIVE
;
1537 if (UsbKeyboardDevice
->CapsOn
) {
1538 KeyState
->KeyToggleState
|= EFI_CAPS_LOCK_ACTIVE
;
1540 if (UsbKeyboardDevice
->IsSupportPartialKey
) {
1541 KeyState
->KeyToggleState
|= EFI_KEY_STATE_EXPOSED
;
1546 Converts USB Keycode ranging from 0x4 to 0x65 to EFI_INPUT_KEY.
1548 @param UsbKeyboardDevice The USB_KB_DEV instance.
1549 @param KeyCode Indicates the key code that will be interpreted.
1550 @param KeyData A pointer to a buffer that is filled in with
1551 the keystroke information for the key that
1554 @retval EFI_SUCCESS Success.
1555 @retval EFI_INVALID_PARAMETER KeyCode is not in the range of 0x4 to 0x65.
1556 @retval EFI_INVALID_PARAMETER Translated EFI_INPUT_KEY has zero for both ScanCode and UnicodeChar.
1557 @retval EFI_NOT_READY KeyCode represents a dead key with EFI_NS_KEY_MODIFIER
1558 @retval EFI_DEVICE_ERROR Keyboard layout is invalid.
1562 UsbKeyCodeToEfiInputKey (
1563 IN USB_KB_DEV
*UsbKeyboardDevice
,
1565 OUT EFI_KEY_DATA
*KeyData
1568 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1570 LIST_ENTRY
*NotifyList
;
1571 KEYBOARD_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
1574 // KeyCode must in the range of [0x4, 0x65] or [0xe0, 0xe7].
1576 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, KeyCode
);
1577 if (KeyDescriptor
== NULL
) {
1578 return EFI_DEVICE_ERROR
;
1581 if (KeyDescriptor
->Modifier
== EFI_NS_KEY_MODIFIER
) {
1583 // If this is a dead key with EFI_NS_KEY_MODIFIER, then record it and return.
1585 UsbKeyboardDevice
->CurrentNsKey
= FindUsbNsKey (UsbKeyboardDevice
, KeyDescriptor
);
1586 return EFI_NOT_READY
;
1589 if (UsbKeyboardDevice
->CurrentNsKey
!= NULL
) {
1591 // If this keystroke follows a non-spacing key, then find the descriptor for corresponding
1594 KeyDescriptor
= FindPhysicalKey (UsbKeyboardDevice
->CurrentNsKey
, KeyDescriptor
);
1595 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
1599 // Make sure modifier of Key Descriptor is in the valid range according to UEFI spec.
1601 if (KeyDescriptor
->Modifier
>= (sizeof (ModifierValueToEfiScanCodeConvertionTable
) / sizeof (UINT8
))) {
1602 return EFI_DEVICE_ERROR
;
1605 KeyData
->Key
.ScanCode
= ModifierValueToEfiScanCodeConvertionTable
[KeyDescriptor
->Modifier
];
1606 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->Unicode
;
1608 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_STANDARD_SHIFT
)!= 0) {
1609 if (UsbKeyboardDevice
->ShiftOn
) {
1610 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->ShiftedUnicode
;
1613 // Need not return associated shift state if a class of printable characters that
1614 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
1616 if ((KeyDescriptor
->Unicode
!= CHAR_NULL
) && (KeyDescriptor
->ShiftedUnicode
!= CHAR_NULL
) &&
1617 (KeyDescriptor
->Unicode
!= KeyDescriptor
->ShiftedUnicode
)) {
1618 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
1619 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
1622 if (UsbKeyboardDevice
->AltGrOn
) {
1623 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->ShiftedAltGrUnicode
;
1629 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->Unicode
;
1631 if (UsbKeyboardDevice
->AltGrOn
) {
1632 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->AltGrUnicode
;
1637 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_CAPS_LOCK
) != 0) {
1638 if (UsbKeyboardDevice
->CapsOn
) {
1639 if (KeyData
->Key
.UnicodeChar
== KeyDescriptor
->Unicode
) {
1640 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->ShiftedUnicode
;
1641 } else if (KeyData
->Key
.UnicodeChar
== KeyDescriptor
->ShiftedUnicode
) {
1642 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->Unicode
;
1647 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_NUM_LOCK
) != 0) {
1649 // For key affected by NumLock, if NumLock is on and Shift is not pressed, then it means
1650 // normal key, instead of original control key. So the ScanCode should be cleaned.
1651 // Otherwise, it means control key, so preserve the EFI Scan Code and clear the unicode keycode.
1653 if ((UsbKeyboardDevice
->NumLockOn
) && (!(UsbKeyboardDevice
->ShiftOn
))) {
1654 KeyData
->Key
.ScanCode
= SCAN_NULL
;
1656 KeyData
->Key
.UnicodeChar
= CHAR_NULL
;
1661 // Translate Unicode 0x1B (ESC) to EFI Scan Code
1663 if (KeyData
->Key
.UnicodeChar
== 0x1B && KeyData
->Key
.ScanCode
== SCAN_NULL
) {
1664 KeyData
->Key
.ScanCode
= SCAN_ESC
;
1665 KeyData
->Key
.UnicodeChar
= CHAR_NULL
;
1669 // Not valid for key without both unicode key code and EFI Scan Code.
1671 if (KeyData
->Key
.UnicodeChar
== 0 && KeyData
->Key
.ScanCode
== SCAN_NULL
) {
1672 if (!UsbKeyboardDevice
->IsSupportPartialKey
) {
1673 return EFI_NOT_READY
;
1678 // Save Shift/Toggle state
1680 InitializeKeyState (UsbKeyboardDevice
, &KeyData
->KeyState
);
1683 // Signal KeyNotify process event if this key pressed matches any key registered.
1685 NotifyList
= &UsbKeyboardDevice
->NotifyList
;
1686 for (Link
= GetFirstNode (NotifyList
); !IsNull (NotifyList
, Link
); Link
= GetNextNode (NotifyList
, Link
)) {
1687 CurrentNotify
= CR (Link
, KEYBOARD_CONSOLE_IN_EX_NOTIFY
, NotifyEntry
, USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
1688 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
1690 // The key notification function needs to run at TPL_CALLBACK
1691 // while current TPL is TPL_NOTIFY. It will be invoked in
1692 // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.
1694 Enqueue (&UsbKeyboardDevice
->EfiKeyQueueForNotify
, KeyData
, sizeof (*KeyData
));
1695 gBS
->SignalEvent (UsbKeyboardDevice
->KeyNotifyProcessEvent
);
1706 @param Queue Points to the queue.
1707 @param ItemSize Size of the single item.
1712 IN OUT USB_SIMPLE_QUEUE
*Queue
,
1718 Queue
->ItemSize
= ItemSize
;
1722 if (Queue
->Buffer
[0] != NULL
) {
1723 FreePool (Queue
->Buffer
[0]);
1726 Queue
->Buffer
[0] = AllocatePool (sizeof (Queue
->Buffer
) / sizeof (Queue
->Buffer
[0]) * ItemSize
);
1727 ASSERT (Queue
->Buffer
[0] != NULL
);
1729 for (Index
= 1; Index
< sizeof (Queue
->Buffer
) / sizeof (Queue
->Buffer
[0]); Index
++) {
1730 Queue
->Buffer
[Index
] = ((UINT8
*) Queue
->Buffer
[Index
- 1]) + ItemSize
;
1737 @param Queue Points to the queue.
1741 IN OUT USB_SIMPLE_QUEUE
*Queue
1744 FreePool (Queue
->Buffer
[0]);
1749 Check whether the queue is empty.
1751 @param Queue Points to the queue.
1753 @retval TRUE Queue is empty.
1754 @retval FALSE Queue is not empty.
1759 IN USB_SIMPLE_QUEUE
*Queue
1763 // Meet FIFO empty condition
1765 return (BOOLEAN
) (Queue
->Head
== Queue
->Tail
);
1770 Check whether the queue is full.
1772 @param Queue Points to the queue.
1774 @retval TRUE Queue is full.
1775 @retval FALSE Queue is not full.
1780 IN USB_SIMPLE_QUEUE
*Queue
1783 return (BOOLEAN
) (((Queue
->Tail
+ 1) % (MAX_KEY_ALLOWED
+ 1)) == Queue
->Head
);
1788 Enqueue the item to the queue.
1790 @param Queue Points to the queue.
1791 @param Item Points to the item to be enqueued.
1792 @param ItemSize Size of the item.
1796 IN OUT USB_SIMPLE_QUEUE
*Queue
,
1801 ASSERT (ItemSize
== Queue
->ItemSize
);
1803 // If keyboard buffer is full, throw the
1804 // first key out of the keyboard buffer.
1806 if (IsQueueFull (Queue
)) {
1807 Queue
->Head
= (Queue
->Head
+ 1) % (MAX_KEY_ALLOWED
+ 1);
1810 CopyMem (Queue
->Buffer
[Queue
->Tail
], Item
, ItemSize
);
1813 // Adjust the tail pointer of the FIFO keyboard buffer.
1815 Queue
->Tail
= (Queue
->Tail
+ 1) % (MAX_KEY_ALLOWED
+ 1);
1820 Dequeue a item from the queue.
1822 @param Queue Points to the queue.
1823 @param Item Receives the item.
1824 @param ItemSize Size of the item.
1826 @retval EFI_SUCCESS Item was successfully dequeued.
1827 @retval EFI_DEVICE_ERROR The queue is empty.
1832 IN OUT USB_SIMPLE_QUEUE
*Queue
,
1837 ASSERT (Queue
->ItemSize
== ItemSize
);
1839 if (IsQueueEmpty (Queue
)) {
1840 return EFI_DEVICE_ERROR
;
1843 CopyMem (Item
, Queue
->Buffer
[Queue
->Head
], ItemSize
);
1846 // Adjust the head pointer of the FIFO keyboard buffer.
1848 Queue
->Head
= (Queue
->Head
+ 1) % (MAX_KEY_ALLOWED
+ 1);
1855 Sets USB keyboard LED state.
1857 @param UsbKeyboardDevice The USB_KB_DEV instance.
1862 IN USB_KB_DEV
*UsbKeyboardDevice
1869 // Set each field in Led map.
1871 Led
.NumLock
= (UINT8
) ((UsbKeyboardDevice
->NumLockOn
) ? 1 : 0);
1872 Led
.CapsLock
= (UINT8
) ((UsbKeyboardDevice
->CapsOn
) ? 1 : 0);
1873 Led
.ScrollLock
= (UINT8
) ((UsbKeyboardDevice
->ScrollOn
) ? 1 : 0);
1878 // Call Set_Report Request to lighten the LED.
1880 UsbSetReportRequest (
1881 UsbKeyboardDevice
->UsbIo
,
1882 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
1892 Handler for Repeat Key event.
1894 This function is the handler for Repeat Key event triggered
1896 After a repeatable key is pressed, the event would be triggered
1897 with interval of USBKBD_REPEAT_DELAY. Once the event is triggered,
1898 following trigger will come with interval of USBKBD_REPEAT_RATE.
1900 @param Event The Repeat Key event.
1901 @param Context Points to the USB_KB_DEV instance.
1906 USBKeyboardRepeatHandler (
1911 USB_KB_DEV
*UsbKeyboardDevice
;
1914 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1917 // Do nothing when there is no repeat key.
1919 if (UsbKeyboardDevice
->RepeatKey
!= 0) {
1921 // Inserts the repeat key into keyboard buffer,
1923 UsbKey
.KeyCode
= UsbKeyboardDevice
->RepeatKey
;
1925 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1928 // Set repeat rate for next repeat key generation.
1931 UsbKeyboardDevice
->RepeatTimer
,
1940 Handler for Delayed Recovery event.
1942 This function is the handler for Delayed Recovery event triggered
1944 After a device error occurs, the event would be triggered
1945 with interval of EFI_USB_INTERRUPT_DELAY. EFI_USB_INTERRUPT_DELAY
1946 is defined in USB standard for error handling.
1948 @param Event The Delayed Recovery event.
1949 @param Context Points to the USB_KB_DEV instance.
1954 USBKeyboardRecoveryHandler (
1960 USB_KB_DEV
*UsbKeyboardDevice
;
1961 EFI_USB_IO_PROTOCOL
*UsbIo
;
1964 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1966 UsbIo
= UsbKeyboardDevice
->UsbIo
;
1968 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
1971 // Re-submit Asynchronous Interrupt Transfer for recovery.
1973 UsbIo
->UsbAsyncInterruptTransfer (
1975 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1977 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,