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