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