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