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 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 {EfiKeyC10
, ';', ':', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
83 {EfiKeyC11
, '\'', '"', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
84 {EfiKeyE0
, '`', '~', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
85 {EfiKeyB8
, ',', '<', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
86 {EfiKeyB9
, '.', '>', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
87 {EfiKeyB10
, '/', '?', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
},
88 {EfiKeyCapsLock
, 0x00, 0x00, 0, 0, EFI_CAPS_LOCK_MODIFIER
, 0},
89 {EfiKeyF1
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ONE_MODIFIER
, 0},
90 {EfiKeyF2
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWO_MODIFIER
, 0},
91 {EfiKeyF3
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_THREE_MODIFIER
, 0},
92 {EfiKeyF4
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FOUR_MODIFIER
, 0},
93 {EfiKeyF5
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FIVE_MODIFIER
, 0},
94 {EfiKeyF6
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SIX_MODIFIER
, 0},
95 {EfiKeyF7
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SEVEN_MODIFIER
, 0},
96 {EfiKeyF8
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_EIGHT_MODIFIER
, 0},
97 {EfiKeyF9
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_NINE_MODIFIER
, 0},
98 {EfiKeyF10
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TEN_MODIFIER
, 0},
99 {EfiKeyF11
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ELEVEN_MODIFIER
, 0},
100 {EfiKeyF12
, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWELVE_MODIFIER
, 0},
101 {EfiKeyPrint
, 0x00, 0x00, 0, 0, EFI_PRINT_MODIFIER
, 0},
102 {EfiKeySLck
, 0x00, 0x00, 0, 0, EFI_SCROLL_LOCK_MODIFIER
, 0},
103 {EfiKeyPause
, 0x00, 0x00, 0, 0, EFI_PAUSE_MODIFIER
, 0},
104 {EfiKeyIns
, 0x00, 0x00, 0, 0, EFI_INSERT_MODIFIER
, 0},
105 {EfiKeyHome
, 0x00, 0x00, 0, 0, EFI_HOME_MODIFIER
, 0},
106 {EfiKeyPgUp
, 0x00, 0x00, 0, 0, EFI_PAGE_UP_MODIFIER
, 0},
107 {EfiKeyDel
, 0x00, 0x00, 0, 0, EFI_DELETE_MODIFIER
, 0},
108 {EfiKeyEnd
, 0x00, 0x00, 0, 0, EFI_END_MODIFIER
, 0},
109 {EfiKeyPgDn
, 0x00, 0x00, 0, 0, EFI_PAGE_DOWN_MODIFIER
, 0},
110 {EfiKeyRightArrow
, 0x00, 0x00, 0, 0, EFI_RIGHT_ARROW_MODIFIER
, 0},
111 {EfiKeyLeftArrow
, 0x00, 0x00, 0, 0, EFI_LEFT_ARROW_MODIFIER
, 0},
112 {EfiKeyDownArrow
, 0x00, 0x00, 0, 0, EFI_DOWN_ARROW_MODIFIER
, 0},
113 {EfiKeyUpArrow
, 0x00, 0x00, 0, 0, EFI_UP_ARROW_MODIFIER
, 0},
114 {EfiKeyNLck
, 0x00, 0x00, 0, 0, EFI_NUM_LOCK_MODIFIER
, 0},
115 {EfiKeySlash
, '/', '/', 0, 0, EFI_NULL_MODIFIER
, 0},
116 {EfiKeyAsterisk
, '*', '*', 0, 0, EFI_NULL_MODIFIER
, 0},
117 {EfiKeyMinus
, '-', '-', 0, 0, EFI_NULL_MODIFIER
, 0},
118 {EfiKeyPlus
, '+', '+', 0, 0, EFI_NULL_MODIFIER
, 0},
119 {EfiKeyEnter
, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER
, 0},
120 {EfiKeyOne
, '1', '1', 0, 0, EFI_END_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
121 {EfiKeyTwo
, '2', '2', 0, 0, EFI_DOWN_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
122 {EfiKeyThree
, '3', '3', 0, 0, EFI_PAGE_DOWN_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
123 {EfiKeyFour
, '4', '4', 0, 0, EFI_LEFT_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
124 {EfiKeyFive
, '5', '5', 0, 0, EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
125 {EfiKeySix
, '6', '6', 0, 0, EFI_RIGHT_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
126 {EfiKeySeven
, '7', '7', 0, 0, EFI_HOME_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
127 {EfiKeyEight
, '8', '8', 0, 0, EFI_UP_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
128 {EfiKeyNine
, '9', '9', 0, 0, EFI_PAGE_UP_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
129 {EfiKeyZero
, '0', '0', 0, 0, EFI_INSERT_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
130 {EfiKeyPeriod
, '.', '.', 0, 0, EFI_DELETE_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
},
131 {EfiKeyA4
, 0x00, 0x00, 0, 0, EFI_MENU_MODIFIER
, 0},
132 {EfiKeyLCtrl
, 0, 0, 0, 0, EFI_LEFT_CONTROL_MODIFIER
, 0},
133 {EfiKeyLShift
, 0, 0, 0, 0, EFI_LEFT_SHIFT_MODIFIER
, 0},
134 {EfiKeyLAlt
, 0, 0, 0, 0, EFI_LEFT_ALT_MODIFIER
, 0},
135 {EfiKeyA0
, 0, 0, 0, 0, EFI_LEFT_LOGO_MODIFIER
, 0},
136 {EfiKeyRCtrl
, 0, 0, 0, 0, EFI_RIGHT_CONTROL_MODIFIER
, 0},
137 {EfiKeyRShift
, 0, 0, 0, 0, EFI_RIGHT_SHIFT_MODIFIER
, 0},
138 {EfiKeyA2
, 0, 0, 0, 0, EFI_RIGHT_ALT_MODIFIER
, 0},
139 {EfiKeyA3
, 0, 0, 0, 0, EFI_RIGHT_LOGO_MODIFIER
, 0},
141 1, // DescriptionCount
142 {'e', 'n', '-', 'U', 'S'}, // RFC4646 language code
144 {'E', 'n', 'g', 'l', 'i', 's', 'h', ' ', 'K', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '\0'}, // DescriptionString[]
148 // EFI_KEY to USB Keycode conversion table
149 // EFI_KEY is defined in UEFI spec.
150 // USB Keycode is defined in USB HID Firmware spec.
152 UINT8 EfiKeyToUsbKeyCodeConvertionTable
[] = {
156 0x2c, // EfiKeySpaceBar
161 0x50, // EfiKeyLeftArrow
162 0x51, // EfiKeyDownArrow
163 0x4F, // EfiKeyRightArrow
165 0x63, // EfiKeyPeriod
167 0xe1, // EfiKeyLShift
179 0xe5, // EfiKeyRShift
180 0x52, // EfiKeyUpArrow
184 0x39, // EfiKeyCapsLock
234 0x2A, // EfiKeyBackSpace
240 0x55, // EfiKeyAsterisk
261 // Keyboard modifier value to EFI Scan Code convertion table
262 // EFI Scan Code and the modifier values are defined in UEFI spec.
264 UINT8 ModifierValueToEfiScanCodeConvertionTable
[] = {
265 SCAN_NULL
, // EFI_NULL_MODIFIER
266 SCAN_NULL
, // EFI_LEFT_CONTROL_MODIFIER
267 SCAN_NULL
, // EFI_RIGHT_CONTROL_MODIFIER
268 SCAN_NULL
, // EFI_LEFT_ALT_MODIFIER
269 SCAN_NULL
, // EFI_RIGHT_ALT_MODIFIER
270 SCAN_NULL
, // EFI_ALT_GR_MODIFIER
271 SCAN_INSERT
, // EFI_INSERT_MODIFIER
272 SCAN_DELETE
, // EFI_DELETE_MODIFIER
273 SCAN_PAGE_DOWN
, // EFI_PAGE_DOWN_MODIFIER
274 SCAN_PAGE_UP
, // EFI_PAGE_UP_MODIFIER
275 SCAN_HOME
, // EFI_HOME_MODIFIER
276 SCAN_END
, // EFI_END_MODIFIER
277 SCAN_NULL
, // EFI_LEFT_SHIFT_MODIFIER
278 SCAN_NULL
, // EFI_RIGHT_SHIFT_MODIFIER
279 SCAN_NULL
, // EFI_CAPS_LOCK_MODIFIER
280 SCAN_NULL
, // EFI_NUM_LOCK_MODIFIER
281 SCAN_LEFT
, // EFI_LEFT_ARROW_MODIFIER
282 SCAN_RIGHT
, // EFI_RIGHT_ARROW_MODIFIER
283 SCAN_DOWN
, // EFI_DOWN_ARROW_MODIFIER
284 SCAN_UP
, // EFI_UP_ARROW_MODIFIER
285 SCAN_NULL
, // EFI_NS_KEY_MODIFIER
286 SCAN_NULL
, // EFI_NS_KEY_DEPENDENCY_MODIFIER
287 SCAN_F1
, // EFI_FUNCTION_KEY_ONE_MODIFIER
288 SCAN_F2
, // EFI_FUNCTION_KEY_TWO_MODIFIER
289 SCAN_F3
, // EFI_FUNCTION_KEY_THREE_MODIFIER
290 SCAN_F4
, // EFI_FUNCTION_KEY_FOUR_MODIFIER
291 SCAN_F5
, // EFI_FUNCTION_KEY_FIVE_MODIFIER
292 SCAN_F6
, // EFI_FUNCTION_KEY_SIX_MODIFIER
293 SCAN_F7
, // EFI_FUNCTION_KEY_SEVEN_MODIFIER
294 SCAN_F8
, // EFI_FUNCTION_KEY_EIGHT_MODIFIER
295 SCAN_F9
, // EFI_FUNCTION_KEY_NINE_MODIFIER
296 SCAN_F10
, // EFI_FUNCTION_KEY_TEN_MODIFIER
297 SCAN_F11
, // EFI_FUNCTION_KEY_ELEVEN_MODIFIER
298 SCAN_F12
, // EFI_FUNCTION_KEY_TWELVE_MODIFIER
300 // For Partial Keystroke support
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
306 SCAN_NULL
, // EFI_BREAK_MODIFIER
307 SCAN_NULL
, // EFI_LEFT_LOGO_MODIFIER
308 SCAN_NULL
, // EFI_RIGHT_LOGO_MODIFER
309 SCAN_NULL
, // EFI_MENU_MODIFER
313 Initialize Key Convention Table by using default keyboard layout.
315 @param UsbKeyboardDevice The USB_KB_DEV instance.
317 @retval EFI_SUCCESS The default keyboard layout was installed successfully
318 @retval Others Failure to install default keyboard layout.
321 InstallDefaultKeyboardLayout (
322 IN OUT USB_KB_DEV
*UsbKeyboardDevice
326 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
327 EFI_HII_HANDLE HiiHandle
;
330 // Locate Hii database protocol
332 Status
= gBS
->LocateProtocol (
333 &gEfiHiiDatabaseProtocolGuid
,
335 (VOID
**) &HiiDatabase
337 if (EFI_ERROR (Status
)) {
342 // Install Keyboard Layout package to HII database
344 HiiHandle
= HiiAddPackages (
345 &gUsbKeyboardLayoutPackageGuid
,
346 UsbKeyboardDevice
->ControllerHandle
,
347 &mUsbKeyboardLayoutBin
,
350 if (HiiHandle
== NULL
) {
351 return EFI_OUT_OF_RESOURCES
;
355 // Set current keyboard layout
357 Status
= HiiDatabase
->SetKeyboardLayout (HiiDatabase
, &gUsbKeyboardLayoutKeyGuid
);
364 Uses USB I/O to check whether the device is a USB keyboard device.
366 @param UsbIo Pointer to a USB I/O protocol instance.
368 @retval TRUE Device is a USB keyboard device.
369 @retval FALSE Device is a not USB keyboard device.
374 IN EFI_USB_IO_PROTOCOL
*UsbIo
378 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
381 // Get the default interface descriptor
383 Status
= UsbIo
->UsbGetInterfaceDescriptor (
388 if (EFI_ERROR (Status
)) {
392 if (InterfaceDescriptor
.InterfaceClass
== CLASS_HID
&&
393 InterfaceDescriptor
.InterfaceSubClass
== SUBCLASS_BOOT
&&
394 InterfaceDescriptor
.InterfaceProtocol
== PROTOCOL_KEYBOARD
403 Get current keyboard layout from HII database.
405 @return Pointer to HII Keyboard Layout.
406 NULL means failure occurred while trying to get keyboard layout.
409 EFI_HII_KEYBOARD_LAYOUT
*
410 GetCurrentKeyboardLayout (
415 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
416 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
420 // Locate HII Database Protocol
422 Status
= gBS
->LocateProtocol (
423 &gEfiHiiDatabaseProtocolGuid
,
425 (VOID
**) &HiiDatabase
427 if (EFI_ERROR (Status
)) {
432 // Get current keyboard layout from HII database
435 KeyboardLayout
= NULL
;
436 Status
= HiiDatabase
->GetKeyboardLayout (
442 if (Status
== EFI_BUFFER_TOO_SMALL
) {
443 KeyboardLayout
= AllocatePool (Length
);
444 ASSERT (KeyboardLayout
!= NULL
);
446 Status
= HiiDatabase
->GetKeyboardLayout (
452 if (EFI_ERROR (Status
)) {
453 FreePool (KeyboardLayout
);
454 KeyboardLayout
= NULL
;
458 return KeyboardLayout
;
462 Find Key Descriptor in Key Convertion Table given its USB keycode.
464 @param UsbKeyboardDevice The USB_KB_DEV instance.
465 @param KeyCode USB Keycode.
467 @return The Key Descriptor in Key Convertion Table.
468 NULL means not found.
473 IN USB_KB_DEV
*UsbKeyboardDevice
,
480 // Make sure KeyCode is in the range of [0x4, 0x65] or [0xe0, 0xe7]
482 if ((!USBKBD_VALID_KEYCODE (KeyCode
)) || ((KeyCode
> 0x65) && (KeyCode
< 0xe0)) || (KeyCode
> 0xe7)) {
487 // Calculate the index of Key Descriptor in Key Convertion Table
489 if (KeyCode
<= 0x65) {
490 Index
= (UINT8
) (KeyCode
- 4);
492 Index
= (UINT8
) (KeyCode
- 0xe0 + NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE
);
495 return &UsbKeyboardDevice
->KeyConvertionTable
[Index
];
499 Find Non-Spacing key for given Key descriptor.
501 @param UsbKeyboardDevice The USB_KB_DEV instance.
502 @param KeyDescriptor Key descriptor.
504 @return The Non-Spacing key corresponding to KeyDescriptor
505 NULL means not found.
510 IN USB_KB_DEV
*UsbKeyboardDevice
,
511 IN EFI_KEY_DESCRIPTOR
*KeyDescriptor
515 LIST_ENTRY
*NsKeyList
;
516 USB_NS_KEY
*UsbNsKey
;
518 NsKeyList
= &UsbKeyboardDevice
->NsKeyList
;
519 Link
= GetFirstNode (NsKeyList
);
520 while (!IsNull (NsKeyList
, Link
)) {
521 UsbNsKey
= USB_NS_KEY_FORM_FROM_LINK (Link
);
523 if (UsbNsKey
->NsKey
[0].Key
== KeyDescriptor
->Key
) {
527 Link
= GetNextNode (NsKeyList
, Link
);
534 Find physical key definition for a given key descriptor.
536 For a specified non-spacing key, there are a list of physical
537 keys following it. This function traverses the list of
538 physical keys and tries to find the physical key matching
541 @param UsbNsKey The non-spacing key information.
542 @param KeyDescriptor The key descriptor.
544 @return The physical key definition.
545 If no physical key is found, parameter KeyDescriptor is returned.
550 IN USB_NS_KEY
*UsbNsKey
,
551 IN EFI_KEY_DESCRIPTOR
*KeyDescriptor
555 EFI_KEY_DESCRIPTOR
*PhysicalKey
;
557 PhysicalKey
= &UsbNsKey
->NsKey
[1];
558 for (Index
= 0; Index
< UsbNsKey
->KeyCount
; Index
++) {
559 if (KeyDescriptor
->Key
== PhysicalKey
->Key
) {
567 // No children definition matched, return original key
569 return KeyDescriptor
;
573 The notification function for EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID.
575 This function is registered to event of EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
576 group type, which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
577 It tries to get curent keyboard layout from HII database.
579 @param Event Event being signaled.
580 @param Context Points to USB_KB_DEV instance.
585 SetKeyboardLayoutEvent (
590 USB_KB_DEV
*UsbKeyboardDevice
;
591 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
592 EFI_KEY_DESCRIPTOR TempKey
;
593 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
594 EFI_KEY_DESCRIPTOR
*TableEntry
;
595 EFI_KEY_DESCRIPTOR
*NsKey
;
596 USB_NS_KEY
*UsbNsKey
;
602 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
603 if (UsbKeyboardDevice
->Signature
!= USB_KB_DEV_SIGNATURE
) {
608 // Try to get current keyboard layout from HII database
610 KeyboardLayout
= GetCurrentKeyboardLayout ();
611 if (KeyboardLayout
== NULL
) {
616 // Re-allocate resource for KeyConvertionTable
618 ReleaseKeyboardLayoutResources (UsbKeyboardDevice
);
619 UsbKeyboardDevice
->KeyConvertionTable
= AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE
) * sizeof (EFI_KEY_DESCRIPTOR
));
620 ASSERT (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
);
623 // Traverse the list of key descriptors following the header of EFI_HII_KEYBOARD_LAYOUT
625 KeyDescriptor
= (EFI_KEY_DESCRIPTOR
*) (((UINT8
*) KeyboardLayout
) + sizeof (EFI_HII_KEYBOARD_LAYOUT
));
626 for (Index
= 0; Index
< KeyboardLayout
->DescriptorCount
; Index
++) {
628 // Copy from HII keyboard layout package binary for alignment
630 CopyMem (&TempKey
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
633 // Fill the key into KeyConvertionTable, whose index is calculated from USB keycode.
635 KeyCode
= EfiKeyToUsbKeyCodeConvertionTable
[(UINT8
) (TempKey
.Key
)];
636 TableEntry
= GetKeyDescriptor (UsbKeyboardDevice
, KeyCode
);
637 if (TableEntry
== NULL
) {
638 ReleaseKeyboardLayoutResources (UsbKeyboardDevice
);
639 FreePool (KeyboardLayout
);
642 CopyMem (TableEntry
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
645 // For non-spacing key, create the list with a non-spacing key followed by physical keys.
647 if (TempKey
.Modifier
== EFI_NS_KEY_MODIFIER
) {
648 UsbNsKey
= AllocateZeroPool (sizeof (USB_NS_KEY
));
649 ASSERT (UsbNsKey
!= NULL
);
652 // Search for sequential children physical key definitions
655 NsKey
= KeyDescriptor
+ 1;
656 for (Index2
= (UINT8
) Index
+ 1; Index2
< KeyboardLayout
->DescriptorCount
; Index2
++) {
657 CopyMem (&TempKey
, NsKey
, sizeof (EFI_KEY_DESCRIPTOR
));
658 if (TempKey
.Modifier
== EFI_NS_KEY_DEPENDENCY_MODIFIER
) {
666 UsbNsKey
->Signature
= USB_NS_KEY_SIGNATURE
;
667 UsbNsKey
->KeyCount
= KeyCount
;
668 UsbNsKey
->NsKey
= AllocateCopyPool (
669 (KeyCount
+ 1) * sizeof (EFI_KEY_DESCRIPTOR
),
672 InsertTailList (&UsbKeyboardDevice
->NsKeyList
, &UsbNsKey
->Link
);
675 // Skip over the child physical keys
678 KeyDescriptor
+= KeyCount
;
685 // There are two EfiKeyEnter, duplicate its key descriptor
687 TableEntry
= GetKeyDescriptor (UsbKeyboardDevice
, 0x58);
688 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, 0x28);
689 CopyMem (TableEntry
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
691 FreePool (KeyboardLayout
);
695 Destroy resources for keyboard layout.
697 @param UsbKeyboardDevice The USB_KB_DEV instance.
701 ReleaseKeyboardLayoutResources (
702 IN OUT USB_KB_DEV
*UsbKeyboardDevice
705 USB_NS_KEY
*UsbNsKey
;
708 if (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
) {
709 FreePool (UsbKeyboardDevice
->KeyConvertionTable
);
711 UsbKeyboardDevice
->KeyConvertionTable
= NULL
;
713 while (!IsListEmpty (&UsbKeyboardDevice
->NsKeyList
)) {
714 Link
= GetFirstNode (&UsbKeyboardDevice
->NsKeyList
);
715 UsbNsKey
= USB_NS_KEY_FORM_FROM_LINK (Link
);
716 RemoveEntryList (&UsbNsKey
->Link
);
718 FreePool (UsbNsKey
->NsKey
);
724 Initialize USB keyboard layout.
726 This function initializes Key Convertion Table for the USB keyboard device.
727 It first tries to retrieve layout from HII database. If failed and default
728 layout is enabled, then it just uses the default layout.
730 @param UsbKeyboardDevice The USB_KB_DEV instance.
732 @retval EFI_SUCCESS Initialization succeeded.
733 @retval EFI_NOT_READY Keyboard layout cannot be retrieve from HII
734 database, and default layout is disabled.
735 @retval Other Fail to register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group.
740 OUT USB_KB_DEV
*UsbKeyboardDevice
743 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
746 UsbKeyboardDevice
->KeyConvertionTable
= AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE
) * sizeof (EFI_KEY_DESCRIPTOR
));
747 ASSERT (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
);
749 InitializeListHead (&UsbKeyboardDevice
->NsKeyList
);
750 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
751 UsbKeyboardDevice
->KeyboardLayoutEvent
= NULL
;
754 // Register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group,
755 // which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
757 Status
= gBS
->CreateEventEx (
760 SetKeyboardLayoutEvent
,
762 &gEfiHiiKeyBoardLayoutGuid
,
763 &UsbKeyboardDevice
->KeyboardLayoutEvent
765 if (EFI_ERROR (Status
)) {
769 KeyboardLayout
= GetCurrentKeyboardLayout ();
770 if (KeyboardLayout
!= NULL
) {
772 // If current keyboard layout is successfully retrieved from HII database,
773 // force to initialize the keyboard layout.
775 gBS
->SignalEvent (UsbKeyboardDevice
->KeyboardLayoutEvent
);
777 if (FeaturePcdGet (PcdDisableDefaultKeyboardLayoutInUsbKbDriver
)) {
779 // If no keyboard layout can be retrieved from HII database, and default layout
780 // is disabled, then return EFI_NOT_READY.
782 return EFI_NOT_READY
;
785 // If no keyboard layout can be retrieved from HII database, and default layout
786 // is enabled, then load the default keyboard layout.
788 InstallDefaultKeyboardLayout (UsbKeyboardDevice
);
796 Initialize USB keyboard device and all private data structures.
798 @param UsbKeyboardDevice The USB_KB_DEV instance.
800 @retval EFI_SUCCESS Initialization is successful.
801 @retval EFI_DEVICE_ERROR Keyboard initialization failed.
806 IN OUT USB_KB_DEV
*UsbKeyboardDevice
814 UINT32 TransferResult
;
816 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
818 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_KEYBOARD_PC_SELF_TEST
),
819 UsbKeyboardDevice
->DevicePath
822 InitQueue (&UsbKeyboardDevice
->UsbKeyQueue
, sizeof (USB_KEY
));
823 InitQueue (&UsbKeyboardDevice
->EfiKeyQueue
, 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
)) {
839 // Uses default configuration to configure the USB Keyboard device.
841 Status
= UsbSetConfiguration (
842 UsbKeyboardDevice
->UsbIo
,
846 if (EFI_ERROR (Status
)) {
848 // If configuration could not be set here, it means
849 // the keyboard interface has some errors and could
850 // not be initialized
852 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
853 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
854 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_INTERFACE_ERROR
),
855 UsbKeyboardDevice
->DevicePath
858 return EFI_DEVICE_ERROR
;
861 UsbGetProtocolRequest (
862 UsbKeyboardDevice
->UsbIo
,
863 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
867 // Set boot protocol for the USB Keyboard.
868 // This driver only supports boot protocol.
870 if (Protocol
!= BOOT_PROTOCOL
) {
871 UsbSetProtocolRequest (
872 UsbKeyboardDevice
->UsbIo
,
873 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
879 // ReportId is zero, which means the idle rate applies to all input reports.
883 // Duration is zero, which means the duration is infinite.
884 // so the endpoint will inhibit reporting forever,
885 // and only reporting when a change is detected in the report data.
889 UsbKeyboardDevice
->UsbIo
,
890 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
895 UsbKeyboardDevice
->CtrlOn
= FALSE
;
896 UsbKeyboardDevice
->AltOn
= FALSE
;
897 UsbKeyboardDevice
->ShiftOn
= FALSE
;
898 UsbKeyboardDevice
->NumLockOn
= FALSE
;
899 UsbKeyboardDevice
->CapsOn
= FALSE
;
900 UsbKeyboardDevice
->ScrollOn
= FALSE
;
902 UsbKeyboardDevice
->LeftCtrlOn
= FALSE
;
903 UsbKeyboardDevice
->LeftAltOn
= FALSE
;
904 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
905 UsbKeyboardDevice
->LeftLogoOn
= FALSE
;
906 UsbKeyboardDevice
->RightCtrlOn
= FALSE
;
907 UsbKeyboardDevice
->RightAltOn
= FALSE
;
908 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
909 UsbKeyboardDevice
->RightLogoOn
= FALSE
;
910 UsbKeyboardDevice
->MenuKeyOn
= FALSE
;
911 UsbKeyboardDevice
->SysReqOn
= FALSE
;
913 UsbKeyboardDevice
->AltGrOn
= FALSE
;
915 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
918 // Sync the initial state of lights on keyboard.
920 SetKeyLED (UsbKeyboardDevice
);
922 ZeroMem (UsbKeyboardDevice
->LastKeyCodeArray
, sizeof (UINT8
) * 8);
925 // Create event for repeat keys' generation.
927 if (UsbKeyboardDevice
->RepeatTimer
!= NULL
) {
928 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
929 UsbKeyboardDevice
->RepeatTimer
= NULL
;
933 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
935 USBKeyboardRepeatHandler
,
937 &UsbKeyboardDevice
->RepeatTimer
941 // Create event for delayed recovery, which deals with device error.
943 if (UsbKeyboardDevice
->DelayedRecoveryEvent
!= NULL
) {
944 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
945 UsbKeyboardDevice
->DelayedRecoveryEvent
= NULL
;
949 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
951 USBKeyboardRecoveryHandler
,
953 &UsbKeyboardDevice
->DelayedRecoveryEvent
961 Handler function for USB keyboard's asynchronous interrupt transfer.
963 This function is the handler function for USB keyboard's asynchronous interrupt transfer
964 to manage the keyboard. It parses the USB keyboard input report, and inserts data to
965 keyboard buffer according to state of modifer keys and normal keys. Timer for repeat key
966 is also set accordingly.
968 @param Data A pointer to a buffer that is filled with key data which is
969 retrieved via asynchronous interrupt transfer.
970 @param DataLength Indicates the size of the data buffer.
971 @param Context Pointing to USB_KB_DEV instance.
972 @param Result Indicates the result of the asynchronous interrupt transfer.
974 @retval EFI_SUCCESS Asynchronous interrupt transfer is handled successfully.
975 @retval EFI_DEVICE_ERROR Hardware error occurs.
987 USB_KB_DEV
*UsbKeyboardDevice
;
988 EFI_USB_IO_PROTOCOL
*UsbIo
;
989 UINT8
*CurKeyCodeBuffer
;
990 UINT8
*OldKeyCodeBuffer
;
991 UINT8 CurModifierMap
;
992 UINT8 OldModifierMap
;
1001 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1003 ASSERT (Context
!= NULL
);
1006 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1007 UsbIo
= UsbKeyboardDevice
->UsbIo
;
1010 // Analyzes Result and performs corresponding action.
1012 if (Result
!= EFI_USB_NOERROR
) {
1014 // Some errors happen during the process
1016 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1017 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1018 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_INPUT_ERROR
),
1019 UsbKeyboardDevice
->DevicePath
1023 // Stop the repeat key generation if any
1025 UsbKeyboardDevice
->RepeatKey
= 0;
1028 UsbKeyboardDevice
->RepeatTimer
,
1033 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
1034 UsbClearEndpointHalt (
1036 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1042 // Delete & Submit this interrupt again
1043 // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt.
1045 UsbIo
->UsbAsyncInterruptTransfer (
1047 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1055 // EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling.
1058 UsbKeyboardDevice
->DelayedRecoveryEvent
,
1060 EFI_USB_INTERRUPT_DELAY
1063 return EFI_DEVICE_ERROR
;
1067 // If no error and no data, just return EFI_SUCCESS.
1069 if (DataLength
== 0 || Data
== NULL
) {
1074 // Following code checks current keyboard input report against old key code buffer.
1075 // According to USB HID Firmware Specification, the report consists of 8 bytes.
1076 // Byte 0 is map of Modifier keys.
1077 // Byte 1 is reserved.
1078 // Bytes 2 to 7 are keycodes.
1080 CurKeyCodeBuffer
= (UINT8
*) Data
;
1081 OldKeyCodeBuffer
= UsbKeyboardDevice
->LastKeyCodeArray
;
1084 // Checks for new key stroke.
1086 for (Index
= 0; Index
< 8; Index
++) {
1087 if (OldKeyCodeBuffer
[Index
] != CurKeyCodeBuffer
[Index
]) {
1093 // If no new key, return EFI_SUCCESS immediately.
1100 // Parse the modifier key, which is the first byte of keyboard input report.
1102 CurModifierMap
= CurKeyCodeBuffer
[0];
1103 OldModifierMap
= OldKeyCodeBuffer
[0];
1106 // Handle modifier key's pressing or releasing situation.
1107 // According to USB HID Firmware spec, Byte 0 uses folloing map of Modifier keys:
1108 // Bit0: Left Control, Keycode: 0xe0
1109 // Bit1: Left Shift, Keycode: 0xe1
1110 // Bit2: Left Alt, Keycode: 0xe2
1111 // Bit3: Left GUI, Keycode: 0xe3
1112 // Bit4: Right Control, Keycode: 0xe4
1113 // Bit5: Right Shift, Keycode: 0xe5
1114 // Bit6: Right Alt, Keycode: 0xe6
1115 // Bit7: Right GUI, Keycode: 0xe7
1117 for (Index
= 0; Index
< 8; Index
++) {
1118 Mask
= (UINT8
) (1 << Index
);
1119 if ((CurModifierMap
& Mask
) != (OldModifierMap
& Mask
)) {
1121 // If current modifier key is up, then CurModifierMap & Mask = 0;
1122 // otherwise it is a non-zero value.
1123 // Insert the changed modifier key into key buffer.
1125 UsbKey
.KeyCode
= (UINT8
) (0xe0 + Index
);
1126 UsbKey
.Down
= (BOOLEAN
) ((CurModifierMap
& Mask
) != 0);
1127 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1132 // Handle normal key's releasing situation
1133 // Bytes 2 to 7 are for normal keycodes
1136 for (Index
= 2; Index
< 8; Index
++) {
1138 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index
])) {
1142 // For any key in old keycode buffer, if it is not in current keycode buffer,
1143 // then it is released. Otherwise, it is not released.
1146 for (Index2
= 2; Index2
< 8; Index2
++) {
1148 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index2
])) {
1152 if (OldKeyCodeBuffer
[Index
] == CurKeyCodeBuffer
[Index2
]) {
1159 UsbKey
.KeyCode
= OldKeyCodeBuffer
[Index
];
1160 UsbKey
.Down
= FALSE
;
1161 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1163 // The original repeat key is released.
1165 if (OldKeyCodeBuffer
[Index
] == UsbKeyboardDevice
->RepeatKey
) {
1166 UsbKeyboardDevice
->RepeatKey
= 0;
1172 // If original repeat key is released, cancel the repeat timer
1174 if (UsbKeyboardDevice
->RepeatKey
== 0) {
1176 UsbKeyboardDevice
->RepeatTimer
,
1183 // Handle normal key's pressing situation
1186 for (Index
= 2; Index
< 8; Index
++) {
1188 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index
])) {
1192 // For any key in current keycode buffer, if it is not in old keycode buffer,
1193 // then it is pressed. Otherwise, it is not pressed.
1196 for (Index2
= 2; Index2
< 8; Index2
++) {
1198 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index2
])) {
1202 if (CurKeyCodeBuffer
[Index
] == OldKeyCodeBuffer
[Index2
]) {
1209 UsbKey
.KeyCode
= CurKeyCodeBuffer
[Index
];
1211 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1214 // Handle repeat key
1216 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, CurKeyCodeBuffer
[Index
]);
1217 ASSERT (KeyDescriptor
!= NULL
);
1219 if (KeyDescriptor
->Modifier
== EFI_NUM_LOCK_MODIFIER
|| KeyDescriptor
->Modifier
== EFI_CAPS_LOCK_MODIFIER
) {
1221 // For NumLock or CapsLock pressed, there is no need to handle repeat key for them.
1223 UsbKeyboardDevice
->RepeatKey
= 0;
1226 // Prepare new repeat key, and clear the original one.
1228 NewRepeatKey
= CurKeyCodeBuffer
[Index
];
1229 UsbKeyboardDevice
->RepeatKey
= 0;
1235 // Update LastKeycodeArray buffer in the UsbKeyboardDevice data structure.
1237 for (Index
= 0; Index
< 8; Index
++) {
1238 UsbKeyboardDevice
->LastKeyCodeArray
[Index
] = CurKeyCodeBuffer
[Index
];
1242 // If there is new key pressed, update the RepeatKey value, and set the
1243 // timer to repeate delay timer
1245 if (NewRepeatKey
!= 0) {
1247 // Sets trigger time to "Repeat Delay Time",
1248 // to trigger the repeat timer when the key is hold long
1252 UsbKeyboardDevice
->RepeatTimer
,
1256 UsbKeyboardDevice
->RepeatKey
= NewRepeatKey
;
1264 Retrieves a USB keycode after parsing the raw data in keyboard buffer.
1266 This function parses keyboard buffer. It updates state of modifier key for
1267 USB_KB_DEV instancem, and returns keycode for output.
1269 @param UsbKeyboardDevice The USB_KB_DEV instance.
1270 @param KeyCode Pointer to the USB keycode for output.
1272 @retval EFI_SUCCESS Keycode successfully parsed.
1273 @retval EFI_NOT_READY Keyboard buffer is not ready for a valid keycode
1278 IN OUT USB_KB_DEV
*UsbKeyboardDevice
,
1283 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1287 while (!IsQueueEmpty (&UsbKeyboardDevice
->UsbKeyQueue
)) {
1289 // Pops one raw data off.
1291 Dequeue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1293 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, UsbKey
.KeyCode
);
1294 ASSERT (KeyDescriptor
!= NULL
);
1300 switch (KeyDescriptor
->Modifier
) {
1305 case EFI_LEFT_CONTROL_MODIFIER
:
1306 UsbKeyboardDevice
->LeftCtrlOn
= FALSE
;
1307 UsbKeyboardDevice
->CtrlOn
= FALSE
;
1309 case EFI_RIGHT_CONTROL_MODIFIER
:
1310 UsbKeyboardDevice
->RightCtrlOn
= FALSE
;
1311 UsbKeyboardDevice
->CtrlOn
= FALSE
;
1317 case EFI_LEFT_SHIFT_MODIFIER
:
1318 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
1319 UsbKeyboardDevice
->ShiftOn
= FALSE
;
1321 case EFI_RIGHT_SHIFT_MODIFIER
:
1322 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
1323 UsbKeyboardDevice
->ShiftOn
= FALSE
;
1329 case EFI_LEFT_ALT_MODIFIER
:
1330 UsbKeyboardDevice
->LeftAltOn
= FALSE
;
1331 UsbKeyboardDevice
->AltOn
= FALSE
;
1333 case EFI_RIGHT_ALT_MODIFIER
:
1334 UsbKeyboardDevice
->RightAltOn
= FALSE
;
1335 UsbKeyboardDevice
->AltOn
= FALSE
;
1339 // Left Logo release
1341 case EFI_LEFT_LOGO_MODIFIER
:
1342 UsbKeyboardDevice
->LeftLogoOn
= FALSE
;
1346 // Right Logo release
1348 case EFI_RIGHT_LOGO_MODIFIER
:
1349 UsbKeyboardDevice
->RightLogoOn
= FALSE
;
1355 case EFI_MENU_MODIFIER
:
1356 UsbKeyboardDevice
->MenuKeyOn
= FALSE
;
1362 case EFI_PRINT_MODIFIER
:
1363 case EFI_SYS_REQUEST_MODIFIER
:
1364 UsbKeyboardDevice
->SysReqOn
= FALSE
;
1370 case EFI_ALT_GR_MODIFIER
:
1371 UsbKeyboardDevice
->AltGrOn
= FALSE
;
1382 // Analyzes key pressing situation
1384 switch (KeyDescriptor
->Modifier
) {
1389 case EFI_LEFT_CONTROL_MODIFIER
:
1390 UsbKeyboardDevice
->LeftCtrlOn
= TRUE
;
1391 UsbKeyboardDevice
->CtrlOn
= TRUE
;
1393 case EFI_RIGHT_CONTROL_MODIFIER
:
1394 UsbKeyboardDevice
->RightCtrlOn
= TRUE
;
1395 UsbKeyboardDevice
->CtrlOn
= TRUE
;
1401 case EFI_LEFT_SHIFT_MODIFIER
:
1402 UsbKeyboardDevice
->LeftShiftOn
= TRUE
;
1403 UsbKeyboardDevice
->ShiftOn
= TRUE
;
1405 case EFI_RIGHT_SHIFT_MODIFIER
:
1406 UsbKeyboardDevice
->RightShiftOn
= TRUE
;
1407 UsbKeyboardDevice
->ShiftOn
= TRUE
;
1413 case EFI_LEFT_ALT_MODIFIER
:
1414 UsbKeyboardDevice
->LeftAltOn
= TRUE
;
1415 UsbKeyboardDevice
->AltOn
= TRUE
;
1417 case EFI_RIGHT_ALT_MODIFIER
:
1418 UsbKeyboardDevice
->RightAltOn
= TRUE
;
1419 UsbKeyboardDevice
->AltOn
= TRUE
;
1425 case EFI_LEFT_LOGO_MODIFIER
:
1426 UsbKeyboardDevice
->LeftLogoOn
= TRUE
;
1432 case EFI_RIGHT_LOGO_MODIFIER
:
1433 UsbKeyboardDevice
->RightLogoOn
= TRUE
;
1439 case EFI_MENU_MODIFIER
:
1440 UsbKeyboardDevice
->MenuKeyOn
= TRUE
;
1446 case EFI_PRINT_MODIFIER
:
1447 case EFI_SYS_REQUEST_MODIFIER
:
1448 UsbKeyboardDevice
->SysReqOn
= TRUE
;
1454 case EFI_ALT_GR_MODIFIER
:
1455 UsbKeyboardDevice
->AltGrOn
= TRUE
;
1458 case EFI_NUM_LOCK_MODIFIER
:
1462 UsbKeyboardDevice
->NumLockOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->NumLockOn
));
1463 SetKeyLED (UsbKeyboardDevice
);
1466 case EFI_CAPS_LOCK_MODIFIER
:
1470 UsbKeyboardDevice
->CapsOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->CapsOn
));
1471 SetKeyLED (UsbKeyboardDevice
);
1474 case EFI_SCROLL_LOCK_MODIFIER
:
1476 // Toggle ScrollLock
1478 UsbKeyboardDevice
->ScrollOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->ScrollOn
));
1479 SetKeyLED (UsbKeyboardDevice
);
1487 // When encountering Ctrl + Alt + Del, then warm reset.
1489 if (KeyDescriptor
->Modifier
== EFI_DELETE_MODIFIER
) {
1490 if ((UsbKeyboardDevice
->CtrlOn
) && (UsbKeyboardDevice
->AltOn
)) {
1491 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1495 *KeyCode
= UsbKey
.KeyCode
;
1499 return EFI_NOT_READY
;
1504 Converts USB Keycode ranging from 0x4 to 0x65 to EFI_INPUT_KEY.
1506 @param UsbKeyboardDevice The USB_KB_DEV instance.
1507 @param KeyCode Indicates the key code that will be interpreted.
1508 @param KeyData A pointer to a buffer that is filled in with
1509 the keystroke information for the key that
1512 @retval EFI_SUCCESS Success.
1513 @retval EFI_INVALID_PARAMETER KeyCode is not in the range of 0x4 to 0x65.
1514 @retval EFI_INVALID_PARAMETER Translated EFI_INPUT_KEY has zero for both ScanCode and UnicodeChar.
1515 @retval EFI_NOT_READY KeyCode represents a dead key with EFI_NS_KEY_MODIFIER
1516 @retval EFI_DEVICE_ERROR Keyboard layout is invalid.
1520 UsbKeyCodeToEfiInputKey (
1521 IN USB_KB_DEV
*UsbKeyboardDevice
,
1523 OUT EFI_KEY_DATA
*KeyData
1526 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1528 LIST_ENTRY
*NotifyList
;
1529 KEYBOARD_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
1532 // KeyCode must in the range of [0x4, 0x65] or [0xe0, 0xe7].
1534 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, KeyCode
);
1535 ASSERT (KeyDescriptor
!= NULL
);
1537 if (KeyDescriptor
->Modifier
== EFI_NS_KEY_MODIFIER
) {
1539 // If this is a dead key with EFI_NS_KEY_MODIFIER, then record it and return.
1541 UsbKeyboardDevice
->CurrentNsKey
= FindUsbNsKey (UsbKeyboardDevice
, KeyDescriptor
);
1542 return EFI_NOT_READY
;
1545 if (UsbKeyboardDevice
->CurrentNsKey
!= NULL
) {
1547 // If this keystroke follows a non-spacing key, then find the descriptor for corresponding
1550 KeyDescriptor
= FindPhysicalKey (UsbKeyboardDevice
->CurrentNsKey
, KeyDescriptor
);
1551 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
1555 // Make sure modifier of Key Descriptor is in the valid range according to UEFI spec.
1557 if (KeyDescriptor
->Modifier
>= (sizeof (ModifierValueToEfiScanCodeConvertionTable
) / sizeof (UINT8
))) {
1558 return EFI_DEVICE_ERROR
;
1561 KeyData
->Key
.ScanCode
= ModifierValueToEfiScanCodeConvertionTable
[KeyDescriptor
->Modifier
];
1562 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->Unicode
;
1564 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_STANDARD_SHIFT
)!= 0) {
1565 if (UsbKeyboardDevice
->ShiftOn
) {
1566 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->ShiftedUnicode
;
1569 // Need not return associated shift state if a class of printable characters that
1570 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
1572 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_CAPS_LOCK
) != 0) {
1573 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
1574 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
1577 if (UsbKeyboardDevice
->AltGrOn
) {
1578 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->ShiftedAltGrUnicode
;
1584 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->Unicode
;
1586 if (UsbKeyboardDevice
->AltGrOn
) {
1587 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->AltGrUnicode
;
1592 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_CAPS_LOCK
) != 0) {
1593 if (UsbKeyboardDevice
->CapsOn
) {
1594 if (KeyData
->Key
.UnicodeChar
== KeyDescriptor
->Unicode
) {
1595 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->ShiftedUnicode
;
1596 } else if (KeyData
->Key
.UnicodeChar
== KeyDescriptor
->ShiftedUnicode
) {
1597 KeyData
->Key
.UnicodeChar
= KeyDescriptor
->Unicode
;
1602 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_NUM_LOCK
) != 0) {
1604 // For key affected by NumLock, if NumLock is on and Shift is not pressed, then it means
1605 // normal key, instead of original control key. So the ScanCode should be cleaned.
1606 // Otherwise, it means control key, so preserve the EFI Scan Code and clear the unicode keycode.
1608 if ((UsbKeyboardDevice
->NumLockOn
) && (!(UsbKeyboardDevice
->ShiftOn
))) {
1609 KeyData
->Key
.ScanCode
= SCAN_NULL
;
1611 KeyData
->Key
.UnicodeChar
= CHAR_NULL
;
1616 // Translate Unicode 0x1B (ESC) to EFI Scan Code
1618 if (KeyData
->Key
.UnicodeChar
== 0x1B && KeyData
->Key
.ScanCode
== SCAN_NULL
) {
1619 KeyData
->Key
.ScanCode
= SCAN_ESC
;
1620 KeyData
->Key
.UnicodeChar
= CHAR_NULL
;
1624 // Not valid for key without both unicode key code and EFI Scan Code.
1626 if (KeyData
->Key
.UnicodeChar
== 0 && KeyData
->Key
.ScanCode
== SCAN_NULL
) {
1627 if (!UsbKeyboardDevice
->IsSupportPartialKey
) {
1628 return EFI_NOT_READY
;
1633 // Save Shift/Toggle state
1635 KeyData
->KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
;
1636 KeyData
->KeyState
.KeyToggleState
= EFI_TOGGLE_STATE_VALID
;
1638 if (UsbKeyboardDevice
->LeftCtrlOn
) {
1639 KeyData
->KeyState
.KeyShiftState
|= EFI_LEFT_CONTROL_PRESSED
;
1641 if (UsbKeyboardDevice
->RightCtrlOn
) {
1642 KeyData
->KeyState
.KeyShiftState
|= EFI_RIGHT_CONTROL_PRESSED
;
1644 if (UsbKeyboardDevice
->LeftAltOn
) {
1645 KeyData
->KeyState
.KeyShiftState
|= EFI_LEFT_ALT_PRESSED
;
1647 if (UsbKeyboardDevice
->RightAltOn
) {
1648 KeyData
->KeyState
.KeyShiftState
|= EFI_RIGHT_ALT_PRESSED
;
1650 if (UsbKeyboardDevice
->LeftShiftOn
) {
1651 KeyData
->KeyState
.KeyShiftState
|= EFI_LEFT_SHIFT_PRESSED
;
1653 if (UsbKeyboardDevice
->RightShiftOn
) {
1654 KeyData
->KeyState
.KeyShiftState
|= EFI_RIGHT_SHIFT_PRESSED
;
1656 if (UsbKeyboardDevice
->LeftLogoOn
) {
1657 KeyData
->KeyState
.KeyShiftState
|= EFI_LEFT_LOGO_PRESSED
;
1659 if (UsbKeyboardDevice
->RightLogoOn
) {
1660 KeyData
->KeyState
.KeyShiftState
|= EFI_RIGHT_LOGO_PRESSED
;
1662 if (UsbKeyboardDevice
->MenuKeyOn
) {
1663 KeyData
->KeyState
.KeyShiftState
|= EFI_MENU_KEY_PRESSED
;
1665 if (UsbKeyboardDevice
->SysReqOn
) {
1666 KeyData
->KeyState
.KeyShiftState
|= EFI_SYS_REQ_PRESSED
;
1669 if (UsbKeyboardDevice
->ScrollOn
) {
1670 KeyData
->KeyState
.KeyToggleState
|= EFI_SCROLL_LOCK_ACTIVE
;
1672 if (UsbKeyboardDevice
->NumLockOn
) {
1673 KeyData
->KeyState
.KeyToggleState
|= EFI_NUM_LOCK_ACTIVE
;
1675 if (UsbKeyboardDevice
->CapsOn
) {
1676 KeyData
->KeyState
.KeyToggleState
|= EFI_CAPS_LOCK_ACTIVE
;
1678 if (UsbKeyboardDevice
->IsSupportPartialKey
) {
1679 KeyData
->KeyState
.KeyToggleState
|= EFI_KEY_STATE_EXPOSED
;
1682 // Invoke notification functions if the key is registered.
1684 NotifyList
= &UsbKeyboardDevice
->NotifyList
;
1685 for (Link
= GetFirstNode (NotifyList
); !IsNull (NotifyList
, Link
); Link
= GetNextNode (NotifyList
, Link
)) {
1686 CurrentNotify
= CR (Link
, KEYBOARD_CONSOLE_IN_EX_NOTIFY
, NotifyEntry
, USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
1687 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
1688 CurrentNotify
->KeyNotificationFn (KeyData
);
1693 // Translate the CTRL-Alpha characters to their corresponding control value
1694 // (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
1696 if (UsbKeyboardDevice
->CtrlOn
) {
1697 if (KeyData
->Key
.UnicodeChar
>= 'a' && KeyData
->Key
.UnicodeChar
<= 'z') {
1698 KeyData
->Key
.UnicodeChar
= (UINT8
) (KeyData
->Key
.UnicodeChar
- 'a' + 1);
1699 } else if (KeyData
->Key
.UnicodeChar
>= 'A' && KeyData
->Key
.UnicodeChar
<= 'Z') {
1700 KeyData
->Key
.UnicodeChar
= (UINT8
) (KeyData
->Key
.UnicodeChar
- 'A' + 1);
1711 @param Queue Points to the queue.
1712 @param ItemSize Size of the single item.
1717 IN OUT USB_SIMPLE_QUEUE
*Queue
,
1723 Queue
->ItemSize
= ItemSize
;
1727 if (Queue
->Buffer
[0] != NULL
) {
1728 FreePool (Queue
->Buffer
[0]);
1731 Queue
->Buffer
[0] = AllocatePool (sizeof (Queue
->Buffer
) / sizeof (Queue
->Buffer
[0]) * ItemSize
);
1732 ASSERT (Queue
->Buffer
[0] != NULL
);
1734 for (Index
= 1; Index
< sizeof (Queue
->Buffer
) / sizeof (Queue
->Buffer
[0]); Index
++) {
1735 Queue
->Buffer
[Index
] = ((UINT8
*) Queue
->Buffer
[Index
- 1]) + ItemSize
;
1742 @param Queue Points to the queue.
1746 IN OUT USB_SIMPLE_QUEUE
*Queue
1749 FreePool (Queue
->Buffer
[0]);
1754 Check whether the queue is empty.
1756 @param Queue Points to the queue.
1758 @retval TRUE Queue is empty.
1759 @retval FALSE Queue is not empty.
1764 IN USB_SIMPLE_QUEUE
*Queue
1768 // Meet FIFO empty condition
1770 return (BOOLEAN
) (Queue
->Head
== Queue
->Tail
);
1775 Check whether the queue is full.
1777 @param Queue Points to the queue.
1779 @retval TRUE Queue is full.
1780 @retval FALSE Queue is not full.
1785 IN USB_SIMPLE_QUEUE
*Queue
1788 return (BOOLEAN
) (((Queue
->Tail
+ 1) % (MAX_KEY_ALLOWED
+ 1)) == Queue
->Head
);
1793 Enqueue the item to the queue.
1795 @param Queue Points to the queue.
1796 @param Item Points to the item to be enqueued.
1797 @param ItemSize Size of the item.
1801 IN OUT USB_SIMPLE_QUEUE
*Queue
,
1806 ASSERT (ItemSize
== Queue
->ItemSize
);
1808 // If keyboard buffer is full, throw the
1809 // first key out of the keyboard buffer.
1811 if (IsQueueFull (Queue
)) {
1812 Queue
->Head
= (Queue
->Head
+ 1) % (MAX_KEY_ALLOWED
+ 1);
1815 CopyMem (Queue
->Buffer
[Queue
->Tail
], Item
, ItemSize
);
1818 // Adjust the tail pointer of the FIFO keyboard buffer.
1820 Queue
->Tail
= (Queue
->Tail
+ 1) % (MAX_KEY_ALLOWED
+ 1);
1825 Dequeue a item from the queue.
1827 @param Queue Points to the queue.
1828 @param Item Receives the item.
1829 @param ItemSize Size of the item.
1831 @retval EFI_SUCCESS Item was successfully dequeued.
1832 @retval EFI_DEVICE_ERROR The queue is empty.
1837 IN OUT USB_SIMPLE_QUEUE
*Queue
,
1842 ASSERT (Queue
->ItemSize
== ItemSize
);
1844 if (IsQueueEmpty (Queue
)) {
1845 return EFI_DEVICE_ERROR
;
1848 CopyMem (Item
, Queue
->Buffer
[Queue
->Head
], ItemSize
);
1851 // Adjust the head pointer of the FIFO keyboard buffer.
1853 Queue
->Head
= (Queue
->Head
+ 1) % (MAX_KEY_ALLOWED
+ 1);
1860 Sets USB keyboard LED state.
1862 @param UsbKeyboardDevice The USB_KB_DEV instance.
1867 IN USB_KB_DEV
*UsbKeyboardDevice
1874 // Set each field in Led map.
1876 Led
.NumLock
= (UINT8
) ((UsbKeyboardDevice
->NumLockOn
) ? 1 : 0);
1877 Led
.CapsLock
= (UINT8
) ((UsbKeyboardDevice
->CapsOn
) ? 1 : 0);
1878 Led
.ScrollLock
= (UINT8
) ((UsbKeyboardDevice
->ScrollOn
) ? 1 : 0);
1883 // Call Set_Report Request to lighten the LED.
1885 UsbSetReportRequest (
1886 UsbKeyboardDevice
->UsbIo
,
1887 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
1897 Handler for Repeat Key event.
1899 This function is the handler for Repeat Key event triggered
1901 After a repeatable key is pressed, the event would be triggered
1902 with interval of USBKBD_REPEAT_DELAY. Once the event is triggered,
1903 following trigger will come with interval of USBKBD_REPEAT_RATE.
1905 @param Event The Repeat Key event.
1906 @param Context Points to the USB_KB_DEV instance.
1911 USBKeyboardRepeatHandler (
1916 USB_KB_DEV
*UsbKeyboardDevice
;
1919 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1922 // Do nothing when there is no repeat key.
1924 if (UsbKeyboardDevice
->RepeatKey
!= 0) {
1926 // Inserts the repeat key into keyboard buffer,
1928 UsbKey
.KeyCode
= UsbKeyboardDevice
->RepeatKey
;
1930 Enqueue (&UsbKeyboardDevice
->UsbKeyQueue
, &UsbKey
, sizeof (UsbKey
));
1933 // Set repeat rate for next repeat key generation.
1936 UsbKeyboardDevice
->RepeatTimer
,
1945 Handler for Delayed Recovery event.
1947 This function is the handler for Delayed Recovery event triggered
1949 After a device error occurs, the event would be triggered
1950 with interval of EFI_USB_INTERRUPT_DELAY. EFI_USB_INTERRUPT_DELAY
1951 is defined in USB standard for error handling.
1953 @param Event The Delayed Recovery event.
1954 @param Context Points to the USB_KB_DEV instance.
1959 USBKeyboardRecoveryHandler (
1965 USB_KB_DEV
*UsbKeyboardDevice
;
1966 EFI_USB_IO_PROTOCOL
*UsbIo
;
1969 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1971 UsbIo
= UsbKeyboardDevice
->UsbIo
;
1973 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
1976 // Re-submit Asynchronous Interrupt Transfer for recovery.
1978 UsbIo
->UsbAsyncInterruptTransfer (
1980 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1982 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,