]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Usb/UsbKbDxe/keyboard.c
Merged in the following trackers from EDK:
[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_NULL_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_NULL_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_NULL_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_SYS_REQUEST_MODIFIER:
1350 UsbKeyboardDevice->SysReqOn = 0;
1351 break;
1352
1353 //
1354 // AltGr release
1355 //
1356 case EFI_ALT_GR_MODIFIER:
1357 UsbKeyboardDevice->AltGrOn = 0;
1358 break;
1359
1360 default:
1361 break;
1362 }
1363
1364 continue;
1365 }
1366
1367 //
1368 // Analyzes key pressing situation
1369 //
1370 switch (KeyDescriptor->Modifier) {
1371
1372 //
1373 // CTRL press
1374 //
1375 case EFI_LEFT_CONTROL_MODIFIER:
1376 UsbKeyboardDevice->LeftCtrlOn = 1;
1377 UsbKeyboardDevice->CtrlOn = 1;
1378 continue;
1379 break;
1380 case EFI_RIGHT_CONTROL_MODIFIER:
1381 UsbKeyboardDevice->RightCtrlOn = 1;
1382 UsbKeyboardDevice->CtrlOn = 1;
1383 continue;
1384 break;
1385
1386 //
1387 // Shift press
1388 //
1389 case EFI_LEFT_SHIFT_MODIFIER:
1390 UsbKeyboardDevice->LeftShiftOn = 1;
1391 UsbKeyboardDevice->ShiftOn = 1;
1392 continue;
1393 break;
1394 case EFI_RIGHT_SHIFT_MODIFIER:
1395 UsbKeyboardDevice->RightShiftOn = 1;
1396 UsbKeyboardDevice->ShiftOn = 1;
1397 continue;
1398 break;
1399
1400 //
1401 // Alt press
1402 //
1403 case EFI_LEFT_ALT_MODIFIER:
1404 UsbKeyboardDevice->LeftAltOn = 1;
1405 UsbKeyboardDevice->AltOn = 1;
1406 continue;
1407 break;
1408 case EFI_RIGHT_ALT_MODIFIER:
1409 UsbKeyboardDevice->RightAltOn = 1;
1410 UsbKeyboardDevice->AltOn = 1;
1411 continue;
1412 break;
1413
1414 //
1415 // Left Logo press
1416 //
1417 case EFI_LEFT_LOGO_MODIFIER:
1418 UsbKeyboardDevice->LeftLogoOn = 1;
1419 break;
1420
1421 //
1422 // Right Logo press
1423 //
1424 case EFI_RIGHT_LOGO_MODIFIER:
1425 UsbKeyboardDevice->RightLogoOn = 1;
1426 break;
1427
1428 //
1429 // Menu key press
1430 //
1431 case EFI_MENU_MODIFIER:
1432 UsbKeyboardDevice->MenuKeyOn = 1;
1433 break;
1434
1435 //
1436 // SysReq press
1437 //
1438 case EFI_SYS_REQUEST_MODIFIER:
1439 UsbKeyboardDevice->SysReqOn = 1;
1440 continue;
1441 break;
1442
1443 //
1444 // AltGr press
1445 //
1446 case EFI_ALT_GR_MODIFIER:
1447 UsbKeyboardDevice->AltGrOn = 1;
1448 break;
1449
1450 case EFI_NUM_LOCK_MODIFIER:
1451 UsbKeyboardDevice->NumLockOn ^= 1;
1452 //
1453 // Turn on the NumLock light on KB
1454 //
1455 SetKeyLED (UsbKeyboardDevice);
1456 continue;
1457 break;
1458
1459 case EFI_CAPS_LOCK_MODIFIER:
1460 UsbKeyboardDevice->CapsOn ^= 1;
1461 //
1462 // Turn on the CapsLock light on KB
1463 //
1464 SetKeyLED (UsbKeyboardDevice);
1465 continue;
1466 break;
1467
1468 case EFI_SCROLL_LOCK_MODIFIER:
1469 UsbKeyboardDevice->ScrollOn ^= 1;
1470 //
1471 // Turn on the ScrollLock light on KB
1472 //
1473 SetKeyLED (UsbKeyboardDevice);
1474 continue;
1475 break;
1476
1477 //
1478 // F11,F12,PrintScreen,Pause/Break
1479 // could not be retrieved via SimpleTxtInEx protocol
1480 //
1481 case EFI_FUNCTION_KEY_ELEVEN_MODIFIER:
1482 case EFI_FUNCTION_KEY_TWELVE_MODIFIER:
1483 case EFI_PRINT_MODIFIER:
1484 case EFI_PAUSE_MODIFIER:
1485 case EFI_BREAK_MODIFIER:
1486 //
1487 // fall through
1488 //
1489 continue;
1490 break;
1491
1492 default:
1493 break;
1494 }
1495
1496 //
1497 // When encountered Del Key...
1498 //
1499 if (KeyDescriptor->Modifier == EFI_DELETE_MODIFIER) {
1500 if (UsbKeyboardDevice->CtrlOn && UsbKeyboardDevice->AltOn) {
1501 gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
1502 }
1503 }
1504
1505 *KeyChar = UsbKey.KeyCode;
1506 return EFI_SUCCESS;
1507 }
1508
1509 return EFI_NOT_READY;
1510 }
1511
1512
1513
1514 /**
1515 Converts USB Keyboard code to EFI Scan Code.
1516
1517 UsbKeyboardDevice The USB_KB_DEV instance.
1518 KeyChar Indicates the key code that will be interpreted.
1519 Key A pointer to a buffer that is filled in with
1520 the keystroke information for the key that
1521 was pressed.
1522
1523 @retval EFI_NOT_READY Device is not ready
1524 @retval EFI_SUCCESS Success
1525
1526 **/
1527 EFI_STATUS
1528 USBKeyCodeToEFIScanCode (
1529 IN USB_KB_DEV *UsbKeyboardDevice,
1530 IN UINT8 KeyChar,
1531 OUT EFI_INPUT_KEY *Key
1532 )
1533 {
1534 UINT8 Index;
1535 EFI_KEY_DESCRIPTOR *KeyDescriptor;
1536
1537 if (!USBKBD_VALID_KEYCODE (KeyChar)) {
1538 return EFI_NOT_READY;
1539 }
1540
1541 //
1542 // valid USB Key Code starts from 4
1543 //
1544 Index = (UINT8) (KeyChar - 4);
1545
1546 if (Index >= USB_KEYCODE_MAX_MAKE) {
1547 return EFI_NOT_READY;
1548 }
1549
1550 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, KeyChar);
1551
1552 //
1553 // Check for Non-spacing key
1554 //
1555 if (KeyDescriptor->Modifier == EFI_NS_KEY_MODIFIER) {
1556 UsbKeyboardDevice->CurrentNsKey = FindUsbNsKey (UsbKeyboardDevice, KeyDescriptor);
1557 return EFI_NOT_READY;
1558 }
1559
1560 //
1561 // Check whether this keystroke follows a Non-spacing key
1562 //
1563 if (UsbKeyboardDevice->CurrentNsKey != NULL) {
1564 KeyDescriptor = FindPhysicalKey (UsbKeyboardDevice->CurrentNsKey, KeyDescriptor);
1565 UsbKeyboardDevice->CurrentNsKey = NULL;
1566 }
1567
1568 Key->ScanCode = EfiScanCodeConvertionTable[KeyDescriptor->Modifier];
1569 Key->UnicodeChar = KeyDescriptor->Unicode;
1570
1571 if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_STANDARD_SHIFT) {
1572 if (UsbKeyboardDevice->ShiftOn) {
1573 Key->UnicodeChar = KeyDescriptor->ShiftedUnicode;
1574
1575 //
1576 // Need not return associated shift state if a class of printable characters that
1577 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
1578 //
1579 if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) {
1580 UsbKeyboardDevice->LeftShiftOn = 0;
1581 UsbKeyboardDevice->RightShiftOn = 0;
1582 }
1583
1584 if (UsbKeyboardDevice->AltGrOn) {
1585 Key->UnicodeChar = KeyDescriptor->ShiftedAltGrUnicode;
1586 }
1587 } else {
1588 //
1589 // Shift off
1590 //
1591 Key->UnicodeChar = KeyDescriptor->Unicode;
1592
1593 if (UsbKeyboardDevice->AltGrOn) {
1594 Key->UnicodeChar = KeyDescriptor->AltGrUnicode;
1595 }
1596 }
1597 }
1598
1599 if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) {
1600 if (UsbKeyboardDevice->CapsOn) {
1601
1602 if (Key->UnicodeChar == KeyDescriptor->Unicode) {
1603
1604 Key->UnicodeChar = KeyDescriptor->ShiftedUnicode;
1605
1606 } else if (Key->UnicodeChar == KeyDescriptor->ShiftedUnicode) {
1607
1608 Key->UnicodeChar = KeyDescriptor->Unicode;
1609
1610 }
1611 }
1612 }
1613
1614 //
1615 // Translate the CTRL-Alpha characters to their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
1616 //
1617 if (UsbKeyboardDevice->CtrlOn) {
1618 if (Key->UnicodeChar >= 'a' && Key->UnicodeChar <= 'z') {
1619 Key->UnicodeChar = (UINT8) (Key->UnicodeChar - 'a' + 1);
1620 } else if (Key->UnicodeChar >= 'A' && Key->UnicodeChar <= 'Z') {
1621 Key->UnicodeChar = (UINT8) (Key->UnicodeChar - 'A' + 1);
1622 }
1623 }
1624
1625 if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_NUM_LOCK) {
1626
1627 if (UsbKeyboardDevice->NumLockOn && !UsbKeyboardDevice->ShiftOn) {
1628
1629 Key->ScanCode = SCAN_NULL;
1630
1631 } else {
1632 Key->UnicodeChar = 0x00;
1633 }
1634 }
1635
1636 //
1637 // Translate Unicode 0x1B (ESC) to EFI Scan Code
1638 //
1639 if (Key->UnicodeChar == 0x1B && Key->ScanCode == SCAN_NULL) {
1640 Key->ScanCode = SCAN_ESC;
1641 Key->UnicodeChar = 0x00;
1642 }
1643
1644 if (Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) {
1645 return EFI_NOT_READY;
1646 }
1647
1648
1649 //
1650 // Save Shift/Toggle state
1651 //
1652 if (UsbKeyboardDevice->LeftCtrlOn == 1) {
1653 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;
1654 }
1655 if (UsbKeyboardDevice->RightCtrlOn == 1) {
1656 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;
1657 }
1658 if (UsbKeyboardDevice->LeftAltOn == 1) {
1659 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED;
1660 }
1661 if (UsbKeyboardDevice->RightAltOn == 1) {
1662 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED;
1663 }
1664 if (UsbKeyboardDevice->LeftShiftOn == 1) {
1665 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
1666 }
1667 if (UsbKeyboardDevice->RightShiftOn == 1) {
1668 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
1669 }
1670 if (UsbKeyboardDevice->LeftLogoOn == 1) {
1671 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;
1672 }
1673 if (UsbKeyboardDevice->RightLogoOn == 1) {
1674 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;
1675 }
1676 if (UsbKeyboardDevice->MenuKeyOn == 1) {
1677 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;
1678 }
1679 if (UsbKeyboardDevice->SysReqOn == 1) {
1680 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;
1681 }
1682
1683 if (UsbKeyboardDevice->ScrollOn == 1) {
1684 UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;
1685 }
1686 if (UsbKeyboardDevice->NumLockOn == 1) {
1687 UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
1688 }
1689 if (UsbKeyboardDevice->CapsOn == 1) {
1690 UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
1691 }
1692
1693 return EFI_SUCCESS;
1694
1695 }
1696
1697
1698
1699 /**
1700 Resets USB Keyboard Buffer.
1701
1702 @param KeyboardBuffer Points to the USB Keyboard Buffer.
1703
1704 @retval EFI_SUCCESS Success
1705
1706 **/
1707 EFI_STATUS
1708 InitUSBKeyBuffer (
1709 IN OUT USB_KB_BUFFER *KeyboardBuffer
1710 )
1711 {
1712 ZeroMem (KeyboardBuffer, sizeof (USB_KB_BUFFER));
1713
1714 KeyboardBuffer->bHead = KeyboardBuffer->bTail;
1715
1716 return EFI_SUCCESS;
1717 }
1718
1719
1720 /**
1721 Check whether USB Keyboard buffer is empty.
1722
1723 @param KeyboardBuffer USB Keyboard Buffer.
1724
1725
1726 **/
1727 BOOLEAN
1728 IsUSBKeyboardBufferEmpty (
1729 IN USB_KB_BUFFER *KeyboardBuffer
1730 )
1731 {
1732 //
1733 // meet FIFO empty condition
1734 //
1735 return (BOOLEAN) (KeyboardBuffer->bHead == KeyboardBuffer->bTail);
1736 }
1737
1738
1739
1740 /**
1741 Check whether USB Keyboard buffer is full.
1742
1743 @param KeyboardBuffer USB Keyboard Buffer.
1744
1745
1746 **/
1747 BOOLEAN
1748 IsUSBKeyboardBufferFull (
1749 IN USB_KB_BUFFER *KeyboardBuffer
1750 )
1751 {
1752 return (BOOLEAN)(((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1)) ==
1753 KeyboardBuffer->bHead);
1754 }
1755
1756
1757
1758 /**
1759 Inserts a key code into keyboard buffer.
1760
1761 @param KeyboardBuffer Points to the USB Keyboard Buffer.
1762 @param Key Key code
1763 @param Down Special key
1764
1765 @retval EFI_SUCCESS Success
1766
1767 **/
1768 EFI_STATUS
1769 InsertKeyCode (
1770 IN OUT USB_KB_BUFFER *KeyboardBuffer,
1771 IN UINT8 Key,
1772 IN UINT8 Down
1773 )
1774 {
1775 USB_KEY UsbKey;
1776
1777 //
1778 // if keyboard buffer is full, throw the
1779 // first key out of the keyboard buffer.
1780 //
1781 if (IsUSBKeyboardBufferFull (KeyboardBuffer)) {
1782 RemoveKeyCode (KeyboardBuffer, &UsbKey);
1783 }
1784
1785 KeyboardBuffer->buffer[KeyboardBuffer->bTail].KeyCode = Key;
1786 KeyboardBuffer->buffer[KeyboardBuffer->bTail].Down = Down;
1787
1788 //
1789 // adjust the tail pointer of the FIFO keyboard buffer.
1790 //
1791 KeyboardBuffer->bTail = (UINT8) ((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1));
1792
1793 return EFI_SUCCESS;
1794 }
1795
1796
1797 /**
1798 Pops a key code off from keyboard buffer.
1799
1800 @param KeyboardBuffer Points to the USB Keyboard Buffer.
1801 @param UsbKey Points to the buffer that contains a usb key code.
1802
1803 @retval EFI_SUCCESS Success
1804 @retval EFI_DEVICE_ERROR Hardware Error
1805
1806 **/
1807 EFI_STATUS
1808 RemoveKeyCode (
1809 IN OUT USB_KB_BUFFER *KeyboardBuffer,
1810 OUT USB_KEY *UsbKey
1811 )
1812 {
1813 if (IsUSBKeyboardBufferEmpty (KeyboardBuffer)) {
1814 return EFI_DEVICE_ERROR;
1815 }
1816
1817 UsbKey->KeyCode = KeyboardBuffer->buffer[KeyboardBuffer->bHead].KeyCode;
1818 UsbKey->Down = KeyboardBuffer->buffer[KeyboardBuffer->bHead].Down;
1819
1820 //
1821 // adjust the head pointer of the FIFO keyboard buffer.
1822 //
1823 KeyboardBuffer->bHead = (UINT8) ((KeyboardBuffer->bHead + 1) % (MAX_KEY_ALLOWED + 1));
1824
1825 return EFI_SUCCESS;
1826 }
1827
1828
1829 /**
1830 Sets USB Keyboard LED state.
1831
1832 @param UsbKeyboardDevice The USB_KB_DEV instance.
1833
1834 @retval EFI_SUCCESS Success
1835
1836 **/
1837 EFI_STATUS
1838 SetKeyLED (
1839 IN USB_KB_DEV *UsbKeyboardDevice
1840 )
1841 {
1842 LED_MAP Led;
1843 UINT8 ReportId;
1844
1845 //
1846 // Set each field in Led map.
1847 //
1848 Led.NumLock = (UINT8) UsbKeyboardDevice->NumLockOn;
1849 Led.CapsLock = (UINT8) UsbKeyboardDevice->CapsOn;
1850 Led.ScrollLock = (UINT8) UsbKeyboardDevice->ScrollOn;
1851 Led.Resrvd = 0;
1852
1853 ReportId = 0;
1854 //
1855 // call Set Report Request to lighten the LED.
1856 //
1857 UsbSetReportRequest (
1858 UsbKeyboardDevice->UsbIo,
1859 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,
1860 ReportId,
1861 HID_OUTPUT_REPORT,
1862 1,
1863 (UINT8 *) &Led
1864 );
1865
1866 return EFI_SUCCESS;
1867 }
1868
1869
1870 /**
1871 Timer handler for Repeat Key timer.
1872
1873 @param Event The Repeat Key event.
1874 @param Context Points to the USB_KB_DEV instance.
1875
1876
1877 **/
1878 VOID
1879 EFIAPI
1880 USBKeyboardRepeatHandler (
1881 IN EFI_EVENT Event,
1882 IN VOID *Context
1883 )
1884 {
1885 USB_KB_DEV *UsbKeyboardDevice;
1886
1887 UsbKeyboardDevice = (USB_KB_DEV *) Context;
1888
1889 //
1890 // Do nothing when there is no repeat key.
1891 //
1892 if (UsbKeyboardDevice->RepeatKey != 0) {
1893 //
1894 // Inserts one Repeat key into keyboard buffer,
1895 //
1896 InsertKeyCode (
1897 &(UsbKeyboardDevice->KeyboardBuffer),
1898 UsbKeyboardDevice->RepeatKey,
1899 1
1900 );
1901
1902 //
1903 // set repeate rate for repeat key generation.
1904 //
1905 gBS->SetTimer (
1906 UsbKeyboardDevice->RepeatTimer,
1907 TimerRelative,
1908 USBKBD_REPEAT_RATE
1909 );
1910
1911 }
1912 }
1913
1914
1915 /**
1916 Timer handler for Delayed Recovery timer.
1917
1918 @param Event The Delayed Recovery event.
1919 @param Context Points to the USB_KB_DEV instance.
1920
1921
1922 **/
1923 VOID
1924 EFIAPI
1925 USBKeyboardRecoveryHandler (
1926 IN EFI_EVENT Event,
1927 IN VOID *Context
1928 )
1929 {
1930
1931 USB_KB_DEV *UsbKeyboardDevice;
1932 EFI_USB_IO_PROTOCOL *UsbIo;
1933 UINT8 PacketSize;
1934
1935 UsbKeyboardDevice = (USB_KB_DEV *) Context;
1936
1937 UsbIo = UsbKeyboardDevice->UsbIo;
1938
1939 PacketSize = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize);
1940
1941 UsbIo->UsbAsyncInterruptTransfer (
1942 UsbIo,
1943 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,
1944 TRUE,
1945 UsbKeyboardDevice->IntEndpointDescriptor.Interval,
1946 PacketSize,
1947 KeyboardHandler,
1948 UsbKeyboardDevice
1949 );
1950 }