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 conversion 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
);
358 Uses USB I/O to check whether the device is a USB keyboard device.
360 @param UsbIo Pointer to a USB I/O protocol instance.
362 @retval TRUE Device is a USB keyboard device.
363 @retval FALSE Device is a not USB keyboard device.
368 IN EFI_USB_IO_PROTOCOL
*UsbIo
372 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
375 // Get the default interface descriptor
377 Status
= UsbIo
->UsbGetInterfaceDescriptor (
382 if (EFI_ERROR (Status
)) {
386 if ((InterfaceDescriptor
.InterfaceClass
== CLASS_HID
) &&
387 (InterfaceDescriptor
.InterfaceSubClass
== SUBCLASS_BOOT
) &&
388 (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 current 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
);
638 CopyMem (TableEntry
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
641 // For non-spacing key, create the list with a non-spacing key followed by physical keys.
643 if (TempKey
.Modifier
== EFI_NS_KEY_MODIFIER
) {
644 UsbNsKey
= AllocateZeroPool (sizeof (USB_NS_KEY
));
645 ASSERT (UsbNsKey
!= NULL
);
648 // Search for sequential children physical key definitions
651 NsKey
= KeyDescriptor
+ 1;
652 for (Index2
= (UINT8
)Index
+ 1; Index2
< KeyboardLayout
->DescriptorCount
; Index2
++) {
653 CopyMem (&TempKey
, NsKey
, sizeof (EFI_KEY_DESCRIPTOR
));
654 if (TempKey
.Modifier
== EFI_NS_KEY_DEPENDENCY_MODIFIER
) {
663 UsbNsKey
->Signature
= USB_NS_KEY_SIGNATURE
;
664 UsbNsKey
->KeyCount
= KeyCount
;
665 UsbNsKey
->NsKey
= AllocateCopyPool (
666 (KeyCount
+ 1) * sizeof (EFI_KEY_DESCRIPTOR
),
669 InsertTailList (&UsbKeyboardDevice
->NsKeyList
, &UsbNsKey
->Link
);
672 // Skip over the child physical keys
675 KeyDescriptor
+= KeyCount
;
682 // There are two EfiKeyEnter, duplicate its key descriptor
684 TableEntry
= GetKeyDescriptor (UsbKeyboardDevice
, 0x58);
685 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, 0x28);
686 CopyMem (TableEntry
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
688 FreePool (KeyboardLayout
);
692 Destroy resources for keyboard layout.
694 @param UsbKeyboardDevice The USB_KB_DEV instance.
698 ReleaseKeyboardLayoutResources (
699 IN OUT USB_KB_DEV
*UsbKeyboardDevice
702 USB_NS_KEY
*UsbNsKey
;
705 if (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
) {
706 FreePool (UsbKeyboardDevice
->KeyConvertionTable
);
709 UsbKeyboardDevice
->KeyConvertionTable
= NULL
;
711 while (!IsListEmpty (&UsbKeyboardDevice
->NsKeyList
)) {
712 Link
= GetFirstNode (&UsbKeyboardDevice
->NsKeyList
);
713 UsbNsKey
= USB_NS_KEY_FORM_FROM_LINK (Link
);
714 RemoveEntryList (&UsbNsKey
->Link
);
716 FreePool (UsbNsKey
->NsKey
);
722 Initialize USB keyboard layout.
724 This function initializes Key Convertion Table for the USB keyboard device.
725 It first tries to retrieve layout from HII database. If failed and default
726 layout is enabled, then it just uses the default layout.
728 @param UsbKeyboardDevice The USB_KB_DEV instance.
730 @retval EFI_SUCCESS Initialization succeeded.
731 @retval EFI_NOT_READY Keyboard layout cannot be retrieve from HII
732 database, and default layout is disabled.
733 @retval Other Fail to register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group.
738 OUT USB_KB_DEV
*UsbKeyboardDevice
741 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
744 UsbKeyboardDevice
->KeyConvertionTable
= AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE
)*sizeof (EFI_KEY_DESCRIPTOR
));
745 ASSERT (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
);
747 InitializeListHead (&UsbKeyboardDevice
->NsKeyList
);
748 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
749 UsbKeyboardDevice
->KeyboardLayoutEvent
= NULL
;
752 // Register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group,
753 // which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
755 Status
= gBS
->CreateEventEx (
758 SetKeyboardLayoutEvent
,
760 &gEfiHiiKeyBoardLayoutGuid
,
761 &UsbKeyboardDevice
->KeyboardLayoutEvent
763 if (EFI_ERROR (Status
)) {
767 KeyboardLayout
= GetCurrentKeyboardLayout ();
768 if (KeyboardLayout
!= NULL
) {
770 // If current keyboard layout is successfully retrieved from HII database,
771 // force to initialize the keyboard layout.
773 gBS
->SignalEvent (UsbKeyboardDevice
->KeyboardLayoutEvent
);
775 if (FeaturePcdGet (PcdDisableDefaultKeyboardLayoutInUsbKbDriver
)) {
777 // If no keyboard layout can be retrieved from HII database, and default layout
778 // is disabled, then return EFI_NOT_READY.
780 return EFI_NOT_READY
;
784 // If no keyboard layout can be retrieved from HII database, and default layout
785 // is enabled, then load the default keyboard layout.
787 InstallDefaultKeyboardLayout (UsbKeyboardDevice
);
794 Initialize USB keyboard device and all private data structures.
796 @param UsbKeyboardDevice The USB_KB_DEV instance.
798 @retval EFI_SUCCESS Initialization is successful.
799 @retval EFI_DEVICE_ERROR Keyboard initialization failed.
804 IN OUT USB_KB_DEV
*UsbKeyboardDevice
809 UINT32 TransferResult
;
811 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
813 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_KEYBOARD_PC_SELF_TEST
),
814 UsbKeyboardDevice
->DevicePath
817 InitQueue (&UsbKeyboardDevice
->UsbKeyQueue
, sizeof (USB_KEY
));
818 InitQueue (&UsbKeyboardDevice
->EfiKeyQueue
, sizeof (EFI_KEY_DATA
));
819 InitQueue (&UsbKeyboardDevice
->EfiKeyQueueForNotify
, sizeof (EFI_KEY_DATA
));
822 // Use the config out of the descriptor
823 // Assumed the first config is the correct one and this is not always the case
825 Status
= UsbGetConfiguration (
826 UsbKeyboardDevice
->UsbIo
,
830 if (EFI_ERROR (Status
)) {
833 // Uses default configuration to configure the USB Keyboard device.
835 Status
= UsbSetConfiguration (
836 UsbKeyboardDevice
->UsbIo
,
840 if (EFI_ERROR (Status
)) {
842 // If configuration could not be set here, it means
843 // the keyboard interface has some errors and could
844 // not be initialized
846 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
847 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
848 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_INTERFACE_ERROR
),
849 UsbKeyboardDevice
->DevicePath
852 return EFI_DEVICE_ERROR
;
857 // Set boot protocol for the USB Keyboard.
858 // This driver only supports boot protocol.
860 UsbSetProtocolRequest (
861 UsbKeyboardDevice
->UsbIo
,
862 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
866 UsbKeyboardDevice
->CtrlOn
= FALSE
;
867 UsbKeyboardDevice
->AltOn
= FALSE
;
868 UsbKeyboardDevice
->ShiftOn
= FALSE
;
869 UsbKeyboardDevice
->NumLockOn
= FALSE
;
870 UsbKeyboardDevice
->CapsOn
= FALSE
;
871 UsbKeyboardDevice
->ScrollOn
= FALSE
;
873 UsbKeyboardDevice
->LeftCtrlOn
= FALSE
;
874 UsbKeyboardDevice
->LeftAltOn
= FALSE
;
875 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
876 UsbKeyboardDevice
->LeftLogoOn
= FALSE
;
877 UsbKeyboardDevice
->RightCtrlOn
= FALSE
;
878 UsbKeyboardDevice
->RightAltOn
= FALSE
;
879 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
880 UsbKeyboardDevice
->RightLogoOn
= FALSE
;
881 UsbKeyboardDevice
->MenuKeyOn
= FALSE
;
882 UsbKeyboardDevice
->SysReqOn
= FALSE
;
884 UsbKeyboardDevice
->AltGrOn
= FALSE
;
886 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
889 // Sync the initial state of lights on keyboard.
891 SetKeyLED (UsbKeyboardDevice
);
893 ZeroMem (UsbKeyboardDevice
->LastKeyCodeArray
, sizeof (UINT8
) * 8);
896 // Create event for repeat keys' generation.
898 if (UsbKeyboardDevice
->RepeatTimer
!= NULL
) {
899 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
900 UsbKeyboardDevice
->RepeatTimer
= NULL
;
904 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
906 USBKeyboardRepeatHandler
,
908 &UsbKeyboardDevice
->RepeatTimer
912 // Create event for delayed recovery, which deals with device error.
914 if (UsbKeyboardDevice
->DelayedRecoveryEvent
!= NULL
) {
915 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
916 UsbKeyboardDevice
->DelayedRecoveryEvent
= NULL
;
920 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
922 USBKeyboardRecoveryHandler
,
924 &UsbKeyboardDevice
->DelayedRecoveryEvent
931 Handler function for USB keyboard's asynchronous interrupt transfer.
933 This function is the handler function for USB keyboard's asynchronous interrupt transfer
934 to manage the keyboard. It parses the USB keyboard input report, and inserts data to
935 keyboard buffer according to state of modifer keys and normal keys. Timer for repeat key
936 is also set accordingly.
938 @param Data A pointer to a buffer that is filled with key data which is
939 retrieved via asynchronous interrupt transfer.
940 @param DataLength Indicates the size of the data buffer.
941 @param Context Pointing to USB_KB_DEV instance.
942 @param Result Indicates the result of the asynchronous interrupt transfer.
944 @retval EFI_SUCCESS Asynchronous interrupt transfer is handled successfully.
945 @retval EFI_DEVICE_ERROR Hardware error occurs.
957 USB_KB_DEV
*UsbKeyboardDevice
;
958 EFI_USB_IO_PROTOCOL
*UsbIo
;
959 UINT8
*CurKeyCodeBuffer
;
960 UINT8
*OldKeyCodeBuffer
;
961 UINT8 CurModifierMap
;
962 UINT8 OldModifierMap
;
971 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
973 ASSERT (Context
!= NULL
);
976 UsbKeyboardDevice
= (USB_KB_DEV
*)Context
;
977 UsbIo
= UsbKeyboardDevice
->UsbIo
;
980 // Analyzes Result and performs corresponding action.
982 if (Result
!= EFI_USB_NOERROR
) {
984 // Some errors happen during the process
986 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
987 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
988 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_INPUT_ERROR
),
989 UsbKeyboardDevice
->DevicePath
993 // Stop the repeat key generation if any
995 UsbKeyboardDevice
->RepeatKey
= 0;
998 UsbKeyboardDevice
->RepeatTimer
,
1003 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
1004 UsbClearEndpointHalt (
1006 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1012 // Delete & Submit this interrupt again
1013 // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt.
1015 UsbIo
->UsbAsyncInterruptTransfer (
1017 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1025 // EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling.
1028 UsbKeyboardDevice
->DelayedRecoveryEvent
,
1030 EFI_USB_INTERRUPT_DELAY
1033 return EFI_DEVICE_ERROR
;
1037 // If no error and no data, just return EFI_SUCCESS.
1039 if ((DataLength
== 0) || (Data
== NULL
)) {
1044 // Following code checks current keyboard input report against old key code buffer.
1045 // According to USB HID Firmware Specification, the report consists of 8 bytes.
1046 // Byte 0 is map of Modifier keys.
1047 // Byte 1 is reserved.
1048 // Bytes 2 to 7 are keycodes.
1050 if (DataLength
< 8) {
1051 return EFI_DEVICE_ERROR
;
1054 CurKeyCodeBuffer
= (UINT8
*)Data
;
1055 OldKeyCodeBuffer
= UsbKeyboardDevice
->LastKeyCodeArray
;
1058 // Checks for new key stroke.
1060 for (Index
= 0; Index
< 8; Index
++) {
1061 if (OldKeyCodeBuffer
[Index
] != CurKeyCodeBuffer
[Index
]) {
1067 // If no new key, return EFI_SUCCESS immediately.
1074 // Parse the modifier key, which is the first byte of keyboard input report.
1076 CurModifierMap
= CurKeyCodeBuffer
[0];
1077 OldModifierMap
= OldKeyCodeBuffer
[0];
1080 // Handle modifier key's pressing or releasing situation.
1081 // According to USB HID Firmware spec, Byte 0 uses following map of Modifier keys:
1082 // Bit0: Left Control, Keycode: 0xe0
1083 // Bit1: Left Shift, Keycode: 0xe1
1084 // Bit2: Left Alt, Keycode: 0xe2
1085 // Bit3: Left GUI, Keycode: 0xe3
1086 // Bit4: Right Control, Keycode: 0xe4
1087 // Bit5: Right Shift, Keycode: 0xe5
1088 // Bit6: Right Alt, Keycode: 0xe6
1089 // Bit7: Right GUI, Keycode: 0xe7
1091 for (Index
= 0; Index
< 8; Index
++) {
1092 Mask
= (UINT8
)(1 << Index
);
1093 if ((CurModifierMap
& Mask
) != (OldModifierMap
& Mask
)) {
1095 // If current modifier key is up, then CurModifierMap & Mask = 0;
1096 // otherwise it is a non-zero value.
1097 // Insert the changed modifier key into key buffer.
1099 UsbKey
.KeyCode
= (UINT8
)(0xe0 + Index
);
1100 UsbKey
.Down
= (BOOLEAN
)((CurModifierMap
& Mask
) != 0);
1101 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1106 // Handle normal key's releasing situation
1107 // Bytes 2 to 7 are for normal keycodes
1110 for (Index
= 2; Index
< 8; Index
++) {
1111 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index
])) {
1116 // For any key in old keycode buffer, if it is not in current keycode buffer,
1117 // then it is released. Otherwise, it is not released.
1120 for (Index2
= 2; Index2
< 8; Index2
++) {
1121 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index2
])) {
1125 if (OldKeyCodeBuffer
[Index
] == CurKeyCodeBuffer
[Index2
]) {
1132 UsbKey
.KeyCode
= OldKeyCodeBuffer
[Index
];
1133 UsbKey
.Down
= FALSE
;
1134 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1136 // The original repeat key is released.
1138 if (OldKeyCodeBuffer
[Index
] == UsbKeyboardDevice
->RepeatKey
) {
1139 UsbKeyboardDevice
->RepeatKey
= 0;
1145 // If original repeat key is released, cancel the repeat timer
1147 if (UsbKeyboardDevice
->RepeatKey
== 0) {
1149 UsbKeyboardDevice
->RepeatTimer
,
1156 // Handle normal key's pressing situation
1159 for (Index
= 2; Index
< 8; Index
++) {
1160 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index
])) {
1165 // For any key in current keycode buffer, if it is not in old keycode buffer,
1166 // then it is pressed. Otherwise, it is not pressed.
1169 for (Index2
= 2; Index2
< 8; Index2
++) {
1170 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index2
])) {
1174 if (CurKeyCodeBuffer
[Index
] == OldKeyCodeBuffer
[Index2
]) {
1181 UsbKey
.KeyCode
= CurKeyCodeBuffer
[Index
];
1183 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1186 // Handle repeat key
1188 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, CurKeyCodeBuffer
[Index
]);
1189 if (KeyDescriptor
== NULL
) {
1193 if ((KeyDescriptor
->Modifier
== EFI_NUM_LOCK_MODIFIER
) || (KeyDescriptor
->Modifier
== EFI_CAPS_LOCK_MODIFIER
)) {
1195 // For NumLock or CapsLock pressed, there is no need to handle repeat key for them.
1197 UsbKeyboardDevice
->RepeatKey
= 0;
1200 // Prepare new repeat key, and clear the original one.
1202 NewRepeatKey
= CurKeyCodeBuffer
[Index
];
1203 UsbKeyboardDevice
->RepeatKey
= 0;
1209 // Update LastKeycodeArray buffer in the UsbKeyboardDevice data structure.
1211 for (Index
= 0; Index
< 8; Index
++) {
1212 UsbKeyboardDevice
->LastKeyCodeArray
[Index
] = CurKeyCodeBuffer
[Index
];
1216 // If there is new key pressed, update the RepeatKey value, and set the
1217 // timer to repeate delay timer
1219 if (NewRepeatKey
!= 0) {
1221 // Sets trigger time to "Repeat Delay Time",
1222 // to trigger the repeat timer when the key is hold long
1226 UsbKeyboardDevice
->RepeatTimer
,
1230 UsbKeyboardDevice
->RepeatKey
= NewRepeatKey
;
1237 Retrieves a USB keycode after parsing the raw data in keyboard buffer.
1239 This function parses keyboard buffer. It updates state of modifier key for
1240 USB_KB_DEV instancem, and returns keycode for output.
1242 @param UsbKeyboardDevice The USB_KB_DEV instance.
1243 @param KeyCode Pointer to the USB keycode for output.
1245 @retval EFI_SUCCESS Keycode successfully parsed.
1246 @retval EFI_NOT_READY Keyboard buffer is not ready for a valid keycode
1251 IN OUT USB_KB_DEV
*UsbKeyboardDevice
,
1256 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1260 while (!IsQueueEmpty (&UsbKeyboardDevice
->UsbKeyQueue
)) {
1262 // Pops one raw data off.
1264 Dequeue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1266 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, UsbKey
.KeyCode
);
1267 if (KeyDescriptor
== NULL
) {
1275 switch (KeyDescriptor
->Modifier
) {
1279 case EFI_LEFT_CONTROL_MODIFIER
:
1280 UsbKeyboardDevice
->LeftCtrlOn
= FALSE
;
1281 UsbKeyboardDevice
->CtrlOn
= FALSE
;
1283 case EFI_RIGHT_CONTROL_MODIFIER
:
1284 UsbKeyboardDevice
->RightCtrlOn
= FALSE
;
1285 UsbKeyboardDevice
->CtrlOn
= FALSE
;
1291 case EFI_LEFT_SHIFT_MODIFIER
:
1292 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
1293 UsbKeyboardDevice
->ShiftOn
= FALSE
;
1295 case EFI_RIGHT_SHIFT_MODIFIER
:
1296 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
1297 UsbKeyboardDevice
->ShiftOn
= FALSE
;
1303 case EFI_LEFT_ALT_MODIFIER
:
1304 UsbKeyboardDevice
->LeftAltOn
= FALSE
;
1305 UsbKeyboardDevice
->AltOn
= FALSE
;
1307 case EFI_RIGHT_ALT_MODIFIER
:
1308 UsbKeyboardDevice
->RightAltOn
= FALSE
;
1309 UsbKeyboardDevice
->AltOn
= FALSE
;
1313 // Left Logo release
1315 case EFI_LEFT_LOGO_MODIFIER
:
1316 UsbKeyboardDevice
->LeftLogoOn
= FALSE
;
1320 // Right Logo release
1322 case EFI_RIGHT_LOGO_MODIFIER
:
1323 UsbKeyboardDevice
->RightLogoOn
= FALSE
;
1329 case EFI_MENU_MODIFIER
:
1330 UsbKeyboardDevice
->MenuKeyOn
= FALSE
;
1336 case EFI_PRINT_MODIFIER
:
1337 case EFI_SYS_REQUEST_MODIFIER
:
1338 UsbKeyboardDevice
->SysReqOn
= FALSE
;
1344 case EFI_ALT_GR_MODIFIER
:
1345 UsbKeyboardDevice
->AltGrOn
= FALSE
;
1356 // Analyzes key pressing situation
1358 switch (KeyDescriptor
->Modifier
) {
1362 case EFI_LEFT_CONTROL_MODIFIER
:
1363 UsbKeyboardDevice
->LeftCtrlOn
= TRUE
;
1364 UsbKeyboardDevice
->CtrlOn
= TRUE
;
1366 case EFI_RIGHT_CONTROL_MODIFIER
:
1367 UsbKeyboardDevice
->RightCtrlOn
= TRUE
;
1368 UsbKeyboardDevice
->CtrlOn
= TRUE
;
1374 case EFI_LEFT_SHIFT_MODIFIER
:
1375 UsbKeyboardDevice
->LeftShiftOn
= TRUE
;
1376 UsbKeyboardDevice
->ShiftOn
= TRUE
;
1378 case EFI_RIGHT_SHIFT_MODIFIER
:
1379 UsbKeyboardDevice
->RightShiftOn
= TRUE
;
1380 UsbKeyboardDevice
->ShiftOn
= TRUE
;
1386 case EFI_LEFT_ALT_MODIFIER
:
1387 UsbKeyboardDevice
->LeftAltOn
= TRUE
;
1388 UsbKeyboardDevice
->AltOn
= TRUE
;
1390 case EFI_RIGHT_ALT_MODIFIER
:
1391 UsbKeyboardDevice
->RightAltOn
= TRUE
;
1392 UsbKeyboardDevice
->AltOn
= TRUE
;
1398 case EFI_LEFT_LOGO_MODIFIER
:
1399 UsbKeyboardDevice
->LeftLogoOn
= TRUE
;
1405 case EFI_RIGHT_LOGO_MODIFIER
:
1406 UsbKeyboardDevice
->RightLogoOn
= TRUE
;
1412 case EFI_MENU_MODIFIER
:
1413 UsbKeyboardDevice
->MenuKeyOn
= TRUE
;
1419 case EFI_PRINT_MODIFIER
:
1420 case EFI_SYS_REQUEST_MODIFIER
:
1421 UsbKeyboardDevice
->SysReqOn
= TRUE
;
1427 case EFI_ALT_GR_MODIFIER
:
1428 UsbKeyboardDevice
->AltGrOn
= TRUE
;
1431 case EFI_NUM_LOCK_MODIFIER
:
1435 UsbKeyboardDevice
->NumLockOn
= (BOOLEAN
)(!(UsbKeyboardDevice
->NumLockOn
));
1436 SetKeyLED (UsbKeyboardDevice
);
1439 case EFI_CAPS_LOCK_MODIFIER
:
1443 UsbKeyboardDevice
->CapsOn
= (BOOLEAN
)(!(UsbKeyboardDevice
->CapsOn
));
1444 SetKeyLED (UsbKeyboardDevice
);
1447 case EFI_SCROLL_LOCK_MODIFIER
:
1449 // Toggle ScrollLock
1451 UsbKeyboardDevice
->ScrollOn
= (BOOLEAN
)(!(UsbKeyboardDevice
->ScrollOn
));
1452 SetKeyLED (UsbKeyboardDevice
);
1460 // When encountering Ctrl + Alt + Del, then warm reset.
1462 if (KeyDescriptor
->Modifier
== EFI_DELETE_MODIFIER
) {
1463 if ((UsbKeyboardDevice
->CtrlOn
) && (UsbKeyboardDevice
->AltOn
)) {
1464 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1468 *KeyCode
= UsbKey
.KeyCode
;
1472 return EFI_NOT_READY
;
1476 Initialize the key state.
1478 @param UsbKeyboardDevice The USB_KB_DEV instance.
1479 @param KeyState A pointer to receive the key state information.
1482 InitializeKeyState (
1483 IN USB_KB_DEV
*UsbKeyboardDevice
,
1484 OUT EFI_KEY_STATE
*KeyState
1487 KeyState
->KeyShiftState
= EFI_SHIFT_STATE_VALID
;
1488 KeyState
->KeyToggleState
= EFI_TOGGLE_STATE_VALID
;
1490 if (UsbKeyboardDevice
->LeftCtrlOn
) {
1491 KeyState
->KeyShiftState
|= EFI_LEFT_CONTROL_PRESSED
;
1494 if (UsbKeyboardDevice
->RightCtrlOn
) {
1495 KeyState
->KeyShiftState
|= EFI_RIGHT_CONTROL_PRESSED
;
1498 if (UsbKeyboardDevice
->LeftAltOn
) {
1499 KeyState
->KeyShiftState
|= EFI_LEFT_ALT_PRESSED
;
1502 if (UsbKeyboardDevice
->RightAltOn
) {
1503 KeyState
->KeyShiftState
|= EFI_RIGHT_ALT_PRESSED
;
1506 if (UsbKeyboardDevice
->LeftShiftOn
) {
1507 KeyState
->KeyShiftState
|= EFI_LEFT_SHIFT_PRESSED
;
1510 if (UsbKeyboardDevice
->RightShiftOn
) {
1511 KeyState
->KeyShiftState
|= EFI_RIGHT_SHIFT_PRESSED
;
1514 if (UsbKeyboardDevice
->LeftLogoOn
) {
1515 KeyState
->KeyShiftState
|= EFI_LEFT_LOGO_PRESSED
;
1518 if (UsbKeyboardDevice
->RightLogoOn
) {
1519 KeyState
->KeyShiftState
|= EFI_RIGHT_LOGO_PRESSED
;
1522 if (UsbKeyboardDevice
->MenuKeyOn
) {
1523 KeyState
->KeyShiftState
|= EFI_MENU_KEY_PRESSED
;
1526 if (UsbKeyboardDevice
->SysReqOn
) {
1527 KeyState
->KeyShiftState
|= EFI_SYS_REQ_PRESSED
;
1530 if (UsbKeyboardDevice
->ScrollOn
) {
1531 KeyState
->KeyToggleState
|= EFI_SCROLL_LOCK_ACTIVE
;
1534 if (UsbKeyboardDevice
->NumLockOn
) {
1535 KeyState
->KeyToggleState
|= EFI_NUM_LOCK_ACTIVE
;
1538 if (UsbKeyboardDevice
->CapsOn
) {
1539 KeyState
->KeyToggleState
|= EFI_CAPS_LOCK_ACTIVE
;
1542 if (UsbKeyboardDevice
->IsSupportPartialKey
) {
1543 KeyState
->KeyToggleState
|= EFI_KEY_STATE_EXPOSED
;
1548 Converts USB Keycode ranging from 0x4 to 0x65 to EFI_INPUT_KEY.
1550 @param UsbKeyboardDevice The USB_KB_DEV instance.
1551 @param KeyCode Indicates the key code that will be interpreted.
1552 @param KeyData A pointer to a buffer that is filled in with
1553 the keystroke information for the key that
1556 @retval EFI_SUCCESS Success.
1557 @retval EFI_INVALID_PARAMETER KeyCode is not in the range of 0x4 to 0x65.
1558 @retval EFI_INVALID_PARAMETER Translated EFI_INPUT_KEY has zero for both ScanCode and UnicodeChar.
1559 @retval EFI_NOT_READY KeyCode represents a dead key with EFI_NS_KEY_MODIFIER
1560 @retval EFI_DEVICE_ERROR Keyboard layout is invalid.
1564 UsbKeyCodeToEfiInputKey (
1565 IN USB_KB_DEV
*UsbKeyboardDevice
,
1567 OUT EFI_KEY_DATA
*KeyData
1570 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1572 LIST_ENTRY
*NotifyList
;
1573 KEYBOARD_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
1576 // KeyCode must in the range of [0x4, 0x65] or [0xe0, 0xe7].
1578 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, KeyCode
);
1579 if (KeyDescriptor
== NULL
) {
1580 return EFI_DEVICE_ERROR
;
1583 if (KeyDescriptor
->Modifier
== EFI_NS_KEY_MODIFIER
) {
1585 // If this is a dead key with EFI_NS_KEY_MODIFIER, then record it and return.
1587 UsbKeyboardDevice
->CurrentNsKey
= FindUsbNsKey (UsbKeyboardDevice
, KeyDescriptor
);
1588 return EFI_NOT_READY
;
1591 if (UsbKeyboardDevice
->CurrentNsKey
!= NULL
) {
1593 // If this keystroke follows a non-spacing key, then find the descriptor for corresponding
1596 KeyDescriptor
= FindPhysicalKey (UsbKeyboardDevice
->CurrentNsKey
, KeyDescriptor
);
1597 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
1601 // Make sure modifier of Key Descriptor is in the valid range according to UEFI spec.
1603 if (KeyDescriptor
->Modifier
>= (sizeof (ModifierValueToEfiScanCodeConvertionTable
) / sizeof (UINT8
))) {
1604 return EFI_DEVICE_ERROR
;
1607 KeyData
->Key
.ScanCode
= ModifierValueToEfiScanCodeConvertionTable
[KeyDescriptor
->Modifier
];
1608 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->Unicode
;
1610 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_STANDARD_SHIFT
) != 0) {
1611 if (UsbKeyboardDevice
->ShiftOn
) {
1612 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->ShiftedUnicode
;
1615 // Need not return associated shift state if a class of printable characters that
1616 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
1618 if ((KeyDescriptor
->Unicode
!= CHAR_NULL
) && (KeyDescriptor
->ShiftedUnicode
!= CHAR_NULL
) &&
1619 (KeyDescriptor
->Unicode
!= KeyDescriptor
->ShiftedUnicode
))
1621 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
1622 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
1625 if (UsbKeyboardDevice
->AltGrOn
) {
1626 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->ShiftedAltGrUnicode
;
1632 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->Unicode
;
1634 if (UsbKeyboardDevice
->AltGrOn
) {
1635 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->AltGrUnicode
;
1640 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_CAPS_LOCK
) != 0) {
1641 if (UsbKeyboardDevice
->CapsOn
) {
1642 if (KeyData
->Key
.UnicodeChar
== KeyDescriptor
->Unicode
) {
1643 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->ShiftedUnicode
;
1644 } else if (KeyData
->Key
.UnicodeChar
== KeyDescriptor
->ShiftedUnicode
) {
1645 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->Unicode
;
1650 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_NUM_LOCK
) != 0) {
1652 // For key affected by NumLock, if NumLock is on and Shift is not pressed, then it means
1653 // normal key, instead of original control key. So the ScanCode should be cleaned.
1654 // Otherwise, it means control key, so preserve the EFI Scan Code and clear the unicode keycode.
1656 if ((UsbKeyboardDevice
->NumLockOn
) && (!(UsbKeyboardDevice
->ShiftOn
))) {
1657 KeyData
->Key
.ScanCode
= SCAN_NULL
;
1659 KeyData
->Key
.UnicodeChar
= CHAR_NULL
;
1664 // Translate Unicode 0x1B (ESC) to EFI Scan Code
1666 if ((KeyData
->Key
.UnicodeChar
== 0x1B) && (KeyData
->Key
.ScanCode
== SCAN_NULL
)) {
1667 KeyData
->Key
.ScanCode
= SCAN_ESC
;
1668 KeyData
->Key
.UnicodeChar
= CHAR_NULL
;
1672 // Not valid for key without both unicode key code and EFI Scan Code.
1674 if ((KeyData
->Key
.UnicodeChar
== 0) && (KeyData
->Key
.ScanCode
== SCAN_NULL
)) {
1675 if (!UsbKeyboardDevice
->IsSupportPartialKey
) {
1676 return EFI_NOT_READY
;
1681 // Save Shift/Toggle state
1683 InitializeKeyState (UsbKeyboardDevice
, &KeyData
->KeyState
);
1686 // Signal KeyNotify process event if this key pressed matches any key registered.
1688 NotifyList
= &UsbKeyboardDevice
->NotifyList
;
1689 for (Link
= GetFirstNode (NotifyList
); !IsNull (NotifyList
, Link
); Link
= GetNextNode (NotifyList
, Link
)) {
1690 CurrentNotify
= CR (Link
, KEYBOARD_CONSOLE_IN_EX_NOTIFY
, NotifyEntry
, USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
1691 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
1693 // The key notification function needs to run at TPL_CALLBACK
1694 // while current TPL is TPL_NOTIFY. It will be invoked in
1695 // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.
1697 Enqueue (&UsbKeyboardDevice
->EfiKeyQueueForNotify
, KeyData
, sizeof (*KeyData
));
1698 gBS
->SignalEvent (UsbKeyboardDevice
->KeyNotifyProcessEvent
);
1709 @param Queue Points to the queue.
1710 @param ItemSize Size of the single item.
1715 IN OUT USB_SIMPLE_QUEUE
*Queue
,
1721 Queue
->ItemSize
= ItemSize
;
1725 if (Queue
->Buffer
[0] != NULL
) {
1726 FreePool (Queue
->Buffer
[0]);
1729 Queue
->Buffer
[0] = AllocatePool (sizeof (Queue
->Buffer
) / sizeof (Queue
->Buffer
[0]) * ItemSize
);
1730 ASSERT (Queue
->Buffer
[0] != NULL
);
1732 for (Index
= 1; Index
< sizeof (Queue
->Buffer
) / sizeof (Queue
->Buffer
[0]); Index
++) {
1733 Queue
->Buffer
[Index
] = ((UINT8
*)Queue
->Buffer
[Index
- 1]) + ItemSize
;
1740 @param Queue Points to the queue.
1744 IN OUT USB_SIMPLE_QUEUE
*Queue
1747 FreePool (Queue
->Buffer
[0]);
1751 Check whether the queue is empty.
1753 @param Queue Points to the queue.
1755 @retval TRUE Queue is empty.
1756 @retval FALSE Queue is not empty.
1761 IN USB_SIMPLE_QUEUE
*Queue
1765 // Meet FIFO empty condition
1767 return (BOOLEAN
)(Queue
->Head
== Queue
->Tail
);
1771 Check whether the queue is full.
1773 @param Queue Points to the queue.
1775 @retval TRUE Queue is full.
1776 @retval FALSE Queue is not full.
1781 IN USB_SIMPLE_QUEUE
*Queue
1784 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);
1819 Dequeue a item from the queue.
1821 @param Queue Points to the queue.
1822 @param Item Receives the item.
1823 @param ItemSize Size of the item.
1825 @retval EFI_SUCCESS Item was successfully dequeued.
1826 @retval EFI_DEVICE_ERROR The queue is empty.
1831 IN OUT USB_SIMPLE_QUEUE
*Queue
,
1836 ASSERT (Queue
->ItemSize
== ItemSize
);
1838 if (IsQueueEmpty (Queue
)) {
1839 return EFI_DEVICE_ERROR
;
1842 CopyMem (Item
, Queue
->Buffer
[Queue
->Head
], ItemSize
);
1845 // Adjust the head pointer of the FIFO keyboard buffer.
1847 Queue
->Head
= (Queue
->Head
+ 1) % (MAX_KEY_ALLOWED
+ 1);
1853 Sets USB keyboard LED state.
1855 @param UsbKeyboardDevice The USB_KB_DEV instance.
1860 IN USB_KB_DEV
*UsbKeyboardDevice
1867 // Set each field in Led map.
1869 Led
.NumLock
= (UINT8
)((UsbKeyboardDevice
->NumLockOn
) ? 1 : 0);
1870 Led
.CapsLock
= (UINT8
)((UsbKeyboardDevice
->CapsOn
) ? 1 : 0);
1871 Led
.ScrollLock
= (UINT8
)((UsbKeyboardDevice
->ScrollOn
) ? 1 : 0);
1876 // Call Set_Report Request to lighten the LED.
1878 UsbSetReportRequest (
1879 UsbKeyboardDevice
->UsbIo
,
1880 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
1889 Handler for Repeat Key event.
1891 This function is the handler for Repeat Key event triggered
1893 After a repeatable key is pressed, the event would be triggered
1894 with interval of USBKBD_REPEAT_DELAY. Once the event is triggered,
1895 following trigger will come with interval of USBKBD_REPEAT_RATE.
1897 @param Event The Repeat Key event.
1898 @param Context Points to the USB_KB_DEV instance.
1903 USBKeyboardRepeatHandler (
1908 USB_KB_DEV
*UsbKeyboardDevice
;
1911 UsbKeyboardDevice
= (USB_KB_DEV
*)Context
;
1914 // Do nothing when there is no repeat key.
1916 if (UsbKeyboardDevice
->RepeatKey
!= 0) {
1918 // Inserts the repeat key into keyboard buffer,
1920 UsbKey
.KeyCode
= UsbKeyboardDevice
->RepeatKey
;
1922 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1925 // Set repeat rate for next repeat key generation.
1928 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 (
1955 USB_KB_DEV
*UsbKeyboardDevice
;
1956 EFI_USB_IO_PROTOCOL
*UsbIo
;
1959 UsbKeyboardDevice
= (USB_KB_DEV
*)Context
;
1961 UsbIo
= UsbKeyboardDevice
->UsbIo
;
1963 PacketSize
= (UINT8
)(UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
1966 // Re-submit Asynchronous Interrupt Transfer for recovery.
1968 UsbIo
->UsbAsyncInterruptTransfer (
1970 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1972 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,