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