3 Copyright (c) 2004 - 2008, Intel Corporation
\r
4 All rights reserved. This program and the accompanying materials
\r
5 are licensed and made available under the terms and conditions of the BSD License
\r
6 which accompanies this distribution. The full text of the license may be found at
\r
7 http://opensource.org/licenses/bsd-license.php
\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
\r
18 Helper functions for USB Keyboard Driver
\r
25 #include "keyboard.h"
\r
26 #include <Library/UsbLib.h>
\r
29 // Static English keyboard layout
\r
30 // Format:<efi key>, <unicode without shift>, <unicode with shift>, <Modifier>, <AffectedAttribute>
\r
33 UINT8 KeyboardLayoutTable[USB_KEYCODE_MAX_MAKE + 8][5] = {
\r
34 {EfiKeyC1, 'a', 'A', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x04
\r
35 {EfiKeyB5, 'b', 'B', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x05
\r
36 {EfiKeyB3, 'c', 'C', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x06
\r
37 {EfiKeyC3, 'd', 'D', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x07
\r
38 {EfiKeyD3, 'e', 'E', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x08
\r
39 {EfiKeyC4, 'f', 'F', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x09
\r
40 {EfiKeyC5, 'g', 'G', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0A
\r
41 {EfiKeyC6, 'h', 'H', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0B
\r
42 {EfiKeyD8, 'i', 'I', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0C
\r
43 {EfiKeyC7, 'j', 'J', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0D
\r
44 {EfiKeyC8, 'k', 'K', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0E
\r
45 {EfiKeyC9, 'l', 'L', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0F
\r
46 {EfiKeyB7, 'm', 'M', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x10
\r
47 {EfiKeyB6, 'n', 'N', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x11
\r
48 {EfiKeyD9, 'o', 'O', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x12
\r
49 {EfiKeyD10, 'p', 'P', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x13
\r
50 {EfiKeyD1, 'q', 'Q', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x14
\r
51 {EfiKeyD4, 'r', 'R', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x15
\r
52 {EfiKeyC2, 's', 'S', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x16
\r
53 {EfiKeyD5, 't', 'T', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x17
\r
54 {EfiKeyD7, 'u', 'U', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x18
\r
55 {EfiKeyB4, 'v', 'V', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x19
\r
56 {EfiKeyD2, 'w', 'W', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x1A
\r
57 {EfiKeyB2, 'x', 'X', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x1B
\r
58 {EfiKeyD6, 'y', 'Y', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x1C
\r
59 {EfiKeyB1, 'z', 'Z', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x1D
\r
60 {EfiKeyE1, '1', '!', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x1E
\r
61 {EfiKeyE2, '2', '@', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x1F
\r
62 {EfiKeyE3, '3', '#', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x20
\r
63 {EfiKeyE4, '4', '$', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x21
\r
64 {EfiKeyE5, '5', '%', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x22
\r
65 {EfiKeyE6, '6', '^', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x23
\r
66 {EfiKeyE7, '7', '&', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x24
\r
67 {EfiKeyE8, '8', '*', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x25
\r
68 {EfiKeyE9, '9', '(', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x26
\r
69 {EfiKeyE10, '0', ')', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x27
\r
70 {EfiKeyEnter, 0x0d, 0x0d, EFI_NULL_MODIFIER, 0}, // 0x28 Enter
\r
71 {EfiKeyEsc, 0x1b, 0x1b, EFI_NULL_MODIFIER, 0}, // 0x29 Esc
\r
72 {EfiKeyBackSpace, 0x08, 0x08, EFI_NULL_MODIFIER, 0}, // 0x2A Backspace
\r
73 {EfiKeyTab, 0x09, 0x09, EFI_NULL_MODIFIER, 0}, // 0x2B Tab
\r
74 {EfiKeySpaceBar, ' ', ' ', EFI_NULL_MODIFIER, 0}, // 0x2C Spacebar
\r
75 {EfiKeyE11, '-', '_', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x2D
\r
76 {EfiKeyE12, '=', '+', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x2E
\r
77 {EfiKeyD11, '[', '{', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x2F
\r
78 {EfiKeyD12, ']', '}', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x30
\r
79 {EfiKeyD13, '\\', '|', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x31
\r
80 {EfiKeyC12, '\\', '|', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x32 Keyboard Non-US # and ~
\r
81 {EfiKeyC10, ';', ':', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x33
\r
82 {EfiKeyC11, '\'', '"', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x34
\r
83 {EfiKeyE0, '`', '~', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x35 Keyboard Grave Accent and Tlide
\r
84 {EfiKeyB8, ',', '<', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x36
\r
85 {EfiKeyB9, '.', '>', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x37
\r
86 {EfiKeyB10, '/', '?', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x38
\r
87 {EfiKeyCapsLock, 0x00, 0x00, EFI_CAPS_LOCK_MODIFIER, 0}, // 0x39 CapsLock
\r
88 {EfiKeyF1, 0x00, 0x00, EFI_FUNCTION_KEY_ONE_MODIFIER, 0}, // 0x3A
\r
89 {EfiKeyF2, 0x00, 0x00, EFI_FUNCTION_KEY_TWO_MODIFIER, 0}, // 0x3B
\r
90 {EfiKeyF3, 0x00, 0x00, EFI_FUNCTION_KEY_THREE_MODIFIER, 0}, // 0x3C
\r
91 {EfiKeyF4, 0x00, 0x00, EFI_FUNCTION_KEY_FOUR_MODIFIER, 0}, // 0x3D
\r
92 {EfiKeyF5, 0x00, 0x00, EFI_FUNCTION_KEY_FIVE_MODIFIER, 0}, // 0x3E
\r
93 {EfiKeyF6, 0x00, 0x00, EFI_FUNCTION_KEY_SIX_MODIFIER, 0}, // 0x3F
\r
94 {EfiKeyF7, 0x00, 0x00, EFI_FUNCTION_KEY_SEVEN_MODIFIER, 0}, // 0x40
\r
95 {EfiKeyF8, 0x00, 0x00, EFI_FUNCTION_KEY_EIGHT_MODIFIER, 0}, // 0x41
\r
96 {EfiKeyF9, 0x00, 0x00, EFI_FUNCTION_KEY_NINE_MODIFIER, 0}, // 0x42
\r
97 {EfiKeyF10, 0x00, 0x00, EFI_FUNCTION_KEY_TEN_MODIFIER, 0}, // 0x43
\r
98 {EfiKeyF11, 0x00, 0x00, EFI_FUNCTION_KEY_ELEVEN_MODIFIER, 0}, // 0x44 F11
\r
99 {EfiKeyF12, 0x00, 0x00, EFI_FUNCTION_KEY_TWELVE_MODIFIER, 0}, // 0x45 F12
\r
100 {EfiKeyPrint, 0x00, 0x00, EFI_PRINT_MODIFIER, 0}, // 0x46 PrintScreen
\r
101 {EfiKeySLck, 0x00, 0x00, EFI_SCROLL_LOCK_MODIFIER, 0}, // 0x47 Scroll Lock
\r
102 {EfiKeyPause, 0x00, 0x00, EFI_PAUSE_MODIFIER, 0}, // 0x48 Pause
\r
103 {EfiKeyIns, 0x00, 0x00, EFI_INSERT_MODIFIER, 0}, // 0x49
\r
104 {EfiKeyHome, 0x00, 0x00, EFI_HOME_MODIFIER, 0}, // 0x4A
\r
105 {EfiKeyPgUp, 0x00, 0x00, EFI_PAGE_UP_MODIFIER, 0}, // 0x4B
\r
106 {EfiKeyDel, 0x00, 0x00, EFI_DELETE_MODIFIER, 0}, // 0x4C
\r
107 {EfiKeyEnd, 0x00, 0x00, EFI_END_MODIFIER, 0}, // 0x4D
\r
108 {EfiKeyPgDn, 0x00, 0x00, EFI_PAGE_DOWN_MODIFIER, 0}, // 0x4E
\r
109 {EfiKeyRightArrow, 0x00, 0x00, EFI_RIGHT_ARROW_MODIFIER, 0}, // 0x4F
\r
110 {EfiKeyLeftArrow, 0x00, 0x00, EFI_LEFT_ARROW_MODIFIER, 0}, // 0x50
\r
111 {EfiKeyDownArrow, 0x00, 0x00, EFI_DOWN_ARROW_MODIFIER, 0}, // 0x51
\r
112 {EfiKeyUpArrow, 0x00, 0x00, EFI_UP_ARROW_MODIFIER, 0}, // 0x52
\r
113 {EfiKeyNLck, 0x00, 0x00, EFI_NUM_LOCK_MODIFIER, 0}, // 0x53 NumLock
\r
114 {EfiKeySlash, '/', '/', EFI_NULL_MODIFIER, 0}, // 0x54
\r
115 {EfiKeyAsterisk, '*', '*', EFI_NULL_MODIFIER, 0}, // 0x55
\r
116 {EfiKeyMinus, '-', '-', EFI_NULL_MODIFIER, 0}, // 0x56
\r
117 {EfiKeyPlus, '+', '+', EFI_NULL_MODIFIER, 0}, // 0x57
\r
118 {EfiKeyEnter, 0x0d, 0x0d, EFI_NULL_MODIFIER, 0}, // 0x58
\r
119 {EfiKeyOne, '1', '1', EFI_END_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x59
\r
120 {EfiKeyTwo, '2', '2', EFI_DOWN_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5A
\r
121 {EfiKeyThree, '3', '3', EFI_PAGE_DOWN_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5B
\r
122 {EfiKeyFour, '4', '4', EFI_LEFT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5C
\r
123 {EfiKeyFive, '5', '5', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5D
\r
124 {EfiKeySix, '6', '6', EFI_RIGHT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5E
\r
125 {EfiKeySeven, '7', '7', EFI_HOME_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5F
\r
126 {EfiKeyEight, '8', '8', EFI_UP_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x60
\r
127 {EfiKeyNine, '9', '9', EFI_PAGE_UP_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x61
\r
128 {EfiKeyZero, '0', '0', EFI_INSERT_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x62
\r
129 {EfiKeyPeriod, '.', '.', EFI_DELETE_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x63
\r
130 {EfiKeyB0, '\\', '|', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x64 Keyboard Non-US \ and |
\r
131 {EfiKeyA4, 0x00, 0x00, EFI_MENU_MODIFIER, 0}, // 0x65 Keyboard Application
\r
133 {EfiKeyLCtrl, 0, 0, EFI_LEFT_CONTROL_MODIFIER, 0}, // 0xe0
\r
134 {EfiKeyLShift, 0, 0, EFI_LEFT_SHIFT_MODIFIER, 0}, // 0xe1
\r
135 {EfiKeyLAlt, 0, 0, EFI_LEFT_ALT_MODIFIER, 0}, // 0xe2
\r
136 {EfiKeyA0, 0, 0, EFI_LEFT_LOGO_MODIFIER, 0}, // 0xe3
\r
137 {EfiKeyRCtrl, 0, 0, EFI_RIGHT_CONTROL_MODIFIER, 0}, // 0xe4
\r
138 {EfiKeyRShift, 0, 0, EFI_RIGHT_SHIFT_MODIFIER, 0}, // 0xe5
\r
139 {EfiKeyA2, 0, 0, EFI_RIGHT_ALT_MODIFIER, 0}, // 0xe6
\r
140 {EfiKeyA3, 0, 0, EFI_RIGHT_LOGO_MODIFIER, 0}, // 0xe7
\r
144 LoadDefaultKeyboardLayout (
\r
145 IN USB_KB_DEV *UsbKeyboardDevice
\r
149 Routine Description:
\r
150 Initialize KeyConvertionTable by using default keyboard layout.
\r
153 UsbKeyboardDevice The USB_KB_DEV instance.
\r
161 EFI_KEY_DESCRIPTOR *KeyDescriptor;
\r
164 // Construct KeyConvertionTable by default keyboard layout
\r
166 KeyDescriptor = &UsbKeyboardDevice->KeyConvertionTable[0];
\r
168 for (Index = 0; Index < (USB_KEYCODE_MAX_MAKE + 8); Index++) {
\r
169 KeyDescriptor->Key = (EFI_KEY) KeyboardLayoutTable[Index][0];
\r
170 KeyDescriptor->Unicode = KeyboardLayoutTable[Index][1];
\r
171 KeyDescriptor->ShiftedUnicode = KeyboardLayoutTable[Index][2];
\r
172 KeyDescriptor->AltGrUnicode = 0;
\r
173 KeyDescriptor->ShiftedAltGrUnicode = 0;
\r
174 KeyDescriptor->Modifier = KeyboardLayoutTable[Index][3];
\r
175 KeyDescriptor->AffectedAttribute = KeyboardLayoutTable[Index][4];
\r
182 // EFI_KEY to USB Scan Code convertion table
\r
185 UINT8 UsbScanCodeConvertionTable[] = {
\r
186 0xe0, // EfiKeyLCtrl
\r
188 0xe2, // EfiKeyLAlt
\r
189 0x2c, // EfiKeySpaceBar
\r
193 0xe4, // EfiKeyRCtrl
\r
194 0x50, // EfiKeyLeftArrow
\r
195 0x51, // EfiKeyDownArrow
\r
196 0x4F, // EfiKeyRightArrow
\r
197 0x62, // EfiKeyZero
\r
198 0x63, // EfiKeyPeriod
\r
199 0x28, // EfiKeyEnter
\r
200 0xe1, // EfiKeyLShift
\r
212 0xe5, // EfiKeyRShift
\r
213 0x52, // EfiKeyUpArrow
\r
216 0x5B, // EfiKeyThree
\r
217 0x39, // EfiKeyCapsLock
\r
230 0x5C, // EfiKeyFour
\r
231 0x5D, // EfiKeyFive
\r
233 0x57, // EfiKeyPlus
\r
250 0x4E, // EfiKeyPgDn
\r
251 0x5F, // EfiKeySeven
\r
252 0x60, // EfiKeyEight
\r
253 0x61, // EfiKeyNine
\r
267 0x2A, // EfiKeyBackSpace
\r
269 0x4A, // EfiKeyHome
\r
270 0x4B, // EfiKeyPgUp
\r
271 0x53, // EfiKeyNLck
\r
272 0x54, // EfiKeySlash
\r
273 0x55, // EfiKeyAsterisk
\r
274 0x56, // EfiKeyMinus
\r
288 0x46, // EfiKeyPrint
\r
289 0x47, // EfiKeySLck
\r
290 0x48 // EfiKeyPause
\r
294 // Keyboard Layout Modifier to EFI Scan Code convertion table
\r
297 UINT8 EfiScanCodeConvertionTable[] = {
\r
298 SCAN_NULL, // EFI_NULL_MODIFIER
\r
299 SCAN_NULL, // EFI_LEFT_CONTROL_MODIFIER
\r
300 SCAN_NULL, // EFI_RIGHT_CONTROL_MODIFIER
\r
301 SCAN_NULL, // EFI_LEFT_ALT_MODIFIER
\r
302 SCAN_NULL, // EFI_RIGHT_ALT_MODIFIER
\r
303 SCAN_NULL, // EFI_ALT_GR_MODIFIER
\r
304 SCAN_INSERT, // EFI_INSERT_MODIFIER
\r
305 SCAN_DELETE, // EFI_DELETE_MODIFIER
\r
306 SCAN_PAGE_DOWN, // EFI_PAGE_DOWN_MODIFIER
\r
307 SCAN_PAGE_UP, // EFI_PAGE_UP_MODIFIER
\r
308 SCAN_HOME, // EFI_HOME_MODIFIER
\r
309 SCAN_END, // EFI_END_MODIFIER
\r
310 SCAN_NULL, // EFI_LEFT_SHIFT_MODIFIER
\r
311 SCAN_NULL, // EFI_RIGHT_SHIFT_MODIFIER
\r
312 SCAN_NULL, // EFI_CAPS_LOCK_MODIFIER
\r
313 SCAN_NULL, // EFI_NUM_LOCK_MODIFIER
\r
314 SCAN_LEFT, // EFI_LEFT_ARROW_MODIFIER
\r
315 SCAN_RIGHT, // EFI_RIGHT_ARROW_MODIFIER
\r
316 SCAN_DOWN, // EFI_DOWN_ARROW_MODIFIER
\r
317 SCAN_UP, // EFI_UP_ARROW_MODIFIER
\r
318 SCAN_NULL, // EFI_NS_KEY_MODIFIER
\r
319 SCAN_NULL, // EFI_NS_KEY_DEPENDENCY_MODIFIER
\r
320 SCAN_F1, // EFI_FUNCTION_KEY_ONE_MODIFIER
\r
321 SCAN_F2, // EFI_FUNCTION_KEY_TWO_MODIFIER
\r
322 SCAN_F3, // EFI_FUNCTION_KEY_THREE_MODIFIER
\r
323 SCAN_F4, // EFI_FUNCTION_KEY_FOUR_MODIFIER
\r
324 SCAN_F5, // EFI_FUNCTION_KEY_FIVE_MODIFIER
\r
325 SCAN_F6, // EFI_FUNCTION_KEY_SIX_MODIFIER
\r
326 SCAN_F7, // EFI_FUNCTION_KEY_SEVEN_MODIFIER
\r
327 SCAN_F8, // EFI_FUNCTION_KEY_EIGHT_MODIFIER
\r
328 SCAN_F9, // EFI_FUNCTION_KEY_NINE_MODIFIER
\r
329 SCAN_F10, // EFI_FUNCTION_KEY_TEN_MODIFIER
\r
330 SCAN_F11, // EFI_FUNCTION_KEY_ELEVEN_MODIFIER
\r
331 SCAN_F12, // EFI_FUNCTION_KEY_TWELVE_MODIFIER
\r
334 EFI_GUID mKeyboardLayoutEventGuid = EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID;
\r
337 STATIC KB_MODIFIER KB_Mod[8] = {
\r
338 { MOD_CONTROL_L, 0xe0 }, // 11100000
\r
339 { MOD_CONTROL_R, 0xe4 }, // 11100100
\r
340 { MOD_SHIFT_L, 0xe1 }, // 11100001
\r
341 { MOD_SHIFT_R, 0xe5 }, // 11100101
\r
342 { MOD_ALT_L, 0xe2 }, // 11100010
\r
343 { MOD_ALT_R, 0xe6 }, // 11100110
\r
344 { MOD_WIN_L, 0xe3 }, // 11100011
\r
345 { MOD_WIN_R, 0xe7 }, // 11100111
\r
351 Uses USB I/O to check whether the device is a USB Keyboard device.
\r
353 UsbIo: Points to a USB I/O protocol instance.
\r
359 IN EFI_USB_IO_PROTOCOL *UsbIo
\r
363 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
\r
366 // Get the Default interface descriptor, currently we
\r
367 // assume it is interface 1
\r
369 Status = UsbIo->UsbGetInterfaceDescriptor (
\r
371 &InterfaceDescriptor
\r
374 if (EFI_ERROR (Status)) {
\r
378 if (InterfaceDescriptor.InterfaceClass == CLASS_HID &&
\r
379 InterfaceDescriptor.InterfaceSubClass == SUBCLASS_BOOT &&
\r
380 InterfaceDescriptor.InterfaceProtocol == PROTOCOL_KEYBOARD
\r
390 EFI_HII_KEYBOARD_LAYOUT *
\r
391 GetCurrentKeyboardLayout (
\r
396 Routine Description:
\r
397 Get current keyboard layout from HII database.
\r
403 Pointer to EFI_HII_KEYBOARD_LAYOUT.
\r
408 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
\r
409 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;
\r
413 // Locate Hii database protocol
\r
415 Status = gBS->LocateProtocol (
\r
416 &gEfiHiiDatabaseProtocolGuid,
\r
418 (VOID **) &HiiDatabase
\r
420 if (EFI_ERROR (Status)) {
\r
425 // Get current keyboard layout from HII database
\r
428 KeyboardLayout = NULL;
\r
429 Status = HiiDatabase->GetKeyboardLayout (
\r
435 if (Status == EFI_BUFFER_TOO_SMALL) {
\r
436 KeyboardLayout = AllocatePool (Length);
\r
437 ASSERT (KeyboardLayout != NULL);
\r
439 Status = HiiDatabase->GetKeyboardLayout (
\r
445 if (EFI_ERROR (Status)) {
\r
446 gBS->FreePool (KeyboardLayout);
\r
447 KeyboardLayout = NULL;
\r
451 return KeyboardLayout;
\r
454 EFI_KEY_DESCRIPTOR *
\r
456 IN USB_KB_DEV *UsbKeyboardDevice,
\r
461 Routine Description:
\r
462 Find Key Descriptor in KeyConvertionTable given its scan code.
\r
465 UsbKeyboardDevice - The USB_KB_DEV instance.
\r
466 ScanCode - USB scan code.
\r
469 The Key descriptor in KeyConvertionTable.
\r
475 if (((ScanCode > 0x65) && (ScanCode < 0xe0)) || (ScanCode > 0xe7)) {
\r
479 if (ScanCode <= 0x65) {
\r
480 Index = (UINT8) (ScanCode - 4);
\r
482 Index = (UINT8) (ScanCode - 0xe0 + USB_KEYCODE_MAX_MAKE);
\r
485 return &UsbKeyboardDevice->KeyConvertionTable[Index];
\r
490 IN USB_KB_DEV *UsbKeyboardDevice,
\r
491 IN EFI_KEY_DESCRIPTOR *KeyDescriptor
\r
495 Routine Description:
\r
496 Find Non-Spacing key for given KeyDescriptor.
\r
499 UsbKeyboardDevice - The USB_KB_DEV instance.
\r
500 KeyDescriptor - Key descriptor.
\r
503 The Non-Spacing key.
\r
508 USB_NS_KEY *UsbNsKey;
\r
510 Link = GetFirstNode (&UsbKeyboardDevice->NsKeyList);
\r
511 while (!IsNull (&UsbKeyboardDevice->NsKeyList, Link)) {
\r
512 UsbNsKey = USB_NS_KEY_FORM_FROM_LINK (Link);
\r
514 if (UsbNsKey->NsKey[0].Key == KeyDescriptor->Key) {
\r
518 Link = GetNextNode (&UsbKeyboardDevice->NsKeyList, Link);
\r
524 EFI_KEY_DESCRIPTOR *
\r
526 IN USB_NS_KEY *UsbNsKey,
\r
527 IN EFI_KEY_DESCRIPTOR *KeyDescriptor
\r
531 Routine Description:
\r
532 Find physical key definition for a given Key stroke.
\r
535 UsbNsKey - The Non-Spacing key information.
\r
536 KeyDescriptor - The key stroke.
\r
539 The physical key definition.
\r
544 EFI_KEY_DESCRIPTOR *PhysicalKey;
\r
546 PhysicalKey = &UsbNsKey->NsKey[1];
\r
547 for (Index = 0; Index < UsbNsKey->KeyCount; Index++) {
\r
548 if (KeyDescriptor->Key == PhysicalKey->Key) {
\r
549 return PhysicalKey;
\r
556 // No children definition matched, return original key
\r
558 return KeyDescriptor;
\r
563 SetKeyboardLayoutEvent (
\r
569 Routine Description:
\r
570 The notification function for SET_KEYBOARD_LAYOUT_EVENT.
\r
578 USB_KB_DEV *UsbKeyboardDevice;
\r
579 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;
\r
580 EFI_KEY_DESCRIPTOR TempKey;
\r
581 EFI_KEY_DESCRIPTOR *KeyDescriptor;
\r
582 EFI_KEY_DESCRIPTOR *TableEntry;
\r
583 EFI_KEY_DESCRIPTOR *NsKey;
\r
584 USB_NS_KEY *UsbNsKey;
\r
590 UsbKeyboardDevice = (USB_KB_DEV *) Context;
\r
593 // Try to get current Keyboard Layout from HII database
\r
595 KeyboardLayout = GetCurrentKeyboardLayout ();
\r
596 if (KeyboardLayout == NULL) {
\r
601 // Allocate resource for KeyConvertionTable
\r
603 ReleaseKeyboardLayoutResources (UsbKeyboardDevice);
\r
604 UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((USB_KEYCODE_MAX_MAKE + 8) * sizeof (EFI_KEY_DESCRIPTOR));
\r
605 ASSERT (UsbKeyboardDevice->KeyConvertionTable != NULL);
\r
607 KeyDescriptor = (EFI_KEY_DESCRIPTOR *) (((UINT8 *) KeyboardLayout) + sizeof (EFI_HII_KEYBOARD_LAYOUT));
\r
608 for (Index = 0; Index < KeyboardLayout->DescriptorCount; Index++) {
\r
610 // Copy from HII keyboard layout package binary for alignment
\r
612 CopyMem (&TempKey, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));
\r
615 // Fill the key into KeyConvertionTable (which use USB Scan Code as index)
\r
617 ScanCode = UsbScanCodeConvertionTable [(UINT8) (TempKey.Key)];
\r
618 TableEntry = GetKeyDescriptor (UsbKeyboardDevice, ScanCode);
\r
619 CopyMem (TableEntry, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));
\r
621 if (TempKey.Modifier == EFI_NS_KEY_MODIFIER) {
\r
625 UsbNsKey = AllocatePool (sizeof (USB_NS_KEY));
\r
626 ASSERT (UsbNsKey != NULL);
\r
629 // Search for sequential children physical key definitions
\r
632 NsKey = KeyDescriptor + 1;
\r
633 for (Index2 = Index + 1; Index2 < KeyboardLayout->DescriptorCount; Index2++) {
\r
634 CopyMem (&TempKey, NsKey, sizeof (EFI_KEY_DESCRIPTOR));
\r
635 if (TempKey.Modifier & EFI_NS_KEY_DEPENDENCY_MODIFIER) {
\r
643 UsbNsKey->Signature = USB_NS_KEY_SIGNATURE;
\r
644 UsbNsKey->KeyCount = KeyCount;
\r
645 UsbNsKey->NsKey = AllocateCopyPool (
\r
646 (KeyCount + 1) * sizeof (EFI_KEY_DESCRIPTOR),
\r
649 InsertTailList (&UsbKeyboardDevice->NsKeyList, &UsbNsKey->Link);
\r
652 // Skip over the child physical keys
\r
655 KeyDescriptor += KeyCount;
\r
662 // There are two EfiKeyEnter, duplicate its Key Descriptor
\r
664 TableEntry = GetKeyDescriptor (UsbKeyboardDevice, 0x58);
\r
665 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, 0x28);
\r
666 CopyMem (TableEntry, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));
\r
668 gBS->FreePool (KeyboardLayout);
\r
672 ReleaseKeyboardLayoutResources (
\r
673 IN USB_KB_DEV *UsbKeyboardDevice
\r
677 Routine Description:
\r
678 Destroy resources for Keyboard layout.
\r
681 UsbKeyboardDevice - The USB_KB_DEV instance.
\r
688 USB_NS_KEY *UsbNsKey;
\r
691 SafeFreePool (UsbKeyboardDevice->KeyConvertionTable);
\r
692 UsbKeyboardDevice->KeyConvertionTable = NULL;
\r
694 while (!IsListEmpty (&UsbKeyboardDevice->NsKeyList)) {
\r
695 Link = GetFirstNode (&UsbKeyboardDevice->NsKeyList);
\r
696 UsbNsKey = USB_NS_KEY_FORM_FROM_LINK (Link);
\r
697 RemoveEntryList (&UsbNsKey->Link);
\r
699 gBS->FreePool (UsbNsKey->NsKey);
\r
700 gBS->FreePool (UsbNsKey);
\r
705 InitKeyboardLayout (
\r
706 IN USB_KB_DEV *UsbKeyboardDevice
\r
710 Routine Description:
\r
711 Initialize USB Keyboard layout.
\r
714 UsbKeyboardDevice The USB_KB_DEV instance.
\r
717 EFI_SUCCESS - Success
\r
718 Other - Keyboard layout initial failed.
\r
721 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;
\r
724 UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((USB_KEYCODE_MAX_MAKE + 8) * sizeof (EFI_KEY_DESCRIPTOR));
\r
725 ASSERT (UsbKeyboardDevice->KeyConvertionTable != NULL);
\r
727 InitializeListHead (&UsbKeyboardDevice->NsKeyList);
\r
728 UsbKeyboardDevice->CurrentNsKey = NULL;
\r
729 UsbKeyboardDevice->KeyboardLayoutEvent = NULL;
\r
732 // Register SET_KEYBOARD_LAYOUT_EVENT notification
\r
734 Status = gBS->CreateEventEx (
\r
735 EFI_EVENT_NOTIFY_SIGNAL,
\r
737 SetKeyboardLayoutEvent,
\r
739 &mKeyboardLayoutEventGuid,
\r
740 &UsbKeyboardDevice->KeyboardLayoutEvent
\r
742 if (EFI_ERROR (Status)) {
\r
747 // Try to get current keyboard layout from HII database
\r
749 KeyboardLayout = GetCurrentKeyboardLayout ();
\r
750 if (KeyboardLayout != NULL) {
\r
752 // Force to initialize the keyboard layout
\r
754 gBS->SignalEvent (UsbKeyboardDevice->KeyboardLayoutEvent);
\r
756 if (FeaturePcdGet (PcdDisableDefaultKeyboardLayoutInUsbKbDriver)) {
\r
757 return EFI_NOT_READY;
\r
761 // Fail to get keyboard layout from HII database,
\r
762 // use default keyboard layout
\r
764 LoadDefaultKeyboardLayout (UsbKeyboardDevice);
\r
768 return EFI_SUCCESS;
\r
773 Initialize USB Keyboard device and all private data structures.
\r
775 UsbKeyboardDevice The USB_KB_DEV instance.
\r
777 @retval EFI_SUCCESS Success
\r
778 @retval EFI_DEVICE_ERROR Hardware Error
\r
783 IN USB_KB_DEV *UsbKeyboardDevice
\r
791 UINT32 TransferResult;
\r
793 KbdReportStatusCode (
\r
794 UsbKeyboardDevice->DevicePath,
\r
796 PcdGet32 (PcdStatusCodeValueKeyboardSelfTest)
\r
799 InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer));
\r
802 // default configurations
\r
804 ConfigValue = 0x01;
\r
807 // Uses default configuration to configure the USB Keyboard device.
\r
809 Status = UsbSetConfiguration (
\r
810 UsbKeyboardDevice->UsbIo,
\r
811 (UINT16) ConfigValue,
\r
814 if (EFI_ERROR (Status)) {
\r
816 // If configuration could not be set here, it means
\r
817 // the keyboard interface has some errors and could
\r
818 // not be initialized
\r
820 KbdReportStatusCode (
\r
821 UsbKeyboardDevice->DevicePath,
\r
822 EFI_ERROR_CODE | EFI_ERROR_MINOR,
\r
823 PcdGet32 (PcdStatusCodeValueKeyboardInterfaceError)
\r
826 return EFI_DEVICE_ERROR;
\r
829 UsbGetProtocolRequest (
\r
830 UsbKeyboardDevice->UsbIo,
\r
831 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,
\r
835 // Sets boot protocol for the USB Keyboard.
\r
836 // This driver only supports boot protocol.
\r
837 // !!BugBug: How about the device that does not support boot protocol?
\r
839 if (Protocol != BOOT_PROTOCOL) {
\r
840 UsbSetProtocolRequest (
\r
841 UsbKeyboardDevice->UsbIo,
\r
842 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,
\r
847 // the duration is indefinite, so the endpoint will inhibit reporting forever,
\r
848 // and only reporting when a change is detected in the report data.
\r
852 // idle value for all report ID
\r
856 // idle forever until there is a key pressed and released.
\r
859 UsbSetIdleRequest (
\r
860 UsbKeyboardDevice->UsbIo,
\r
861 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,
\r
866 UsbKeyboardDevice->CtrlOn = 0;
\r
867 UsbKeyboardDevice->AltOn = 0;
\r
868 UsbKeyboardDevice->ShiftOn = 0;
\r
869 UsbKeyboardDevice->NumLockOn = 0;
\r
870 UsbKeyboardDevice->CapsOn = 0;
\r
871 UsbKeyboardDevice->ScrollOn = 0;
\r
873 UsbKeyboardDevice->LeftCtrlOn = 0;
\r
874 UsbKeyboardDevice->LeftAltOn = 0;
\r
875 UsbKeyboardDevice->LeftShiftOn = 0;
\r
876 UsbKeyboardDevice->LeftLogoOn = 0;
\r
877 UsbKeyboardDevice->RightCtrlOn = 0;
\r
878 UsbKeyboardDevice->RightAltOn = 0;
\r
879 UsbKeyboardDevice->RightShiftOn = 0;
\r
880 UsbKeyboardDevice->RightLogoOn = 0;
\r
881 UsbKeyboardDevice->MenuKeyOn = 0;
\r
882 UsbKeyboardDevice->SysReqOn = 0;
\r
884 UsbKeyboardDevice->AltGrOn = 0;
\r
886 UsbKeyboardDevice->CurrentNsKey = NULL;
\r
889 // Sync the initial state of lights
\r
891 SetKeyLED (UsbKeyboardDevice);
\r
893 ZeroMem (UsbKeyboardDevice->LastKeyCodeArray, sizeof (UINT8) * 8);
\r
896 // Set a timer for repeat keys' generation.
\r
898 if (UsbKeyboardDevice->RepeatTimer) {
\r
899 gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);
\r
900 UsbKeyboardDevice->RepeatTimer = 0;
\r
903 Status = gBS->CreateEvent (
\r
904 EVT_TIMER | EVT_NOTIFY_SIGNAL,
\r
906 USBKeyboardRepeatHandler,
\r
908 &UsbKeyboardDevice->RepeatTimer
\r
911 if (UsbKeyboardDevice->DelayedRecoveryEvent) {
\r
912 gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);
\r
913 UsbKeyboardDevice->DelayedRecoveryEvent = 0;
\r
916 Status = gBS->CreateEvent (
\r
917 EVT_TIMER | EVT_NOTIFY_SIGNAL,
\r
919 USBKeyboardRecoveryHandler,
\r
921 &UsbKeyboardDevice->DelayedRecoveryEvent
\r
924 return EFI_SUCCESS;
\r
929 Handler function for USB Keyboard's asynchronous interrupt transfer.
\r
931 Data A pointer to a buffer that is filled with key data which is
\r
932 retrieved via asynchronous interrupt transfer.
\r
933 DataLength Indicates the size of the data buffer.
\r
934 Context Pointing to USB_KB_DEV instance.
\r
935 Result Indicates the result of the asynchronous interrupt transfer.
\r
937 @retval EFI_SUCCESS Success
\r
938 @retval EFI_DEVICE_ERROR Hardware Error
\r
945 IN UINTN DataLength,
\r
950 USB_KB_DEV *UsbKeyboardDevice;
\r
951 EFI_USB_IO_PROTOCOL *UsbIo;
\r
952 UINT8 *CurKeyCodeBuffer;
\r
953 UINT8 *OldKeyCodeBuffer;
\r
954 UINT8 CurModifierMap;
\r
955 UINT8 OldModifierMap;
\r
959 BOOLEAN KeyRelease;
\r
963 UINT8 NewRepeatKey;
\r
965 EFI_KEY_DESCRIPTOR *KeyDescriptor;
\r
970 UsbKeyboardDevice = (USB_KB_DEV *) Context;
\r
971 UsbIo = UsbKeyboardDevice->UsbIo;
\r
974 // Analyzes the Result and performs corresponding action.
\r
976 if (Result != EFI_USB_NOERROR) {
\r
978 // Some errors happen during the process
\r
980 KbdReportStatusCode (
\r
981 UsbKeyboardDevice->DevicePath,
\r
982 EFI_ERROR_CODE | EFI_ERROR_MINOR,
\r
983 PcdGet32 (PcdStatusCodeValueKeyboardInputError)
\r
987 // stop the repeat key generation if any
\r
989 UsbKeyboardDevice->RepeatKey = 0;
\r
992 UsbKeyboardDevice->RepeatTimer,
\r
997 if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
\r
998 UsbClearEndpointHalt (
\r
1000 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,
\r
1006 // Delete & Submit this interrupt again
\r
1009 UsbIo->UsbAsyncInterruptTransfer (
\r
1011 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,
\r
1020 UsbKeyboardDevice->DelayedRecoveryEvent,
\r
1022 EFI_USB_INTERRUPT_DELAY
\r
1025 return EFI_DEVICE_ERROR;
\r
1028 if (DataLength == 0 || Data == NULL) {
\r
1029 return EFI_SUCCESS;
\r
1032 CurKeyCodeBuffer = (UINT8 *) Data;
\r
1033 OldKeyCodeBuffer = UsbKeyboardDevice->LastKeyCodeArray;
\r
1036 // checks for new key stroke.
\r
1037 // if no new key got, return immediately.
\r
1039 for (Index = 0; Index < 8; Index++) {
\r
1040 if (OldKeyCodeBuffer[Index] != CurKeyCodeBuffer[Index]) {
\r
1046 return EFI_SUCCESS;
\r
1050 // Parse the modifier key
\r
1052 CurModifierMap = CurKeyCodeBuffer[0];
\r
1053 OldModifierMap = OldKeyCodeBuffer[0];
\r
1056 // handle modifier key's pressing or releasing situation.
\r
1058 for (Index = 0; Index < 8; Index++) {
\r
1060 if ((CurModifierMap & KB_Mod[Index].Mask) != (OldModifierMap & KB_Mod[Index].Mask)) {
\r
1062 // if current modifier key is up, then
\r
1063 // CurModifierMap & KB_Mod[Index].Mask = 0;
\r
1064 // otherwize it is a non-zero value.
\r
1065 // Inserts the pressed modifier key into key buffer.
\r
1067 Down = (UINT8) (CurModifierMap & KB_Mod[Index].Mask);
\r
1068 InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), KB_Mod[Index].Key, Down);
\r
1073 // handle normal key's releasing situation
\r
1075 KeyRelease = FALSE;
\r
1076 for (Index = 2; Index < 8; Index++) {
\r
1078 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index])) {
\r
1082 KeyRelease = TRUE;
\r
1083 for (Index2 = 2; Index2 < 8; Index2++) {
\r
1085 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index2])) {
\r
1089 if (OldKeyCodeBuffer[Index] == CurKeyCodeBuffer[Index2]) {
\r
1090 KeyRelease = FALSE;
\r
1097 &(UsbKeyboardDevice->KeyboardBuffer),
\r
1098 OldKeyCodeBuffer[Index],
\r
1102 // the original reapeat key is released.
\r
1104 if (OldKeyCodeBuffer[Index] == UsbKeyboardDevice->RepeatKey) {
\r
1105 UsbKeyboardDevice->RepeatKey = 0;
\r
1111 // original repeat key is released, cancel the repeat timer
\r
1113 if (UsbKeyboardDevice->RepeatKey == 0) {
\r
1115 UsbKeyboardDevice->RepeatTimer,
\r
1117 USBKBD_REPEAT_RATE
\r
1122 // handle normal key's pressing situation
\r
1125 for (Index = 2; Index < 8; Index++) {
\r
1127 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index])) {
\r
1132 for (Index2 = 2; Index2 < 8; Index2++) {
\r
1134 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index2])) {
\r
1138 if (CurKeyCodeBuffer[Index] == OldKeyCodeBuffer[Index2]) {
\r
1145 InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), CurKeyCodeBuffer[Index], 1);
\r
1147 // NumLock pressed or CapsLock pressed
\r
1149 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, CurKeyCodeBuffer[Index]);
\r
1150 if (KeyDescriptor->Modifier == EFI_NUM_LOCK_MODIFIER || KeyDescriptor->Modifier == EFI_CAPS_LOCK_MODIFIER) {
\r
1151 UsbKeyboardDevice->RepeatKey = 0;
\r
1153 NewRepeatKey = CurKeyCodeBuffer[Index];
\r
1155 // do not repeat the original repeated key
\r
1157 UsbKeyboardDevice->RepeatKey = 0;
\r
1163 // Update LastKeycodeArray[] buffer in the
\r
1164 // Usb Keyboard Device data structure.
\r
1166 for (Index = 0; Index < 8; Index++) {
\r
1167 UsbKeyboardDevice->LastKeyCodeArray[Index] = CurKeyCodeBuffer[Index];
\r
1171 // pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence
\r
1172 // and judge whether it will invoke reset event.
\r
1174 SavedTail = UsbKeyboardDevice->KeyboardBuffer.bTail;
\r
1175 Index = UsbKeyboardDevice->KeyboardBuffer.bHead;
\r
1176 while (Index != SavedTail) {
\r
1177 RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey);
\r
1179 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode);
\r
1181 switch (KeyDescriptor->Modifier) {
\r
1183 case EFI_LEFT_CONTROL_MODIFIER:
\r
1184 case EFI_RIGHT_CONTROL_MODIFIER:
\r
1185 if (UsbKey.Down) {
\r
1186 UsbKeyboardDevice->CtrlOn = 1;
\r
1188 UsbKeyboardDevice->CtrlOn = 0;
\r
1192 case EFI_LEFT_ALT_MODIFIER:
\r
1193 case EFI_RIGHT_ALT_MODIFIER:
\r
1194 if (UsbKey.Down) {
\r
1195 UsbKeyboardDevice->AltOn = 1;
\r
1197 UsbKeyboardDevice->AltOn = 0;
\r
1201 case EFI_ALT_GR_MODIFIER:
\r
1202 if (UsbKey.Down) {
\r
1203 UsbKeyboardDevice->AltGrOn = 1;
\r
1205 UsbKeyboardDevice->AltGrOn = 0;
\r
1212 case EFI_DELETE_MODIFIER:
\r
1213 if (UsbKey.Down) {
\r
1214 if (UsbKeyboardDevice->CtrlOn && UsbKeyboardDevice->AltOn) {
\r
1215 gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
\r
1225 // insert the key back to the buffer.
\r
1226 // so the key sequence will not be destroyed.
\r
1229 &(UsbKeyboardDevice->KeyboardBuffer),
\r
1233 Index = UsbKeyboardDevice->KeyboardBuffer.bHead;
\r
1237 // If have new key pressed, update the RepeatKey value, and set the
\r
1238 // timer to repeate delay timer
\r
1240 if (NewRepeatKey != 0) {
\r
1242 // sets trigger time to "Repeat Delay Time",
\r
1243 // to trigger the repeat timer when the key is hold long
\r
1247 UsbKeyboardDevice->RepeatTimer,
\r
1249 USBKBD_REPEAT_DELAY
\r
1251 UsbKeyboardDevice->RepeatKey = NewRepeatKey;
\r
1254 return EFI_SUCCESS;
\r
1259 Retrieves a key character after parsing the raw data in keyboard buffer.
\r
1261 UsbKeyboardDevice The USB_KB_DEV instance.
\r
1262 KeyChar Points to the Key character after key parsing.
\r
1264 @retval EFI_SUCCESS Success
\r
1265 @retval EFI_NOT_READY Device is not ready
\r
1270 IN OUT USB_KB_DEV *UsbKeyboardDevice,
\r
1271 OUT UINT8 *KeyChar
\r
1275 EFI_KEY_DESCRIPTOR *KeyDescriptor;
\r
1279 while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice->KeyboardBuffer)) {
\r
1281 // pops one raw data off.
\r
1283 RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey);
\r
1285 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode);
\r
1286 if (!UsbKey.Down) {
\r
1287 switch (KeyDescriptor->Modifier) {
\r
1292 case EFI_LEFT_CONTROL_MODIFIER:
\r
1293 UsbKeyboardDevice->LeftCtrlOn = 0;
\r
1294 UsbKeyboardDevice->CtrlOn = 0;
\r
1296 case EFI_RIGHT_CONTROL_MODIFIER:
\r
1297 UsbKeyboardDevice->RightCtrlOn = 0;
\r
1298 UsbKeyboardDevice->CtrlOn = 0;
\r
1304 case EFI_LEFT_SHIFT_MODIFIER:
\r
1305 UsbKeyboardDevice->LeftShiftOn = 0;
\r
1306 UsbKeyboardDevice->ShiftOn = 0;
\r
1308 case EFI_RIGHT_SHIFT_MODIFIER:
\r
1309 UsbKeyboardDevice->RightShiftOn = 0;
\r
1310 UsbKeyboardDevice->ShiftOn = 0;
\r
1316 case EFI_LEFT_ALT_MODIFIER:
\r
1317 UsbKeyboardDevice->LeftAltOn = 0;
\r
1318 UsbKeyboardDevice->AltOn = 0;
\r
1320 case EFI_RIGHT_ALT_MODIFIER:
\r
1321 UsbKeyboardDevice->RightAltOn = 0;
\r
1322 UsbKeyboardDevice->AltOn = 0;
\r
1326 // Left Logo release
\r
1328 case EFI_LEFT_LOGO_MODIFIER:
\r
1329 UsbKeyboardDevice->LeftLogoOn = 0;
\r
1333 // Right Logo release
\r
1335 case EFI_RIGHT_LOGO_MODIFIER:
\r
1336 UsbKeyboardDevice->RightLogoOn = 0;
\r
1340 // Menu key release
\r
1342 case EFI_MENU_MODIFIER:
\r
1343 UsbKeyboardDevice->MenuKeyOn = 0;
\r
1349 case EFI_PRINT_MODIFIER:
\r
1350 case EFI_SYS_REQUEST_MODIFIER:
\r
1351 UsbKeyboardDevice->SysReqOn = 0;
\r
1357 case EFI_ALT_GR_MODIFIER:
\r
1358 UsbKeyboardDevice->AltGrOn = 0;
\r
1369 // Analyzes key pressing situation
\r
1371 switch (KeyDescriptor->Modifier) {
\r
1376 case EFI_LEFT_CONTROL_MODIFIER:
\r
1377 UsbKeyboardDevice->LeftCtrlOn = 1;
\r
1378 UsbKeyboardDevice->CtrlOn = 1;
\r
1381 case EFI_RIGHT_CONTROL_MODIFIER:
\r
1382 UsbKeyboardDevice->RightCtrlOn = 1;
\r
1383 UsbKeyboardDevice->CtrlOn = 1;
\r
1390 case EFI_LEFT_SHIFT_MODIFIER:
\r
1391 UsbKeyboardDevice->LeftShiftOn = 1;
\r
1392 UsbKeyboardDevice->ShiftOn = 1;
\r
1395 case EFI_RIGHT_SHIFT_MODIFIER:
\r
1396 UsbKeyboardDevice->RightShiftOn = 1;
\r
1397 UsbKeyboardDevice->ShiftOn = 1;
\r
1404 case EFI_LEFT_ALT_MODIFIER:
\r
1405 UsbKeyboardDevice->LeftAltOn = 1;
\r
1406 UsbKeyboardDevice->AltOn = 1;
\r
1409 case EFI_RIGHT_ALT_MODIFIER:
\r
1410 UsbKeyboardDevice->RightAltOn = 1;
\r
1411 UsbKeyboardDevice->AltOn = 1;
\r
1416 // Left Logo press
\r
1418 case EFI_LEFT_LOGO_MODIFIER:
\r
1419 UsbKeyboardDevice->LeftLogoOn = 1;
\r
1423 // Right Logo press
\r
1425 case EFI_RIGHT_LOGO_MODIFIER:
\r
1426 UsbKeyboardDevice->RightLogoOn = 1;
\r
1432 case EFI_MENU_MODIFIER:
\r
1433 UsbKeyboardDevice->MenuKeyOn = 1;
\r
1439 case EFI_PRINT_MODIFIER:
\r
1440 case EFI_SYS_REQUEST_MODIFIER:
\r
1441 UsbKeyboardDevice->SysReqOn = 1;
\r
1448 case EFI_ALT_GR_MODIFIER:
\r
1449 UsbKeyboardDevice->AltGrOn = 1;
\r
1452 case EFI_NUM_LOCK_MODIFIER:
\r
1453 UsbKeyboardDevice->NumLockOn ^= 1;
\r
1455 // Turn on the NumLock light on KB
\r
1457 SetKeyLED (UsbKeyboardDevice);
\r
1461 case EFI_CAPS_LOCK_MODIFIER:
\r
1462 UsbKeyboardDevice->CapsOn ^= 1;
\r
1464 // Turn on the CapsLock light on KB
\r
1466 SetKeyLED (UsbKeyboardDevice);
\r
1470 case EFI_SCROLL_LOCK_MODIFIER:
\r
1471 UsbKeyboardDevice->ScrollOn ^= 1;
\r
1473 // Turn on the ScrollLock light on KB
\r
1475 SetKeyLED (UsbKeyboardDevice);
\r
1480 // F11,F12,PrintScreen,Pause/Break
\r
1481 // could not be retrieved via SimpleTxtInEx protocol
\r
1483 case EFI_FUNCTION_KEY_ELEVEN_MODIFIER:
\r
1484 case EFI_FUNCTION_KEY_TWELVE_MODIFIER:
\r
1485 case EFI_PAUSE_MODIFIER:
\r
1486 case EFI_BREAK_MODIFIER:
\r
1498 // When encountered Del Key...
\r
1500 if (KeyDescriptor->Modifier == EFI_DELETE_MODIFIER) {
\r
1501 if (UsbKeyboardDevice->CtrlOn && UsbKeyboardDevice->AltOn) {
\r
1502 gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
\r
1506 *KeyChar = UsbKey.KeyCode;
\r
1507 return EFI_SUCCESS;
\r
1510 return EFI_NOT_READY;
\r
1516 Converts USB Keyboard code to EFI Scan Code.
\r
1518 UsbKeyboardDevice The USB_KB_DEV instance.
\r
1519 KeyChar Indicates the key code that will be interpreted.
\r
1520 Key A pointer to a buffer that is filled in with
\r
1521 the keystroke information for the key that
\r
1524 @retval EFI_NOT_READY Device is not ready
\r
1525 @retval EFI_SUCCESS Success
\r
1529 USBKeyCodeToEFIScanCode (
\r
1530 IN USB_KB_DEV *UsbKeyboardDevice,
\r
1532 OUT EFI_INPUT_KEY *Key
\r
1536 EFI_KEY_DESCRIPTOR *KeyDescriptor;
\r
1538 if (!USBKBD_VALID_KEYCODE (KeyChar)) {
\r
1539 return EFI_NOT_READY;
\r
1543 // valid USB Key Code starts from 4
\r
1545 Index = (UINT8) (KeyChar - 4);
\r
1547 if (Index >= USB_KEYCODE_MAX_MAKE) {
\r
1548 return EFI_NOT_READY;
\r
1551 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, KeyChar);
\r
1554 // Check for Non-spacing key
\r
1556 if (KeyDescriptor->Modifier == EFI_NS_KEY_MODIFIER) {
\r
1557 UsbKeyboardDevice->CurrentNsKey = FindUsbNsKey (UsbKeyboardDevice, KeyDescriptor);
\r
1558 return EFI_NOT_READY;
\r
1562 // Check whether this keystroke follows a Non-spacing key
\r
1564 if (UsbKeyboardDevice->CurrentNsKey != NULL) {
\r
1565 KeyDescriptor = FindPhysicalKey (UsbKeyboardDevice->CurrentNsKey, KeyDescriptor);
\r
1566 UsbKeyboardDevice->CurrentNsKey = NULL;
\r
1569 Key->ScanCode = EfiScanCodeConvertionTable[KeyDescriptor->Modifier];
\r
1570 Key->UnicodeChar = KeyDescriptor->Unicode;
\r
1572 if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_STANDARD_SHIFT) {
\r
1573 if (UsbKeyboardDevice->ShiftOn) {
\r
1574 Key->UnicodeChar = KeyDescriptor->ShiftedUnicode;
\r
1577 // Need not return associated shift state if a class of printable characters that
\r
1578 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
\r
1580 if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) {
\r
1581 UsbKeyboardDevice->LeftShiftOn = 0;
\r
1582 UsbKeyboardDevice->RightShiftOn = 0;
\r
1585 if (UsbKeyboardDevice->AltGrOn) {
\r
1586 Key->UnicodeChar = KeyDescriptor->ShiftedAltGrUnicode;
\r
1592 Key->UnicodeChar = KeyDescriptor->Unicode;
\r
1594 if (UsbKeyboardDevice->AltGrOn) {
\r
1595 Key->UnicodeChar = KeyDescriptor->AltGrUnicode;
\r
1600 if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) {
\r
1601 if (UsbKeyboardDevice->CapsOn) {
\r
1603 if (Key->UnicodeChar == KeyDescriptor->Unicode) {
\r
1605 Key->UnicodeChar = KeyDescriptor->ShiftedUnicode;
\r
1607 } else if (Key->UnicodeChar == KeyDescriptor->ShiftedUnicode) {
\r
1609 Key->UnicodeChar = KeyDescriptor->Unicode;
\r
1616 // Translate the CTRL-Alpha characters to their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
\r
1618 if (UsbKeyboardDevice->CtrlOn) {
\r
1619 if (Key->UnicodeChar >= 'a' && Key->UnicodeChar <= 'z') {
\r
1620 Key->UnicodeChar = (UINT8) (Key->UnicodeChar - 'a' + 1);
\r
1621 } else if (Key->UnicodeChar >= 'A' && Key->UnicodeChar <= 'Z') {
\r
1622 Key->UnicodeChar = (UINT8) (Key->UnicodeChar - 'A' + 1);
\r
1626 if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_NUM_LOCK) {
\r
1628 if (UsbKeyboardDevice->NumLockOn && !UsbKeyboardDevice->ShiftOn) {
\r
1630 Key->ScanCode = SCAN_NULL;
\r
1633 Key->UnicodeChar = 0x00;
\r
1638 // Translate Unicode 0x1B (ESC) to EFI Scan Code
\r
1640 if (Key->UnicodeChar == 0x1B && Key->ScanCode == SCAN_NULL) {
\r
1641 Key->ScanCode = SCAN_ESC;
\r
1642 Key->UnicodeChar = 0x00;
\r
1645 if (Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) {
\r
1646 return EFI_NOT_READY;
\r
1651 // Save Shift/Toggle state
\r
1653 if (UsbKeyboardDevice->LeftCtrlOn == 1) {
\r
1654 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;
\r
1656 if (UsbKeyboardDevice->RightCtrlOn == 1) {
\r
1657 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;
\r
1659 if (UsbKeyboardDevice->LeftAltOn == 1) {
\r
1660 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED;
\r
1662 if (UsbKeyboardDevice->RightAltOn == 1) {
\r
1663 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED;
\r
1665 if (UsbKeyboardDevice->LeftShiftOn == 1) {
\r
1666 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
\r
1668 if (UsbKeyboardDevice->RightShiftOn == 1) {
\r
1669 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
\r
1671 if (UsbKeyboardDevice->LeftLogoOn == 1) {
\r
1672 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;
\r
1674 if (UsbKeyboardDevice->RightLogoOn == 1) {
\r
1675 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;
\r
1677 if (UsbKeyboardDevice->MenuKeyOn == 1) {
\r
1678 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;
\r
1680 if (UsbKeyboardDevice->SysReqOn == 1) {
\r
1681 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;
\r
1684 if (UsbKeyboardDevice->ScrollOn == 1) {
\r
1685 UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;
\r
1687 if (UsbKeyboardDevice->NumLockOn == 1) {
\r
1688 UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
\r
1690 if (UsbKeyboardDevice->CapsOn == 1) {
\r
1691 UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
\r
1694 return EFI_SUCCESS;
\r
1701 Resets USB Keyboard Buffer.
\r
1703 @param KeyboardBuffer Points to the USB Keyboard Buffer.
\r
1705 @retval EFI_SUCCESS Success
\r
1709 InitUSBKeyBuffer (
\r
1710 IN OUT USB_KB_BUFFER *KeyboardBuffer
\r
1713 ZeroMem (KeyboardBuffer, sizeof (USB_KB_BUFFER));
\r
1715 KeyboardBuffer->bHead = KeyboardBuffer->bTail;
\r
1717 return EFI_SUCCESS;
\r
1722 Check whether USB Keyboard buffer is empty.
\r
1724 @param KeyboardBuffer USB Keyboard Buffer.
\r
1729 IsUSBKeyboardBufferEmpty (
\r
1730 IN USB_KB_BUFFER *KeyboardBuffer
\r
1734 // meet FIFO empty condition
\r
1736 return (BOOLEAN) (KeyboardBuffer->bHead == KeyboardBuffer->bTail);
\r
1742 Check whether USB Keyboard buffer is full.
\r
1744 @param KeyboardBuffer USB Keyboard Buffer.
\r
1749 IsUSBKeyboardBufferFull (
\r
1750 IN USB_KB_BUFFER *KeyboardBuffer
\r
1753 return (BOOLEAN)(((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1)) ==
\r
1754 KeyboardBuffer->bHead);
\r
1760 Inserts a key code into keyboard buffer.
\r
1762 @param KeyboardBuffer Points to the USB Keyboard Buffer.
\r
1763 @param Key Key code
\r
1764 @param Down Special key
\r
1766 @retval EFI_SUCCESS Success
\r
1771 IN OUT USB_KB_BUFFER *KeyboardBuffer,
\r
1779 // if keyboard buffer is full, throw the
\r
1780 // first key out of the keyboard buffer.
\r
1782 if (IsUSBKeyboardBufferFull (KeyboardBuffer)) {
\r
1783 RemoveKeyCode (KeyboardBuffer, &UsbKey);
\r
1786 KeyboardBuffer->buffer[KeyboardBuffer->bTail].KeyCode = Key;
\r
1787 KeyboardBuffer->buffer[KeyboardBuffer->bTail].Down = Down;
\r
1790 // adjust the tail pointer of the FIFO keyboard buffer.
\r
1792 KeyboardBuffer->bTail = (UINT8) ((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1));
\r
1794 return EFI_SUCCESS;
\r
1799 Pops a key code off from keyboard buffer.
\r
1801 @param KeyboardBuffer Points to the USB Keyboard Buffer.
\r
1802 @param UsbKey Points to the buffer that contains a usb key code.
\r
1804 @retval EFI_SUCCESS Success
\r
1805 @retval EFI_DEVICE_ERROR Hardware Error
\r
1810 IN OUT USB_KB_BUFFER *KeyboardBuffer,
\r
1811 OUT USB_KEY *UsbKey
\r
1814 if (IsUSBKeyboardBufferEmpty (KeyboardBuffer)) {
\r
1815 return EFI_DEVICE_ERROR;
\r
1818 UsbKey->KeyCode = KeyboardBuffer->buffer[KeyboardBuffer->bHead].KeyCode;
\r
1819 UsbKey->Down = KeyboardBuffer->buffer[KeyboardBuffer->bHead].Down;
\r
1822 // adjust the head pointer of the FIFO keyboard buffer.
\r
1824 KeyboardBuffer->bHead = (UINT8) ((KeyboardBuffer->bHead + 1) % (MAX_KEY_ALLOWED + 1));
\r
1826 return EFI_SUCCESS;
\r
1831 Sets USB Keyboard LED state.
\r
1833 @param UsbKeyboardDevice The USB_KB_DEV instance.
\r
1835 @retval EFI_SUCCESS Success
\r
1840 IN USB_KB_DEV *UsbKeyboardDevice
\r
1847 // Set each field in Led map.
\r
1849 Led.NumLock = (UINT8) UsbKeyboardDevice->NumLockOn;
\r
1850 Led.CapsLock = (UINT8) UsbKeyboardDevice->CapsOn;
\r
1851 Led.ScrollLock = (UINT8) UsbKeyboardDevice->ScrollOn;
\r
1856 // call Set Report Request to lighten the LED.
\r
1858 UsbSetReportRequest (
\r
1859 UsbKeyboardDevice->UsbIo,
\r
1860 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,
\r
1862 HID_OUTPUT_REPORT,
\r
1867 return EFI_SUCCESS;
\r
1872 Timer handler for Repeat Key timer.
\r
1874 @param Event The Repeat Key event.
\r
1875 @param Context Points to the USB_KB_DEV instance.
\r
1881 USBKeyboardRepeatHandler (
\r
1882 IN EFI_EVENT Event,
\r
1886 USB_KB_DEV *UsbKeyboardDevice;
\r
1888 UsbKeyboardDevice = (USB_KB_DEV *) Context;
\r
1891 // Do nothing when there is no repeat key.
\r
1893 if (UsbKeyboardDevice->RepeatKey != 0) {
\r
1895 // Inserts one Repeat key into keyboard buffer,
\r
1898 &(UsbKeyboardDevice->KeyboardBuffer),
\r
1899 UsbKeyboardDevice->RepeatKey,
\r
1904 // set repeate rate for repeat key generation.
\r
1907 UsbKeyboardDevice->RepeatTimer,
\r
1909 USBKBD_REPEAT_RATE
\r
1917 Timer handler for Delayed Recovery timer.
\r
1919 @param Event The Delayed Recovery event.
\r
1920 @param Context Points to the USB_KB_DEV instance.
\r
1926 USBKeyboardRecoveryHandler (
\r
1927 IN EFI_EVENT Event,
\r
1932 USB_KB_DEV *UsbKeyboardDevice;
\r
1933 EFI_USB_IO_PROTOCOL *UsbIo;
\r
1936 UsbKeyboardDevice = (USB_KB_DEV *) Context;
\r
1938 UsbIo = UsbKeyboardDevice->UsbIo;
\r
1940 PacketSize = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize);
\r
1942 UsbIo->UsbAsyncInterruptTransfer (
\r
1944 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,
\r
1946 UsbKeyboardDevice->IntEndpointDescriptor.Interval,
\r