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