2 Helper functions for USB Keyboard Driver.
4 Copyright (c) 2004 - 2011, 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 EFI_GUID mUsbKeyboardLayoutPackageGuid
= USB_KEYBOARD_LAYOUT_PACKAGE_GUID
;
18 EFI_GUID mUsbKeyboardLayoutKeyGuid
= USB_KEYBOARD_LAYOUT_KEY_GUID
;
20 USB_KEYBOARD_LAYOUT_PACK_BIN mUsbKeyboardLayoutBin
= {
21 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN
), // Binary size
24 // EFI_HII_PACKAGE_HEADER
27 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN
) - sizeof (UINT32
),
28 EFI_HII_PACKAGE_KEYBOARD_LAYOUT
31 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN
) - sizeof (UINT32
) - sizeof (EFI_HII_PACKAGE_HEADER
) - sizeof (UINT16
), // LayoutLength
32 USB_KEYBOARD_LAYOUT_KEY_GUID
, // KeyGuid
33 sizeof (UINT16
) + sizeof (EFI_GUID
) + sizeof (UINT32
) + sizeof (UINT8
) + (USB_KEYBOARD_KEY_COUNT
* sizeof (EFI_KEY_DESCRIPTOR
)), // LayoutDescriptorStringOffset
34 USB_KEYBOARD_KEY_COUNT
, // DescriptorCount
37 // EFI_KEY_DESCRIPTOR (total number is USB_KEYBOARD_KEY_COUNT)
39 {EfiKeyC1
, 'a', 'A', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
40 {EfiKeyB5
, 'b', 'B', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
41 {EfiKeyB3
, 'c', 'C', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
42 {EfiKeyC3
, 'd', 'D', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
43 {EfiKeyD3
, 'e', 'E', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
44 {EfiKeyC4
, 'f', 'F', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
45 {EfiKeyC5
, 'g', 'G', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
46 {EfiKeyC6
, 'h', 'H', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
47 {EfiKeyD8
, 'i', 'I', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
48 {EfiKeyC7
, 'j', 'J', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
49 {EfiKeyC8
, 'k', 'K', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
50 {EfiKeyC9
, 'l', 'L', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
51 {EfiKeyB7
, 'm', 'M', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
52 {EfiKeyB6
, 'n', 'N', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
53 {EfiKeyD9
, 'o', 'O', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
54 {EfiKeyD10
, 'p', 'P', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
55 {EfiKeyD1
, 'q', 'Q', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
56 {EfiKeyD4
, 'r', 'R', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
57 {EfiKeyC2
, 's', 'S', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
58 {EfiKeyD5
, 't', 'T', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
59 {EfiKeyD7
, 'u', 'U', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
60 {EfiKeyB4
, 'v', 'V', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
61 {EfiKeyD2
, 'w', 'W', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
62 {EfiKeyB2
, 'x', 'X', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
63 {EfiKeyD6
, 'y', 'Y', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
64 {EfiKeyB1
, 'z', 'Z', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
},
65 {EfiKeyE1
, '1', '!', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
66 {EfiKeyE2
, '2', '@', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
67 {EfiKeyE3
, '3', '#', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
68 {EfiKeyE4
, '4', '$', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
69 {EfiKeyE5
, '5', '%', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
70 {EfiKeyE6
, '6', '^', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
71 {EfiKeyE7
, '7', '&', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
72 {EfiKeyE8
, '8', '*', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
73 {EfiKeyE9
, '9', '(', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
74 {EfiKeyE10
, '0', ')', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
75 {EfiKeyEnter
, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER
, 0},
76 {EfiKeyEsc
, 0x1b, 0x1b, 0, 0, EFI_NULL_MODIFIER
, 0},
77 {EfiKeyBackSpace
, 0x08, 0x08, 0, 0, EFI_NULL_MODIFIER
, 0},
78 {EfiKeyTab
, 0x09, 0x09, 0, 0, EFI_NULL_MODIFIER
, 0},
79 {EfiKeySpaceBar
, ' ', ' ', 0, 0, EFI_NULL_MODIFIER
, 0},
80 {EfiKeyE11
, '-', '_', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
81 {EfiKeyE12
, '=', '+', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
82 {EfiKeyD11
, '[', '{', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
83 {EfiKeyD12
, ']', '}', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
84 {EfiKeyD13
, '\\', '|', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
85 {EfiKeyC10
, ';', ':', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
86 {EfiKeyC11
, '\'', '"', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
87 {EfiKeyE0
, '`', '~', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
88 {EfiKeyB8
, ',', '<', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
89 {EfiKeyB9
, '.', '>', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
90 {EfiKeyB10
, '/', '?', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
91 {EfiKeyCapsLock
, 0x00, 0x00, 0, 0, EFI_CAPS_LOCK_MODIFIER
, 0},
92 {EfiKeyF1
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ONE_MODIFIER
, 0},
93 {EfiKeyF2
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWO_MODIFIER
, 0},
94 {EfiKeyF3
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_THREE_MODIFIER
, 0},
95 {EfiKeyF4
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FOUR_MODIFIER
, 0},
96 {EfiKeyF5
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FIVE_MODIFIER
, 0},
97 {EfiKeyF6
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SIX_MODIFIER
, 0},
98 {EfiKeyF7
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SEVEN_MODIFIER
, 0},
99 {EfiKeyF8
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_EIGHT_MODIFIER
, 0},
100 {EfiKeyF9
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_NINE_MODIFIER
, 0},
101 {EfiKeyF10
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TEN_MODIFIER
, 0},
102 {EfiKeyF11
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ELEVEN_MODIFIER
, 0},
103 {EfiKeyF12
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWELVE_MODIFIER
, 0},
104 {EfiKeyPrint
, 0x00, 0x00, 0, 0, EFI_PRINT_MODIFIER
, 0},
105 {EfiKeySLck
, 0x00, 0x00, 0, 0, EFI_SCROLL_LOCK_MODIFIER
, 0},
106 {EfiKeyPause
, 0x00, 0x00, 0, 0, EFI_PAUSE_MODIFIER
, 0},
107 {EfiKeyIns
, 0x00, 0x00, 0, 0, EFI_INSERT_MODIFIER
, 0},
108 {EfiKeyHome
, 0x00, 0x00, 0, 0, EFI_HOME_MODIFIER
, 0},
109 {EfiKeyPgUp
, 0x00, 0x00, 0, 0, EFI_PAGE_UP_MODIFIER
, 0},
110 {EfiKeyDel
, 0x00, 0x00, 0, 0, EFI_DELETE_MODIFIER
, 0},
111 {EfiKeyEnd
, 0x00, 0x00, 0, 0, EFI_END_MODIFIER
, 0},
112 {EfiKeyPgDn
, 0x00, 0x00, 0, 0, EFI_PAGE_DOWN_MODIFIER
, 0},
113 {EfiKeyRightArrow
, 0x00, 0x00, 0, 0, EFI_RIGHT_ARROW_MODIFIER
, 0},
114 {EfiKeyLeftArrow
, 0x00, 0x00, 0, 0, EFI_LEFT_ARROW_MODIFIER
, 0},
115 {EfiKeyDownArrow
, 0x00, 0x00, 0, 0, EFI_DOWN_ARROW_MODIFIER
, 0},
116 {EfiKeyUpArrow
, 0x00, 0x00, 0, 0, EFI_UP_ARROW_MODIFIER
, 0},
117 {EfiKeyNLck
, 0x00, 0x00, 0, 0, EFI_NUM_LOCK_MODIFIER
, 0},
118 {EfiKeySlash
, '/', '/', 0, 0, EFI_NULL_MODIFIER
, 0},
119 {EfiKeyAsterisk
, '*', '*', 0, 0, EFI_NULL_MODIFIER
, 0},
120 {EfiKeyMinus
, '-', '-', 0, 0, EFI_NULL_MODIFIER
, 0},
121 {EfiKeyPlus
, '+', '+', 0, 0, EFI_NULL_MODIFIER
, 0},
122 {EfiKeyEnter
, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER
, 0},
123 {EfiKeyOne
, '1', '1', 0, 0, EFI_END_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
124 {EfiKeyTwo
, '2', '2', 0, 0, EFI_DOWN_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
125 {EfiKeyThree
, '3', '3', 0, 0, EFI_PAGE_DOWN_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
126 {EfiKeyFour
, '4', '4', 0, 0, EFI_LEFT_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
127 {EfiKeyFive
, '5', '5', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
128 {EfiKeySix
, '6', '6', 0, 0, EFI_RIGHT_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
129 {EfiKeySeven
, '7', '7', 0, 0, EFI_HOME_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
130 {EfiKeyEight
, '8', '8', 0, 0, EFI_UP_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
131 {EfiKeyNine
, '9', '9', 0, 0, EFI_PAGE_UP_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
132 {EfiKeyZero
, '0', '0', 0, 0, EFI_INSERT_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
133 {EfiKeyPeriod
, '.', '.', 0, 0, EFI_DELETE_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
134 {EfiKeyA4
, 0x00, 0x00, 0, 0, EFI_MENU_MODIFIER
, 0},
135 {EfiKeyLCtrl
, 0, 0, 0, 0, EFI_LEFT_CONTROL_MODIFIER
, 0},
136 {EfiKeyLShift
, 0, 0, 0, 0, EFI_LEFT_SHIFT_MODIFIER
, 0},
137 {EfiKeyLAlt
, 0, 0, 0, 0, EFI_LEFT_ALT_MODIFIER
, 0},
138 {EfiKeyA0
, 0, 0, 0, 0, EFI_LEFT_LOGO_MODIFIER
, 0},
139 {EfiKeyRCtrl
, 0, 0, 0, 0, EFI_RIGHT_CONTROL_MODIFIER
, 0},
140 {EfiKeyRShift
, 0, 0, 0, 0, EFI_RIGHT_SHIFT_MODIFIER
, 0},
141 {EfiKeyA2
, 0, 0, 0, 0, EFI_RIGHT_ALT_MODIFIER
, 0},
142 {EfiKeyA3
, 0, 0, 0, 0, EFI_RIGHT_LOGO_MODIFIER
, 0},
144 1, // DescriptionCount
145 {'e', 'n', '-', 'U', 'S'}, // RFC4646 language code
147 {'E', 'n', 'g', 'l', 'i', 's', 'h', ' ', 'K', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '\0'}, // DescriptionString[]
151 // EFI_KEY to USB Keycode conversion table
152 // EFI_KEY is defined in UEFI spec.
153 // USB Keycode is defined in USB HID Firmware spec.
155 UINT8 EfiKeyToUsbKeyCodeConvertionTable
[] = {
159 0x2c, // EfiKeySpaceBar
164 0x50, // EfiKeyLeftArrow
165 0x51, // EfiKeyDownArrow
166 0x4F, // EfiKeyRightArrow
168 0x63, // EfiKeyPeriod
170 0xe1, // EfiKeyLShift
182 0xe5, // EfiKeyRShift
183 0x52, // EfiKeyUpArrow
187 0x39, // EfiKeyCapsLock
237 0x2A, // EfiKeyBackSpace
243 0x55, // EfiKeyAsterisk
264 // Keyboard modifier value to EFI Scan Code convertion table
265 // EFI Scan Code and the modifier values are defined in UEFI spec.
267 UINT8 ModifierValueToEfiScanCodeConvertionTable
[] = {
268 SCAN_NULL
, // EFI_NULL_MODIFIER
269 SCAN_NULL
, // EFI_LEFT_CONTROL_MODIFIER
270 SCAN_NULL
, // EFI_RIGHT_CONTROL_MODIFIER
271 SCAN_NULL
, // EFI_LEFT_ALT_MODIFIER
272 SCAN_NULL
, // EFI_RIGHT_ALT_MODIFIER
273 SCAN_NULL
, // EFI_ALT_GR_MODIFIER
274 SCAN_INSERT
, // EFI_INSERT_MODIFIER
275 SCAN_DELETE
, // EFI_DELETE_MODIFIER
276 SCAN_PAGE_DOWN
, // EFI_PAGE_DOWN_MODIFIER
277 SCAN_PAGE_UP
, // EFI_PAGE_UP_MODIFIER
278 SCAN_HOME
, // EFI_HOME_MODIFIER
279 SCAN_END
, // EFI_END_MODIFIER
280 SCAN_NULL
, // EFI_LEFT_SHIFT_MODIFIER
281 SCAN_NULL
, // EFI_RIGHT_SHIFT_MODIFIER
282 SCAN_NULL
, // EFI_CAPS_LOCK_MODIFIER
283 SCAN_NULL
, // EFI_NUM_LOCK_MODIFIER
284 SCAN_LEFT
, // EFI_LEFT_ARROW_MODIFIER
285 SCAN_RIGHT
, // EFI_RIGHT_ARROW_MODIFIER
286 SCAN_DOWN
, // EFI_DOWN_ARROW_MODIFIER
287 SCAN_UP
, // EFI_UP_ARROW_MODIFIER
288 SCAN_NULL
, // EFI_NS_KEY_MODIFIER
289 SCAN_NULL
, // EFI_NS_KEY_DEPENDENCY_MODIFIER
290 SCAN_F1
, // EFI_FUNCTION_KEY_ONE_MODIFIER
291 SCAN_F2
, // EFI_FUNCTION_KEY_TWO_MODIFIER
292 SCAN_F3
, // EFI_FUNCTION_KEY_THREE_MODIFIER
293 SCAN_F4
, // EFI_FUNCTION_KEY_FOUR_MODIFIER
294 SCAN_F5
, // EFI_FUNCTION_KEY_FIVE_MODIFIER
295 SCAN_F6
, // EFI_FUNCTION_KEY_SIX_MODIFIER
296 SCAN_F7
, // EFI_FUNCTION_KEY_SEVEN_MODIFIER
297 SCAN_F8
, // EFI_FUNCTION_KEY_EIGHT_MODIFIER
298 SCAN_F9
, // EFI_FUNCTION_KEY_NINE_MODIFIER
299 SCAN_F10
, // EFI_FUNCTION_KEY_TEN_MODIFIER
300 SCAN_F11
, // EFI_FUNCTION_KEY_ELEVEN_MODIFIER
301 SCAN_F12
, // EFI_FUNCTION_KEY_TWELVE_MODIFIER
302 SCAN_NULL
, // EFI_PRINT_MODIFIER
303 SCAN_NULL
, // EFI_SYS_REQUEST_MODIFIER
304 SCAN_NULL
, // EFI_SCROLL_LOCK_MODIFIER
305 SCAN_PAUSE
// EFI_PAUSE_MODIFIER
309 Initialize Key Convention Table by using default keyboard layout.
311 @param UsbKeyboardDevice The USB_KB_DEV instance.
313 @retval EFI_SUCCESS The default keyboard layout was installed successfully
314 @retval Others Failure to install default keyboard layout.
317 InstallDefaultKeyboardLayout (
318 IN OUT USB_KB_DEV
*UsbKeyboardDevice
322 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
323 EFI_HII_HANDLE HiiHandle
;
326 // Locate Hii database protocol
328 Status
= gBS
->LocateProtocol (
329 &gEfiHiiDatabaseProtocolGuid
,
331 (VOID
**) &HiiDatabase
333 if (EFI_ERROR (Status
)) {
338 // Install Keyboard Layout package to HII database
340 HiiHandle
= HiiAddPackages (
341 &mUsbKeyboardLayoutPackageGuid
,
342 UsbKeyboardDevice
->ControllerHandle
,
343 &mUsbKeyboardLayoutBin
,
346 if (HiiHandle
== NULL
) {
347 return EFI_OUT_OF_RESOURCES
;
351 // Set current keyboard layout
353 Status
= HiiDatabase
->SetKeyboardLayout (HiiDatabase
, &mUsbKeyboardLayoutKeyGuid
);
360 Uses USB I/O to check whether the device is a USB keyboard device.
362 @param UsbIo Pointer to a USB I/O protocol instance.
364 @retval TRUE Device is a USB keyboard device.
365 @retval FALSE Device is a not USB keyboard device.
370 IN EFI_USB_IO_PROTOCOL
*UsbIo
374 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
377 // Get the default interface descriptor
379 Status
= UsbIo
->UsbGetInterfaceDescriptor (
384 if (EFI_ERROR (Status
)) {
388 if (InterfaceDescriptor
.InterfaceClass
== CLASS_HID
&&
389 InterfaceDescriptor
.InterfaceSubClass
== SUBCLASS_BOOT
&&
390 InterfaceDescriptor
.InterfaceProtocol
== PROTOCOL_KEYBOARD
399 Get current keyboard layout from HII database.
401 @return Pointer to HII Keyboard Layout.
402 NULL means failure occurred while trying to get keyboard layout.
405 EFI_HII_KEYBOARD_LAYOUT
*
406 GetCurrentKeyboardLayout (
411 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
412 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
416 // Locate HII Database Protocol
418 Status
= gBS
->LocateProtocol (
419 &gEfiHiiDatabaseProtocolGuid
,
421 (VOID
**) &HiiDatabase
423 if (EFI_ERROR (Status
)) {
428 // Get current keyboard layout from HII database
431 KeyboardLayout
= NULL
;
432 Status
= HiiDatabase
->GetKeyboardLayout (
438 if (Status
== EFI_BUFFER_TOO_SMALL
) {
439 KeyboardLayout
= AllocatePool (Length
);
440 ASSERT (KeyboardLayout
!= NULL
);
442 Status
= HiiDatabase
->GetKeyboardLayout (
448 if (EFI_ERROR (Status
)) {
449 FreePool (KeyboardLayout
);
450 KeyboardLayout
= NULL
;
454 return KeyboardLayout
;
458 Find Key Descriptor in Key Convertion Table given its USB keycode.
460 @param UsbKeyboardDevice The USB_KB_DEV instance.
461 @param KeyCode USB Keycode.
463 @return The Key Descriptor in Key Convertion Table.
464 NULL means not found.
469 IN USB_KB_DEV
*UsbKeyboardDevice
,
476 // Make sure KeyCode is in the range of [0x4, 0x65] or [0xe0, 0xe7]
478 if ((!USBKBD_VALID_KEYCODE (KeyCode
)) || ((KeyCode
> 0x65) && (KeyCode
< 0xe0)) || (KeyCode
> 0xe7)) {
483 // Calculate the index of Key Descriptor in Key Convertion Table
485 if (KeyCode
<= 0x65) {
486 Index
= (UINT8
) (KeyCode
- 4);
488 Index
= (UINT8
) (KeyCode
- 0xe0 + NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE
);
491 return &UsbKeyboardDevice
->KeyConvertionTable
[Index
];
495 Find Non-Spacing key for given Key descriptor.
497 @param UsbKeyboardDevice The USB_KB_DEV instance.
498 @param KeyDescriptor Key descriptor.
500 @return The Non-Spacing key corresponding to KeyDescriptor
501 NULL means not found.
506 IN USB_KB_DEV
*UsbKeyboardDevice
,
507 IN EFI_KEY_DESCRIPTOR
*KeyDescriptor
511 LIST_ENTRY
*NsKeyList
;
512 USB_NS_KEY
*UsbNsKey
;
514 NsKeyList
= &UsbKeyboardDevice
->NsKeyList
;
515 Link
= GetFirstNode (NsKeyList
);
516 while (!IsNull (NsKeyList
, Link
)) {
517 UsbNsKey
= USB_NS_KEY_FORM_FROM_LINK (Link
);
519 if (UsbNsKey
->NsKey
[0].Key
== KeyDescriptor
->Key
) {
523 Link
= GetNextNode (NsKeyList
, Link
);
530 Find physical key definition for a given key descriptor.
532 For a specified non-spacing key, there are a list of physical
533 keys following it. This function traverses the list of
534 physical keys and tries to find the physical key matching
537 @param UsbNsKey The non-spacing key information.
538 @param KeyDescriptor The key descriptor.
540 @return The physical key definition.
541 If no physical key is found, parameter KeyDescriptor is returned.
546 IN USB_NS_KEY
*UsbNsKey
,
547 IN EFI_KEY_DESCRIPTOR
*KeyDescriptor
551 EFI_KEY_DESCRIPTOR
*PhysicalKey
;
553 PhysicalKey
= &UsbNsKey
->NsKey
[1];
554 for (Index
= 0; Index
< UsbNsKey
->KeyCount
; Index
++) {
555 if (KeyDescriptor
->Key
== PhysicalKey
->Key
) {
563 // No children definition matched, return original key
565 return KeyDescriptor
;
569 The notification function for EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID.
571 This function is registered to event of EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
572 group type, which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
573 It tries to get curent keyboard layout from HII database.
575 @param Event Event being signaled.
576 @param Context Points to USB_KB_DEV instance.
581 SetKeyboardLayoutEvent (
586 USB_KB_DEV
*UsbKeyboardDevice
;
587 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
588 EFI_KEY_DESCRIPTOR TempKey
;
589 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
590 EFI_KEY_DESCRIPTOR
*TableEntry
;
591 EFI_KEY_DESCRIPTOR
*NsKey
;
592 USB_NS_KEY
*UsbNsKey
;
598 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
599 if (UsbKeyboardDevice
->Signature
!= USB_KB_DEV_SIGNATURE
) {
604 // Try to get current keyboard layout from HII database
606 KeyboardLayout
= GetCurrentKeyboardLayout ();
607 if (KeyboardLayout
== NULL
) {
612 // Re-allocate resource for KeyConvertionTable
614 ReleaseKeyboardLayoutResources (UsbKeyboardDevice
);
615 UsbKeyboardDevice
->KeyConvertionTable
= AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE
) * sizeof (EFI_KEY_DESCRIPTOR
));
616 ASSERT (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
);
619 // Traverse the list of key descriptors following the header of EFI_HII_KEYBOARD_LAYOUT
621 KeyDescriptor
= (EFI_KEY_DESCRIPTOR
*) (((UINT8
*) KeyboardLayout
) + sizeof (EFI_HII_KEYBOARD_LAYOUT
));
622 for (Index
= 0; Index
< KeyboardLayout
->DescriptorCount
; Index
++) {
624 // Copy from HII keyboard layout package binary for alignment
626 CopyMem (&TempKey
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
629 // Fill the key into KeyConvertionTable, whose index is calculated from USB keycode.
631 KeyCode
= EfiKeyToUsbKeyCodeConvertionTable
[(UINT8
) (TempKey
.Key
)];
632 TableEntry
= GetKeyDescriptor (UsbKeyboardDevice
, KeyCode
);
633 CopyMem (TableEntry
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
636 // For non-spacing key, create the list with a non-spacing key followed by physical keys.
638 if (TempKey
.Modifier
== EFI_NS_KEY_MODIFIER
) {
639 UsbNsKey
= AllocatePool (sizeof (USB_NS_KEY
));
640 ASSERT (UsbNsKey
!= NULL
);
643 // Search for sequential children physical key definitions
646 NsKey
= KeyDescriptor
+ 1;
647 for (Index2
= (UINT8
) Index
+ 1; Index2
< KeyboardLayout
->DescriptorCount
; Index2
++) {
648 CopyMem (&TempKey
, NsKey
, sizeof (EFI_KEY_DESCRIPTOR
));
649 if (TempKey
.Modifier
== EFI_NS_KEY_DEPENDENCY_MODIFIER
) {
657 UsbNsKey
->Signature
= USB_NS_KEY_SIGNATURE
;
658 UsbNsKey
->KeyCount
= KeyCount
;
659 UsbNsKey
->NsKey
= AllocateCopyPool (
660 (KeyCount
+ 1) * sizeof (EFI_KEY_DESCRIPTOR
),
663 InsertTailList (&UsbKeyboardDevice
->NsKeyList
, &UsbNsKey
->Link
);
666 // Skip over the child physical keys
669 KeyDescriptor
+= KeyCount
;
676 // There are two EfiKeyEnter, duplicate its key descriptor
678 TableEntry
= GetKeyDescriptor (UsbKeyboardDevice
, 0x58);
679 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, 0x28);
680 CopyMem (TableEntry
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
682 FreePool (KeyboardLayout
);
686 Destroy resources for keyboard layout.
688 @param UsbKeyboardDevice The USB_KB_DEV instance.
692 ReleaseKeyboardLayoutResources (
693 IN OUT USB_KB_DEV
*UsbKeyboardDevice
696 USB_NS_KEY
*UsbNsKey
;
699 if (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
) {
700 FreePool (UsbKeyboardDevice
->KeyConvertionTable
);
702 UsbKeyboardDevice
->KeyConvertionTable
= NULL
;
704 while (!IsListEmpty (&UsbKeyboardDevice
->NsKeyList
)) {
705 Link
= GetFirstNode (&UsbKeyboardDevice
->NsKeyList
);
706 UsbNsKey
= USB_NS_KEY_FORM_FROM_LINK (Link
);
707 RemoveEntryList (&UsbNsKey
->Link
);
709 FreePool (UsbNsKey
->NsKey
);
715 Initialize USB keyboard layout.
717 This function initializes Key Convertion Table for the USB keyboard device.
718 It first tries to retrieve layout from HII database. If failed and default
719 layout is enabled, then it just uses the default layout.
721 @param UsbKeyboardDevice The USB_KB_DEV instance.
723 @retval EFI_SUCCESS Initialization succeeded.
724 @retval EFI_NOT_READY Keyboard layout cannot be retrieve from HII
725 database, and default layout is disabled.
726 @retval Other Fail to register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group.
731 OUT USB_KB_DEV
*UsbKeyboardDevice
734 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
737 UsbKeyboardDevice
->KeyConvertionTable
= AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE
) * sizeof (EFI_KEY_DESCRIPTOR
));
738 ASSERT (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
);
740 InitializeListHead (&UsbKeyboardDevice
->NsKeyList
);
741 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
742 UsbKeyboardDevice
->KeyboardLayoutEvent
= NULL
;
745 // Register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group,
746 // which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
748 Status
= gBS
->CreateEventEx (
751 SetKeyboardLayoutEvent
,
753 &gEfiHiiKeyBoardLayoutGuid
,
754 &UsbKeyboardDevice
->KeyboardLayoutEvent
756 if (EFI_ERROR (Status
)) {
760 KeyboardLayout
= GetCurrentKeyboardLayout ();
761 if (KeyboardLayout
!= NULL
) {
763 // If current keyboard layout is successfully retrieved from HII database,
764 // force to initialize the keyboard layout.
766 gBS
->SignalEvent (UsbKeyboardDevice
->KeyboardLayoutEvent
);
768 if (FeaturePcdGet (PcdDisableDefaultKeyboardLayoutInUsbKbDriver
)) {
770 // If no keyboard layout can be retrieved from HII database, and default layout
771 // is disabled, then return EFI_NOT_READY.
773 return EFI_NOT_READY
;
776 // If no keyboard layout can be retrieved from HII database, and default layout
777 // is enabled, then load the default keyboard layout.
779 InstallDefaultKeyboardLayout (UsbKeyboardDevice
);
787 Initialize USB keyboard device and all private data structures.
789 @param UsbKeyboardDevice The USB_KB_DEV instance.
791 @retval EFI_SUCCESS Initialization is successful.
792 @retval EFI_DEVICE_ERROR Keyboard initialization failed.
797 IN OUT USB_KB_DEV
*UsbKeyboardDevice
805 UINT32 TransferResult
;
807 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
809 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_KEYBOARD_PC_SELF_TEST
),
810 UsbKeyboardDevice
->DevicePath
813 InitQueue (&UsbKeyboardDevice
->UsbKeyQueue
, sizeof (USB_KEY
));
814 InitQueue (&UsbKeyboardDevice
->EfiKeyQueue
, sizeof (EFI_KEY_DATA
));
817 // Use the config out of the descriptor
818 // Assumed the first config is the correct one and this is not always the case
820 Status
= UsbGetConfiguration (
821 UsbKeyboardDevice
->UsbIo
,
825 if (EFI_ERROR (Status
)) {
830 // Uses default configuration to configure the USB Keyboard device.
832 Status
= UsbSetConfiguration (
833 UsbKeyboardDevice
->UsbIo
,
837 if (EFI_ERROR (Status
)) {
839 // If configuration could not be set here, it means
840 // the keyboard interface has some errors and could
841 // not be initialized
843 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
844 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
845 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_INTERFACE_ERROR
),
846 UsbKeyboardDevice
->DevicePath
849 return EFI_DEVICE_ERROR
;
852 UsbGetProtocolRequest (
853 UsbKeyboardDevice
->UsbIo
,
854 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
858 // Set boot protocol for the USB Keyboard.
859 // This driver only supports boot protocol.
861 if (Protocol
!= BOOT_PROTOCOL
) {
862 UsbSetProtocolRequest (
863 UsbKeyboardDevice
->UsbIo
,
864 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
870 // ReportId is zero, which means the idle rate applies to all input reports.
874 // Duration is zero, which means the duration is infinite.
875 // so the endpoint will inhibit reporting forever,
876 // and only reporting when a change is detected in the report data.
880 UsbKeyboardDevice
->UsbIo
,
881 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
886 UsbKeyboardDevice
->CtrlOn
= FALSE
;
887 UsbKeyboardDevice
->AltOn
= FALSE
;
888 UsbKeyboardDevice
->ShiftOn
= FALSE
;
889 UsbKeyboardDevice
->NumLockOn
= FALSE
;
890 UsbKeyboardDevice
->CapsOn
= FALSE
;
891 UsbKeyboardDevice
->ScrollOn
= FALSE
;
893 UsbKeyboardDevice
->LeftCtrlOn
= FALSE
;
894 UsbKeyboardDevice
->LeftAltOn
= FALSE
;
895 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
896 UsbKeyboardDevice
->LeftLogoOn
= FALSE
;
897 UsbKeyboardDevice
->RightCtrlOn
= FALSE
;
898 UsbKeyboardDevice
->RightAltOn
= FALSE
;
899 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
900 UsbKeyboardDevice
->RightLogoOn
= FALSE
;
901 UsbKeyboardDevice
->MenuKeyOn
= FALSE
;
902 UsbKeyboardDevice
->SysReqOn
= FALSE
;
904 UsbKeyboardDevice
->AltGrOn
= FALSE
;
906 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
909 // Sync the initial state of lights on keyboard.
911 SetKeyLED (UsbKeyboardDevice
);
913 ZeroMem (UsbKeyboardDevice
->LastKeyCodeArray
, sizeof (UINT8
) * 8);
916 // Create event for repeat keys' generation.
918 if (UsbKeyboardDevice
->RepeatTimer
!= NULL
) {
919 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
920 UsbKeyboardDevice
->RepeatTimer
= NULL
;
924 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
926 USBKeyboardRepeatHandler
,
928 &UsbKeyboardDevice
->RepeatTimer
932 // Create event for delayed recovery, which deals with device error.
934 if (UsbKeyboardDevice
->DelayedRecoveryEvent
!= NULL
) {
935 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
936 UsbKeyboardDevice
->DelayedRecoveryEvent
= NULL
;
940 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
942 USBKeyboardRecoveryHandler
,
944 &UsbKeyboardDevice
->DelayedRecoveryEvent
952 Handler function for USB keyboard's asynchronous interrupt transfer.
954 This function is the handler function for USB keyboard's asynchronous interrupt transfer
955 to manage the keyboard. It parses the USB keyboard input report, and inserts data to
956 keyboard buffer according to state of modifer keys and normal keys. Timer for repeat key
957 is also set accordingly.
959 @param Data A pointer to a buffer that is filled with key data which is
960 retrieved via asynchronous interrupt transfer.
961 @param DataLength Indicates the size of the data buffer.
962 @param Context Pointing to USB_KB_DEV instance.
963 @param Result Indicates the result of the asynchronous interrupt transfer.
965 @retval EFI_SUCCESS Asynchronous interrupt transfer is handled successfully.
966 @retval EFI_DEVICE_ERROR Hardware error occurs.
978 USB_KB_DEV
*UsbKeyboardDevice
;
979 EFI_USB_IO_PROTOCOL
*UsbIo
;
980 UINT8
*CurKeyCodeBuffer
;
981 UINT8
*OldKeyCodeBuffer
;
982 UINT8 CurModifierMap
;
983 UINT8 OldModifierMap
;
992 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
994 ASSERT (Context
!= NULL
);
997 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
998 UsbIo
= UsbKeyboardDevice
->UsbIo
;
1001 // Analyzes Result and performs corresponding action.
1003 if (Result
!= EFI_USB_NOERROR
) {
1005 // Some errors happen during the process
1007 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1008 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1009 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_INPUT_ERROR
),
1010 UsbKeyboardDevice
->DevicePath
1014 // Stop the repeat key generation if any
1016 UsbKeyboardDevice
->RepeatKey
= 0;
1019 UsbKeyboardDevice
->RepeatTimer
,
1024 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
1025 UsbClearEndpointHalt (
1027 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1033 // Delete & Submit this interrupt again
1034 // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt.
1036 UsbIo
->UsbAsyncInterruptTransfer (
1038 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1046 // EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling.
1049 UsbKeyboardDevice
->DelayedRecoveryEvent
,
1051 EFI_USB_INTERRUPT_DELAY
1054 return EFI_DEVICE_ERROR
;
1058 // If no error and no data, just return EFI_SUCCESS.
1060 if (DataLength
== 0 || Data
== NULL
) {
1065 // Following code checks current keyboard input report against old key code buffer.
1066 // According to USB HID Firmware Specification, the report consists of 8 bytes.
1067 // Byte 0 is map of Modifier keys.
1068 // Byte 1 is reserved.
1069 // Bytes 2 to 7 are keycodes.
1071 CurKeyCodeBuffer
= (UINT8
*) Data
;
1072 OldKeyCodeBuffer
= UsbKeyboardDevice
->LastKeyCodeArray
;
1075 // Checks for new key stroke.
1077 for (Index
= 0; Index
< 8; Index
++) {
1078 if (OldKeyCodeBuffer
[Index
] != CurKeyCodeBuffer
[Index
]) {
1084 // If no new key, return EFI_SUCCESS immediately.
1091 // Parse the modifier key, which is the first byte of keyboard input report.
1093 CurModifierMap
= CurKeyCodeBuffer
[0];
1094 OldModifierMap
= OldKeyCodeBuffer
[0];
1097 // Handle modifier key's pressing or releasing situation.
1098 // According to USB HID Firmware spec, Byte 0 uses folloing map of Modifier keys:
1099 // Bit0: Left Control, Keycode: 0xe0
1100 // Bit1: Left Shift, Keycode: 0xe1
1101 // Bit2: Left Alt, Keycode: 0xe2
1102 // Bit3: Left GUI, Keycode: 0xe3
1103 // Bit4: Right Control, Keycode: 0xe4
1104 // Bit5: Right Shift, Keycode: 0xe5
1105 // Bit6: Right Alt, Keycode: 0xe6
1106 // Bit7: Right GUI, Keycode: 0xe7
1108 for (Index
= 0; Index
< 8; Index
++) {
1109 Mask
= (UINT8
) (1 << Index
);
1110 if ((CurModifierMap
& Mask
) != (OldModifierMap
& Mask
)) {
1112 // If current modifier key is up, then CurModifierMap & Mask = 0;
1113 // otherwise it is a non-zero value.
1114 // Insert the changed modifier key into key buffer.
1116 UsbKey
.KeyCode
= (UINT8
) (0xe0 + Index
);
1117 UsbKey
.Down
= (BOOLEAN
) ((CurModifierMap
& Mask
) != 0);
1118 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1123 // Handle normal key's releasing situation
1124 // Bytes 2 to 7 are for normal keycodes
1127 for (Index
= 2; Index
< 8; Index
++) {
1129 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index
])) {
1133 // For any key in old keycode buffer, if it is not in current keycode buffer,
1134 // then it is released. Otherwise, it is not released.
1137 for (Index2
= 2; Index2
< 8; Index2
++) {
1139 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index2
])) {
1143 if (OldKeyCodeBuffer
[Index
] == CurKeyCodeBuffer
[Index2
]) {
1150 UsbKey
.KeyCode
= OldKeyCodeBuffer
[Index
];
1151 UsbKey
.Down
= FALSE
;
1152 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1154 // The original repeat key is released.
1156 if (OldKeyCodeBuffer
[Index
] == UsbKeyboardDevice
->RepeatKey
) {
1157 UsbKeyboardDevice
->RepeatKey
= 0;
1163 // If original repeat key is released, cancel the repeat timer
1165 if (UsbKeyboardDevice
->RepeatKey
== 0) {
1167 UsbKeyboardDevice
->RepeatTimer
,
1174 // Handle normal key's pressing situation
1177 for (Index
= 2; Index
< 8; Index
++) {
1179 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index
])) {
1183 // For any key in current keycode buffer, if it is not in old keycode buffer,
1184 // then it is pressed. Otherwise, it is not pressed.
1187 for (Index2
= 2; Index2
< 8; Index2
++) {
1189 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index2
])) {
1193 if (CurKeyCodeBuffer
[Index
] == OldKeyCodeBuffer
[Index2
]) {
1200 UsbKey
.KeyCode
= CurKeyCodeBuffer
[Index
];
1202 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1205 // Handle repeat key
1207 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, CurKeyCodeBuffer
[Index
]);
1208 ASSERT (KeyDescriptor
!= NULL
);
1210 if (KeyDescriptor
->Modifier
== EFI_NUM_LOCK_MODIFIER
|| KeyDescriptor
->Modifier
== EFI_CAPS_LOCK_MODIFIER
) {
1212 // For NumLock or CapsLock pressed, there is no need to handle repeat key for them.
1214 UsbKeyboardDevice
->RepeatKey
= 0;
1217 // Prepare new repeat key, and clear the original one.
1219 NewRepeatKey
= CurKeyCodeBuffer
[Index
];
1220 UsbKeyboardDevice
->RepeatKey
= 0;
1226 // Update LastKeycodeArray buffer in the UsbKeyboardDevice data structure.
1228 for (Index
= 0; Index
< 8; Index
++) {
1229 UsbKeyboardDevice
->LastKeyCodeArray
[Index
] = CurKeyCodeBuffer
[Index
];
1233 // If there is new key pressed, update the RepeatKey value, and set the
1234 // timer to repeate delay timer
1236 if (NewRepeatKey
!= 0) {
1238 // Sets trigger time to "Repeat Delay Time",
1239 // to trigger the repeat timer when the key is hold long
1243 UsbKeyboardDevice
->RepeatTimer
,
1247 UsbKeyboardDevice
->RepeatKey
= NewRepeatKey
;
1255 Retrieves a USB keycode after parsing the raw data in keyboard buffer.
1257 This function parses keyboard buffer. It updates state of modifier key for
1258 USB_KB_DEV instancem, and returns keycode for output.
1260 @param UsbKeyboardDevice The USB_KB_DEV instance.
1261 @param KeyCode Pointer to the USB keycode for output.
1263 @retval EFI_SUCCESS Keycode successfully parsed.
1264 @retval EFI_NOT_READY Keyboard buffer is not ready for a valid keycode
1269 IN OUT USB_KB_DEV
*UsbKeyboardDevice
,
1274 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1278 while (!IsQueueEmpty (&UsbKeyboardDevice
->UsbKeyQueue
)) {
1280 // Pops one raw data off.
1282 Dequeue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1284 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, UsbKey
.KeyCode
);
1285 ASSERT (KeyDescriptor
!= NULL
);
1291 switch (KeyDescriptor
->Modifier
) {
1296 case EFI_LEFT_CONTROL_MODIFIER
:
1297 UsbKeyboardDevice
->LeftCtrlOn
= FALSE
;
1298 UsbKeyboardDevice
->CtrlOn
= FALSE
;
1300 case EFI_RIGHT_CONTROL_MODIFIER
:
1301 UsbKeyboardDevice
->RightCtrlOn
= FALSE
;
1302 UsbKeyboardDevice
->CtrlOn
= FALSE
;
1308 case EFI_LEFT_SHIFT_MODIFIER
:
1309 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
1310 UsbKeyboardDevice
->ShiftOn
= FALSE
;
1312 case EFI_RIGHT_SHIFT_MODIFIER
:
1313 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
1314 UsbKeyboardDevice
->ShiftOn
= FALSE
;
1320 case EFI_LEFT_ALT_MODIFIER
:
1321 UsbKeyboardDevice
->LeftAltOn
= FALSE
;
1322 UsbKeyboardDevice
->AltOn
= FALSE
;
1324 case EFI_RIGHT_ALT_MODIFIER
:
1325 UsbKeyboardDevice
->RightAltOn
= FALSE
;
1326 UsbKeyboardDevice
->AltOn
= FALSE
;
1330 // Left Logo release
1332 case EFI_LEFT_LOGO_MODIFIER
:
1333 UsbKeyboardDevice
->LeftLogoOn
= FALSE
;
1337 // Right Logo release
1339 case EFI_RIGHT_LOGO_MODIFIER
:
1340 UsbKeyboardDevice
->RightLogoOn
= FALSE
;
1346 case EFI_MENU_MODIFIER
:
1347 UsbKeyboardDevice
->MenuKeyOn
= FALSE
;
1353 case EFI_PRINT_MODIFIER
:
1354 case EFI_SYS_REQUEST_MODIFIER
:
1355 UsbKeyboardDevice
->SysReqOn
= FALSE
;
1361 case EFI_ALT_GR_MODIFIER
:
1362 UsbKeyboardDevice
->AltGrOn
= FALSE
;
1373 // Analyzes key pressing situation
1375 switch (KeyDescriptor
->Modifier
) {
1380 case EFI_LEFT_CONTROL_MODIFIER
:
1381 UsbKeyboardDevice
->LeftCtrlOn
= TRUE
;
1382 UsbKeyboardDevice
->CtrlOn
= TRUE
;
1385 case EFI_RIGHT_CONTROL_MODIFIER
:
1386 UsbKeyboardDevice
->RightCtrlOn
= TRUE
;
1387 UsbKeyboardDevice
->CtrlOn
= TRUE
;
1394 case EFI_LEFT_SHIFT_MODIFIER
:
1395 UsbKeyboardDevice
->LeftShiftOn
= TRUE
;
1396 UsbKeyboardDevice
->ShiftOn
= TRUE
;
1399 case EFI_RIGHT_SHIFT_MODIFIER
:
1400 UsbKeyboardDevice
->RightShiftOn
= TRUE
;
1401 UsbKeyboardDevice
->ShiftOn
= TRUE
;
1408 case EFI_LEFT_ALT_MODIFIER
:
1409 UsbKeyboardDevice
->LeftAltOn
= TRUE
;
1410 UsbKeyboardDevice
->AltOn
= TRUE
;
1413 case EFI_RIGHT_ALT_MODIFIER
:
1414 UsbKeyboardDevice
->RightAltOn
= TRUE
;
1415 UsbKeyboardDevice
->AltOn
= TRUE
;
1422 case EFI_LEFT_LOGO_MODIFIER
:
1423 UsbKeyboardDevice
->LeftLogoOn
= TRUE
;
1429 case EFI_RIGHT_LOGO_MODIFIER
:
1430 UsbKeyboardDevice
->RightLogoOn
= TRUE
;
1436 case EFI_MENU_MODIFIER
:
1437 UsbKeyboardDevice
->MenuKeyOn
= TRUE
;
1443 case EFI_PRINT_MODIFIER
:
1444 case EFI_SYS_REQUEST_MODIFIER
:
1445 UsbKeyboardDevice
->SysReqOn
= TRUE
;
1452 case EFI_ALT_GR_MODIFIER
:
1453 UsbKeyboardDevice
->AltGrOn
= TRUE
;
1456 case EFI_NUM_LOCK_MODIFIER
:
1460 UsbKeyboardDevice
->NumLockOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->NumLockOn
));
1461 SetKeyLED (UsbKeyboardDevice
);
1465 case EFI_CAPS_LOCK_MODIFIER
:
1469 UsbKeyboardDevice
->CapsOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->CapsOn
));
1470 SetKeyLED (UsbKeyboardDevice
);
1474 case EFI_SCROLL_LOCK_MODIFIER
:
1476 // Toggle ScrollLock
1478 UsbKeyboardDevice
->ScrollOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->ScrollOn
));
1479 SetKeyLED (UsbKeyboardDevice
);
1488 // When encountering Ctrl + Alt + Del, then warm reset.
1490 if (KeyDescriptor
->Modifier
== EFI_DELETE_MODIFIER
) {
1491 if ((UsbKeyboardDevice
->CtrlOn
) && (UsbKeyboardDevice
->AltOn
)) {
1492 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1496 *KeyCode
= UsbKey
.KeyCode
;
1500 return EFI_NOT_READY
;
1505 Converts USB Keycode ranging from 0x4 to 0x65 to EFI_INPUT_KEY.
1507 @param UsbKeyboardDevice The USB_KB_DEV instance.
1508 @param KeyCode Indicates the key code that will be interpreted.
1509 @param KeyData A pointer to a buffer that is filled in with
1510 the keystroke information for the key that
1513 @retval EFI_SUCCESS Success.
1514 @retval EFI_INVALID_PARAMETER KeyCode is not in the range of 0x4 to 0x65.
1515 @retval EFI_INVALID_PARAMETER Translated EFI_INPUT_KEY has zero for both ScanCode and UnicodeChar.
1516 @retval EFI_NOT_READY KeyCode represents a dead key with EFI_NS_KEY_MODIFIER
1517 @retval EFI_DEVICE_ERROR Keyboard layout is invalid.
1521 UsbKeyCodeToEfiInputKey (
1522 IN USB_KB_DEV
*UsbKeyboardDevice
,
1524 OUT EFI_KEY_DATA
*KeyData
1527 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1529 LIST_ENTRY
*NotifyList
;
1530 KEYBOARD_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
1533 // KeyCode must in the range of 0x4 to 0x65
1535 if (!USBKBD_VALID_KEYCODE (KeyCode
)) {
1536 return EFI_INVALID_PARAMETER
;
1538 if ((KeyCode
- 4) >= NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE
) {
1539 return EFI_INVALID_PARAMETER
;
1542 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, KeyCode
);
1543 ASSERT (KeyDescriptor
!= NULL
);
1545 if (KeyDescriptor
->Modifier
== EFI_NS_KEY_MODIFIER
) {
1547 // If this is a dead key with EFI_NS_KEY_MODIFIER, then record it and return.
1549 UsbKeyboardDevice
->CurrentNsKey
= FindUsbNsKey (UsbKeyboardDevice
, KeyDescriptor
);
1550 return EFI_NOT_READY
;
1553 if (UsbKeyboardDevice
->CurrentNsKey
!= NULL
) {
1555 // If this keystroke follows a non-spacing key, then find the descriptor for corresponding
1558 KeyDescriptor
= FindPhysicalKey (UsbKeyboardDevice
->CurrentNsKey
, KeyDescriptor
);
1559 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
1563 // Make sure modifier of Key Descriptor is in the valid range according to UEFI spec.
1565 if (KeyDescriptor
->Modifier
>= (sizeof (ModifierValueToEfiScanCodeConvertionTable
) / sizeof (UINT8
))) {
1566 return EFI_DEVICE_ERROR
;
1569 KeyData
->Key
.ScanCode
= ModifierValueToEfiScanCodeConvertionTable
[KeyDescriptor
->Modifier
];
1570 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->Unicode
;
1572 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_STANDARD_SHIFT
)!= 0) {
1573 if (UsbKeyboardDevice
->ShiftOn
) {
1574 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->ShiftedUnicode
;
1577 // Need not return associated shift state if a class of printable characters that
1578 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
1580 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_CAPS_LOCK
) != 0) {
1581 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
1582 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
1585 if (UsbKeyboardDevice
->AltGrOn
) {
1586 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->ShiftedAltGrUnicode
;
1592 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->Unicode
;
1594 if (UsbKeyboardDevice
->AltGrOn
) {
1595 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->AltGrUnicode
;
1600 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_CAPS_LOCK
) != 0) {
1601 if (UsbKeyboardDevice
->CapsOn
) {
1602 if (KeyData
->Key
.UnicodeChar
== KeyDescriptor
->Unicode
) {
1603 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->ShiftedUnicode
;
1604 } else if (KeyData
->Key
.UnicodeChar
== KeyDescriptor
->ShiftedUnicode
) {
1605 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->Unicode
;
1610 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_NUM_LOCK
) != 0) {
1612 // For key affected by NumLock, if NumLock is on and Shift is not pressed, then it means
1613 // normal key, instead of original control key. So the ScanCode should be cleaned.
1614 // Otherwise, it means control key, so preserve the EFI Scan Code and clear the unicode keycode.
1616 if ((UsbKeyboardDevice
->NumLockOn
) && (!(UsbKeyboardDevice
->ShiftOn
))) {
1617 KeyData
->Key
.ScanCode
= SCAN_NULL
;
1619 KeyData
->Key
.UnicodeChar
= 0x00;
1624 // Translate Unicode 0x1B (ESC) to EFI Scan Code
1626 if (KeyData
->Key
.UnicodeChar
== 0x1B && KeyData
->Key
.ScanCode
== SCAN_NULL
) {
1627 KeyData
->Key
.ScanCode
= SCAN_ESC
;
1628 KeyData
->Key
.UnicodeChar
= 0x00;
1632 // Not valid for key without both unicode key code and EFI Scan Code.
1634 if (KeyData
->Key
.UnicodeChar
== 0 && KeyData
->Key
.ScanCode
== SCAN_NULL
) {
1635 return EFI_NOT_READY
;
1639 // Save Shift/Toggle state
1641 KeyData
->KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
;
1642 KeyData
->KeyState
.KeyToggleState
= EFI_TOGGLE_STATE_VALID
;
1644 if (UsbKeyboardDevice
->LeftCtrlOn
) {
1645 KeyData
->KeyState
.KeyShiftState
|= EFI_LEFT_CONTROL_PRESSED
;
1647 if (UsbKeyboardDevice
->RightCtrlOn
) {
1648 KeyData
->KeyState
.KeyShiftState
|= EFI_RIGHT_CONTROL_PRESSED
;
1650 if (UsbKeyboardDevice
->LeftAltOn
) {
1651 KeyData
->KeyState
.KeyShiftState
|= EFI_LEFT_ALT_PRESSED
;
1653 if (UsbKeyboardDevice
->RightAltOn
) {
1654 KeyData
->KeyState
.KeyShiftState
|= EFI_RIGHT_ALT_PRESSED
;
1656 if (UsbKeyboardDevice
->LeftShiftOn
) {
1657 KeyData
->KeyState
.KeyShiftState
|= EFI_LEFT_SHIFT_PRESSED
;
1659 if (UsbKeyboardDevice
->RightShiftOn
) {
1660 KeyData
->KeyState
.KeyShiftState
|= EFI_RIGHT_SHIFT_PRESSED
;
1662 if (UsbKeyboardDevice
->LeftLogoOn
) {
1663 KeyData
->KeyState
.KeyShiftState
|= EFI_LEFT_LOGO_PRESSED
;
1665 if (UsbKeyboardDevice
->RightLogoOn
) {
1666 KeyData
->KeyState
.KeyShiftState
|= EFI_RIGHT_LOGO_PRESSED
;
1668 if (UsbKeyboardDevice
->MenuKeyOn
) {
1669 KeyData
->KeyState
.KeyShiftState
|= EFI_MENU_KEY_PRESSED
;
1671 if (UsbKeyboardDevice
->SysReqOn
) {
1672 KeyData
->KeyState
.KeyShiftState
|= EFI_SYS_REQ_PRESSED
;
1675 if (UsbKeyboardDevice
->ScrollOn
) {
1676 KeyData
->KeyState
.KeyToggleState
|= EFI_SCROLL_LOCK_ACTIVE
;
1678 if (UsbKeyboardDevice
->NumLockOn
) {
1679 KeyData
->KeyState
.KeyToggleState
|= EFI_NUM_LOCK_ACTIVE
;
1681 if (UsbKeyboardDevice
->CapsOn
) {
1682 KeyData
->KeyState
.KeyToggleState
|= EFI_CAPS_LOCK_ACTIVE
;
1686 // Invoke notification functions if the key is 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
)) {
1692 CurrentNotify
->KeyNotificationFn (KeyData
);
1697 // Translate the CTRL-Alpha characters to their corresponding control value
1698 // (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
1700 if (UsbKeyboardDevice
->CtrlOn
) {
1701 if (KeyData
->Key
.UnicodeChar
>= 'a' && KeyData
->Key
.UnicodeChar
<= 'z') {
1702 KeyData
->Key
.UnicodeChar
= (UINT8
) (KeyData
->Key
.UnicodeChar
- 'a' + 1);
1703 } else if (KeyData
->Key
.UnicodeChar
>= 'A' && KeyData
->Key
.UnicodeChar
<= 'Z') {
1704 KeyData
->Key
.UnicodeChar
= (UINT8
) (KeyData
->Key
.UnicodeChar
- 'A' + 1);
1715 @param Queue Points to the queue.
1716 @param ItemSize Size of the single item.
1721 IN OUT USB_SIMPLE_QUEUE
*Queue
,
1727 Queue
->ItemSize
= ItemSize
;
1731 if (Queue
->Buffer
[0] != NULL
) {
1732 FreePool (Queue
->Buffer
[0]);
1735 Queue
->Buffer
[0] = AllocatePool (sizeof (Queue
->Buffer
) / sizeof (Queue
->Buffer
[0]) * ItemSize
);
1736 ASSERT (Queue
->Buffer
[0] != NULL
);
1738 for (Index
= 1; Index
< sizeof (Queue
->Buffer
) / sizeof (Queue
->Buffer
[0]); Index
++) {
1739 Queue
->Buffer
[Index
] = ((UINT8
*) Queue
->Buffer
[Index
- 1]) + ItemSize
;
1746 @param Queue Points to the queue.
1750 IN OUT USB_SIMPLE_QUEUE
*Queue
1753 FreePool (Queue
->Buffer
[0]);
1758 Check whether the queue is empty.
1760 @param Queue Points to the queue.
1762 @retval TRUE Queue is empty.
1763 @retval FALSE Queue is not empty.
1768 IN USB_SIMPLE_QUEUE
*Queue
1772 // Meet FIFO empty condition
1774 return (BOOLEAN
) (Queue
->Head
== Queue
->Tail
);
1779 Check whether the queue is full.
1781 @param Queue Points to the queue.
1783 @retval TRUE Queue is full.
1784 @retval FALSE Queue is not full.
1789 IN USB_SIMPLE_QUEUE
*Queue
1792 return (BOOLEAN
) (((Queue
->Tail
+ 1) % (MAX_KEY_ALLOWED
+ 1)) == Queue
->Head
);
1797 Enqueue the item to the queue.
1799 @param Queue Points to the queue.
1800 @param Item Points to the item to be enqueued.
1801 @param ItemSize Size of the item.
1805 IN OUT USB_SIMPLE_QUEUE
*Queue
,
1810 ASSERT (ItemSize
== Queue
->ItemSize
);
1812 // If keyboard buffer is full, throw the
1813 // first key out of the keyboard buffer.
1815 if (IsQueueFull (Queue
)) {
1816 Queue
->Head
= (Queue
->Head
+ 1) % (MAX_KEY_ALLOWED
+ 1);
1819 CopyMem (Queue
->Buffer
[Queue
->Tail
], Item
, ItemSize
);
1822 // Adjust the tail pointer of the FIFO keyboard buffer.
1824 Queue
->Tail
= (Queue
->Tail
+ 1) % (MAX_KEY_ALLOWED
+ 1);
1829 Dequeue a item from the queue.
1831 @param Queue Points to the queue.
1832 @param Item Receives the item.
1833 @param ItemSize Size of the item.
1835 @retval EFI_SUCCESS Item was successfully dequeued.
1836 @retval EFI_DEVICE_ERROR The queue is empty.
1841 IN OUT USB_SIMPLE_QUEUE
*Queue
,
1846 ASSERT (Queue
->ItemSize
== ItemSize
);
1848 if (IsQueueEmpty (Queue
)) {
1849 return EFI_DEVICE_ERROR
;
1852 CopyMem (Item
, Queue
->Buffer
[Queue
->Head
], ItemSize
);
1855 // Adjust the head pointer of the FIFO keyboard buffer.
1857 Queue
->Head
= (Queue
->Head
+ 1) % (MAX_KEY_ALLOWED
+ 1);
1864 Sets USB keyboard LED state.
1866 @param UsbKeyboardDevice The USB_KB_DEV instance.
1871 IN USB_KB_DEV
*UsbKeyboardDevice
1878 // Set each field in Led map.
1880 Led
.NumLock
= (UINT8
) ((UsbKeyboardDevice
->NumLockOn
) ? 1 : 0);
1881 Led
.CapsLock
= (UINT8
) ((UsbKeyboardDevice
->CapsOn
) ? 1 : 0);
1882 Led
.ScrollLock
= (UINT8
) ((UsbKeyboardDevice
->ScrollOn
) ? 1 : 0);
1887 // Call Set_Report Request to lighten the LED.
1889 UsbSetReportRequest (
1890 UsbKeyboardDevice
->UsbIo
,
1891 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
1901 Handler for Repeat Key event.
1903 This function is the handler for Repeat Key event triggered
1905 After a repeatable key is pressed, the event would be triggered
1906 with interval of USBKBD_REPEAT_DELAY. Once the event is triggered,
1907 following trigger will come with interval of USBKBD_REPEAT_RATE.
1909 @param Event The Repeat Key event.
1910 @param Context Points to the USB_KB_DEV instance.
1915 USBKeyboardRepeatHandler (
1920 USB_KB_DEV
*UsbKeyboardDevice
;
1923 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1926 // Do nothing when there is no repeat key.
1928 if (UsbKeyboardDevice
->RepeatKey
!= 0) {
1930 // Inserts the repeat key into keyboard buffer,
1932 UsbKey
.KeyCode
= UsbKeyboardDevice
->RepeatKey
;
1934 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1937 // Set repeat rate for next repeat key generation.
1940 UsbKeyboardDevice
->RepeatTimer
,
1949 Handler for Delayed Recovery event.
1951 This function is the handler for Delayed Recovery event triggered
1953 After a device error occurs, the event would be triggered
1954 with interval of EFI_USB_INTERRUPT_DELAY. EFI_USB_INTERRUPT_DELAY
1955 is defined in USB standard for error handling.
1957 @param Event The Delayed Recovery event.
1958 @param Context Points to the USB_KB_DEV instance.
1963 USBKeyboardRecoveryHandler (
1969 USB_KB_DEV
*UsbKeyboardDevice
;
1970 EFI_USB_IO_PROTOCOL
*UsbIo
;
1973 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1975 UsbIo
= UsbKeyboardDevice
->UsbIo
;
1977 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
1980 // Re-submit Asynchronous Interrupt Transfer for recovery.
1982 UsbIo
->UsbAsyncInterruptTransfer (
1984 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1986 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,