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