2 Helper functions for USB Keyboard Driver.
4 Copyright (c) 2004 - 2008, Intel Corporation
5 All rights reserved. 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
305 Initialize Key Convention Table by using default keyboard layout.
307 @param UsbKeyboardDevice The USB_KB_DEV instance.
309 @retval EFI_SUCCESS The default keyboard layout was installed successfully
310 @retval Others Failure to install default keyboard layout.
314 InstallDefaultKeyboardLayout (
315 IN OUT USB_KB_DEV
*UsbKeyboardDevice
319 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
320 EFI_HII_HANDLE HiiHandle
;
323 // Locate Hii database protocol
325 Status
= gBS
->LocateProtocol (
326 &gEfiHiiDatabaseProtocolGuid
,
328 (VOID
**) &HiiDatabase
330 if (EFI_ERROR (Status
)) {
335 // Install Keyboard Layout package to HII database
337 HiiHandle
= HiiAddPackages (
338 &mUsbKeyboardLayoutPackageGuid
,
339 UsbKeyboardDevice
->ControllerHandle
,
340 &mUsbKeyboardLayoutBin
,
343 if (HiiHandle
== NULL
) {
344 return EFI_OUT_OF_RESOURCES
;
348 // Set current keyboard layout
350 Status
= HiiDatabase
->SetKeyboardLayout (HiiDatabase
, &mUsbKeyboardLayoutKeyGuid
);
357 Uses USB I/O to check whether the device is a USB keyboard device.
359 @param UsbIo Pointer to a USB I/O protocol instance.
361 @retval TRUE Device is a USB keyboard device.
362 @retval FALSE Device is a not USB keyboard device.
368 IN EFI_USB_IO_PROTOCOL
*UsbIo
372 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
375 // Get the default interface descriptor
377 Status
= UsbIo
->UsbGetInterfaceDescriptor (
382 if (EFI_ERROR (Status
)) {
386 if (InterfaceDescriptor
.InterfaceClass
== CLASS_HID
&&
387 InterfaceDescriptor
.InterfaceSubClass
== SUBCLASS_BOOT
&&
388 InterfaceDescriptor
.InterfaceProtocol
== PROTOCOL_KEYBOARD
397 Get current keyboard layout from HII database.
399 @return Pointer to HII Keyboard Layout.
400 NULL means failure occurred while trying to get keyboard layout.
403 EFI_HII_KEYBOARD_LAYOUT
*
405 GetCurrentKeyboardLayout (
410 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
411 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
415 // Locate HII Database Protocol
417 Status
= gBS
->LocateProtocol (
418 &gEfiHiiDatabaseProtocolGuid
,
420 (VOID
**) &HiiDatabase
422 if (EFI_ERROR (Status
)) {
427 // Get current keyboard layout from HII database
430 KeyboardLayout
= NULL
;
431 Status
= HiiDatabase
->GetKeyboardLayout (
437 if (Status
== EFI_BUFFER_TOO_SMALL
) {
438 KeyboardLayout
= AllocatePool (Length
);
439 ASSERT (KeyboardLayout
!= NULL
);
441 Status
= HiiDatabase
->GetKeyboardLayout (
447 if (EFI_ERROR (Status
)) {
448 FreePool (KeyboardLayout
);
449 KeyboardLayout
= NULL
;
453 return KeyboardLayout
;
457 Find Key Descriptor in Key Convertion Table given its USB keycode.
459 @param UsbKeyboardDevice The USB_KB_DEV instance.
460 @param KeyCode USB Keycode.
462 @return The Key Descriptor in Key Convertion Table.
463 NULL means not found.
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.
507 IN USB_KB_DEV
*UsbKeyboardDevice
,
508 IN EFI_KEY_DESCRIPTOR
*KeyDescriptor
512 LIST_ENTRY
*NsKeyList
;
513 USB_NS_KEY
*UsbNsKey
;
515 NsKeyList
= &UsbKeyboardDevice
->NsKeyList
;
516 Link
= GetFirstNode (NsKeyList
);
517 while (!IsNull (NsKeyList
, Link
)) {
518 UsbNsKey
= USB_NS_KEY_FORM_FROM_LINK (Link
);
520 if (UsbNsKey
->NsKey
[0].Key
== KeyDescriptor
->Key
) {
524 Link
= GetNextNode (NsKeyList
, Link
);
531 Find physical key definition for a given key descriptor.
533 For a specified non-spacing key, there are a list of physical
534 keys following it. This function traverses the list of
535 physical keys and tries to find the physical key matching
538 @param UsbNsKey The non-spacing key information.
539 @param KeyDescriptor The key descriptor.
541 @return The physical key definition.
542 If no physical key is found, parameter KeyDescriptor is returned.
548 IN USB_NS_KEY
*UsbNsKey
,
549 IN EFI_KEY_DESCRIPTOR
*KeyDescriptor
553 EFI_KEY_DESCRIPTOR
*PhysicalKey
;
555 PhysicalKey
= &UsbNsKey
->NsKey
[1];
556 for (Index
= 0; Index
< UsbNsKey
->KeyCount
; Index
++) {
557 if (KeyDescriptor
->Key
== PhysicalKey
->Key
) {
565 // No children definition matched, return original key
567 return KeyDescriptor
;
571 The notification function for EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID.
573 This function is registered to event of EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
574 group type, which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
575 It tries to get curent keyboard layout from HII database.
577 @param Event Event being signaled.
578 @param Context Points to USB_KB_DEV instance.
583 SetKeyboardLayoutEvent (
588 USB_KB_DEV
*UsbKeyboardDevice
;
589 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
590 EFI_KEY_DESCRIPTOR TempKey
;
591 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
592 EFI_KEY_DESCRIPTOR
*TableEntry
;
593 EFI_KEY_DESCRIPTOR
*NsKey
;
594 USB_NS_KEY
*UsbNsKey
;
600 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
603 // Try to get current keyboard layout from HII database
605 KeyboardLayout
= GetCurrentKeyboardLayout ();
606 if (KeyboardLayout
== NULL
) {
611 // Re-allocate resource for KeyConvertionTable
613 ReleaseKeyboardLayoutResources (UsbKeyboardDevice
);
614 UsbKeyboardDevice
->KeyConvertionTable
= AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE
) * sizeof (EFI_KEY_DESCRIPTOR
));
615 ASSERT (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
);
618 // Traverse the list of key descriptors following the header of EFI_HII_KEYBOARD_LAYOUT
620 KeyDescriptor
= (EFI_KEY_DESCRIPTOR
*) (((UINT8
*) KeyboardLayout
) + sizeof (EFI_HII_KEYBOARD_LAYOUT
));
621 for (Index
= 0; Index
< KeyboardLayout
->DescriptorCount
; Index
++) {
623 // Copy from HII keyboard layout package binary for alignment
625 CopyMem (&TempKey
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
628 // Fill the key into KeyConvertionTable, whose index is calculated from USB keycode.
630 KeyCode
= EfiKeyToUsbKeyCodeConvertionTable
[(UINT8
) (TempKey
.Key
)];
631 TableEntry
= GetKeyDescriptor (UsbKeyboardDevice
, KeyCode
);
632 CopyMem (TableEntry
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
635 // For non-spacing key, create the list with a non-spacing key followed by physical keys.
637 if (TempKey
.Modifier
== EFI_NS_KEY_MODIFIER
) {
638 UsbNsKey
= AllocatePool (sizeof (USB_NS_KEY
));
639 ASSERT (UsbNsKey
!= NULL
);
642 // Search for sequential children physical key definitions
645 NsKey
= KeyDescriptor
+ 1;
646 for (Index2
= Index
+ 1; Index2
< KeyboardLayout
->DescriptorCount
; Index2
++) {
647 CopyMem (&TempKey
, NsKey
, sizeof (EFI_KEY_DESCRIPTOR
));
648 if (TempKey
.Modifier
== EFI_NS_KEY_DEPENDENCY_MODIFIER
) {
656 UsbNsKey
->Signature
= USB_NS_KEY_SIGNATURE
;
657 UsbNsKey
->KeyCount
= KeyCount
;
658 UsbNsKey
->NsKey
= AllocateCopyPool (
659 (KeyCount
+ 1) * sizeof (EFI_KEY_DESCRIPTOR
),
662 InsertTailList (&UsbKeyboardDevice
->NsKeyList
, &UsbNsKey
->Link
);
665 // Skip over the child physical keys
668 KeyDescriptor
+= KeyCount
;
675 // There are two EfiKeyEnter, duplicate its key descriptor
677 TableEntry
= GetKeyDescriptor (UsbKeyboardDevice
, 0x58);
678 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, 0x28);
679 CopyMem (TableEntry
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
681 FreePool (KeyboardLayout
);
685 Destroy resources for keyboard layout.
687 @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.
732 OUT USB_KB_DEV
*UsbKeyboardDevice
735 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
738 UsbKeyboardDevice
->KeyConvertionTable
= AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE
) * sizeof (EFI_KEY_DESCRIPTOR
));
739 ASSERT (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
);
741 InitializeListHead (&UsbKeyboardDevice
->NsKeyList
);
742 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
743 UsbKeyboardDevice
->KeyboardLayoutEvent
= NULL
;
746 // Register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group,
747 // which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
749 Status
= gBS
->CreateEventEx (
752 SetKeyboardLayoutEvent
,
754 &gEfiHiiKeyBoardLayoutGuid
,
755 &UsbKeyboardDevice
->KeyboardLayoutEvent
757 if (EFI_ERROR (Status
)) {
761 KeyboardLayout
= GetCurrentKeyboardLayout ();
762 if (KeyboardLayout
!= NULL
) {
764 // If current keyboard layout is successfully retrieved from HII database,
765 // force to initialize the keyboard layout.
767 gBS
->SignalEvent (UsbKeyboardDevice
->KeyboardLayoutEvent
);
769 if (FeaturePcdGet (PcdDisableDefaultKeyboardLayoutInUsbKbDriver
)) {
771 // If no keyboard layout can be retrieved from HII database, and default layout
772 // is disabled, then return EFI_NOT_READY.
774 return EFI_NOT_READY
;
777 // If no keyboard layout can be retrieved from HII database, and default layout
778 // is enabled, then load the default keyboard layout.
780 InstallDefaultKeyboardLayout (UsbKeyboardDevice
);
788 Initialize USB keyboard device and all private data structures.
790 @param UsbKeyboardDevice The USB_KB_DEV instance.
792 @retval EFI_SUCCESS Initialization is successful.
793 @retval EFI_DEVICE_ERROR Keyboard initialization failed.
799 IN OUT USB_KB_DEV
*UsbKeyboardDevice
807 UINT32 TransferResult
;
809 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
811 PcdGet32 (PcdStatusCodeValueKeyboardSelfTest
),
812 UsbKeyboardDevice
->DevicePath
815 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
818 // Uses default configuration to configure the USB keyboard device.
821 Status
= UsbSetConfiguration (
822 UsbKeyboardDevice
->UsbIo
,
823 (UINT16
) ConfigValue
,
826 if (EFI_ERROR (Status
)) {
828 // If configuration could not be set here, it means
829 // the keyboard interface has some errors and could
830 // not be initialized
832 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
833 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
834 PcdGet32 (PcdStatusCodeValueKeyboardInterfaceError
),
835 UsbKeyboardDevice
->DevicePath
838 return EFI_DEVICE_ERROR
;
841 UsbGetProtocolRequest (
842 UsbKeyboardDevice
->UsbIo
,
843 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
847 // Set boot protocol for the USB Keyboard.
848 // This driver only supports boot protocol.
850 if (Protocol
!= BOOT_PROTOCOL
) {
851 UsbSetProtocolRequest (
852 UsbKeyboardDevice
->UsbIo
,
853 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
859 // ReportId is zero, which means the idle rate applies to all input reports.
863 // Duration is zero, which means the duration is infinite.
864 // so the endpoint will inhibit reporting forever,
865 // and only reporting when a change is detected in the report data.
869 UsbKeyboardDevice
->UsbIo
,
870 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
875 UsbKeyboardDevice
->CtrlOn
= FALSE
;
876 UsbKeyboardDevice
->AltOn
= FALSE
;
877 UsbKeyboardDevice
->ShiftOn
= FALSE
;
878 UsbKeyboardDevice
->NumLockOn
= FALSE
;
879 UsbKeyboardDevice
->CapsOn
= FALSE
;
880 UsbKeyboardDevice
->ScrollOn
= FALSE
;
882 UsbKeyboardDevice
->LeftCtrlOn
= FALSE
;
883 UsbKeyboardDevice
->LeftAltOn
= FALSE
;
884 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
885 UsbKeyboardDevice
->LeftLogoOn
= FALSE
;
886 UsbKeyboardDevice
->RightCtrlOn
= FALSE
;
887 UsbKeyboardDevice
->RightAltOn
= FALSE
;
888 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
889 UsbKeyboardDevice
->RightLogoOn
= FALSE
;
890 UsbKeyboardDevice
->MenuKeyOn
= FALSE
;
891 UsbKeyboardDevice
->SysReqOn
= FALSE
;
893 UsbKeyboardDevice
->AltGrOn
= FALSE
;
895 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
898 // Sync the initial state of lights on keyboard.
900 SetKeyLED (UsbKeyboardDevice
);
902 ZeroMem (UsbKeyboardDevice
->LastKeyCodeArray
, sizeof (UINT8
) * 8);
905 // Create event for repeat keys' generation.
907 if (UsbKeyboardDevice
->RepeatTimer
!= NULL
) {
908 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
909 UsbKeyboardDevice
->RepeatTimer
= NULL
;
913 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
915 USBKeyboardRepeatHandler
,
917 &UsbKeyboardDevice
->RepeatTimer
921 // Create event for delayed recovery, which deals with device error.
923 if (UsbKeyboardDevice
->DelayedRecoveryEvent
!= NULL
) {
924 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
925 UsbKeyboardDevice
->DelayedRecoveryEvent
= NULL
;
929 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
931 USBKeyboardRecoveryHandler
,
933 &UsbKeyboardDevice
->DelayedRecoveryEvent
941 Handler function for USB keyboard's asynchronous interrupt transfer.
943 This function is the handler function for USB keyboard's asynchronous interrupt transfer
944 to manage the keyboard. It parses the USB keyboard input report, and inserts data to
945 keyboard buffer according to state of modifer keys and normal keys. Timer for repeat key
946 is also set accordingly.
948 @param Data A pointer to a buffer that is filled with key data which is
949 retrieved via asynchronous interrupt transfer.
950 @param DataLength Indicates the size of the data buffer.
951 @param Context Pointing to USB_KB_DEV instance.
952 @param Result Indicates the result of the asynchronous interrupt transfer.
954 @retval EFI_SUCCESS Asynchronous interrupt transfer is handled successfully.
955 @retval EFI_DEVICE_ERROR Hardware error occurs.
967 USB_KB_DEV
*UsbKeyboardDevice
;
968 EFI_USB_IO_PROTOCOL
*UsbIo
;
969 UINT8
*CurKeyCodeBuffer
;
970 UINT8
*OldKeyCodeBuffer
;
971 UINT8 CurModifierMap
;
972 UINT8 OldModifierMap
;
983 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
985 ASSERT (Context
!= NULL
);
988 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
989 UsbIo
= UsbKeyboardDevice
->UsbIo
;
992 // Analyzes Result and performs corresponding action.
994 if (Result
!= EFI_USB_NOERROR
) {
996 // Some errors happen during the process
998 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
999 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1000 PcdGet32 (PcdStatusCodeValueKeyboardInputError
),
1001 UsbKeyboardDevice
->DevicePath
1005 // Stop the repeat key generation if any
1007 UsbKeyboardDevice
->RepeatKey
= 0;
1010 UsbKeyboardDevice
->RepeatTimer
,
1015 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
1016 UsbClearEndpointHalt (
1018 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1024 // Delete & Submit this interrupt again
1025 // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt.
1027 UsbIo
->UsbAsyncInterruptTransfer (
1029 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1037 // EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling.
1040 UsbKeyboardDevice
->DelayedRecoveryEvent
,
1042 EFI_USB_INTERRUPT_DELAY
1045 return EFI_DEVICE_ERROR
;
1049 // If no error and no data, just return EFI_SUCCESS.
1051 if (DataLength
== 0 || Data
== NULL
) {
1056 // Following code checks current keyboard input report against old key code buffer.
1057 // According to USB HID Firmware Specification, the report consists of 8 bytes.
1058 // Byte 0 is map of Modifier keys.
1059 // Byte 1 is reserved.
1060 // Bytes 2 to 7 are keycodes.
1062 CurKeyCodeBuffer
= (UINT8
*) Data
;
1063 OldKeyCodeBuffer
= UsbKeyboardDevice
->LastKeyCodeArray
;
1066 // Checks for new key stroke.
1068 for (Index
= 0; Index
< 8; Index
++) {
1069 if (OldKeyCodeBuffer
[Index
] != CurKeyCodeBuffer
[Index
]) {
1075 // If no new key, return EFI_SUCCESS immediately.
1082 // Parse the modifier key, which is the first byte of keyboard input report.
1084 CurModifierMap
= CurKeyCodeBuffer
[0];
1085 OldModifierMap
= OldKeyCodeBuffer
[0];
1088 // Handle modifier key's pressing or releasing situation.
1089 // According to USB HID Firmware spec, Byte 0 uses folloing map of Modifier keys:
1090 // Bit0: Left Control, Keycode: 0xe0
1091 // Bit1: Left Shift, Keycode: 0xe1
1092 // Bit2: Left Alt, Keycode: 0xe2
1093 // Bit3: Left GUI, Keycode: 0xe3
1094 // Bit4: Right Control, Keycode: 0xe4
1095 // Bit5: Right Shift, Keycode: 0xe5
1096 // Bit6: Right Alt, Keycode: 0xe6
1097 // Bit7: Right GUI, Keycode: 0xe7
1099 for (Index
= 0; Index
< 8; Index
++) {
1100 Mask
= (UINT8
) (1 << Index
);
1101 if ((CurModifierMap
& Mask
) != (OldModifierMap
& Mask
)) {
1103 // If current modifier key is up, then CurModifierMap & Mask = 0;
1104 // otherwise it is a non-zero value.
1105 // Insert the changed modifier key into key buffer.
1107 Down
= (BOOLEAN
) ((CurModifierMap
& Mask
) != 0);
1108 InsertKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), (UINT8
) (0xe0 + Index
), Down
);
1113 // Handle normal key's releasing situation
1114 // Bytes 2 to 7 are for normal keycodes
1117 for (Index
= 2; Index
< 8; Index
++) {
1119 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index
])) {
1123 // For any key in old keycode buffer, if it is not in current keycode buffer,
1124 // then it is released. Otherwise, it is not released.
1127 for (Index2
= 2; Index2
< 8; Index2
++) {
1129 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index2
])) {
1133 if (OldKeyCodeBuffer
[Index
] == CurKeyCodeBuffer
[Index2
]) {
1141 &(UsbKeyboardDevice
->KeyboardBuffer
),
1142 OldKeyCodeBuffer
[Index
],
1146 // The original repeat key is released.
1148 if (OldKeyCodeBuffer
[Index
] == UsbKeyboardDevice
->RepeatKey
) {
1149 UsbKeyboardDevice
->RepeatKey
= 0;
1155 // If original repeat key is released, cancel the repeat timer
1157 if (UsbKeyboardDevice
->RepeatKey
== 0) {
1159 UsbKeyboardDevice
->RepeatTimer
,
1166 // Handle normal key's pressing situation
1169 for (Index
= 2; Index
< 8; Index
++) {
1171 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index
])) {
1175 // For any key in current keycode buffer, if it is not in old keycode buffer,
1176 // then it is pressed. Otherwise, it is not pressed.
1179 for (Index2
= 2; Index2
< 8; Index2
++) {
1181 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index2
])) {
1185 if (CurKeyCodeBuffer
[Index
] == OldKeyCodeBuffer
[Index2
]) {
1192 InsertKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), CurKeyCodeBuffer
[Index
], TRUE
);
1195 // Handle repeat key
1197 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, CurKeyCodeBuffer
[Index
]);
1198 ASSERT (KeyDescriptor
!= NULL
);
1200 if (KeyDescriptor
->Modifier
== EFI_NUM_LOCK_MODIFIER
|| KeyDescriptor
->Modifier
== EFI_CAPS_LOCK_MODIFIER
) {
1202 // For NumLock or CapsLock pressed, there is no need to handle repeat key for them.
1204 UsbKeyboardDevice
->RepeatKey
= 0;
1207 // Prepare new repeat key, and clear the original one.
1209 NewRepeatKey
= CurKeyCodeBuffer
[Index
];
1210 UsbKeyboardDevice
->RepeatKey
= 0;
1216 // Update LastKeycodeArray buffer in the UsbKeyboardDevice data structure.
1218 for (Index
= 0; Index
< 8; Index
++) {
1219 UsbKeyboardDevice
->LastKeyCodeArray
[Index
] = CurKeyCodeBuffer
[Index
];
1223 // Pre-process KeyboardBuffer to check if Ctrl + Alt + Del is pressed.
1225 SavedTail
= UsbKeyboardDevice
->KeyboardBuffer
.BufferTail
;
1226 Index
= UsbKeyboardDevice
->KeyboardBuffer
.BufferHead
;
1227 while (Index
!= SavedTail
) {
1228 RemoveKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), &UsbKey
);
1230 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, UsbKey
.KeyCode
);
1231 ASSERT (KeyDescriptor
!= NULL
);
1233 switch (KeyDescriptor
->Modifier
) {
1235 case EFI_LEFT_CONTROL_MODIFIER
:
1236 case EFI_RIGHT_CONTROL_MODIFIER
:
1238 UsbKeyboardDevice
->CtrlOn
= TRUE
;
1240 UsbKeyboardDevice
->CtrlOn
= FALSE
;
1244 case EFI_LEFT_ALT_MODIFIER
:
1245 case EFI_RIGHT_ALT_MODIFIER
:
1247 UsbKeyboardDevice
->AltOn
= TRUE
;
1249 UsbKeyboardDevice
->AltOn
= FALSE
;
1253 case EFI_ALT_GR_MODIFIER
:
1255 UsbKeyboardDevice
->AltGrOn
= TRUE
;
1257 UsbKeyboardDevice
->AltGrOn
= FALSE
;
1262 // For Del Key, check if Ctrl + Alt + Del occurs for reset.
1264 case EFI_DELETE_MODIFIER
:
1266 if ((UsbKeyboardDevice
->CtrlOn
) && (UsbKeyboardDevice
->AltOn
)) {
1267 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1277 // Insert the key back to the buffer,
1278 // so the key sequence will not be destroyed.
1281 &(UsbKeyboardDevice
->KeyboardBuffer
),
1285 Index
= UsbKeyboardDevice
->KeyboardBuffer
.BufferHead
;
1289 // If there is new key pressed, update the RepeatKey value, and set the
1290 // timer to repeate delay timer
1292 if (NewRepeatKey
!= 0) {
1294 // Sets trigger time to "Repeat Delay Time",
1295 // to trigger the repeat timer when the key is hold long
1299 UsbKeyboardDevice
->RepeatTimer
,
1303 UsbKeyboardDevice
->RepeatKey
= NewRepeatKey
;
1311 Retrieves a USB keycode after parsing the raw data in keyboard buffer.
1313 This function parses keyboard buffer. It updates state of modifier key for
1314 USB_KB_DEV instancem, and returns keycode for output.
1316 @param UsbKeyboardDevice The USB_KB_DEV instance.
1317 @param KeyCode Pointer to the USB keycode for output.
1319 @retval EFI_SUCCESS Keycode successfully parsed.
1320 @retval EFI_NOT_READY Keyboard buffer is not ready for a valid keycode
1326 IN OUT USB_KB_DEV
*UsbKeyboardDevice
,
1331 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1335 while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice
->KeyboardBuffer
)) {
1337 // Pops one raw data off.
1339 RemoveKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), &UsbKey
);
1341 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, UsbKey
.KeyCode
);
1342 ASSERT (KeyDescriptor
!= NULL
);
1348 switch (KeyDescriptor
->Modifier
) {
1353 case EFI_LEFT_CONTROL_MODIFIER
:
1354 UsbKeyboardDevice
->LeftCtrlOn
= FALSE
;
1355 UsbKeyboardDevice
->CtrlOn
= FALSE
;
1357 case EFI_RIGHT_CONTROL_MODIFIER
:
1358 UsbKeyboardDevice
->RightCtrlOn
= FALSE
;
1359 UsbKeyboardDevice
->CtrlOn
= FALSE
;
1365 case EFI_LEFT_SHIFT_MODIFIER
:
1366 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
1367 UsbKeyboardDevice
->ShiftOn
= FALSE
;
1369 case EFI_RIGHT_SHIFT_MODIFIER
:
1370 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
1371 UsbKeyboardDevice
->ShiftOn
= FALSE
;
1377 case EFI_LEFT_ALT_MODIFIER
:
1378 UsbKeyboardDevice
->LeftAltOn
= FALSE
;
1379 UsbKeyboardDevice
->AltOn
= FALSE
;
1381 case EFI_RIGHT_ALT_MODIFIER
:
1382 UsbKeyboardDevice
->RightAltOn
= FALSE
;
1383 UsbKeyboardDevice
->AltOn
= FALSE
;
1387 // Left Logo release
1389 case EFI_LEFT_LOGO_MODIFIER
:
1390 UsbKeyboardDevice
->LeftLogoOn
= FALSE
;
1394 // Right Logo release
1396 case EFI_RIGHT_LOGO_MODIFIER
:
1397 UsbKeyboardDevice
->RightLogoOn
= FALSE
;
1403 case EFI_MENU_MODIFIER
:
1404 UsbKeyboardDevice
->MenuKeyOn
= FALSE
;
1410 case EFI_PRINT_MODIFIER
:
1411 case EFI_SYS_REQUEST_MODIFIER
:
1412 UsbKeyboardDevice
->SysReqOn
= FALSE
;
1418 case EFI_ALT_GR_MODIFIER
:
1419 UsbKeyboardDevice
->AltGrOn
= FALSE
;
1430 // Analyzes key pressing situation
1432 switch (KeyDescriptor
->Modifier
) {
1437 case EFI_LEFT_CONTROL_MODIFIER
:
1438 UsbKeyboardDevice
->LeftCtrlOn
= TRUE
;
1439 UsbKeyboardDevice
->CtrlOn
= TRUE
;
1442 case EFI_RIGHT_CONTROL_MODIFIER
:
1443 UsbKeyboardDevice
->RightCtrlOn
= TRUE
;
1444 UsbKeyboardDevice
->CtrlOn
= TRUE
;
1451 case EFI_LEFT_SHIFT_MODIFIER
:
1452 UsbKeyboardDevice
->LeftShiftOn
= TRUE
;
1453 UsbKeyboardDevice
->ShiftOn
= TRUE
;
1456 case EFI_RIGHT_SHIFT_MODIFIER
:
1457 UsbKeyboardDevice
->RightShiftOn
= TRUE
;
1458 UsbKeyboardDevice
->ShiftOn
= TRUE
;
1465 case EFI_LEFT_ALT_MODIFIER
:
1466 UsbKeyboardDevice
->LeftAltOn
= TRUE
;
1467 UsbKeyboardDevice
->AltOn
= TRUE
;
1470 case EFI_RIGHT_ALT_MODIFIER
:
1471 UsbKeyboardDevice
->RightAltOn
= TRUE
;
1472 UsbKeyboardDevice
->AltOn
= TRUE
;
1479 case EFI_LEFT_LOGO_MODIFIER
:
1480 UsbKeyboardDevice
->LeftLogoOn
= TRUE
;
1486 case EFI_RIGHT_LOGO_MODIFIER
:
1487 UsbKeyboardDevice
->RightLogoOn
= TRUE
;
1493 case EFI_MENU_MODIFIER
:
1494 UsbKeyboardDevice
->MenuKeyOn
= TRUE
;
1500 case EFI_PRINT_MODIFIER
:
1501 case EFI_SYS_REQUEST_MODIFIER
:
1502 UsbKeyboardDevice
->SysReqOn
= TRUE
;
1509 case EFI_ALT_GR_MODIFIER
:
1510 UsbKeyboardDevice
->AltGrOn
= TRUE
;
1513 case EFI_NUM_LOCK_MODIFIER
:
1517 UsbKeyboardDevice
->NumLockOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->NumLockOn
));
1518 SetKeyLED (UsbKeyboardDevice
);
1522 case EFI_CAPS_LOCK_MODIFIER
:
1526 UsbKeyboardDevice
->CapsOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->CapsOn
));
1527 SetKeyLED (UsbKeyboardDevice
);
1531 case EFI_SCROLL_LOCK_MODIFIER
:
1533 // Toggle ScrollLock
1535 UsbKeyboardDevice
->ScrollOn
= (BOOLEAN
) (!(UsbKeyboardDevice
->ScrollOn
));
1536 SetKeyLED (UsbKeyboardDevice
);
1541 // PrintScreen, Pause/Break could not be retrieved via SimpleTextInEx protocol
1543 case EFI_PAUSE_MODIFIER
:
1544 case EFI_BREAK_MODIFIER
:
1556 // When encountering Ctrl + Alt + Del, then warm reset.
1558 if (KeyDescriptor
->Modifier
== EFI_DELETE_MODIFIER
) {
1559 if ((UsbKeyboardDevice
->CtrlOn
) && (UsbKeyboardDevice
->AltOn
)) {
1560 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1564 *KeyCode
= UsbKey
.KeyCode
;
1568 return EFI_NOT_READY
;
1573 Converts USB Keycode ranging from 0x4 to 0x65 to EFI_INPUT_KEY.
1575 @param UsbKeyboardDevice The USB_KB_DEV instance.
1576 @param KeyCode Indicates the key code that will be interpreted.
1577 @param Key A pointer to a buffer that is filled in with
1578 the keystroke information for the key that
1581 @retval EFI_SUCCESS Success.
1582 @retval EFI_INVALID_PARAMETER KeyCode is not in the range of 0x4 to 0x65.
1583 @retval EFI_INVALID_PARAMETER Translated EFI_INPUT_KEY has zero for both ScanCode and UnicodeChar.
1584 @retval EFI_NOT_READY KeyCode represents a dead key with EFI_NS_KEY_MODIFIER
1585 @retval EFI_DEVICE_ERROR Keyboard layout is invalid.
1590 UsbKeyCodeToEfiInputKey (
1591 IN USB_KB_DEV
*UsbKeyboardDevice
,
1593 OUT EFI_INPUT_KEY
*Key
1596 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1599 // KeyCode must in the range of 0x4 to 0x65
1601 if (!USBKBD_VALID_KEYCODE (KeyCode
)) {
1602 return EFI_INVALID_PARAMETER
;
1604 if ((KeyCode
- 4) >= NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE
) {
1605 return EFI_INVALID_PARAMETER
;
1608 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, KeyCode
);
1609 ASSERT (KeyDescriptor
!= NULL
);
1611 if (KeyDescriptor
->Modifier
== EFI_NS_KEY_MODIFIER
) {
1613 // If this is a dead key with EFI_NS_KEY_MODIFIER, then record it and return.
1615 UsbKeyboardDevice
->CurrentNsKey
= FindUsbNsKey (UsbKeyboardDevice
, KeyDescriptor
);
1616 return EFI_NOT_READY
;
1619 if (UsbKeyboardDevice
->CurrentNsKey
!= NULL
) {
1621 // If this keystroke follows a non-spacing key, then find the descriptor for corresponding
1624 KeyDescriptor
= FindPhysicalKey (UsbKeyboardDevice
->CurrentNsKey
, KeyDescriptor
);
1625 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
1629 // Make sure modifier of Key Descriptor is in the valid range according to UEFI spec.
1631 if (KeyDescriptor
->Modifier
> EFI_FUNCTION_KEY_TWELVE_MODIFIER
) {
1632 return EFI_DEVICE_ERROR
;
1635 Key
->ScanCode
= ModifierValueToEfiScanCodeConvertionTable
[KeyDescriptor
->Modifier
];
1636 Key
->UnicodeChar
= KeyDescriptor
->Unicode
;
1638 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_STANDARD_SHIFT
)!= 0) {
1639 if (UsbKeyboardDevice
->ShiftOn
) {
1640 Key
->UnicodeChar
= KeyDescriptor
->ShiftedUnicode
;
1643 // Need not return associated shift state if a class of printable characters that
1644 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
1646 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_CAPS_LOCK
) != 0) {
1647 UsbKeyboardDevice
->LeftShiftOn
= FALSE
;
1648 UsbKeyboardDevice
->RightShiftOn
= FALSE
;
1651 if (UsbKeyboardDevice
->AltGrOn
) {
1652 Key
->UnicodeChar
= KeyDescriptor
->ShiftedAltGrUnicode
;
1658 Key
->UnicodeChar
= KeyDescriptor
->Unicode
;
1660 if (UsbKeyboardDevice
->AltGrOn
) {
1661 Key
->UnicodeChar
= KeyDescriptor
->AltGrUnicode
;
1666 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_CAPS_LOCK
) != 0) {
1667 if (UsbKeyboardDevice
->CapsOn
) {
1668 if (Key
->UnicodeChar
== KeyDescriptor
->Unicode
) {
1669 Key
->UnicodeChar
= KeyDescriptor
->ShiftedUnicode
;
1670 } else if (Key
->UnicodeChar
== KeyDescriptor
->ShiftedUnicode
) {
1671 Key
->UnicodeChar
= KeyDescriptor
->Unicode
;
1677 // Translate the CTRL-Alpha characters to their corresponding control value
1678 // (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
1680 if (UsbKeyboardDevice
->CtrlOn
) {
1681 if (Key
->UnicodeChar
>= 'a' && Key
->UnicodeChar
<= 'z') {
1682 Key
->UnicodeChar
= (UINT8
) (Key
->UnicodeChar
- 'a' + 1);
1683 } else if (Key
->UnicodeChar
>= 'A' && Key
->UnicodeChar
<= 'Z') {
1684 Key
->UnicodeChar
= (UINT8
) (Key
->UnicodeChar
- 'A' + 1);
1688 if ((KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_NUM_LOCK
) != 0) {
1690 // For key affected by NumLock, if NumLock is on and Shift is not pressed, then it means
1691 // normal key, instead of original control key. So the ScanCode should be cleaned.
1692 // Otherwise, it means control key, so preserve the EFI Scan Code and clear the unicode keycode.
1694 if ((UsbKeyboardDevice
->NumLockOn
) && (!(UsbKeyboardDevice
->ShiftOn
))) {
1695 Key
->ScanCode
= SCAN_NULL
;
1697 Key
->UnicodeChar
= 0x00;
1702 // Translate Unicode 0x1B (ESC) to EFI Scan Code
1704 if (Key
->UnicodeChar
== 0x1B && Key
->ScanCode
== SCAN_NULL
) {
1705 Key
->ScanCode
= SCAN_ESC
;
1706 Key
->UnicodeChar
= 0x00;
1710 // Not valid for key without both unicode key code and EFI Scan Code.
1712 if (Key
->UnicodeChar
== 0 && Key
->ScanCode
== SCAN_NULL
) {
1713 return EFI_NOT_READY
;
1718 // Save Shift/Toggle state
1720 if (UsbKeyboardDevice
->LeftCtrlOn
) {
1721 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_LEFT_CONTROL_PRESSED
;
1723 if (UsbKeyboardDevice
->RightCtrlOn
) {
1724 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_RIGHT_CONTROL_PRESSED
;
1726 if (UsbKeyboardDevice
->LeftAltOn
) {
1727 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_LEFT_ALT_PRESSED
;
1729 if (UsbKeyboardDevice
->RightAltOn
) {
1730 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_RIGHT_ALT_PRESSED
;
1732 if (UsbKeyboardDevice
->LeftShiftOn
) {
1733 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_LEFT_SHIFT_PRESSED
;
1735 if (UsbKeyboardDevice
->RightShiftOn
) {
1736 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_RIGHT_SHIFT_PRESSED
;
1738 if (UsbKeyboardDevice
->LeftLogoOn
) {
1739 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_LEFT_LOGO_PRESSED
;
1741 if (UsbKeyboardDevice
->RightLogoOn
) {
1742 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_RIGHT_LOGO_PRESSED
;
1744 if (UsbKeyboardDevice
->MenuKeyOn
) {
1745 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_MENU_KEY_PRESSED
;
1747 if (UsbKeyboardDevice
->SysReqOn
) {
1748 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_SYS_REQ_PRESSED
;
1751 if (UsbKeyboardDevice
->ScrollOn
) {
1752 UsbKeyboardDevice
->KeyState
.KeyToggleState
|= EFI_SCROLL_LOCK_ACTIVE
;
1754 if (UsbKeyboardDevice
->NumLockOn
) {
1755 UsbKeyboardDevice
->KeyState
.KeyToggleState
|= EFI_NUM_LOCK_ACTIVE
;
1757 if (UsbKeyboardDevice
->CapsOn
) {
1758 UsbKeyboardDevice
->KeyState
.KeyToggleState
|= EFI_CAPS_LOCK_ACTIVE
;
1767 Resets USB keyboard buffer.
1769 @param KeyboardBuffer Points to the USB keyboard buffer.
1775 OUT USB_KB_BUFFER
*KeyboardBuffer
1778 ZeroMem (KeyboardBuffer
, sizeof (USB_KB_BUFFER
));
1780 KeyboardBuffer
->BufferHead
= KeyboardBuffer
->BufferTail
;
1785 Check whether USB keyboard buffer is empty.
1787 @param KeyboardBuffer USB keyboard buffer
1789 @retval TRUE Keyboard buffer is empty.
1790 @retval FALSE Keyboard buffer is not empty.
1795 IsUSBKeyboardBufferEmpty (
1796 IN USB_KB_BUFFER
*KeyboardBuffer
1800 // Meet FIFO empty condition
1802 return (BOOLEAN
) (KeyboardBuffer
->BufferHead
== KeyboardBuffer
->BufferTail
);
1807 Check whether USB keyboard buffer is full.
1809 @param KeyboardBuffer USB keyboard buffer
1811 @retval TRUE Keyboard buffer is full.
1812 @retval FALSE Keyboard buffer is not full.
1817 IsUSBKeyboardBufferFull (
1818 IN USB_KB_BUFFER
*KeyboardBuffer
1821 return (BOOLEAN
)(((KeyboardBuffer
->BufferTail
+ 1) % (MAX_KEY_ALLOWED
+ 1)) == KeyboardBuffer
->BufferHead
);
1826 Inserts a keycode into keyboard buffer.
1828 @param KeyboardBuffer Points to the USB keyboard buffer.
1829 @param Key Keycode to insert.
1830 @param Down TRUE means key is pressed.
1831 FALSE means key is released.
1837 IN OUT USB_KB_BUFFER
*KeyboardBuffer
,
1845 // If keyboard buffer is full, throw the
1846 // first key out of the keyboard buffer.
1848 if (IsUSBKeyboardBufferFull (KeyboardBuffer
)) {
1849 RemoveKeyCode (KeyboardBuffer
, &UsbKey
);
1852 ASSERT (KeyboardBuffer
->BufferTail
<= MAX_KEY_ALLOWED
);
1854 KeyboardBuffer
->Buffer
[KeyboardBuffer
->BufferTail
].KeyCode
= Key
;
1855 KeyboardBuffer
->Buffer
[KeyboardBuffer
->BufferTail
].Down
= Down
;
1858 // Adjust the tail pointer of the FIFO keyboard buffer.
1860 KeyboardBuffer
->BufferTail
= (UINT8
) ((KeyboardBuffer
->BufferTail
+ 1) % (MAX_KEY_ALLOWED
+ 1));
1865 Remove a keycode from keyboard buffer and return it.
1867 @param KeyboardBuffer Points to the USB keyboard buffer.
1868 @param UsbKey Points to the buffer that contains keycode for output.
1870 @retval EFI_SUCCESS Keycode successfully removed from keyboard buffer.
1871 @retval EFI_DEVICE_ERROR Keyboard buffer is empty.
1877 IN OUT USB_KB_BUFFER
*KeyboardBuffer
,
1881 if (IsUSBKeyboardBufferEmpty (KeyboardBuffer
)) {
1882 return EFI_DEVICE_ERROR
;
1885 ASSERT (KeyboardBuffer
->BufferHead
<= MAX_KEY_ALLOWED
);
1887 UsbKey
->KeyCode
= KeyboardBuffer
->Buffer
[KeyboardBuffer
->BufferHead
].KeyCode
;
1888 UsbKey
->Down
= KeyboardBuffer
->Buffer
[KeyboardBuffer
->BufferHead
].Down
;
1891 // Adjust the head pointer of the FIFO keyboard buffer.
1893 KeyboardBuffer
->BufferHead
= (UINT8
) ((KeyboardBuffer
->BufferHead
+ 1) % (MAX_KEY_ALLOWED
+ 1));
1900 Sets USB keyboard LED state.
1902 @param UsbKeyboardDevice The USB_KB_DEV instance.
1908 IN USB_KB_DEV
*UsbKeyboardDevice
1915 // Set each field in Led map.
1917 Led
.NumLock
= (UINT8
) ((UsbKeyboardDevice
->NumLockOn
) ? 1 : 0);
1918 Led
.CapsLock
= (UINT8
) ((UsbKeyboardDevice
->CapsOn
) ? 1 : 0);
1919 Led
.ScrollLock
= (UINT8
) ((UsbKeyboardDevice
->ScrollOn
) ? 1 : 0);
1924 // Call Set_Report Request to lighten the LED.
1926 UsbSetReportRequest (
1927 UsbKeyboardDevice
->UsbIo
,
1928 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
1938 Handler for Repeat Key event.
1940 This function is the handler for Repeat Key event triggered
1942 After a repeatable key is pressed, the event would be triggered
1943 with interval of USBKBD_REPEAT_DELAY. Once the event is triggered,
1944 following trigger will come with interval of USBKBD_REPEAT_RATE.
1946 @param Event The Repeat Key event.
1947 @param Context Points to the USB_KB_DEV instance.
1952 USBKeyboardRepeatHandler (
1957 USB_KB_DEV
*UsbKeyboardDevice
;
1959 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1962 // Do nothing when there is no repeat key.
1964 if (UsbKeyboardDevice
->RepeatKey
!= 0) {
1966 // Inserts the repeat key into keyboard buffer,
1969 &(UsbKeyboardDevice
->KeyboardBuffer
),
1970 UsbKeyboardDevice
->RepeatKey
,
1975 // Set repeat rate for next repeat key generation.
1978 UsbKeyboardDevice
->RepeatTimer
,
1987 Handler for Delayed Recovery event.
1989 This function is the handler for Delayed Recovery event triggered
1991 After a device error occurs, the event would be triggered
1992 with interval of EFI_USB_INTERRUPT_DELAY. EFI_USB_INTERRUPT_DELAY
1993 is defined in USB standard for error handling.
1995 @param Event The Delayed Recovery event.
1996 @param Context Points to the USB_KB_DEV instance.
2001 USBKeyboardRecoveryHandler (
2007 USB_KB_DEV
*UsbKeyboardDevice
;
2008 EFI_USB_IO_PROTOCOL
*UsbIo
;
2011 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
2013 UsbIo
= UsbKeyboardDevice
->UsbIo
;
2015 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
2018 // Re-submit Asynchronous Interrupt Transfer for recovery.
2020 UsbIo
->UsbAsyncInterruptTransfer (
2022 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
2024 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,