2 Helper functions for USB Keyboard Driver.
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 USB_KEYBOARD_LAYOUT_PACK_BIN mUsbKeyboardLayoutBin
= {
18 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN
), // Binary size
21 // EFI_HII_PACKAGE_HEADER
24 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN
) - sizeof (UINT32
),
25 EFI_HII_PACKAGE_KEYBOARD_LAYOUT
28 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN
) - sizeof (UINT32
) - sizeof (EFI_HII_PACKAGE_HEADER
) - sizeof (UINT16
), // LayoutLength
29 USB_KEYBOARD_LAYOUT_KEY_GUID
, // KeyGuid
30 sizeof (UINT16
) + sizeof (EFI_GUID
) + sizeof (UINT32
) + sizeof (UINT8
) + (USB_KEYBOARD_KEY_COUNT
* sizeof (EFI_KEY_DESCRIPTOR
)), // LayoutDescriptorStringOffset
31 USB_KEYBOARD_KEY_COUNT
, // DescriptorCount
34 // EFI_KEY_DESCRIPTOR (total number is USB_KEYBOARD_KEY_COUNT)
36 {EfiKeyC1
, 'a', 'A', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
37 {EfiKeyB5
, 'b', 'B', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
38 {EfiKeyB3
, 'c', 'C', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
39 {EfiKeyC3
, 'd', 'D', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
40 {EfiKeyD3
, 'e', 'E', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
41 {EfiKeyC4
, 'f', 'F', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
42 {EfiKeyC5
, 'g', 'G', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
43 {EfiKeyC6
, 'h', 'H', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
44 {EfiKeyD8
, 'i', 'I', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
45 {EfiKeyC7
, 'j', 'J', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
46 {EfiKeyC8
, 'k', 'K', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
47 {EfiKeyC9
, 'l', 'L', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
48 {EfiKeyB7
, 'm', 'M', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
49 {EfiKeyB6
, 'n', 'N', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
50 {EfiKeyD9
, 'o', 'O', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
51 {EfiKeyD10
, 'p', 'P', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
52 {EfiKeyD1
, 'q', 'Q', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
53 {EfiKeyD4
, 'r', 'R', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
54 {EfiKeyC2
, 's', 'S', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
55 {EfiKeyD5
, 't', 'T', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
56 {EfiKeyD7
, 'u', 'U', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
57 {EfiKeyB4
, 'v', 'V', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
58 {EfiKeyD2
, 'w', 'W', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
59 {EfiKeyB2
, 'x', 'X', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
60 {EfiKeyD6
, 'y', 'Y', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
61 {EfiKeyB1
, 'z', 'Z', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
62 {EfiKeyE1
, '1', '!', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
63 {EfiKeyE2
, '2', '@', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
64 {EfiKeyE3
, '3', '#', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
65 {EfiKeyE4
, '4', '$', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
66 {EfiKeyE5
, '5', '%', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
67 {EfiKeyE6
, '6', '^', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
68 {EfiKeyE7
, '7', '&', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
69 {EfiKeyE8
, '8', '*', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
70 {EfiKeyE9
, '9', '(', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
71 {EfiKeyE10
, '0', ')', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
72 {EfiKeyEnter
, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER
, 0},
73 {EfiKeyEsc
, 0x1b, 0x1b, 0, 0, EFI_NULL_MODIFIER
, 0},
74 {EfiKeyBackSpace
, 0x08, 0x08, 0, 0, EFI_NULL_MODIFIER
, 0},
75 {EfiKeyTab
, 0x09, 0x09, 0, 0, EFI_NULL_MODIFIER
, 0},
76 {EfiKeySpaceBar
, ' ', ' ', 0, 0, EFI_NULL_MODIFIER
, 0},
77 {EfiKeyE11
, '-', '_', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
78 {EfiKeyE12
, '=', '+', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
79 {EfiKeyD11
, '[', '{', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
80 {EfiKeyD12
, ']', '}', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
81 {EfiKeyD13
, '\\', '|', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
82 {EfiKeyC12
, '\\', '|', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
83 {EfiKeyC10
, ';', ':', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
84 {EfiKeyC11
, '\'', '"', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
85 {EfiKeyE0
, '`', '~', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
86 {EfiKeyB8
, ',', '<', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
87 {EfiKeyB9
, '.', '>', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
88 {EfiKeyB10
, '/', '?', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
89 {EfiKeyCapsLock
, 0x00, 0x00, 0, 0, EFI_CAPS_LOCK_MODIFIER
, 0},
90 {EfiKeyF1
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ONE_MODIFIER
, 0},
91 {EfiKeyF2
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWO_MODIFIER
, 0},
92 {EfiKeyF3
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_THREE_MODIFIER
, 0},
93 {EfiKeyF4
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FOUR_MODIFIER
, 0},
94 {EfiKeyF5
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FIVE_MODIFIER
, 0},
95 {EfiKeyF6
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SIX_MODIFIER
, 0},
96 {EfiKeyF7
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SEVEN_MODIFIER
, 0},
97 {EfiKeyF8
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_EIGHT_MODIFIER
, 0},
98 {EfiKeyF9
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_NINE_MODIFIER
, 0},
99 {EfiKeyF10
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TEN_MODIFIER
, 0},
100 {EfiKeyF11
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ELEVEN_MODIFIER
, 0},
101 {EfiKeyF12
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWELVE_MODIFIER
, 0},
102 {EfiKeyPrint
, 0x00, 0x00, 0, 0, EFI_PRINT_MODIFIER
, 0},
103 {EfiKeySLck
, 0x00, 0x00, 0, 0, EFI_SCROLL_LOCK_MODIFIER
, 0},
104 {EfiKeyPause
, 0x00, 0x00, 0, 0, EFI_PAUSE_MODIFIER
, 0},
105 {EfiKeyIns
, 0x00, 0x00, 0, 0, EFI_INSERT_MODIFIER
, 0},
106 {EfiKeyHome
, 0x00, 0x00, 0, 0, EFI_HOME_MODIFIER
, 0},
107 {EfiKeyPgUp
, 0x00, 0x00, 0, 0, EFI_PAGE_UP_MODIFIER
, 0},
108 {EfiKeyDel
, 0x00, 0x00, 0, 0, EFI_DELETE_MODIFIER
, 0},
109 {EfiKeyEnd
, 0x00, 0x00, 0, 0, EFI_END_MODIFIER
, 0},
110 {EfiKeyPgDn
, 0x00, 0x00, 0, 0, EFI_PAGE_DOWN_MODIFIER
, 0},
111 {EfiKeyRightArrow
, 0x00, 0x00, 0, 0, EFI_RIGHT_ARROW_MODIFIER
, 0},
112 {EfiKeyLeftArrow
, 0x00, 0x00, 0, 0, EFI_LEFT_ARROW_MODIFIER
, 0},
113 {EfiKeyDownArrow
, 0x00, 0x00, 0, 0, EFI_DOWN_ARROW_MODIFIER
, 0},
114 {EfiKeyUpArrow
, 0x00, 0x00, 0, 0, EFI_UP_ARROW_MODIFIER
, 0},
115 {EfiKeyNLck
, 0x00, 0x00, 0, 0, EFI_NUM_LOCK_MODIFIER
, 0},
116 {EfiKeySlash
, '/', '/', 0, 0, EFI_NULL_MODIFIER
, 0},
117 {EfiKeyAsterisk
, '*', '*', 0, 0, EFI_NULL_MODIFIER
, 0},
118 {EfiKeyMinus
, '-', '-', 0, 0, EFI_NULL_MODIFIER
, 0},
119 {EfiKeyPlus
, '+', '+', 0, 0, EFI_NULL_MODIFIER
, 0},
120 {EfiKeyEnter
, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER
, 0},
121 {EfiKeyOne
, '1', '1', 0, 0, EFI_END_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
122 {EfiKeyTwo
, '2', '2', 0, 0, EFI_DOWN_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
123 {EfiKeyThree
, '3', '3', 0, 0, EFI_PAGE_DOWN_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
124 {EfiKeyFour
, '4', '4', 0, 0, EFI_LEFT_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
125 {EfiKeyFive
, '5', '5', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
126 {EfiKeySix
, '6', '6', 0, 0, EFI_RIGHT_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
127 {EfiKeySeven
, '7', '7', 0, 0, EFI_HOME_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
128 {EfiKeyEight
, '8', '8', 0, 0, EFI_UP_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
129 {EfiKeyNine
, '9', '9', 0, 0, EFI_PAGE_UP_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
130 {EfiKeyZero
, '0', '0', 0, 0, EFI_INSERT_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
131 {EfiKeyPeriod
, '.', '.', 0, 0, EFI_DELETE_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
132 {EfiKeyA4
, 0x00, 0x00, 0, 0, EFI_MENU_MODIFIER
, 0},
133 {EfiKeyLCtrl
, 0, 0, 0, 0, EFI_LEFT_CONTROL_MODIFIER
, 0},
134 {EfiKeyLShift
, 0, 0, 0, 0, EFI_LEFT_SHIFT_MODIFIER
, 0},
135 {EfiKeyLAlt
, 0, 0, 0, 0, EFI_LEFT_ALT_MODIFIER
, 0},
136 {EfiKeyA0
, 0, 0, 0, 0, EFI_LEFT_LOGO_MODIFIER
, 0},
137 {EfiKeyRCtrl
, 0, 0, 0, 0, EFI_RIGHT_CONTROL_MODIFIER
, 0},
138 {EfiKeyRShift
, 0, 0, 0, 0, EFI_RIGHT_SHIFT_MODIFIER
, 0},
139 {EfiKeyA2
, 0, 0, 0, 0, EFI_RIGHT_ALT_MODIFIER
, 0},
140 {EfiKeyA3
, 0, 0, 0, 0, EFI_RIGHT_LOGO_MODIFIER
, 0},
142 1, // DescriptionCount
143 {'e', 'n', '-', 'U', 'S'}, // RFC4646 language code
145 {'E', 'n', 'g', 'l', 'i', 's', 'h', ' ', 'K', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '\0'}, // DescriptionString[]
149 // EFI_KEY to USB Keycode conversion table
150 // EFI_KEY is defined in UEFI spec.
151 // USB Keycode is defined in USB HID Firmware spec.
153 UINT8 EfiKeyToUsbKeyCodeConvertionTable
[] = {
157 0x2c, // EfiKeySpaceBar
162 0x50, // EfiKeyLeftArrow
163 0x51, // EfiKeyDownArrow
164 0x4F, // EfiKeyRightArrow
166 0x63, // EfiKeyPeriod
168 0xe1, // EfiKeyLShift
180 0xe5, // EfiKeyRShift
181 0x52, // EfiKeyUpArrow
185 0x39, // EfiKeyCapsLock
235 0x2A, // EfiKeyBackSpace
241 0x55, // EfiKeyAsterisk
262 // Keyboard modifier value to EFI Scan Code convertion table
263 // EFI Scan Code and the modifier values are defined in UEFI spec.
265 UINT8 ModifierValueToEfiScanCodeConvertionTable
[] = {
266 SCAN_NULL
, // EFI_NULL_MODIFIER
267 SCAN_NULL
, // EFI_LEFT_CONTROL_MODIFIER
268 SCAN_NULL
, // EFI_RIGHT_CONTROL_MODIFIER
269 SCAN_NULL
, // EFI_LEFT_ALT_MODIFIER
270 SCAN_NULL
, // EFI_RIGHT_ALT_MODIFIER
271 SCAN_NULL
, // EFI_ALT_GR_MODIFIER
272 SCAN_INSERT
, // EFI_INSERT_MODIFIER
273 SCAN_DELETE
, // EFI_DELETE_MODIFIER
274 SCAN_PAGE_DOWN
, // EFI_PAGE_DOWN_MODIFIER
275 SCAN_PAGE_UP
, // EFI_PAGE_UP_MODIFIER
276 SCAN_HOME
, // EFI_HOME_MODIFIER
277 SCAN_END
, // EFI_END_MODIFIER
278 SCAN_NULL
, // EFI_LEFT_SHIFT_MODIFIER
279 SCAN_NULL
, // EFI_RIGHT_SHIFT_MODIFIER
280 SCAN_NULL
, // EFI_CAPS_LOCK_MODIFIER
281 SCAN_NULL
, // EFI_NUM_LOCK_MODIFIER
282 SCAN_LEFT
, // EFI_LEFT_ARROW_MODIFIER
283 SCAN_RIGHT
, // EFI_RIGHT_ARROW_MODIFIER
284 SCAN_DOWN
, // EFI_DOWN_ARROW_MODIFIER
285 SCAN_UP
, // EFI_UP_ARROW_MODIFIER
286 SCAN_NULL
, // EFI_NS_KEY_MODIFIER
287 SCAN_NULL
, // EFI_NS_KEY_DEPENDENCY_MODIFIER
288 SCAN_F1
, // EFI_FUNCTION_KEY_ONE_MODIFIER
289 SCAN_F2
, // EFI_FUNCTION_KEY_TWO_MODIFIER
290 SCAN_F3
, // EFI_FUNCTION_KEY_THREE_MODIFIER
291 SCAN_F4
, // EFI_FUNCTION_KEY_FOUR_MODIFIER
292 SCAN_F5
, // EFI_FUNCTION_KEY_FIVE_MODIFIER
293 SCAN_F6
, // EFI_FUNCTION_KEY_SIX_MODIFIER
294 SCAN_F7
, // EFI_FUNCTION_KEY_SEVEN_MODIFIER
295 SCAN_F8
, // EFI_FUNCTION_KEY_EIGHT_MODIFIER
296 SCAN_F9
, // EFI_FUNCTION_KEY_NINE_MODIFIER
297 SCAN_F10
, // EFI_FUNCTION_KEY_TEN_MODIFIER
298 SCAN_F11
, // EFI_FUNCTION_KEY_ELEVEN_MODIFIER
299 SCAN_F12
, // EFI_FUNCTION_KEY_TWELVE_MODIFIER
301 // For Partial Keystroke support
303 SCAN_NULL
, // EFI_PRINT_MODIFIER
304 SCAN_NULL
, // EFI_SYS_REQUEST_MODIFIER
305 SCAN_NULL
, // EFI_SCROLL_LOCK_MODIFIER
306 SCAN_PAUSE
, // EFI_PAUSE_MODIFIER
307 SCAN_NULL
, // EFI_BREAK_MODIFIER
308 SCAN_NULL
, // EFI_LEFT_LOGO_MODIFIER
309 SCAN_NULL
, // EFI_RIGHT_LOGO_MODIFER
310 SCAN_NULL
, // EFI_MENU_MODIFER
314 Initialize Key Convention Table by using default keyboard layout.
316 @param UsbKeyboardDevice The USB_KB_DEV instance.
318 @retval EFI_SUCCESS The default keyboard layout was installed successfully
319 @retval Others Failure to install default keyboard layout.
322 InstallDefaultKeyboardLayout (
323 IN OUT USB_KB_DEV
*UsbKeyboardDevice
327 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
328 EFI_HII_HANDLE HiiHandle
;
331 // Locate Hii database protocol
333 Status
= gBS
->LocateProtocol (
334 &gEfiHiiDatabaseProtocolGuid
,
336 (VOID
**) &HiiDatabase
338 if (EFI_ERROR (Status
)) {
343 // Install Keyboard Layout package to HII database
345 HiiHandle
= HiiAddPackages (
346 &gUsbKeyboardLayoutPackageGuid
,
347 UsbKeyboardDevice
->ControllerHandle
,
348 &mUsbKeyboardLayoutBin
,
351 if (HiiHandle
== NULL
) {
352 return EFI_OUT_OF_RESOURCES
;
356 // Set current keyboard layout
358 Status
= HiiDatabase
->SetKeyboardLayout (HiiDatabase
, &gUsbKeyboardLayoutKeyGuid
);
365 Uses USB I/O to check whether the device is a USB keyboard device.
367 @param UsbIo Pointer to a USB I/O protocol instance.
369 @retval TRUE Device is a USB keyboard device.
370 @retval FALSE Device is a not USB keyboard device.
375 IN EFI_USB_IO_PROTOCOL
*UsbIo
379 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
382 // Get the default interface descriptor
384 Status
= UsbIo
->UsbGetInterfaceDescriptor (
389 if (EFI_ERROR (Status
)) {
393 if (InterfaceDescriptor
.InterfaceClass
== CLASS_HID
&&
394 InterfaceDescriptor
.InterfaceSubClass
== SUBCLASS_BOOT
&&
395 InterfaceDescriptor
.InterfaceProtocol
== PROTOCOL_KEYBOARD
404 Get current keyboard layout from HII database.
406 @return Pointer to HII Keyboard Layout.
407 NULL means failure occurred while trying to get keyboard layout.
410 EFI_HII_KEYBOARD_LAYOUT
*
411 GetCurrentKeyboardLayout (
416 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
417 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
421 // Locate HII Database Protocol
423 Status
= gBS
->LocateProtocol (
424 &gEfiHiiDatabaseProtocolGuid
,
426 (VOID
**) &HiiDatabase
428 if (EFI_ERROR (Status
)) {
433 // Get current keyboard layout from HII database
436 KeyboardLayout
= NULL
;
437 Status
= HiiDatabase
->GetKeyboardLayout (
443 if (Status
== EFI_BUFFER_TOO_SMALL
) {
444 KeyboardLayout
= AllocatePool (Length
);
445 ASSERT (KeyboardLayout
!= NULL
);
447 Status
= HiiDatabase
->GetKeyboardLayout (
453 if (EFI_ERROR (Status
)) {
454 FreePool (KeyboardLayout
);
455 KeyboardLayout
= NULL
;
459 return KeyboardLayout
;
463 Find Key Descriptor in Key Convertion Table given its USB keycode.
465 @param UsbKeyboardDevice The USB_KB_DEV instance.
466 @param KeyCode USB Keycode.
468 @return The Key Descriptor in Key Convertion Table.
469 NULL means not found.
474 IN USB_KB_DEV
*UsbKeyboardDevice
,
481 // Make sure KeyCode is in the range of [0x4, 0x65] or [0xe0, 0xe7]
483 if ((!USBKBD_VALID_KEYCODE (KeyCode
)) || ((KeyCode
> 0x65) && (KeyCode
< 0xe0)) || (KeyCode
> 0xe7)) {
488 // Calculate the index of Key Descriptor in Key Convertion Table
490 if (KeyCode
<= 0x65) {
491 Index
= (UINT8
) (KeyCode
- 4);
493 Index
= (UINT8
) (KeyCode
- 0xe0 + NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE
);
496 return &UsbKeyboardDevice
->KeyConvertionTable
[Index
];
500 Find Non-Spacing key for given Key descriptor.
502 @param UsbKeyboardDevice The USB_KB_DEV instance.
503 @param KeyDescriptor Key descriptor.
505 @return The Non-Spacing key corresponding to KeyDescriptor
506 NULL means not found.
511 IN USB_KB_DEV
*UsbKeyboardDevice
,
512 IN EFI_KEY_DESCRIPTOR
*KeyDescriptor
516 LIST_ENTRY
*NsKeyList
;
517 USB_NS_KEY
*UsbNsKey
;
519 NsKeyList
= &UsbKeyboardDevice
->NsKeyList
;
520 Link
= GetFirstNode (NsKeyList
);
521 while (!IsNull (NsKeyList
, Link
)) {
522 UsbNsKey
= USB_NS_KEY_FORM_FROM_LINK (Link
);
524 if (UsbNsKey
->NsKey
[0].Key
== KeyDescriptor
->Key
) {
528 Link
= GetNextNode (NsKeyList
, Link
);
535 Find physical key definition for a given key descriptor.
537 For a specified non-spacing key, there are a list of physical
538 keys following it. This function traverses the list of
539 physical keys and tries to find the physical key matching
542 @param UsbNsKey The non-spacing key information.
543 @param KeyDescriptor The key descriptor.
545 @return The physical key definition.
546 If no physical key is found, parameter KeyDescriptor is returned.
551 IN USB_NS_KEY
*UsbNsKey
,
552 IN EFI_KEY_DESCRIPTOR
*KeyDescriptor
556 EFI_KEY_DESCRIPTOR
*PhysicalKey
;
558 PhysicalKey
= &UsbNsKey
->NsKey
[1];
559 for (Index
= 0; Index
< UsbNsKey
->KeyCount
; Index
++) {
560 if (KeyDescriptor
->Key
== PhysicalKey
->Key
) {
568 // No children definition matched, return original key
570 return KeyDescriptor
;
574 The notification function for EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID.
576 This function is registered to event of EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
577 group type, which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
578 It tries to get curent keyboard layout from HII database.
580 @param Event Event being signaled.
581 @param Context Points to USB_KB_DEV instance.
586 SetKeyboardLayoutEvent (
591 USB_KB_DEV
*UsbKeyboardDevice
;
592 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
593 EFI_KEY_DESCRIPTOR TempKey
;
594 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
595 EFI_KEY_DESCRIPTOR
*TableEntry
;
596 EFI_KEY_DESCRIPTOR
*NsKey
;
597 USB_NS_KEY
*UsbNsKey
;
603 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
604 if (UsbKeyboardDevice
->Signature
!= USB_KB_DEV_SIGNATURE
) {
609 // Try to get current keyboard layout from HII database
611 KeyboardLayout
= GetCurrentKeyboardLayout ();
612 if (KeyboardLayout
== NULL
) {
617 // Re-allocate resource for KeyConvertionTable
619 ReleaseKeyboardLayoutResources (UsbKeyboardDevice
);
620 UsbKeyboardDevice
->KeyConvertionTable
= AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE
) * sizeof (EFI_KEY_DESCRIPTOR
));
621 ASSERT (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
);
624 // Traverse the list of key descriptors following the header of EFI_HII_KEYBOARD_LAYOUT
626 KeyDescriptor
= (EFI_KEY_DESCRIPTOR
*) (((UINT8
*) KeyboardLayout
) + sizeof (EFI_HII_KEYBOARD_LAYOUT
));
627 for (Index
= 0; Index
< KeyboardLayout
->DescriptorCount
; Index
++) {
629 // Copy from HII keyboard layout package binary for alignment
631 CopyMem (&TempKey
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
634 // Fill the key into KeyConvertionTable, whose index is calculated from USB keycode.
636 KeyCode
= EfiKeyToUsbKeyCodeConvertionTable
[(UINT8
) (TempKey
.Key
)];
637 TableEntry
= GetKeyDescriptor (UsbKeyboardDevice
, KeyCode
);
638 if (TableEntry
== NULL
) {
639 ReleaseKeyboardLayoutResources (UsbKeyboardDevice
);
640 FreePool (KeyboardLayout
);
643 CopyMem (TableEntry
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
646 // For non-spacing key, create the list with a non-spacing key followed by physical keys.
648 if (TempKey
.Modifier
== EFI_NS_KEY_MODIFIER
) {
649 UsbNsKey
= AllocateZeroPool (sizeof (USB_NS_KEY
));
650 ASSERT (UsbNsKey
!= NULL
);
653 // Search for sequential children physical key definitions
656 NsKey
= KeyDescriptor
+ 1;
657 for (Index2
= (UINT8
) Index
+ 1; Index2
< KeyboardLayout
->DescriptorCount
; Index2
++) {
658 CopyMem (&TempKey
, NsKey
, sizeof (EFI_KEY_DESCRIPTOR
));
659 if (TempKey
.Modifier
== EFI_NS_KEY_DEPENDENCY_MODIFIER
) {
667 UsbNsKey
->Signature
= USB_NS_KEY_SIGNATURE
;
668 UsbNsKey
->KeyCount
= KeyCount
;
669 UsbNsKey
->NsKey
= AllocateCopyPool (
670 (KeyCount
+ 1) * sizeof (EFI_KEY_DESCRIPTOR
),
673 InsertTailList (&UsbKeyboardDevice
->NsKeyList
, &UsbNsKey
->Link
);
676 // Skip over the child physical keys
679 KeyDescriptor
+= KeyCount
;
686 // There are two EfiKeyEnter, duplicate its key descriptor
688 TableEntry
= GetKeyDescriptor (UsbKeyboardDevice
, 0x58);
689 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, 0x28);
690 CopyMem (TableEntry
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
692 FreePool (KeyboardLayout
);
696 Destroy resources for keyboard layout.
698 @param UsbKeyboardDevice The USB_KB_DEV instance.
702 ReleaseKeyboardLayoutResources (
703 IN OUT USB_KB_DEV
*UsbKeyboardDevice
706 USB_NS_KEY
*UsbNsKey
;
709 if (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
) {
710 FreePool (UsbKeyboardDevice
->KeyConvertionTable
);
712 UsbKeyboardDevice
->KeyConvertionTable
= NULL
;
714 while (!IsListEmpty (&UsbKeyboardDevice
->NsKeyList
)) {
715 Link
= GetFirstNode (&UsbKeyboardDevice
->NsKeyList
);
716 UsbNsKey
= USB_NS_KEY_FORM_FROM_LINK (Link
);
717 RemoveEntryList (&UsbNsKey
->Link
);
719 FreePool (UsbNsKey
->NsKey
);
725 Initialize USB keyboard layout.
727 This function initializes Key Convertion Table for the USB keyboard device.
728 It first tries to retrieve layout from HII database. If failed and default
729 layout is enabled, then it just uses the default layout.
731 @param UsbKeyboardDevice The USB_KB_DEV instance.
733 @retval EFI_SUCCESS Initialization succeeded.
734 @retval EFI_NOT_READY Keyboard layout cannot be retrieve from HII
735 database, and default layout is disabled.
736 @retval Other Fail to register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group.
741 OUT USB_KB_DEV
*UsbKeyboardDevice
744 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
747 UsbKeyboardDevice
->KeyConvertionTable
= AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE
) * sizeof (EFI_KEY_DESCRIPTOR
));
748 ASSERT (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
);
750 InitializeListHead (&UsbKeyboardDevice
->NsKeyList
);
751 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
752 UsbKeyboardDevice
->KeyboardLayoutEvent
= NULL
;
755 // Register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group,
756 // which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
758 Status
= gBS
->CreateEventEx (
761 SetKeyboardLayoutEvent
,
763 &gEfiHiiKeyBoardLayoutGuid
,
764 &UsbKeyboardDevice
->KeyboardLayoutEvent
766 if (EFI_ERROR (Status
)) {
770 KeyboardLayout
= GetCurrentKeyboardLayout ();
771 if (KeyboardLayout
!= NULL
) {
773 // If current keyboard layout is successfully retrieved from HII database,
774 // force to initialize the keyboard layout.
776 gBS
->SignalEvent (UsbKeyboardDevice
->KeyboardLayoutEvent
);
778 if (FeaturePcdGet (PcdDisableDefaultKeyboardLayoutInUsbKbDriver
)) {
780 // If no keyboard layout can be retrieved from HII database, and default layout
781 // is disabled, then return EFI_NOT_READY.
783 return EFI_NOT_READY
;
786 // If no keyboard layout can be retrieved from HII database, and default layout
787 // is enabled, then load the default keyboard layout.
789 InstallDefaultKeyboardLayout (UsbKeyboardDevice
);
797 Initialize USB keyboard device and all private data structures.
799 @param UsbKeyboardDevice The USB_KB_DEV instance.
801 @retval EFI_SUCCESS Initialization is successful.
802 @retval EFI_DEVICE_ERROR Keyboard initialization failed.
807 IN OUT USB_KB_DEV
*UsbKeyboardDevice
813 UINT32 TransferResult
;
815 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
817 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_KEYBOARD_PC_SELF_TEST
),
818 UsbKeyboardDevice
->DevicePath
821 InitQueue (&UsbKeyboardDevice
->UsbKeyQueue
, sizeof (USB_KEY
));
822 InitQueue (&UsbKeyboardDevice
->EfiKeyQueue
, sizeof (EFI_KEY_DATA
));
823 InitQueue (&UsbKeyboardDevice
->EfiKeyQueueForNotify
, sizeof (EFI_KEY_DATA
));
826 // Use the config out of the descriptor
827 // Assumed the first config is the correct one and this is not always the case
829 Status
= UsbGetConfiguration (
830 UsbKeyboardDevice
->UsbIo
,
834 if (EFI_ERROR (Status
)) {
837 // Uses default configuration to configure the USB Keyboard device.
839 Status
= UsbSetConfiguration (
840 UsbKeyboardDevice
->UsbIo
,
844 if (EFI_ERROR (Status
)) {
846 // If configuration could not be set here, it means
847 // the keyboard interface has some errors and could
848 // not be initialized
850 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
851 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
852 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_INTERFACE_ERROR
),
853 UsbKeyboardDevice
->DevicePath
856 return EFI_DEVICE_ERROR
;
860 UsbGetProtocolRequest (
861 UsbKeyboardDevice
->UsbIo
,
862 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
866 // Set boot protocol for the USB Keyboard.
867 // This driver only supports boot protocol.
869 if (Protocol
!= BOOT_PROTOCOL
) {
870 UsbSetProtocolRequest (
871 UsbKeyboardDevice
->UsbIo
,
872 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
877 UsbKeyboardDevice
->CtrlOn
= FALSE
;
878 UsbKeyboardDevice
->AltOn
= FALSE
;
879 UsbKeyboardDevice
->ShiftOn
= FALSE
;
880 UsbKeyboardDevice
->NumLockOn
= FALSE
;
881 UsbKeyboardDevice
->CapsOn
= FALSE
;
882 UsbKeyboardDevice
->ScrollOn
= FALSE
;
884 UsbKeyboardDevice
->LeftCtrlOn
= FALSE
;
885 UsbKeyboardDevice
->LeftAltOn
= FALSE
;
886 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
887 UsbKeyboardDevice
->LeftLogoOn
= FALSE
;
888 UsbKeyboardDevice
->RightCtrlOn
= FALSE
;
889 UsbKeyboardDevice
->RightAltOn
= FALSE
;
890 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
891 UsbKeyboardDevice
->RightLogoOn
= FALSE
;
892 UsbKeyboardDevice
->MenuKeyOn
= FALSE
;
893 UsbKeyboardDevice
->SysReqOn
= FALSE
;
895 UsbKeyboardDevice
->AltGrOn
= FALSE
;
897 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
900 // Sync the initial state of lights on keyboard.
902 SetKeyLED (UsbKeyboardDevice
);
904 ZeroMem (UsbKeyboardDevice
->LastKeyCodeArray
, sizeof (UINT8
) * 8);
907 // Create event for repeat keys' generation.
909 if (UsbKeyboardDevice
->RepeatTimer
!= NULL
) {
910 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
911 UsbKeyboardDevice
->RepeatTimer
= NULL
;
915 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
917 USBKeyboardRepeatHandler
,
919 &UsbKeyboardDevice
->RepeatTimer
923 // Create event for delayed recovery, which deals with device error.
925 if (UsbKeyboardDevice
->DelayedRecoveryEvent
!= NULL
) {
926 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
927 UsbKeyboardDevice
->DelayedRecoveryEvent
= NULL
;
931 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
933 USBKeyboardRecoveryHandler
,
935 &UsbKeyboardDevice
->DelayedRecoveryEvent
943 Handler function for USB keyboard's asynchronous interrupt transfer.
945 This function is the handler function for USB keyboard's asynchronous interrupt transfer
946 to manage the keyboard. It parses the USB keyboard input report, and inserts data to
947 keyboard buffer according to state of modifer keys and normal keys. Timer for repeat key
948 is also set accordingly.
950 @param Data A pointer to a buffer that is filled with key data which is
951 retrieved via asynchronous interrupt transfer.
952 @param DataLength Indicates the size of the data buffer.
953 @param Context Pointing to USB_KB_DEV instance.
954 @param Result Indicates the result of the asynchronous interrupt transfer.
956 @retval EFI_SUCCESS Asynchronous interrupt transfer is handled successfully.
957 @retval EFI_DEVICE_ERROR Hardware error occurs.
969 USB_KB_DEV
*UsbKeyboardDevice
;
970 EFI_USB_IO_PROTOCOL
*UsbIo
;
971 UINT8
*CurKeyCodeBuffer
;
972 UINT8
*OldKeyCodeBuffer
;
973 UINT8 CurModifierMap
;
974 UINT8 OldModifierMap
;
983 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
985 ASSERT (Context
!= NULL
);
988 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
989 UsbIo
= UsbKeyboardDevice
->UsbIo
;
992 // Analyzes Result and performs corresponding action.
994 if (Result
!= EFI_USB_NOERROR
) {
996 // Some errors happen during the process
998 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
999 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1000 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_INPUT_ERROR
),
1001 UsbKeyboardDevice
->DevicePath
1005 // Stop the repeat key generation if any
1007 UsbKeyboardDevice
->RepeatKey
= 0;
1010 UsbKeyboardDevice
->RepeatTimer
,
1015 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
1016 UsbClearEndpointHalt (
1018 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1024 // Delete & Submit this interrupt again
1025 // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt.
1027 UsbIo
->UsbAsyncInterruptTransfer (
1029 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1037 // EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling.
1040 UsbKeyboardDevice
->DelayedRecoveryEvent
,
1042 EFI_USB_INTERRUPT_DELAY
1045 return EFI_DEVICE_ERROR
;
1049 // If no error and no data, just return EFI_SUCCESS.
1051 if (DataLength
== 0 || Data
== NULL
) {
1056 // Following code checks current keyboard input report against old key code buffer.
1057 // According to USB HID Firmware Specification, the report consists of 8 bytes.
1058 // Byte 0 is map of Modifier keys.
1059 // Byte 1 is reserved.
1060 // Bytes 2 to 7 are keycodes.
1062 if (DataLength
< 8) {
1063 return EFI_DEVICE_ERROR
;
1066 CurKeyCodeBuffer
= (UINT8
*) Data
;
1067 OldKeyCodeBuffer
= UsbKeyboardDevice
->LastKeyCodeArray
;
1070 // Checks for new key stroke.
1072 for (Index
= 0; Index
< 8; Index
++) {
1073 if (OldKeyCodeBuffer
[Index
] != CurKeyCodeBuffer
[Index
]) {
1079 // If no new key, return EFI_SUCCESS immediately.
1086 // Parse the modifier key, which is the first byte of keyboard input report.
1088 CurModifierMap
= CurKeyCodeBuffer
[0];
1089 OldModifierMap
= OldKeyCodeBuffer
[0];
1092 // Handle modifier key's pressing or releasing situation.
1093 // According to USB HID Firmware spec, Byte 0 uses folloing map of Modifier keys:
1094 // Bit0: Left Control, Keycode: 0xe0
1095 // Bit1: Left Shift, Keycode: 0xe1
1096 // Bit2: Left Alt, Keycode: 0xe2
1097 // Bit3: Left GUI, Keycode: 0xe3
1098 // Bit4: Right Control, Keycode: 0xe4
1099 // Bit5: Right Shift, Keycode: 0xe5
1100 // Bit6: Right Alt, Keycode: 0xe6
1101 // Bit7: Right GUI, Keycode: 0xe7
1103 for (Index
= 0; Index
< 8; Index
++) {
1104 Mask
= (UINT8
) (1 << Index
);
1105 if ((CurModifierMap
& Mask
) != (OldModifierMap
& Mask
)) {
1107 // If current modifier key is up, then CurModifierMap & Mask = 0;
1108 // otherwise it is a non-zero value.
1109 // Insert the changed modifier key into key buffer.
1111 UsbKey
.KeyCode
= (UINT8
) (0xe0 + Index
);
1112 UsbKey
.Down
= (BOOLEAN
) ((CurModifierMap
& Mask
) != 0);
1113 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1118 // Handle normal key's releasing situation
1119 // Bytes 2 to 7 are for normal keycodes
1122 for (Index
= 2; Index
< 8; Index
++) {
1124 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index
])) {
1128 // For any key in old keycode buffer, if it is not in current keycode buffer,
1129 // then it is released. Otherwise, it is not released.
1132 for (Index2
= 2; Index2
< 8; Index2
++) {
1134 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index2
])) {
1138 if (OldKeyCodeBuffer
[Index
] == CurKeyCodeBuffer
[Index2
]) {
1145 UsbKey
.KeyCode
= OldKeyCodeBuffer
[Index
];
1146 UsbKey
.Down
= FALSE
;
1147 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1149 // The original repeat key is released.
1151 if (OldKeyCodeBuffer
[Index
] == UsbKeyboardDevice
->RepeatKey
) {
1152 UsbKeyboardDevice
->RepeatKey
= 0;
1158 // If original repeat key is released, cancel the repeat timer
1160 if (UsbKeyboardDevice
->RepeatKey
== 0) {
1162 UsbKeyboardDevice
->RepeatTimer
,
1169 // Handle normal key's pressing situation
1172 for (Index
= 2; Index
< 8; Index
++) {
1174 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index
])) {
1178 // For any key in current keycode buffer, if it is not in old keycode buffer,
1179 // then it is pressed. Otherwise, it is not pressed.
1182 for (Index2
= 2; Index2
< 8; Index2
++) {
1184 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index2
])) {
1188 if (CurKeyCodeBuffer
[Index
] == OldKeyCodeBuffer
[Index2
]) {
1195 UsbKey
.KeyCode
= CurKeyCodeBuffer
[Index
];
1197 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1200 // Handle repeat key
1202 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, CurKeyCodeBuffer
[Index
]);
1203 if (KeyDescriptor
== NULL
) {
1207 if (KeyDescriptor
->Modifier
== EFI_NUM_LOCK_MODIFIER
|| KeyDescriptor
->Modifier
== EFI_CAPS_LOCK_MODIFIER
) {
1209 // For NumLock or CapsLock pressed, there is no need to handle repeat key for them.
1211 UsbKeyboardDevice
->RepeatKey
= 0;
1214 // Prepare new repeat key, and clear the original one.
1216 NewRepeatKey
= CurKeyCodeBuffer
[Index
];
1217 UsbKeyboardDevice
->RepeatKey
= 0;
1223 // Update LastKeycodeArray buffer in the UsbKeyboardDevice data structure.
1225 for (Index
= 0; Index
< 8; Index
++) {
1226 UsbKeyboardDevice
->LastKeyCodeArray
[Index
] = CurKeyCodeBuffer
[Index
];
1230 // If there is new key pressed, update the RepeatKey value, and set the
1231 // timer to repeate delay timer
1233 if (NewRepeatKey
!= 0) {
1235 // Sets trigger time to "Repeat Delay Time",
1236 // to trigger the repeat timer when the key is hold long
1240 UsbKeyboardDevice
->RepeatTimer
,
1244 UsbKeyboardDevice
->RepeatKey
= NewRepeatKey
;
1252 Retrieves a USB keycode after parsing the raw data in keyboard buffer.
1254 This function parses keyboard buffer. It updates state of modifier key for
1255 USB_KB_DEV instancem, and returns keycode for output.
1257 @param UsbKeyboardDevice The USB_KB_DEV instance.
1258 @param KeyCode Pointer to the USB keycode for output.
1260 @retval EFI_SUCCESS Keycode successfully parsed.
1261 @retval EFI_NOT_READY Keyboard buffer is not ready for a valid keycode
1266 IN OUT USB_KB_DEV
*UsbKeyboardDevice
,
1271 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1275 while (!IsQueueEmpty (&UsbKeyboardDevice
->UsbKeyQueue
)) {
1277 // Pops one raw data off.
1279 Dequeue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1281 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, UsbKey
.KeyCode
);
1282 if (KeyDescriptor
== NULL
) {
1289 switch (KeyDescriptor
->Modifier
) {
1294 case EFI_LEFT_CONTROL_MODIFIER
:
1295 UsbKeyboardDevice
->LeftCtrlOn
= FALSE
;
1296 UsbKeyboardDevice
->CtrlOn
= FALSE
;
1298 case EFI_RIGHT_CONTROL_MODIFIER
:
1299 UsbKeyboardDevice
->RightCtrlOn
= FALSE
;
1300 UsbKeyboardDevice
->CtrlOn
= FALSE
;
1306 case EFI_LEFT_SHIFT_MODIFIER
:
1307 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
1308 UsbKeyboardDevice
->ShiftOn
= FALSE
;
1310 case EFI_RIGHT_SHIFT_MODIFIER
:
1311 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
1312 UsbKeyboardDevice
->ShiftOn
= FALSE
;
1318 case EFI_LEFT_ALT_MODIFIER
:
1319 UsbKeyboardDevice
->LeftAltOn
= FALSE
;
1320 UsbKeyboardDevice
->AltOn
= FALSE
;
1322 case EFI_RIGHT_ALT_MODIFIER
:
1323 UsbKeyboardDevice
->RightAltOn
= FALSE
;
1324 UsbKeyboardDevice
->AltOn
= FALSE
;
1328 // Left Logo release
1330 case EFI_LEFT_LOGO_MODIFIER
:
1331 UsbKeyboardDevice
->LeftLogoOn
= FALSE
;
1335 // Right Logo release
1337 case EFI_RIGHT_LOGO_MODIFIER
:
1338 UsbKeyboardDevice
->RightLogoOn
= FALSE
;
1344 case EFI_MENU_MODIFIER
:
1345 UsbKeyboardDevice
->MenuKeyOn
= FALSE
;
1351 case EFI_PRINT_MODIFIER
:
1352 case EFI_SYS_REQUEST_MODIFIER
:
1353 UsbKeyboardDevice
->SysReqOn
= FALSE
;
1359 case EFI_ALT_GR_MODIFIER
:
1360 UsbKeyboardDevice
->AltGrOn
= FALSE
;
1371 // Analyzes key pressing situation
1373 switch (KeyDescriptor
->Modifier
) {
1378 case EFI_LEFT_CONTROL_MODIFIER
:
1379 UsbKeyboardDevice
->LeftCtrlOn
= TRUE
;
1380 UsbKeyboardDevice
->CtrlOn
= TRUE
;
1382 case EFI_RIGHT_CONTROL_MODIFIER
:
1383 UsbKeyboardDevice
->RightCtrlOn
= TRUE
;
1384 UsbKeyboardDevice
->CtrlOn
= TRUE
;
1390 case EFI_LEFT_SHIFT_MODIFIER
:
1391 UsbKeyboardDevice
->LeftShiftOn
= TRUE
;
1392 UsbKeyboardDevice
->ShiftOn
= TRUE
;
1394 case EFI_RIGHT_SHIFT_MODIFIER
:
1395 UsbKeyboardDevice
->RightShiftOn
= TRUE
;
1396 UsbKeyboardDevice
->ShiftOn
= TRUE
;
1402 case EFI_LEFT_ALT_MODIFIER
:
1403 UsbKeyboardDevice
->LeftAltOn
= TRUE
;
1404 UsbKeyboardDevice
->AltOn
= TRUE
;
1406 case EFI_RIGHT_ALT_MODIFIER
:
1407 UsbKeyboardDevice
->RightAltOn
= TRUE
;
1408 UsbKeyboardDevice
->AltOn
= TRUE
;
1414 case EFI_LEFT_LOGO_MODIFIER
:
1415 UsbKeyboardDevice
->LeftLogoOn
= TRUE
;
1421 case EFI_RIGHT_LOGO_MODIFIER
:
1422 UsbKeyboardDevice
->RightLogoOn
= TRUE
;
1428 case EFI_MENU_MODIFIER
:
1429 UsbKeyboardDevice
->MenuKeyOn
= TRUE
;
1435 case EFI_PRINT_MODIFIER
:
1436 case EFI_SYS_REQUEST_MODIFIER
:
1437 UsbKeyboardDevice
->SysReqOn
= TRUE
;
1443 case EFI_ALT_GR_MODIFIER
:
1444 UsbKeyboardDevice
->AltGrOn
= TRUE
;
1447 case EFI_NUM_LOCK_MODIFIER
:
1451 UsbKeyboardDevice
->NumLockOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->NumLockOn
));
1452 SetKeyLED (UsbKeyboardDevice
);
1455 case EFI_CAPS_LOCK_MODIFIER
:
1459 UsbKeyboardDevice
->CapsOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->CapsOn
));
1460 SetKeyLED (UsbKeyboardDevice
);
1463 case EFI_SCROLL_LOCK_MODIFIER
:
1465 // Toggle ScrollLock
1467 UsbKeyboardDevice
->ScrollOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->ScrollOn
));
1468 SetKeyLED (UsbKeyboardDevice
);
1476 // When encountering Ctrl + Alt + Del, then warm reset.
1478 if (KeyDescriptor
->Modifier
== EFI_DELETE_MODIFIER
) {
1479 if ((UsbKeyboardDevice
->CtrlOn
) && (UsbKeyboardDevice
->AltOn
)) {
1480 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1484 *KeyCode
= UsbKey
.KeyCode
;
1488 return EFI_NOT_READY
;
1492 Initialize the key state.
1494 @param UsbKeyboardDevice The USB_KB_DEV instance.
1495 @param KeyState A pointer to receive the key state information.
1498 InitializeKeyState (
1499 IN USB_KB_DEV
*UsbKeyboardDevice
,
1500 OUT EFI_KEY_STATE
*KeyState
1503 KeyState
->KeyShiftState
= EFI_SHIFT_STATE_VALID
;
1504 KeyState
->KeyToggleState
= EFI_TOGGLE_STATE_VALID
;
1506 if (UsbKeyboardDevice
->LeftCtrlOn
) {
1507 KeyState
->KeyShiftState
|= EFI_LEFT_CONTROL_PRESSED
;
1509 if (UsbKeyboardDevice
->RightCtrlOn
) {
1510 KeyState
->KeyShiftState
|= EFI_RIGHT_CONTROL_PRESSED
;
1512 if (UsbKeyboardDevice
->LeftAltOn
) {
1513 KeyState
->KeyShiftState
|= EFI_LEFT_ALT_PRESSED
;
1515 if (UsbKeyboardDevice
->RightAltOn
) {
1516 KeyState
->KeyShiftState
|= EFI_RIGHT_ALT_PRESSED
;
1518 if (UsbKeyboardDevice
->LeftShiftOn
) {
1519 KeyState
->KeyShiftState
|= EFI_LEFT_SHIFT_PRESSED
;
1521 if (UsbKeyboardDevice
->RightShiftOn
) {
1522 KeyState
->KeyShiftState
|= EFI_RIGHT_SHIFT_PRESSED
;
1524 if (UsbKeyboardDevice
->LeftLogoOn
) {
1525 KeyState
->KeyShiftState
|= EFI_LEFT_LOGO_PRESSED
;
1527 if (UsbKeyboardDevice
->RightLogoOn
) {
1528 KeyState
->KeyShiftState
|= EFI_RIGHT_LOGO_PRESSED
;
1530 if (UsbKeyboardDevice
->MenuKeyOn
) {
1531 KeyState
->KeyShiftState
|= EFI_MENU_KEY_PRESSED
;
1533 if (UsbKeyboardDevice
->SysReqOn
) {
1534 KeyState
->KeyShiftState
|= EFI_SYS_REQ_PRESSED
;
1537 if (UsbKeyboardDevice
->ScrollOn
) {
1538 KeyState
->KeyToggleState
|= EFI_SCROLL_LOCK_ACTIVE
;
1540 if (UsbKeyboardDevice
->NumLockOn
) {
1541 KeyState
->KeyToggleState
|= EFI_NUM_LOCK_ACTIVE
;
1543 if (UsbKeyboardDevice
->CapsOn
) {
1544 KeyState
->KeyToggleState
|= EFI_CAPS_LOCK_ACTIVE
;
1546 if (UsbKeyboardDevice
->IsSupportPartialKey
) {
1547 KeyState
->KeyToggleState
|= EFI_KEY_STATE_EXPOSED
;
1552 Converts USB Keycode ranging from 0x4 to 0x65 to EFI_INPUT_KEY.
1554 @param UsbKeyboardDevice The USB_KB_DEV instance.
1555 @param KeyCode Indicates the key code that will be interpreted.
1556 @param KeyData A pointer to a buffer that is filled in with
1557 the keystroke information for the key that
1560 @retval EFI_SUCCESS Success.
1561 @retval EFI_INVALID_PARAMETER KeyCode is not in the range of 0x4 to 0x65.
1562 @retval EFI_INVALID_PARAMETER Translated EFI_INPUT_KEY has zero for both ScanCode and UnicodeChar.
1563 @retval EFI_NOT_READY KeyCode represents a dead key with EFI_NS_KEY_MODIFIER
1564 @retval EFI_DEVICE_ERROR Keyboard layout is invalid.
1568 UsbKeyCodeToEfiInputKey (
1569 IN USB_KB_DEV
*UsbKeyboardDevice
,
1571 OUT EFI_KEY_DATA
*KeyData
1574 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1576 LIST_ENTRY
*NotifyList
;
1577 KEYBOARD_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
1580 // KeyCode must in the range of [0x4, 0x65] or [0xe0, 0xe7].
1582 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, KeyCode
);
1583 if (KeyDescriptor
== NULL
) {
1584 return EFI_DEVICE_ERROR
;
1587 if (KeyDescriptor
->Modifier
== EFI_NS_KEY_MODIFIER
) {
1589 // If this is a dead key with EFI_NS_KEY_MODIFIER, then record it and return.
1591 UsbKeyboardDevice
->CurrentNsKey
= FindUsbNsKey (UsbKeyboardDevice
, KeyDescriptor
);
1592 return EFI_NOT_READY
;
1595 if (UsbKeyboardDevice
->CurrentNsKey
!= NULL
) {
1597 // If this keystroke follows a non-spacing key, then find the descriptor for corresponding
1600 KeyDescriptor
= FindPhysicalKey (UsbKeyboardDevice
->CurrentNsKey
, KeyDescriptor
);
1601 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
1605 // Make sure modifier of Key Descriptor is in the valid range according to UEFI spec.
1607 if (KeyDescriptor
->Modifier
>= (sizeof (ModifierValueToEfiScanCodeConvertionTable
) / sizeof (UINT8
))) {
1608 return EFI_DEVICE_ERROR
;
1611 KeyData
->Key
.ScanCode
= ModifierValueToEfiScanCodeConvertionTable
[KeyDescriptor
->Modifier
];
1612 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->Unicode
;
1614 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_STANDARD_SHIFT
)!= 0) {
1615 if (UsbKeyboardDevice
->ShiftOn
) {
1616 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->ShiftedUnicode
;
1619 // Need not return associated shift state if a class of printable characters that
1620 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
1622 if ((KeyDescriptor
->Unicode
!= CHAR_NULL
) && (KeyDescriptor
->ShiftedUnicode
!= CHAR_NULL
) &&
1623 (KeyDescriptor
->Unicode
!= KeyDescriptor
->ShiftedUnicode
)) {
1624 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
1625 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
1628 if (UsbKeyboardDevice
->AltGrOn
) {
1629 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->ShiftedAltGrUnicode
;
1635 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->Unicode
;
1637 if (UsbKeyboardDevice
->AltGrOn
) {
1638 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->AltGrUnicode
;
1643 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_CAPS_LOCK
) != 0) {
1644 if (UsbKeyboardDevice
->CapsOn
) {
1645 if (KeyData
->Key
.UnicodeChar
== KeyDescriptor
->Unicode
) {
1646 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->ShiftedUnicode
;
1647 } else if (KeyData
->Key
.UnicodeChar
== KeyDescriptor
->ShiftedUnicode
) {
1648 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->Unicode
;
1653 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_NUM_LOCK
) != 0) {
1655 // For key affected by NumLock, if NumLock is on and Shift is not pressed, then it means
1656 // normal key, instead of original control key. So the ScanCode should be cleaned.
1657 // Otherwise, it means control key, so preserve the EFI Scan Code and clear the unicode keycode.
1659 if ((UsbKeyboardDevice
->NumLockOn
) && (!(UsbKeyboardDevice
->ShiftOn
))) {
1660 KeyData
->Key
.ScanCode
= SCAN_NULL
;
1662 KeyData
->Key
.UnicodeChar
= CHAR_NULL
;
1667 // Translate Unicode 0x1B (ESC) to EFI Scan Code
1669 if (KeyData
->Key
.UnicodeChar
== 0x1B && KeyData
->Key
.ScanCode
== SCAN_NULL
) {
1670 KeyData
->Key
.ScanCode
= SCAN_ESC
;
1671 KeyData
->Key
.UnicodeChar
= CHAR_NULL
;
1675 // Not valid for key without both unicode key code and EFI Scan Code.
1677 if (KeyData
->Key
.UnicodeChar
== 0 && KeyData
->Key
.ScanCode
== SCAN_NULL
) {
1678 if (!UsbKeyboardDevice
->IsSupportPartialKey
) {
1679 return EFI_NOT_READY
;
1684 // Save Shift/Toggle state
1686 InitializeKeyState (UsbKeyboardDevice
, &KeyData
->KeyState
);
1689 // Signal KeyNotify process event if this key pressed matches any key registered.
1691 NotifyList
= &UsbKeyboardDevice
->NotifyList
;
1692 for (Link
= GetFirstNode (NotifyList
); !IsNull (NotifyList
, Link
); Link
= GetNextNode (NotifyList
, Link
)) {
1693 CurrentNotify
= CR (Link
, KEYBOARD_CONSOLE_IN_EX_NOTIFY
, NotifyEntry
, USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
1694 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
1696 // The key notification function needs to run at TPL_CALLBACK
1697 // while current TPL is TPL_NOTIFY. It will be invoked in
1698 // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.
1700 Enqueue (&UsbKeyboardDevice
->EfiKeyQueueForNotify
, KeyData
, sizeof (*KeyData
));
1701 gBS
->SignalEvent (UsbKeyboardDevice
->KeyNotifyProcessEvent
);
1712 @param Queue Points to the queue.
1713 @param ItemSize Size of the single item.
1718 IN OUT USB_SIMPLE_QUEUE
*Queue
,
1724 Queue
->ItemSize
= ItemSize
;
1728 if (Queue
->Buffer
[0] != NULL
) {
1729 FreePool (Queue
->Buffer
[0]);
1732 Queue
->Buffer
[0] = AllocatePool (sizeof (Queue
->Buffer
) / sizeof (Queue
->Buffer
[0]) * ItemSize
);
1733 ASSERT (Queue
->Buffer
[0] != NULL
);
1735 for (Index
= 1; Index
< sizeof (Queue
->Buffer
) / sizeof (Queue
->Buffer
[0]); Index
++) {
1736 Queue
->Buffer
[Index
] = ((UINT8
*) Queue
->Buffer
[Index
- 1]) + ItemSize
;
1743 @param Queue Points to the queue.
1747 IN OUT USB_SIMPLE_QUEUE
*Queue
1750 FreePool (Queue
->Buffer
[0]);
1755 Check whether the queue is empty.
1757 @param Queue Points to the queue.
1759 @retval TRUE Queue is empty.
1760 @retval FALSE Queue is not empty.
1765 IN USB_SIMPLE_QUEUE
*Queue
1769 // Meet FIFO empty condition
1771 return (BOOLEAN
) (Queue
->Head
== Queue
->Tail
);
1776 Check whether the queue is full.
1778 @param Queue Points to the queue.
1780 @retval TRUE Queue is full.
1781 @retval FALSE Queue is not full.
1786 IN USB_SIMPLE_QUEUE
*Queue
1789 return (BOOLEAN
) (((Queue
->Tail
+ 1) % (MAX_KEY_ALLOWED
+ 1)) == Queue
->Head
);
1794 Enqueue the item to the queue.
1796 @param Queue Points to the queue.
1797 @param Item Points to the item to be enqueued.
1798 @param ItemSize Size of the item.
1802 IN OUT USB_SIMPLE_QUEUE
*Queue
,
1807 ASSERT (ItemSize
== Queue
->ItemSize
);
1809 // If keyboard buffer is full, throw the
1810 // first key out of the keyboard buffer.
1812 if (IsQueueFull (Queue
)) {
1813 Queue
->Head
= (Queue
->Head
+ 1) % (MAX_KEY_ALLOWED
+ 1);
1816 CopyMem (Queue
->Buffer
[Queue
->Tail
], Item
, ItemSize
);
1819 // Adjust the tail pointer of the FIFO keyboard buffer.
1821 Queue
->Tail
= (Queue
->Tail
+ 1) % (MAX_KEY_ALLOWED
+ 1);
1826 Dequeue a item from the queue.
1828 @param Queue Points to the queue.
1829 @param Item Receives the item.
1830 @param ItemSize Size of the item.
1832 @retval EFI_SUCCESS Item was successfully dequeued.
1833 @retval EFI_DEVICE_ERROR The queue is empty.
1838 IN OUT USB_SIMPLE_QUEUE
*Queue
,
1843 ASSERT (Queue
->ItemSize
== ItemSize
);
1845 if (IsQueueEmpty (Queue
)) {
1846 return EFI_DEVICE_ERROR
;
1849 CopyMem (Item
, Queue
->Buffer
[Queue
->Head
], ItemSize
);
1852 // Adjust the head pointer of the FIFO keyboard buffer.
1854 Queue
->Head
= (Queue
->Head
+ 1) % (MAX_KEY_ALLOWED
+ 1);
1861 Sets USB keyboard LED state.
1863 @param UsbKeyboardDevice The USB_KB_DEV instance.
1868 IN USB_KB_DEV
*UsbKeyboardDevice
1875 // Set each field in Led map.
1877 Led
.NumLock
= (UINT8
) ((UsbKeyboardDevice
->NumLockOn
) ? 1 : 0);
1878 Led
.CapsLock
= (UINT8
) ((UsbKeyboardDevice
->CapsOn
) ? 1 : 0);
1879 Led
.ScrollLock
= (UINT8
) ((UsbKeyboardDevice
->ScrollOn
) ? 1 : 0);
1884 // Call Set_Report Request to lighten the LED.
1886 UsbSetReportRequest (
1887 UsbKeyboardDevice
->UsbIo
,
1888 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
1898 Handler for Repeat Key event.
1900 This function is the handler for Repeat Key event triggered
1902 After a repeatable key is pressed, the event would be triggered
1903 with interval of USBKBD_REPEAT_DELAY. Once the event is triggered,
1904 following trigger will come with interval of USBKBD_REPEAT_RATE.
1906 @param Event The Repeat Key event.
1907 @param Context Points to the USB_KB_DEV instance.
1912 USBKeyboardRepeatHandler (
1917 USB_KB_DEV
*UsbKeyboardDevice
;
1920 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1923 // Do nothing when there is no repeat key.
1925 if (UsbKeyboardDevice
->RepeatKey
!= 0) {
1927 // Inserts the repeat key into keyboard buffer,
1929 UsbKey
.KeyCode
= UsbKeyboardDevice
->RepeatKey
;
1931 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1934 // Set repeat rate for next repeat key generation.
1937 UsbKeyboardDevice
->RepeatTimer
,
1946 Handler for Delayed Recovery event.
1948 This function is the handler for Delayed Recovery event triggered
1950 After a device error occurs, the event would be triggered
1951 with interval of EFI_USB_INTERRUPT_DELAY. EFI_USB_INTERRUPT_DELAY
1952 is defined in USB standard for error handling.
1954 @param Event The Delayed Recovery event.
1955 @param Context Points to the USB_KB_DEV instance.
1960 USBKeyboardRecoveryHandler (
1966 USB_KB_DEV
*UsbKeyboardDevice
;
1967 EFI_USB_IO_PROTOCOL
*UsbIo
;
1970 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1972 UsbIo
= UsbKeyboardDevice
->UsbIo
;
1974 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
1977 // Re-submit Asynchronous Interrupt Transfer for recovery.
1979 UsbIo
->UsbAsyncInterruptTransfer (
1981 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1983 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,