]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c
Fix the USB keyboard driver to call hotkey callback even no one is calling ReadKeyStroke
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbKbDxe / KeyBoard.c
1 /** @file
2 Helper functions for USB Keyboard Driver.
3
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
9
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.
12
13 **/
14
15 #include "KeyBoard.h"
16
17 EFI_GUID mUsbKeyboardLayoutPackageGuid = USB_KEYBOARD_LAYOUT_PACKAGE_GUID;
18 EFI_GUID mUsbKeyboardLayoutKeyGuid = USB_KEYBOARD_LAYOUT_KEY_GUID;
19
20 USB_KEYBOARD_LAYOUT_PACK_BIN mUsbKeyboardLayoutBin = {
21 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN), // Binary size
22
23 //
24 // EFI_HII_PACKAGE_HEADER
25 //
26 {
27 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN) - sizeof (UINT32),
28 EFI_HII_PACKAGE_KEYBOARD_LAYOUT
29 },
30 1, // LayoutCount
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
35 {
36 //
37 // EFI_KEY_DESCRIPTOR (total number is USB_KEYBOARD_KEY_COUNT)
38 //
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},
143 },
144 1, // DescriptionCount
145 {'e', 'n', '-', 'U', 'S'}, // RFC4646 language code
146 ' ', // Space
147 {'E', 'n', 'g', 'l', 'i', 's', 'h', ' ', 'K', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '\0'}, // DescriptionString[]
148 };
149
150 //
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.
154 //
155 UINT8 EfiKeyToUsbKeyCodeConvertionTable[] = {
156 0xe0, // EfiKeyLCtrl
157 0xe3, // EfiKeyA0
158 0xe2, // EfiKeyLAlt
159 0x2c, // EfiKeySpaceBar
160 0xe6, // EfiKeyA2
161 0xe7, // EfiKeyA3
162 0x65, // EfiKeyA4
163 0xe4, // EfiKeyRCtrl
164 0x50, // EfiKeyLeftArrow
165 0x51, // EfiKeyDownArrow
166 0x4F, // EfiKeyRightArrow
167 0x62, // EfiKeyZero
168 0x63, // EfiKeyPeriod
169 0x28, // EfiKeyEnter
170 0xe1, // EfiKeyLShift
171 0x64, // EfiKeyB0
172 0x1D, // EfiKeyB1
173 0x1B, // EfiKeyB2
174 0x06, // EfiKeyB3
175 0x19, // EfiKeyB4
176 0x05, // EfiKeyB5
177 0x11, // EfiKeyB6
178 0x10, // EfiKeyB7
179 0x36, // EfiKeyB8
180 0x37, // EfiKeyB9
181 0x38, // EfiKeyB10
182 0xe5, // EfiKeyRShift
183 0x52, // EfiKeyUpArrow
184 0x59, // EfiKeyOne
185 0x5A, // EfiKeyTwo
186 0x5B, // EfiKeyThree
187 0x39, // EfiKeyCapsLock
188 0x04, // EfiKeyC1
189 0x16, // EfiKeyC2
190 0x07, // EfiKeyC3
191 0x09, // EfiKeyC4
192 0x0A, // EfiKeyC5
193 0x0B, // EfiKeyC6
194 0x0D, // EfiKeyC7
195 0x0E, // EfiKeyC8
196 0x0F, // EfiKeyC9
197 0x33, // EfiKeyC10
198 0x34, // EfiKeyC11
199 0x32, // EfiKeyC12
200 0x5C, // EfiKeyFour
201 0x5D, // EfiKeyFive
202 0x5E, // EfiKeySix
203 0x57, // EfiKeyPlus
204 0x2B, // EfiKeyTab
205 0x14, // EfiKeyD1
206 0x1A, // EfiKeyD2
207 0x08, // EfiKeyD3
208 0x15, // EfiKeyD4
209 0x17, // EfiKeyD5
210 0x1C, // EfiKeyD6
211 0x18, // EfiKeyD7
212 0x0C, // EfiKeyD8
213 0x12, // EfiKeyD9
214 0x13, // EfiKeyD10
215 0x2F, // EfiKeyD11
216 0x30, // EfiKeyD12
217 0x31, // EfiKeyD13
218 0x4C, // EfiKeyDel
219 0x4D, // EfiKeyEnd
220 0x4E, // EfiKeyPgDn
221 0x5F, // EfiKeySeven
222 0x60, // EfiKeyEight
223 0x61, // EfiKeyNine
224 0x35, // EfiKeyE0
225 0x1E, // EfiKeyE1
226 0x1F, // EfiKeyE2
227 0x20, // EfiKeyE3
228 0x21, // EfiKeyE4
229 0x22, // EfiKeyE5
230 0x23, // EfiKeyE6
231 0x24, // EfiKeyE7
232 0x25, // EfiKeyE8
233 0x26, // EfiKeyE9
234 0x27, // EfiKeyE10
235 0x2D, // EfiKeyE11
236 0x2E, // EfiKeyE12
237 0x2A, // EfiKeyBackSpace
238 0x49, // EfiKeyIns
239 0x4A, // EfiKeyHome
240 0x4B, // EfiKeyPgUp
241 0x53, // EfiKeyNLck
242 0x54, // EfiKeySlash
243 0x55, // EfiKeyAsterisk
244 0x56, // EfiKeyMinus
245 0x29, // EfiKeyEsc
246 0x3A, // EfiKeyF1
247 0x3B, // EfiKeyF2
248 0x3C, // EfiKeyF3
249 0x3D, // EfiKeyF4
250 0x3E, // EfiKeyF5
251 0x3F, // EfiKeyF6
252 0x40, // EfiKeyF7
253 0x41, // EfiKeyF8
254 0x42, // EfiKeyF9
255 0x43, // EfiKeyF10
256 0x44, // EfiKeyF11
257 0x45, // EfiKeyF12
258 0x46, // EfiKeyPrint
259 0x47, // EfiKeySLck
260 0x48 // EfiKeyPause
261 };
262
263 //
264 // Keyboard modifier value to EFI Scan Code convertion table
265 // EFI Scan Code and the modifier values are defined in UEFI spec.
266 //
267 UINT8 ModifierValueToEfiScanCodeConvertionTable[] = {
268 SCAN_NULL, // EFI_NULL_MODIFIER
269 SCAN_NULL, // EFI_LEFT_CONTROL_MODIFIER
270 SCAN_NULL, // EFI_RIGHT_CONTROL_MODIFIER
271 SCAN_NULL, // EFI_LEFT_ALT_MODIFIER
272 SCAN_NULL, // EFI_RIGHT_ALT_MODIFIER
273 SCAN_NULL, // EFI_ALT_GR_MODIFIER
274 SCAN_INSERT, // EFI_INSERT_MODIFIER
275 SCAN_DELETE, // EFI_DELETE_MODIFIER
276 SCAN_PAGE_DOWN, // EFI_PAGE_DOWN_MODIFIER
277 SCAN_PAGE_UP, // EFI_PAGE_UP_MODIFIER
278 SCAN_HOME, // EFI_HOME_MODIFIER
279 SCAN_END, // EFI_END_MODIFIER
280 SCAN_NULL, // EFI_LEFT_SHIFT_MODIFIER
281 SCAN_NULL, // EFI_RIGHT_SHIFT_MODIFIER
282 SCAN_NULL, // EFI_CAPS_LOCK_MODIFIER
283 SCAN_NULL, // EFI_NUM_LOCK_MODIFIER
284 SCAN_LEFT, // EFI_LEFT_ARROW_MODIFIER
285 SCAN_RIGHT, // EFI_RIGHT_ARROW_MODIFIER
286 SCAN_DOWN, // EFI_DOWN_ARROW_MODIFIER
287 SCAN_UP, // EFI_UP_ARROW_MODIFIER
288 SCAN_NULL, // EFI_NS_KEY_MODIFIER
289 SCAN_NULL, // EFI_NS_KEY_DEPENDENCY_MODIFIER
290 SCAN_F1, // EFI_FUNCTION_KEY_ONE_MODIFIER
291 SCAN_F2, // EFI_FUNCTION_KEY_TWO_MODIFIER
292 SCAN_F3, // EFI_FUNCTION_KEY_THREE_MODIFIER
293 SCAN_F4, // EFI_FUNCTION_KEY_FOUR_MODIFIER
294 SCAN_F5, // EFI_FUNCTION_KEY_FIVE_MODIFIER
295 SCAN_F6, // EFI_FUNCTION_KEY_SIX_MODIFIER
296 SCAN_F7, // EFI_FUNCTION_KEY_SEVEN_MODIFIER
297 SCAN_F8, // EFI_FUNCTION_KEY_EIGHT_MODIFIER
298 SCAN_F9, // EFI_FUNCTION_KEY_NINE_MODIFIER
299 SCAN_F10, // EFI_FUNCTION_KEY_TEN_MODIFIER
300 SCAN_F11, // EFI_FUNCTION_KEY_ELEVEN_MODIFIER
301 SCAN_F12, // EFI_FUNCTION_KEY_TWELVE_MODIFIER
302 };
303
304 /**
305 Initialize Key Convention Table by using default keyboard layout.
306
307 @param UsbKeyboardDevice The USB_KB_DEV instance.
308
309 @retval EFI_SUCCESS The default keyboard layout was installed successfully
310 @retval Others Failure to install default keyboard layout.
311 **/
312 EFI_STATUS
313 InstallDefaultKeyboardLayout (
314 IN OUT USB_KB_DEV *UsbKeyboardDevice
315 )
316 {
317 EFI_STATUS Status;
318 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
319 EFI_HII_HANDLE HiiHandle;
320
321 //
322 // Locate Hii database protocol
323 //
324 Status = gBS->LocateProtocol (
325 &gEfiHiiDatabaseProtocolGuid,
326 NULL,
327 (VOID **) &HiiDatabase
328 );
329 if (EFI_ERROR (Status)) {
330 return Status;
331 }
332
333 //
334 // Install Keyboard Layout package to HII database
335 //
336 HiiHandle = HiiAddPackages (
337 &mUsbKeyboardLayoutPackageGuid,
338 UsbKeyboardDevice->ControllerHandle,
339 &mUsbKeyboardLayoutBin,
340 NULL
341 );
342 if (HiiHandle == NULL) {
343 return EFI_OUT_OF_RESOURCES;
344 }
345
346 //
347 // Set current keyboard layout
348 //
349 Status = HiiDatabase->SetKeyboardLayout (HiiDatabase, &mUsbKeyboardLayoutKeyGuid);
350
351 return Status;
352 }
353
354
355 /**
356 Uses USB I/O to check whether the device is a USB keyboard device.
357
358 @param UsbIo Pointer to a USB I/O protocol instance.
359
360 @retval TRUE Device is a USB keyboard device.
361 @retval FALSE Device is a not USB keyboard device.
362
363 **/
364 BOOLEAN
365 IsUSBKeyboard (
366 IN EFI_USB_IO_PROTOCOL *UsbIo
367 )
368 {
369 EFI_STATUS Status;
370 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
371
372 //
373 // Get the default interface descriptor
374 //
375 Status = UsbIo->UsbGetInterfaceDescriptor (
376 UsbIo,
377 &InterfaceDescriptor
378 );
379
380 if (EFI_ERROR (Status)) {
381 return FALSE;
382 }
383
384 if (InterfaceDescriptor.InterfaceClass == CLASS_HID &&
385 InterfaceDescriptor.InterfaceSubClass == SUBCLASS_BOOT &&
386 InterfaceDescriptor.InterfaceProtocol == PROTOCOL_KEYBOARD
387 ) {
388 return TRUE;
389 }
390
391 return FALSE;
392 }
393
394 /**
395 Get current keyboard layout from HII database.
396
397 @return Pointer to HII Keyboard Layout.
398 NULL means failure occurred while trying to get keyboard layout.
399
400 **/
401 EFI_HII_KEYBOARD_LAYOUT *
402 GetCurrentKeyboardLayout (
403 VOID
404 )
405 {
406 EFI_STATUS Status;
407 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
408 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;
409 UINT16 Length;
410
411 //
412 // Locate HII Database Protocol
413 //
414 Status = gBS->LocateProtocol (
415 &gEfiHiiDatabaseProtocolGuid,
416 NULL,
417 (VOID **) &HiiDatabase
418 );
419 if (EFI_ERROR (Status)) {
420 return NULL;
421 }
422
423 //
424 // Get current keyboard layout from HII database
425 //
426 Length = 0;
427 KeyboardLayout = NULL;
428 Status = HiiDatabase->GetKeyboardLayout (
429 HiiDatabase,
430 NULL,
431 &Length,
432 KeyboardLayout
433 );
434 if (Status == EFI_BUFFER_TOO_SMALL) {
435 KeyboardLayout = AllocatePool (Length);
436 ASSERT (KeyboardLayout != NULL);
437
438 Status = HiiDatabase->GetKeyboardLayout (
439 HiiDatabase,
440 NULL,
441 &Length,
442 KeyboardLayout
443 );
444 if (EFI_ERROR (Status)) {
445 FreePool (KeyboardLayout);
446 KeyboardLayout = NULL;
447 }
448 }
449
450 return KeyboardLayout;
451 }
452
453 /**
454 Find Key Descriptor in Key Convertion Table given its USB keycode.
455
456 @param UsbKeyboardDevice The USB_KB_DEV instance.
457 @param KeyCode USB Keycode.
458
459 @return The Key Descriptor in Key Convertion Table.
460 NULL means not found.
461
462 **/
463 EFI_KEY_DESCRIPTOR *
464 GetKeyDescriptor (
465 IN USB_KB_DEV *UsbKeyboardDevice,
466 IN UINT8 KeyCode
467 )
468 {
469 UINT8 Index;
470
471 //
472 // Make sure KeyCode is in the range of [0x4, 0x65] or [0xe0, 0xe7]
473 //
474 if ((!USBKBD_VALID_KEYCODE (KeyCode)) || ((KeyCode > 0x65) && (KeyCode < 0xe0)) || (KeyCode > 0xe7)) {
475 return NULL;
476 }
477
478 //
479 // Calculate the index of Key Descriptor in Key Convertion Table
480 //
481 if (KeyCode <= 0x65) {
482 Index = (UINT8) (KeyCode - 4);
483 } else {
484 Index = (UINT8) (KeyCode - 0xe0 + NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE);
485 }
486
487 return &UsbKeyboardDevice->KeyConvertionTable[Index];
488 }
489
490 /**
491 Find Non-Spacing key for given Key descriptor.
492
493 @param UsbKeyboardDevice The USB_KB_DEV instance.
494 @param KeyDescriptor Key descriptor.
495
496 @return The Non-Spacing key corresponding to KeyDescriptor
497 NULL means not found.
498
499 **/
500 USB_NS_KEY *
501 FindUsbNsKey (
502 IN USB_KB_DEV *UsbKeyboardDevice,
503 IN EFI_KEY_DESCRIPTOR *KeyDescriptor
504 )
505 {
506 LIST_ENTRY *Link;
507 LIST_ENTRY *NsKeyList;
508 USB_NS_KEY *UsbNsKey;
509
510 NsKeyList = &UsbKeyboardDevice->NsKeyList;
511 Link = GetFirstNode (NsKeyList);
512 while (!IsNull (NsKeyList, Link)) {
513 UsbNsKey = USB_NS_KEY_FORM_FROM_LINK (Link);
514
515 if (UsbNsKey->NsKey[0].Key == KeyDescriptor->Key) {
516 return UsbNsKey;
517 }
518
519 Link = GetNextNode (NsKeyList, Link);
520 }
521
522 return NULL;
523 }
524
525 /**
526 Find physical key definition for a given key descriptor.
527
528 For a specified non-spacing key, there are a list of physical
529 keys following it. This function traverses the list of
530 physical keys and tries to find the physical key matching
531 the KeyDescriptor.
532
533 @param UsbNsKey The non-spacing key information.
534 @param KeyDescriptor The key descriptor.
535
536 @return The physical key definition.
537 If no physical key is found, parameter KeyDescriptor is returned.
538
539 **/
540 EFI_KEY_DESCRIPTOR *
541 FindPhysicalKey (
542 IN USB_NS_KEY *UsbNsKey,
543 IN EFI_KEY_DESCRIPTOR *KeyDescriptor
544 )
545 {
546 UINTN Index;
547 EFI_KEY_DESCRIPTOR *PhysicalKey;
548
549 PhysicalKey = &UsbNsKey->NsKey[1];
550 for (Index = 0; Index < UsbNsKey->KeyCount; Index++) {
551 if (KeyDescriptor->Key == PhysicalKey->Key) {
552 return PhysicalKey;
553 }
554
555 PhysicalKey++;
556 }
557
558 //
559 // No children definition matched, return original key
560 //
561 return KeyDescriptor;
562 }
563
564 /**
565 The notification function for EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID.
566
567 This function is registered to event of EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
568 group type, which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
569 It tries to get curent keyboard layout from HII database.
570
571 @param Event Event being signaled.
572 @param Context Points to USB_KB_DEV instance.
573
574 **/
575 VOID
576 EFIAPI
577 SetKeyboardLayoutEvent (
578 IN EFI_EVENT Event,
579 IN VOID *Context
580 )
581 {
582 USB_KB_DEV *UsbKeyboardDevice;
583 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;
584 EFI_KEY_DESCRIPTOR TempKey;
585 EFI_KEY_DESCRIPTOR *KeyDescriptor;
586 EFI_KEY_DESCRIPTOR *TableEntry;
587 EFI_KEY_DESCRIPTOR *NsKey;
588 USB_NS_KEY *UsbNsKey;
589 UINTN Index;
590 UINTN Index2;
591 UINTN KeyCount;
592 UINT8 KeyCode;
593
594 UsbKeyboardDevice = (USB_KB_DEV *) Context;
595 if (UsbKeyboardDevice->Signature != USB_KB_DEV_SIGNATURE) {
596 return;
597 }
598
599 //
600 // Try to get current keyboard layout from HII database
601 //
602 KeyboardLayout = GetCurrentKeyboardLayout ();
603 if (KeyboardLayout == NULL) {
604 return;
605 }
606
607 //
608 // Re-allocate resource for KeyConvertionTable
609 //
610 ReleaseKeyboardLayoutResources (UsbKeyboardDevice);
611 UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE) * sizeof (EFI_KEY_DESCRIPTOR));
612 ASSERT (UsbKeyboardDevice->KeyConvertionTable != NULL);
613
614 //
615 // Traverse the list of key descriptors following the header of EFI_HII_KEYBOARD_LAYOUT
616 //
617 KeyDescriptor = (EFI_KEY_DESCRIPTOR *) (((UINT8 *) KeyboardLayout) + sizeof (EFI_HII_KEYBOARD_LAYOUT));
618 for (Index = 0; Index < KeyboardLayout->DescriptorCount; Index++) {
619 //
620 // Copy from HII keyboard layout package binary for alignment
621 //
622 CopyMem (&TempKey, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));
623
624 //
625 // Fill the key into KeyConvertionTable, whose index is calculated from USB keycode.
626 //
627 KeyCode = EfiKeyToUsbKeyCodeConvertionTable [(UINT8) (TempKey.Key)];
628 TableEntry = GetKeyDescriptor (UsbKeyboardDevice, KeyCode);
629 CopyMem (TableEntry, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));
630
631 //
632 // For non-spacing key, create the list with a non-spacing key followed by physical keys.
633 //
634 if (TempKey.Modifier == EFI_NS_KEY_MODIFIER) {
635 UsbNsKey = AllocatePool (sizeof (USB_NS_KEY));
636 ASSERT (UsbNsKey != NULL);
637
638 //
639 // Search for sequential children physical key definitions
640 //
641 KeyCount = 0;
642 NsKey = KeyDescriptor + 1;
643 for (Index2 = (UINT8) Index + 1; Index2 < KeyboardLayout->DescriptorCount; Index2++) {
644 CopyMem (&TempKey, NsKey, sizeof (EFI_KEY_DESCRIPTOR));
645 if (TempKey.Modifier == EFI_NS_KEY_DEPENDENCY_MODIFIER) {
646 KeyCount++;
647 } else {
648 break;
649 }
650 NsKey++;
651 }
652
653 UsbNsKey->Signature = USB_NS_KEY_SIGNATURE;
654 UsbNsKey->KeyCount = KeyCount;
655 UsbNsKey->NsKey = AllocateCopyPool (
656 (KeyCount + 1) * sizeof (EFI_KEY_DESCRIPTOR),
657 KeyDescriptor
658 );
659 InsertTailList (&UsbKeyboardDevice->NsKeyList, &UsbNsKey->Link);
660
661 //
662 // Skip over the child physical keys
663 //
664 Index += KeyCount;
665 KeyDescriptor += KeyCount;
666 }
667
668 KeyDescriptor++;
669 }
670
671 //
672 // There are two EfiKeyEnter, duplicate its key descriptor
673 //
674 TableEntry = GetKeyDescriptor (UsbKeyboardDevice, 0x58);
675 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, 0x28);
676 CopyMem (TableEntry, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));
677
678 FreePool (KeyboardLayout);
679 }
680
681 /**
682 Destroy resources for keyboard layout.
683
684 @param UsbKeyboardDevice The USB_KB_DEV instance.
685
686 **/
687 VOID
688 ReleaseKeyboardLayoutResources (
689 IN OUT USB_KB_DEV *UsbKeyboardDevice
690 )
691 {
692 USB_NS_KEY *UsbNsKey;
693 LIST_ENTRY *Link;
694
695 if (UsbKeyboardDevice->KeyConvertionTable != NULL) {
696 FreePool (UsbKeyboardDevice->KeyConvertionTable);
697 }
698 UsbKeyboardDevice->KeyConvertionTable = NULL;
699
700 while (!IsListEmpty (&UsbKeyboardDevice->NsKeyList)) {
701 Link = GetFirstNode (&UsbKeyboardDevice->NsKeyList);
702 UsbNsKey = USB_NS_KEY_FORM_FROM_LINK (Link);
703 RemoveEntryList (&UsbNsKey->Link);
704
705 FreePool (UsbNsKey->NsKey);
706 FreePool (UsbNsKey);
707 }
708 }
709
710 /**
711 Initialize USB keyboard layout.
712
713 This function initializes Key Convertion Table for the USB keyboard device.
714 It first tries to retrieve layout from HII database. If failed and default
715 layout is enabled, then it just uses the default layout.
716
717 @param UsbKeyboardDevice The USB_KB_DEV instance.
718
719 @retval EFI_SUCCESS Initialization succeeded.
720 @retval EFI_NOT_READY Keyboard layout cannot be retrieve from HII
721 database, and default layout is disabled.
722 @retval Other Fail to register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group.
723
724 **/
725 EFI_STATUS
726 InitKeyboardLayout (
727 OUT USB_KB_DEV *UsbKeyboardDevice
728 )
729 {
730 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;
731 EFI_STATUS Status;
732
733 UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE) * sizeof (EFI_KEY_DESCRIPTOR));
734 ASSERT (UsbKeyboardDevice->KeyConvertionTable != NULL);
735
736 InitializeListHead (&UsbKeyboardDevice->NsKeyList);
737 UsbKeyboardDevice->CurrentNsKey = NULL;
738 UsbKeyboardDevice->KeyboardLayoutEvent = NULL;
739
740 //
741 // Register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group,
742 // which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
743 //
744 Status = gBS->CreateEventEx (
745 EVT_NOTIFY_SIGNAL,
746 TPL_NOTIFY,
747 SetKeyboardLayoutEvent,
748 UsbKeyboardDevice,
749 &gEfiHiiKeyBoardLayoutGuid,
750 &UsbKeyboardDevice->KeyboardLayoutEvent
751 );
752 if (EFI_ERROR (Status)) {
753 return Status;
754 }
755
756 KeyboardLayout = GetCurrentKeyboardLayout ();
757 if (KeyboardLayout != NULL) {
758 //
759 // If current keyboard layout is successfully retrieved from HII database,
760 // force to initialize the keyboard layout.
761 //
762 gBS->SignalEvent (UsbKeyboardDevice->KeyboardLayoutEvent);
763 } else {
764 if (FeaturePcdGet (PcdDisableDefaultKeyboardLayoutInUsbKbDriver)) {
765 //
766 // If no keyboard layout can be retrieved from HII database, and default layout
767 // is disabled, then return EFI_NOT_READY.
768 //
769 return EFI_NOT_READY;
770 }
771 //
772 // If no keyboard layout can be retrieved from HII database, and default layout
773 // is enabled, then load the default keyboard layout.
774 //
775 InstallDefaultKeyboardLayout (UsbKeyboardDevice);
776 }
777
778 return EFI_SUCCESS;
779 }
780
781
782 /**
783 Initialize USB keyboard device and all private data structures.
784
785 @param UsbKeyboardDevice The USB_KB_DEV instance.
786
787 @retval EFI_SUCCESS Initialization is successful.
788 @retval EFI_DEVICE_ERROR Keyboard initialization failed.
789
790 **/
791 EFI_STATUS
792 InitUSBKeyboard (
793 IN OUT USB_KB_DEV *UsbKeyboardDevice
794 )
795 {
796 UINT16 ConfigValue;
797 UINT8 Protocol;
798 UINT8 ReportId;
799 UINT8 Duration;
800 EFI_STATUS Status;
801 UINT32 TransferResult;
802
803 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
804 EFI_PROGRESS_CODE,
805 (EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST),
806 UsbKeyboardDevice->DevicePath
807 );
808
809 InitQueue (&UsbKeyboardDevice->UsbKeyQueue, sizeof (USB_KEY));
810 InitQueue (&UsbKeyboardDevice->EfiKeyQueue, sizeof (EFI_KEY_DATA));
811
812 //
813 // Use the config out of the descriptor
814 // Assumed the first config is the correct one and this is not always the case
815 //
816 Status = UsbGetConfiguration (
817 UsbKeyboardDevice->UsbIo,
818 &ConfigValue,
819 &TransferResult
820 );
821 if (EFI_ERROR (Status)) {
822 ConfigValue = 0x01;
823 }
824
825 //
826 // Uses default configuration to configure the USB Keyboard device.
827 //
828 Status = UsbSetConfiguration (
829 UsbKeyboardDevice->UsbIo,
830 ConfigValue,
831 &TransferResult
832 );
833 if (EFI_ERROR (Status)) {
834 //
835 // If configuration could not be set here, it means
836 // the keyboard interface has some errors and could
837 // not be initialized
838 //
839 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
840 EFI_ERROR_CODE | EFI_ERROR_MINOR,
841 (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_INTERFACE_ERROR),
842 UsbKeyboardDevice->DevicePath
843 );
844
845 return EFI_DEVICE_ERROR;
846 }
847
848 UsbGetProtocolRequest (
849 UsbKeyboardDevice->UsbIo,
850 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,
851 &Protocol
852 );
853 //
854 // Set boot protocol for the USB Keyboard.
855 // This driver only supports boot protocol.
856 //
857 if (Protocol != BOOT_PROTOCOL) {
858 UsbSetProtocolRequest (
859 UsbKeyboardDevice->UsbIo,
860 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,
861 BOOT_PROTOCOL
862 );
863 }
864
865 //
866 // ReportId is zero, which means the idle rate applies to all input reports.
867 //
868 ReportId = 0;
869 //
870 // Duration is zero, which means the duration is infinite.
871 // so the endpoint will inhibit reporting forever,
872 // and only reporting when a change is detected in the report data.
873 //
874 Duration = 0;
875 UsbSetIdleRequest (
876 UsbKeyboardDevice->UsbIo,
877 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,
878 ReportId,
879 Duration
880 );
881
882 UsbKeyboardDevice->CtrlOn = FALSE;
883 UsbKeyboardDevice->AltOn = FALSE;
884 UsbKeyboardDevice->ShiftOn = FALSE;
885 UsbKeyboardDevice->NumLockOn = FALSE;
886 UsbKeyboardDevice->CapsOn = FALSE;
887 UsbKeyboardDevice->ScrollOn = FALSE;
888
889 UsbKeyboardDevice->LeftCtrlOn = FALSE;
890 UsbKeyboardDevice->LeftAltOn = FALSE;
891 UsbKeyboardDevice->LeftShiftOn = FALSE;
892 UsbKeyboardDevice->LeftLogoOn = FALSE;
893 UsbKeyboardDevice->RightCtrlOn = FALSE;
894 UsbKeyboardDevice->RightAltOn = FALSE;
895 UsbKeyboardDevice->RightShiftOn = FALSE;
896 UsbKeyboardDevice->RightLogoOn = FALSE;
897 UsbKeyboardDevice->MenuKeyOn = FALSE;
898 UsbKeyboardDevice->SysReqOn = FALSE;
899
900 UsbKeyboardDevice->AltGrOn = FALSE;
901
902 UsbKeyboardDevice->CurrentNsKey = NULL;
903
904 //
905 // Sync the initial state of lights on keyboard.
906 //
907 SetKeyLED (UsbKeyboardDevice);
908
909 ZeroMem (UsbKeyboardDevice->LastKeyCodeArray, sizeof (UINT8) * 8);
910
911 //
912 // Create event for repeat keys' generation.
913 //
914 if (UsbKeyboardDevice->RepeatTimer != NULL) {
915 gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);
916 UsbKeyboardDevice->RepeatTimer = NULL;
917 }
918
919 gBS->CreateEvent (
920 EVT_TIMER | EVT_NOTIFY_SIGNAL,
921 TPL_CALLBACK,
922 USBKeyboardRepeatHandler,
923 UsbKeyboardDevice,
924 &UsbKeyboardDevice->RepeatTimer
925 );
926
927 //
928 // Create event for delayed recovery, which deals with device error.
929 //
930 if (UsbKeyboardDevice->DelayedRecoveryEvent != NULL) {
931 gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);
932 UsbKeyboardDevice->DelayedRecoveryEvent = NULL;
933 }
934
935 gBS->CreateEvent (
936 EVT_TIMER | EVT_NOTIFY_SIGNAL,
937 TPL_NOTIFY,
938 USBKeyboardRecoveryHandler,
939 UsbKeyboardDevice,
940 &UsbKeyboardDevice->DelayedRecoveryEvent
941 );
942
943 return EFI_SUCCESS;
944 }
945
946
947 /**
948 Handler function for USB keyboard's asynchronous interrupt transfer.
949
950 This function is the handler function for USB keyboard's asynchronous interrupt transfer
951 to manage the keyboard. It parses the USB keyboard input report, and inserts data to
952 keyboard buffer according to state of modifer keys and normal keys. Timer for repeat key
953 is also set accordingly.
954
955 @param Data A pointer to a buffer that is filled with key data which is
956 retrieved via asynchronous interrupt transfer.
957 @param DataLength Indicates the size of the data buffer.
958 @param Context Pointing to USB_KB_DEV instance.
959 @param Result Indicates the result of the asynchronous interrupt transfer.
960
961 @retval EFI_SUCCESS Asynchronous interrupt transfer is handled successfully.
962 @retval EFI_DEVICE_ERROR Hardware error occurs.
963
964 **/
965 EFI_STATUS
966 EFIAPI
967 KeyboardHandler (
968 IN VOID *Data,
969 IN UINTN DataLength,
970 IN VOID *Context,
971 IN UINT32 Result
972 )
973 {
974 USB_KB_DEV *UsbKeyboardDevice;
975 EFI_USB_IO_PROTOCOL *UsbIo;
976 UINT8 *CurKeyCodeBuffer;
977 UINT8 *OldKeyCodeBuffer;
978 UINT8 CurModifierMap;
979 UINT8 OldModifierMap;
980 UINT8 Mask;
981 UINTN Index;
982 UINT8 Index2;
983 BOOLEAN KeyRelease;
984 BOOLEAN KeyPress;
985 USB_KEY UsbKey;
986 UINT8 NewRepeatKey;
987 UINT32 UsbStatus;
988 EFI_KEY_DESCRIPTOR *KeyDescriptor;
989
990 ASSERT (Context != NULL);
991
992 NewRepeatKey = 0;
993 UsbKeyboardDevice = (USB_KB_DEV *) Context;
994 UsbIo = UsbKeyboardDevice->UsbIo;
995
996 //
997 // Analyzes Result and performs corresponding action.
998 //
999 if (Result != EFI_USB_NOERROR) {
1000 //
1001 // Some errors happen during the process
1002 //
1003 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1004 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1005 (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_INPUT_ERROR),
1006 UsbKeyboardDevice->DevicePath
1007 );
1008
1009 //
1010 // Stop the repeat key generation if any
1011 //
1012 UsbKeyboardDevice->RepeatKey = 0;
1013
1014 gBS->SetTimer (
1015 UsbKeyboardDevice->RepeatTimer,
1016 TimerCancel,
1017 USBKBD_REPEAT_RATE
1018 );
1019
1020 if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
1021 UsbClearEndpointHalt (
1022 UsbIo,
1023 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,
1024 &UsbStatus
1025 );
1026 }
1027
1028 //
1029 // Delete & Submit this interrupt again
1030 // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt.
1031 //
1032 UsbIo->UsbAsyncInterruptTransfer (
1033 UsbIo,
1034 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,
1035 FALSE,
1036 0,
1037 0,
1038 NULL,
1039 NULL
1040 );
1041 //
1042 // EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling.
1043 //
1044 gBS->SetTimer (
1045 UsbKeyboardDevice->DelayedRecoveryEvent,
1046 TimerRelative,
1047 EFI_USB_INTERRUPT_DELAY
1048 );
1049
1050 return EFI_DEVICE_ERROR;
1051 }
1052
1053 //
1054 // If no error and no data, just return EFI_SUCCESS.
1055 //
1056 if (DataLength == 0 || Data == NULL) {
1057 return EFI_SUCCESS;
1058 }
1059
1060 //
1061 // Following code checks current keyboard input report against old key code buffer.
1062 // According to USB HID Firmware Specification, the report consists of 8 bytes.
1063 // Byte 0 is map of Modifier keys.
1064 // Byte 1 is reserved.
1065 // Bytes 2 to 7 are keycodes.
1066 //
1067 CurKeyCodeBuffer = (UINT8 *) Data;
1068 OldKeyCodeBuffer = UsbKeyboardDevice->LastKeyCodeArray;
1069
1070 //
1071 // Checks for new key stroke.
1072 //
1073 for (Index = 0; Index < 8; Index++) {
1074 if (OldKeyCodeBuffer[Index] != CurKeyCodeBuffer[Index]) {
1075 break;
1076 }
1077 }
1078
1079 //
1080 // If no new key, return EFI_SUCCESS immediately.
1081 //
1082 if (Index == 8) {
1083 return EFI_SUCCESS;
1084 }
1085
1086 //
1087 // Parse the modifier key, which is the first byte of keyboard input report.
1088 //
1089 CurModifierMap = CurKeyCodeBuffer[0];
1090 OldModifierMap = OldKeyCodeBuffer[0];
1091
1092 //
1093 // Handle modifier key's pressing or releasing situation.
1094 // According to USB HID Firmware spec, Byte 0 uses folloing map of Modifier keys:
1095 // Bit0: Left Control, Keycode: 0xe0
1096 // Bit1: Left Shift, Keycode: 0xe1
1097 // Bit2: Left Alt, Keycode: 0xe2
1098 // Bit3: Left GUI, Keycode: 0xe3
1099 // Bit4: Right Control, Keycode: 0xe4
1100 // Bit5: Right Shift, Keycode: 0xe5
1101 // Bit6: Right Alt, Keycode: 0xe6
1102 // Bit7: Right GUI, Keycode: 0xe7
1103 //
1104 for (Index = 0; Index < 8; Index++) {
1105 Mask = (UINT8) (1 << Index);
1106 if ((CurModifierMap & Mask) != (OldModifierMap & Mask)) {
1107 //
1108 // If current modifier key is up, then CurModifierMap & Mask = 0;
1109 // otherwise it is a non-zero value.
1110 // Insert the changed modifier key into key buffer.
1111 //
1112 UsbKey.KeyCode = (UINT8) (0xe0 + Index);
1113 UsbKey.Down = (BOOLEAN) ((CurModifierMap & Mask) != 0);
1114 Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));
1115 }
1116 }
1117
1118 //
1119 // Handle normal key's releasing situation
1120 // Bytes 2 to 7 are for normal keycodes
1121 //
1122 KeyRelease = FALSE;
1123 for (Index = 2; Index < 8; Index++) {
1124
1125 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index])) {
1126 continue;
1127 }
1128 //
1129 // For any key in old keycode buffer, if it is not in current keycode buffer,
1130 // then it is released. Otherwise, it is not released.
1131 //
1132 KeyRelease = TRUE;
1133 for (Index2 = 2; Index2 < 8; Index2++) {
1134
1135 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index2])) {
1136 continue;
1137 }
1138
1139 if (OldKeyCodeBuffer[Index] == CurKeyCodeBuffer[Index2]) {
1140 KeyRelease = FALSE;
1141 break;
1142 }
1143 }
1144
1145 if (KeyRelease) {
1146 UsbKey.KeyCode = OldKeyCodeBuffer[Index];
1147 UsbKey.Down = FALSE;
1148 Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));
1149 //
1150 // The original repeat key is released.
1151 //
1152 if (OldKeyCodeBuffer[Index] == UsbKeyboardDevice->RepeatKey) {
1153 UsbKeyboardDevice->RepeatKey = 0;
1154 }
1155 }
1156 }
1157
1158 //
1159 // If original repeat key is released, cancel the repeat timer
1160 //
1161 if (UsbKeyboardDevice->RepeatKey == 0) {
1162 gBS->SetTimer (
1163 UsbKeyboardDevice->RepeatTimer,
1164 TimerCancel,
1165 USBKBD_REPEAT_RATE
1166 );
1167 }
1168
1169 //
1170 // Handle normal key's pressing situation
1171 //
1172 KeyPress = FALSE;
1173 for (Index = 2; Index < 8; Index++) {
1174
1175 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index])) {
1176 continue;
1177 }
1178 //
1179 // For any key in current keycode buffer, if it is not in old keycode buffer,
1180 // then it is pressed. Otherwise, it is not pressed.
1181 //
1182 KeyPress = TRUE;
1183 for (Index2 = 2; Index2 < 8; Index2++) {
1184
1185 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index2])) {
1186 continue;
1187 }
1188
1189 if (CurKeyCodeBuffer[Index] == OldKeyCodeBuffer[Index2]) {
1190 KeyPress = FALSE;
1191 break;
1192 }
1193 }
1194
1195 if (KeyPress) {
1196 UsbKey.KeyCode = CurKeyCodeBuffer[Index];
1197 UsbKey.Down = TRUE;
1198 Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));
1199
1200 //
1201 // Handle repeat key
1202 //
1203 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, CurKeyCodeBuffer[Index]);
1204 ASSERT (KeyDescriptor != NULL);
1205
1206 if (KeyDescriptor->Modifier == EFI_NUM_LOCK_MODIFIER || KeyDescriptor->Modifier == EFI_CAPS_LOCK_MODIFIER) {
1207 //
1208 // For NumLock or CapsLock pressed, there is no need to handle repeat key for them.
1209 //
1210 UsbKeyboardDevice->RepeatKey = 0;
1211 } else {
1212 //
1213 // Prepare new repeat key, and clear the original one.
1214 //
1215 NewRepeatKey = CurKeyCodeBuffer[Index];
1216 UsbKeyboardDevice->RepeatKey = 0;
1217 }
1218 }
1219 }
1220
1221 //
1222 // Update LastKeycodeArray buffer in the UsbKeyboardDevice data structure.
1223 //
1224 for (Index = 0; Index < 8; Index++) {
1225 UsbKeyboardDevice->LastKeyCodeArray[Index] = CurKeyCodeBuffer[Index];
1226 }
1227
1228 //
1229 // If there is new key pressed, update the RepeatKey value, and set the
1230 // timer to repeate delay timer
1231 //
1232 if (NewRepeatKey != 0) {
1233 //
1234 // Sets trigger time to "Repeat Delay Time",
1235 // to trigger the repeat timer when the key is hold long
1236 // enough time.
1237 //
1238 gBS->SetTimer (
1239 UsbKeyboardDevice->RepeatTimer,
1240 TimerRelative,
1241 USBKBD_REPEAT_DELAY
1242 );
1243 UsbKeyboardDevice->RepeatKey = NewRepeatKey;
1244 }
1245
1246 return EFI_SUCCESS;
1247 }
1248
1249
1250 /**
1251 Retrieves a USB keycode after parsing the raw data in keyboard buffer.
1252
1253 This function parses keyboard buffer. It updates state of modifier key for
1254 USB_KB_DEV instancem, and returns keycode for output.
1255
1256 @param UsbKeyboardDevice The USB_KB_DEV instance.
1257 @param KeyCode Pointer to the USB keycode for output.
1258
1259 @retval EFI_SUCCESS Keycode successfully parsed.
1260 @retval EFI_NOT_READY Keyboard buffer is not ready for a valid keycode
1261
1262 **/
1263 EFI_STATUS
1264 USBParseKey (
1265 IN OUT USB_KB_DEV *UsbKeyboardDevice,
1266 OUT UINT8 *KeyCode
1267 )
1268 {
1269 USB_KEY UsbKey;
1270 EFI_KEY_DESCRIPTOR *KeyDescriptor;
1271
1272 *KeyCode = 0;
1273
1274 while (!IsQueueEmpty (&UsbKeyboardDevice->UsbKeyQueue)) {
1275 //
1276 // Pops one raw data off.
1277 //
1278 Dequeue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));
1279
1280 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode);
1281 ASSERT (KeyDescriptor != NULL);
1282
1283 if (!UsbKey.Down) {
1284 //
1285 // Key is released.
1286 //
1287 switch (KeyDescriptor->Modifier) {
1288
1289 //
1290 // Ctrl release
1291 //
1292 case EFI_LEFT_CONTROL_MODIFIER:
1293 UsbKeyboardDevice->LeftCtrlOn = FALSE;
1294 UsbKeyboardDevice->CtrlOn = FALSE;
1295 break;
1296 case EFI_RIGHT_CONTROL_MODIFIER:
1297 UsbKeyboardDevice->RightCtrlOn = FALSE;
1298 UsbKeyboardDevice->CtrlOn = FALSE;
1299 break;
1300
1301 //
1302 // Shift release
1303 //
1304 case EFI_LEFT_SHIFT_MODIFIER:
1305 UsbKeyboardDevice->LeftShiftOn = FALSE;
1306 UsbKeyboardDevice->ShiftOn = FALSE;
1307 break;
1308 case EFI_RIGHT_SHIFT_MODIFIER:
1309 UsbKeyboardDevice->RightShiftOn = FALSE;
1310 UsbKeyboardDevice->ShiftOn = FALSE;
1311 break;
1312
1313 //
1314 // Alt release
1315 //
1316 case EFI_LEFT_ALT_MODIFIER:
1317 UsbKeyboardDevice->LeftAltOn = FALSE;
1318 UsbKeyboardDevice->AltOn = FALSE;
1319 break;
1320 case EFI_RIGHT_ALT_MODIFIER:
1321 UsbKeyboardDevice->RightAltOn = FALSE;
1322 UsbKeyboardDevice->AltOn = FALSE;
1323 break;
1324
1325 //
1326 // Left Logo release
1327 //
1328 case EFI_LEFT_LOGO_MODIFIER:
1329 UsbKeyboardDevice->LeftLogoOn = FALSE;
1330 break;
1331
1332 //
1333 // Right Logo release
1334 //
1335 case EFI_RIGHT_LOGO_MODIFIER:
1336 UsbKeyboardDevice->RightLogoOn = FALSE;
1337 break;
1338
1339 //
1340 // Menu key release
1341 //
1342 case EFI_MENU_MODIFIER:
1343 UsbKeyboardDevice->MenuKeyOn = FALSE;
1344 break;
1345
1346 //
1347 // SysReq release
1348 //
1349 case EFI_PRINT_MODIFIER:
1350 case EFI_SYS_REQUEST_MODIFIER:
1351 UsbKeyboardDevice->SysReqOn = FALSE;
1352 break;
1353
1354 //
1355 // AltGr release
1356 //
1357 case EFI_ALT_GR_MODIFIER:
1358 UsbKeyboardDevice->AltGrOn = FALSE;
1359 break;
1360
1361 default:
1362 break;
1363 }
1364
1365 continue;
1366 }
1367
1368 //
1369 // Analyzes key pressing situation
1370 //
1371 switch (KeyDescriptor->Modifier) {
1372
1373 //
1374 // Ctrl press
1375 //
1376 case EFI_LEFT_CONTROL_MODIFIER:
1377 UsbKeyboardDevice->LeftCtrlOn = TRUE;
1378 UsbKeyboardDevice->CtrlOn = TRUE;
1379 continue;
1380 break;
1381 case EFI_RIGHT_CONTROL_MODIFIER:
1382 UsbKeyboardDevice->RightCtrlOn = TRUE;
1383 UsbKeyboardDevice->CtrlOn = TRUE;
1384 continue;
1385 break;
1386
1387 //
1388 // Shift press
1389 //
1390 case EFI_LEFT_SHIFT_MODIFIER:
1391 UsbKeyboardDevice->LeftShiftOn = TRUE;
1392 UsbKeyboardDevice->ShiftOn = TRUE;
1393 continue;
1394 break;
1395 case EFI_RIGHT_SHIFT_MODIFIER:
1396 UsbKeyboardDevice->RightShiftOn = TRUE;
1397 UsbKeyboardDevice->ShiftOn = TRUE;
1398 continue;
1399 break;
1400
1401 //
1402 // Alt press
1403 //
1404 case EFI_LEFT_ALT_MODIFIER:
1405 UsbKeyboardDevice->LeftAltOn = TRUE;
1406 UsbKeyboardDevice->AltOn = TRUE;
1407 continue;
1408 break;
1409 case EFI_RIGHT_ALT_MODIFIER:
1410 UsbKeyboardDevice->RightAltOn = TRUE;
1411 UsbKeyboardDevice->AltOn = TRUE;
1412 continue;
1413 break;
1414
1415 //
1416 // Left Logo press
1417 //
1418 case EFI_LEFT_LOGO_MODIFIER:
1419 UsbKeyboardDevice->LeftLogoOn = TRUE;
1420 break;
1421
1422 //
1423 // Right Logo press
1424 //
1425 case EFI_RIGHT_LOGO_MODIFIER:
1426 UsbKeyboardDevice->RightLogoOn = TRUE;
1427 break;
1428
1429 //
1430 // Menu key press
1431 //
1432 case EFI_MENU_MODIFIER:
1433 UsbKeyboardDevice->MenuKeyOn = TRUE;
1434 break;
1435
1436 //
1437 // SysReq press
1438 //
1439 case EFI_PRINT_MODIFIER:
1440 case EFI_SYS_REQUEST_MODIFIER:
1441 UsbKeyboardDevice->SysReqOn = TRUE;
1442 continue;
1443 break;
1444
1445 //
1446 // AltGr press
1447 //
1448 case EFI_ALT_GR_MODIFIER:
1449 UsbKeyboardDevice->AltGrOn = TRUE;
1450 break;
1451
1452 case EFI_NUM_LOCK_MODIFIER:
1453 //
1454 // Toggle NumLock
1455 //
1456 UsbKeyboardDevice->NumLockOn = (BOOLEAN) (!(UsbKeyboardDevice->NumLockOn));
1457 SetKeyLED (UsbKeyboardDevice);
1458 continue;
1459 break;
1460
1461 case EFI_CAPS_LOCK_MODIFIER:
1462 //
1463 // Toggle CapsLock
1464 //
1465 UsbKeyboardDevice->CapsOn = (BOOLEAN) (!(UsbKeyboardDevice->CapsOn));
1466 SetKeyLED (UsbKeyboardDevice);
1467 continue;
1468 break;
1469
1470 case EFI_SCROLL_LOCK_MODIFIER:
1471 //
1472 // Toggle ScrollLock
1473 //
1474 UsbKeyboardDevice->ScrollOn = (BOOLEAN) (!(UsbKeyboardDevice->ScrollOn));
1475 SetKeyLED (UsbKeyboardDevice);
1476 continue;
1477 break;
1478
1479 //
1480 // PrintScreen, Pause/Break could not be retrieved via SimpleTextInEx protocol
1481 //
1482 case EFI_PAUSE_MODIFIER:
1483 case EFI_BREAK_MODIFIER:
1484 //
1485 // Fall through
1486 //
1487 continue;
1488 break;
1489
1490 default:
1491 break;
1492 }
1493
1494 //
1495 // When encountering Ctrl + Alt + Del, then warm reset.
1496 //
1497 if (KeyDescriptor->Modifier == EFI_DELETE_MODIFIER) {
1498 if ((UsbKeyboardDevice->CtrlOn) && (UsbKeyboardDevice->AltOn)) {
1499 gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
1500 }
1501 }
1502
1503 *KeyCode = UsbKey.KeyCode;
1504 return EFI_SUCCESS;
1505 }
1506
1507 return EFI_NOT_READY;
1508 }
1509
1510
1511 /**
1512 Converts USB Keycode ranging from 0x4 to 0x65 to EFI_INPUT_KEY.
1513
1514 @param UsbKeyboardDevice The USB_KB_DEV instance.
1515 @param KeyCode Indicates the key code that will be interpreted.
1516 @param KeyData A pointer to a buffer that is filled in with
1517 the keystroke information for the key that
1518 was pressed.
1519
1520 @retval EFI_SUCCESS Success.
1521 @retval EFI_INVALID_PARAMETER KeyCode is not in the range of 0x4 to 0x65.
1522 @retval EFI_INVALID_PARAMETER Translated EFI_INPUT_KEY has zero for both ScanCode and UnicodeChar.
1523 @retval EFI_NOT_READY KeyCode represents a dead key with EFI_NS_KEY_MODIFIER
1524 @retval EFI_DEVICE_ERROR Keyboard layout is invalid.
1525
1526 **/
1527 EFI_STATUS
1528 UsbKeyCodeToEfiInputKey (
1529 IN USB_KB_DEV *UsbKeyboardDevice,
1530 IN UINT8 KeyCode,
1531 OUT EFI_KEY_DATA *KeyData
1532 )
1533 {
1534 EFI_KEY_DESCRIPTOR *KeyDescriptor;
1535 LIST_ENTRY *Link;
1536 LIST_ENTRY *NotifyList;
1537 KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
1538
1539 //
1540 // KeyCode must in the range of 0x4 to 0x65
1541 //
1542 if (!USBKBD_VALID_KEYCODE (KeyCode)) {
1543 return EFI_INVALID_PARAMETER;
1544 }
1545 if ((KeyCode - 4) >= NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE) {
1546 return EFI_INVALID_PARAMETER;
1547 }
1548
1549 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, KeyCode);
1550 ASSERT (KeyDescriptor != NULL);
1551
1552 if (KeyDescriptor->Modifier == EFI_NS_KEY_MODIFIER) {
1553 //
1554 // If this is a dead key with EFI_NS_KEY_MODIFIER, then record it and return.
1555 //
1556 UsbKeyboardDevice->CurrentNsKey = FindUsbNsKey (UsbKeyboardDevice, KeyDescriptor);
1557 return EFI_NOT_READY;
1558 }
1559
1560 if (UsbKeyboardDevice->CurrentNsKey != NULL) {
1561 //
1562 // If this keystroke follows a non-spacing key, then find the descriptor for corresponding
1563 // physical key.
1564 //
1565 KeyDescriptor = FindPhysicalKey (UsbKeyboardDevice->CurrentNsKey, KeyDescriptor);
1566 UsbKeyboardDevice->CurrentNsKey = NULL;
1567 }
1568
1569 //
1570 // Make sure modifier of Key Descriptor is in the valid range according to UEFI spec.
1571 //
1572 if (KeyDescriptor->Modifier > EFI_FUNCTION_KEY_TWELVE_MODIFIER) {
1573 return EFI_DEVICE_ERROR;
1574 }
1575
1576 KeyData->Key.ScanCode = ModifierValueToEfiScanCodeConvertionTable[KeyDescriptor->Modifier];
1577 KeyData->Key.UnicodeChar = KeyDescriptor->Unicode;
1578
1579 if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_STANDARD_SHIFT)!= 0) {
1580 if (UsbKeyboardDevice->ShiftOn) {
1581 KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedUnicode;
1582
1583 //
1584 // Need not return associated shift state if a class of printable characters that
1585 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
1586 //
1587 if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) != 0) {
1588 UsbKeyboardDevice->LeftShiftOn = FALSE;
1589 UsbKeyboardDevice->RightShiftOn = FALSE;
1590 }
1591
1592 if (UsbKeyboardDevice->AltGrOn) {
1593 KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedAltGrUnicode;
1594 }
1595 } else {
1596 //
1597 // Shift off
1598 //
1599 KeyData->Key.UnicodeChar = KeyDescriptor->Unicode;
1600
1601 if (UsbKeyboardDevice->AltGrOn) {
1602 KeyData->Key.UnicodeChar = KeyDescriptor->AltGrUnicode;
1603 }
1604 }
1605 }
1606
1607 if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) != 0) {
1608 if (UsbKeyboardDevice->CapsOn) {
1609 if (KeyData->Key.UnicodeChar == KeyDescriptor->Unicode) {
1610 KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedUnicode;
1611 } else if (KeyData->Key.UnicodeChar == KeyDescriptor->ShiftedUnicode) {
1612 KeyData->Key.UnicodeChar = KeyDescriptor->Unicode;
1613 }
1614 }
1615 }
1616
1617 if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_NUM_LOCK) != 0) {
1618 //
1619 // For key affected by NumLock, if NumLock is on and Shift is not pressed, then it means
1620 // normal key, instead of original control key. So the ScanCode should be cleaned.
1621 // Otherwise, it means control key, so preserve the EFI Scan Code and clear the unicode keycode.
1622 //
1623 if ((UsbKeyboardDevice->NumLockOn) && (!(UsbKeyboardDevice->ShiftOn))) {
1624 KeyData->Key.ScanCode = SCAN_NULL;
1625 } else {
1626 KeyData->Key.UnicodeChar = 0x00;
1627 }
1628 }
1629
1630 //
1631 // Translate Unicode 0x1B (ESC) to EFI Scan Code
1632 //
1633 if (KeyData->Key.UnicodeChar == 0x1B && KeyData->Key.ScanCode == SCAN_NULL) {
1634 KeyData->Key.ScanCode = SCAN_ESC;
1635 KeyData->Key.UnicodeChar = 0x00;
1636 }
1637
1638 //
1639 // Not valid for key without both unicode key code and EFI Scan Code.
1640 //
1641 if (KeyData->Key.UnicodeChar == 0 && KeyData->Key.ScanCode == SCAN_NULL) {
1642 return EFI_NOT_READY;
1643 }
1644
1645 //
1646 // Save Shift/Toggle state
1647 //
1648 KeyData->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
1649 KeyData->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
1650
1651 if (UsbKeyboardDevice->LeftCtrlOn) {
1652 KeyData->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;
1653 }
1654 if (UsbKeyboardDevice->RightCtrlOn) {
1655 KeyData->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;
1656 }
1657 if (UsbKeyboardDevice->LeftAltOn) {
1658 KeyData->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED;
1659 }
1660 if (UsbKeyboardDevice->RightAltOn) {
1661 KeyData->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED;
1662 }
1663 if (UsbKeyboardDevice->LeftShiftOn) {
1664 KeyData->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
1665 }
1666 if (UsbKeyboardDevice->RightShiftOn) {
1667 KeyData->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
1668 }
1669 if (UsbKeyboardDevice->LeftLogoOn) {
1670 KeyData->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;
1671 }
1672 if (UsbKeyboardDevice->RightLogoOn) {
1673 KeyData->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;
1674 }
1675 if (UsbKeyboardDevice->MenuKeyOn) {
1676 KeyData->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;
1677 }
1678 if (UsbKeyboardDevice->SysReqOn) {
1679 KeyData->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;
1680 }
1681
1682 if (UsbKeyboardDevice->ScrollOn) {
1683 KeyData->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;
1684 }
1685 if (UsbKeyboardDevice->NumLockOn) {
1686 KeyData->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
1687 }
1688 if (UsbKeyboardDevice->CapsOn) {
1689 KeyData->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
1690 }
1691
1692 //
1693 // Invoke notification functions if the key is registered.
1694 //
1695 NotifyList = &UsbKeyboardDevice->NotifyList;
1696 for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {
1697 CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
1698 if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
1699 CurrentNotify->KeyNotificationFn (KeyData);
1700 }
1701 }
1702
1703 //
1704 // Translate the CTRL-Alpha characters to their corresponding control value
1705 // (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
1706 //
1707 if (UsbKeyboardDevice->CtrlOn) {
1708 if (KeyData->Key.UnicodeChar >= 'a' && KeyData->Key.UnicodeChar <= 'z') {
1709 KeyData->Key.UnicodeChar = (UINT8) (KeyData->Key.UnicodeChar - 'a' + 1);
1710 } else if (KeyData->Key.UnicodeChar >= 'A' && KeyData->Key.UnicodeChar <= 'Z') {
1711 KeyData->Key.UnicodeChar = (UINT8) (KeyData->Key.UnicodeChar - 'A' + 1);
1712 }
1713 }
1714
1715 return EFI_SUCCESS;
1716 }
1717
1718
1719 /**
1720 Create the queue.
1721
1722 @param Queue Points to the queue.
1723 @param ItemSize Size of the single item.
1724
1725 **/
1726 VOID
1727 InitQueue (
1728 IN OUT USB_SIMPLE_QUEUE *Queue,
1729 IN UINTN ItemSize
1730 )
1731 {
1732 UINTN Index;
1733
1734 Queue->ItemSize = ItemSize;
1735 Queue->Head = 0;
1736 Queue->Tail = 0;
1737
1738 if (Queue->Buffer[0] != NULL) {
1739 FreePool (Queue->Buffer[0]);
1740 }
1741
1742 Queue->Buffer[0] = AllocatePool (sizeof (Queue->Buffer) / sizeof (Queue->Buffer[0]) * ItemSize);
1743 ASSERT (Queue->Buffer[0] != NULL);
1744
1745 for (Index = 1; Index < sizeof (Queue->Buffer) / sizeof (Queue->Buffer[0]); Index++) {
1746 Queue->Buffer[Index] = ((UINT8 *) Queue->Buffer[Index - 1]) + ItemSize;
1747 }
1748 }
1749
1750 /**
1751 Destroy the queue
1752
1753 @param Queue Points to the queue.
1754 **/
1755 VOID
1756 DestroyQueue (
1757 IN OUT USB_SIMPLE_QUEUE *Queue
1758 )
1759 {
1760 FreePool (Queue->Buffer[0]);
1761 }
1762
1763
1764 /**
1765 Check whether the queue is empty.
1766
1767 @param Queue Points to the queue.
1768
1769 @retval TRUE Queue is empty.
1770 @retval FALSE Queue is not empty.
1771
1772 **/
1773 BOOLEAN
1774 IsQueueEmpty (
1775 IN USB_SIMPLE_QUEUE *Queue
1776 )
1777 {
1778 //
1779 // Meet FIFO empty condition
1780 //
1781 return (BOOLEAN) (Queue->Head == Queue->Tail);
1782 }
1783
1784
1785 /**
1786 Check whether the queue is full.
1787
1788 @param Queue Points to the queue.
1789
1790 @retval TRUE Queue is full.
1791 @retval FALSE Queue is not full.
1792
1793 **/
1794 BOOLEAN
1795 IsQueueFull (
1796 IN USB_SIMPLE_QUEUE *Queue
1797 )
1798 {
1799 return (BOOLEAN) (((Queue->Tail + 1) % (MAX_KEY_ALLOWED + 1)) == Queue->Head);
1800 }
1801
1802
1803 /**
1804 Enqueue the item to the queue.
1805
1806 @param Queue Points to the queue.
1807 @param Item Points to the item to be enqueued.
1808 @param ItemSize Size of the item.
1809 **/
1810 VOID
1811 Enqueue (
1812 IN OUT USB_SIMPLE_QUEUE *Queue,
1813 IN VOID *Item,
1814 IN UINTN ItemSize
1815 )
1816 {
1817 ASSERT (ItemSize == Queue->ItemSize);
1818 //
1819 // If keyboard buffer is full, throw the
1820 // first key out of the keyboard buffer.
1821 //
1822 if (IsQueueFull (Queue)) {
1823 Queue->Head = (Queue->Head + 1) % (MAX_KEY_ALLOWED + 1);
1824 }
1825
1826 CopyMem (Queue->Buffer[Queue->Tail], Item, ItemSize);
1827
1828 //
1829 // Adjust the tail pointer of the FIFO keyboard buffer.
1830 //
1831 Queue->Tail = (Queue->Tail + 1) % (MAX_KEY_ALLOWED + 1);
1832 }
1833
1834
1835 /**
1836 Dequeue a item from the queue.
1837
1838 @param Queue Points to the queue.
1839 @param Item Receives the item.
1840 @param ItemSize Size of the item.
1841
1842 @retval EFI_SUCCESS Item was successfully dequeued.
1843 @retval EFI_DEVICE_ERROR The queue is empty.
1844
1845 **/
1846 EFI_STATUS
1847 Dequeue (
1848 IN OUT USB_SIMPLE_QUEUE *Queue,
1849 OUT VOID *Item,
1850 IN UINTN ItemSize
1851 )
1852 {
1853 ASSERT (Queue->ItemSize == ItemSize);
1854
1855 if (IsQueueEmpty (Queue)) {
1856 return EFI_DEVICE_ERROR;
1857 }
1858
1859 CopyMem (Item, Queue->Buffer[Queue->Head], ItemSize);
1860
1861 //
1862 // Adjust the head pointer of the FIFO keyboard buffer.
1863 //
1864 Queue->Head = (Queue->Head + 1) % (MAX_KEY_ALLOWED + 1);
1865
1866 return EFI_SUCCESS;
1867 }
1868
1869
1870 /**
1871 Sets USB keyboard LED state.
1872
1873 @param UsbKeyboardDevice The USB_KB_DEV instance.
1874
1875 **/
1876 VOID
1877 SetKeyLED (
1878 IN USB_KB_DEV *UsbKeyboardDevice
1879 )
1880 {
1881 LED_MAP Led;
1882 UINT8 ReportId;
1883
1884 //
1885 // Set each field in Led map.
1886 //
1887 Led.NumLock = (UINT8) ((UsbKeyboardDevice->NumLockOn) ? 1 : 0);
1888 Led.CapsLock = (UINT8) ((UsbKeyboardDevice->CapsOn) ? 1 : 0);
1889 Led.ScrollLock = (UINT8) ((UsbKeyboardDevice->ScrollOn) ? 1 : 0);
1890 Led.Resrvd = 0;
1891
1892 ReportId = 0;
1893 //
1894 // Call Set_Report Request to lighten the LED.
1895 //
1896 UsbSetReportRequest (
1897 UsbKeyboardDevice->UsbIo,
1898 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,
1899 ReportId,
1900 HID_OUTPUT_REPORT,
1901 1,
1902 (UINT8 *) &Led
1903 );
1904 }
1905
1906
1907 /**
1908 Handler for Repeat Key event.
1909
1910 This function is the handler for Repeat Key event triggered
1911 by timer.
1912 After a repeatable key is pressed, the event would be triggered
1913 with interval of USBKBD_REPEAT_DELAY. Once the event is triggered,
1914 following trigger will come with interval of USBKBD_REPEAT_RATE.
1915
1916 @param Event The Repeat Key event.
1917 @param Context Points to the USB_KB_DEV instance.
1918
1919 **/
1920 VOID
1921 EFIAPI
1922 USBKeyboardRepeatHandler (
1923 IN EFI_EVENT Event,
1924 IN VOID *Context
1925 )
1926 {
1927 USB_KB_DEV *UsbKeyboardDevice;
1928 USB_KEY UsbKey;
1929
1930 UsbKeyboardDevice = (USB_KB_DEV *) Context;
1931
1932 //
1933 // Do nothing when there is no repeat key.
1934 //
1935 if (UsbKeyboardDevice->RepeatKey != 0) {
1936 //
1937 // Inserts the repeat key into keyboard buffer,
1938 //
1939 UsbKey.KeyCode = UsbKeyboardDevice->RepeatKey;
1940 UsbKey.Down = TRUE;
1941 Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));
1942
1943 //
1944 // Set repeat rate for next repeat key generation.
1945 //
1946 gBS->SetTimer (
1947 UsbKeyboardDevice->RepeatTimer,
1948 TimerRelative,
1949 USBKBD_REPEAT_RATE
1950 );
1951 }
1952 }
1953
1954
1955 /**
1956 Handler for Delayed Recovery event.
1957
1958 This function is the handler for Delayed Recovery event triggered
1959 by timer.
1960 After a device error occurs, the event would be triggered
1961 with interval of EFI_USB_INTERRUPT_DELAY. EFI_USB_INTERRUPT_DELAY
1962 is defined in USB standard for error handling.
1963
1964 @param Event The Delayed Recovery event.
1965 @param Context Points to the USB_KB_DEV instance.
1966
1967 **/
1968 VOID
1969 EFIAPI
1970 USBKeyboardRecoveryHandler (
1971 IN EFI_EVENT Event,
1972 IN VOID *Context
1973 )
1974 {
1975
1976 USB_KB_DEV *UsbKeyboardDevice;
1977 EFI_USB_IO_PROTOCOL *UsbIo;
1978 UINT8 PacketSize;
1979
1980 UsbKeyboardDevice = (USB_KB_DEV *) Context;
1981
1982 UsbIo = UsbKeyboardDevice->UsbIo;
1983
1984 PacketSize = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize);
1985
1986 //
1987 // Re-submit Asynchronous Interrupt Transfer for recovery.
1988 //
1989 UsbIo->UsbAsyncInterruptTransfer (
1990 UsbIo,
1991 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,
1992 TRUE,
1993 UsbKeyboardDevice->IntEndpointDescriptor.Interval,
1994 PacketSize,
1995 KeyboardHandler,
1996 UsbKeyboardDevice
1997 );
1998 }