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