]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Usb/UsbKbDxe/keyboard.c
Merged in the following trackers from EDK:
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbKbDxe / keyboard.c
CommitLineData
ed838d0c 1/** @file\r
2\r
3Copyright (c) 2004 - 2005, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 Keyboard.c\r
15\r
16Abstract:\r
17\r
18 Helper functions for USB Keyboard Driver\r
19\r
20Revision History\r
21\r
22\r
23**/\r
24\r
25#include "keyboard.h"\r
26#include <Library/UsbLib.h>\r
27//\r
28// USB Key Code to Efi key mapping table\r
29// Format:<efi scan code>, <unicode without shift>, <unicode with shift>\r
30//\r
31STATIC\r
32UINT8 KeyConvertionTable[USB_KEYCODE_MAX_MAKE][3] = {\r
33 { SCAN_NULL, 'a', 'A' }, // 0x04\r
34 { SCAN_NULL, 'b', 'B' }, // 0x05\r
35 { SCAN_NULL, 'c', 'C' }, // 0x06\r
36 { SCAN_NULL, 'd', 'D' }, // 0x07\r
37 { SCAN_NULL, 'e', 'E' }, // 0x08\r
38 { SCAN_NULL, 'f', 'F' }, // 0x09\r
39 { SCAN_NULL, 'g', 'G' }, // 0x0A\r
40 { SCAN_NULL, 'h', 'H' }, // 0x0B\r
41 { SCAN_NULL, 'i', 'I' }, // 0x0C\r
42 { SCAN_NULL, 'j', 'J' }, // 0x0D\r
43 { SCAN_NULL, 'k', 'K' }, // 0x0E\r
44 { SCAN_NULL, 'l', 'L' }, // 0x0F\r
45 { SCAN_NULL, 'm', 'M' }, // 0x10\r
46 { SCAN_NULL, 'n', 'N' }, // 0x11\r
47 { SCAN_NULL, 'o', 'O' }, // 0x12\r
48 { SCAN_NULL, 'p', 'P' }, // 0x13\r
49 { SCAN_NULL, 'q', 'Q' }, // 0x14\r
50 { SCAN_NULL, 'r', 'R' }, // 0x15\r
51 { SCAN_NULL, 's', 'S' }, // 0x16\r
52 { SCAN_NULL, 't', 'T' }, // 0x17\r
53 { SCAN_NULL, 'u', 'U' }, // 0x18\r
54 { SCAN_NULL, 'v', 'V' }, // 0x19\r
55 { SCAN_NULL, 'w', 'W' }, // 0x1A\r
56 { SCAN_NULL, 'x', 'X' }, // 0x1B\r
57 { SCAN_NULL, 'y', 'Y' }, // 0x1C\r
58 { SCAN_NULL, 'z', 'Z' }, // 0x1D\r
59 { SCAN_NULL, '1', '!' }, // 0x1E\r
60 { SCAN_NULL, '2', '@' }, // 0x1F\r
61 { SCAN_NULL, '3', '#' }, // 0x20\r
62 { SCAN_NULL, '4', '$' }, // 0x21\r
63 { SCAN_NULL, '5', '%' }, // 0x22\r
64 { SCAN_NULL, '6', '^' }, // 0x23\r
65 { SCAN_NULL, '7', '&' }, // 0x24\r
66 { SCAN_NULL, '8', '*' }, // 0x25\r
67 { SCAN_NULL, '9', '(' }, // 0x26\r
68 { SCAN_NULL, '0', ')' }, // 0x27\r
69 { SCAN_NULL, 0x0d, 0x0d }, // 0x28 Enter\r
70 { SCAN_ESC, 0x00, 0x00 }, // 0x29 Esc\r
71 { SCAN_NULL, 0x08, 0x08 }, // 0x2A Backspace\r
72 { SCAN_NULL, 0x09, 0x09 }, // 0x2B Tab\r
73 { SCAN_NULL, ' ', ' ' }, // 0x2C Spacebar\r
74 { SCAN_NULL, '-', '_' }, // 0x2D\r
75 { SCAN_NULL, '=', '+' }, // 0x2E\r
76 { SCAN_NULL, '[', '{' }, // 0x2F\r
77 { SCAN_NULL, ']', '}' }, // 0x30\r
78 { SCAN_NULL, '\\', '|' }, // 0x31\r
79 { SCAN_NULL, '\\', '|' }, // 0x32 Keyboard US \ and |\r
80 { SCAN_NULL, ';', ':' }, // 0x33\r
81 { SCAN_NULL, '\'', '"' }, // 0x34\r
82 { SCAN_NULL, '`', '~' }, // 0x35 Keyboard Grave Accent and Tlide\r
83 { SCAN_NULL, ',', '<' }, // 0x36\r
84 { SCAN_NULL, '.', '>' }, // 0x37\r
85 { SCAN_NULL, '/', '?' }, // 0x38\r
86 { SCAN_NULL, 0x00, 0x00 }, // 0x39 CapsLock\r
87 { SCAN_F1, 0x00, 0x00 }, // 0x3A\r
88 { SCAN_F2, 0x00, 0x00 }, // 0x3B\r
89 { SCAN_F3, 0x00, 0x00 }, // 0x3C\r
90 { SCAN_F4, 0x00, 0x00 }, // 0x3D\r
91 { SCAN_F5, 0x00, 0x00 }, // 0x3E\r
92 { SCAN_F6, 0x00, 0x00 }, // 0x3F\r
93 { SCAN_F7, 0x00, 0x00 }, // 0x40\r
94 { SCAN_F8, 0x00, 0x00 }, // 0x41\r
95 { SCAN_F9, 0x00, 0x00 }, // 0x42\r
96 { SCAN_F10, 0x00, 0x00 }, // 0x43\r
66aa04e4 97 { SCAN_F11, 0x00, 0x00 }, // 0x44 F11\r
98 { SCAN_F12, 0x00, 0x00 }, // 0x45 F12\r
ed838d0c 99 { SCAN_NULL, 0x00, 0x00 }, // 0x46 PrintScreen\r
100 { SCAN_NULL, 0x00, 0x00 }, // 0x47 Scroll Lock\r
101 { SCAN_NULL, 0x00, 0x00 }, // 0x48 Pause\r
102 { SCAN_INSERT, 0x00, 0x00 }, // 0x49\r
103 { SCAN_HOME, 0x00, 0x00 }, // 0x4A\r
104 { SCAN_PAGE_UP, 0x00, 0x00 }, // 0x4B\r
105 { SCAN_DELETE, 0x00, 0x00 }, // 0x4C\r
106 { SCAN_END, 0x00, 0x00 }, // 0x4D\r
107 { SCAN_PAGE_DOWN, 0x00, 0x00 }, // 0x4E\r
108 { SCAN_RIGHT, 0x00, 0x00 }, // 0x4F\r
109 { SCAN_LEFT, 0x00, 0x00 }, // 0x50\r
110 { SCAN_DOWN, 0x00, 0x00 }, // 0x51\r
111 { SCAN_UP, 0x00, 0x00 }, // 0x52\r
112 { SCAN_NULL, 0x00, 0x00 }, // 0x53 NumLock\r
113 { SCAN_NULL, '/', '/' }, // 0x54\r
114 { SCAN_NULL, '*', '*' }, // 0x55\r
115 { SCAN_NULL, '-', '-' }, // 0x56\r
116 { SCAN_NULL, '+', '+' }, // 0x57\r
117 { SCAN_NULL, 0x0d, 0x0d }, // 0x58\r
118 { SCAN_END, '1', '1' }, // 0x59\r
119 { SCAN_DOWN, '2', '2' }, // 0x5A\r
120 { SCAN_PAGE_DOWN, '3', '3' }, // 0x5B\r
121 { SCAN_LEFT, '4', '4' }, // 0x5C\r
122 { SCAN_NULL, '5', '5' }, // 0x5D\r
123 { SCAN_RIGHT, '6', '6' }, // 0x5E\r
124 { SCAN_HOME, '7', '7' }, // 0x5F\r
125 { SCAN_UP, '8', '8' }, // 0x60\r
126 { SCAN_PAGE_UP, '9', '9' }, // 0x61\r
127 { SCAN_INSERT, '0', '0' }, // 0x62\r
128 { SCAN_DELETE, '.', '.' }, // 0x63\r
129 { SCAN_NULL, '\\', '|' }, // 0x64 Keyboard Non-US \ and |\r
130 { SCAN_NULL, 0x00, 0x00 }, // 0x65 Keyboard Application\r
131 { SCAN_NULL, 0x00, 0x00 }, // 0x66 Keyboard Power\r
66aa04e4 132 { SCAN_NULL, '=' , '=' }, // 0x67 Keypad =\r
133 { SCAN_F13, 0x00, 0x00 }, // 0x68\r
134 { SCAN_F14, 0x00, 0x00 }, // 0x69\r
135 { SCAN_F15, 0x00, 0x00 }, // 0x6A \r
136 { SCAN_F16, 0x00, 0x00 }, // 0x6B \r
137 { SCAN_F17, 0x00, 0x00 }, // 0x6C\r
138 { SCAN_F18, 0x00, 0x00 }, // 0x6D\r
139 { SCAN_F19, 0x00, 0x00 }, // 0x6E\r
140 { SCAN_F20, 0x00, 0x00 }, // 0x6F\r
141 { SCAN_F21, 0x00, 0x00 }, // 0x70\r
142 { SCAN_F22, 0x00, 0x00 }, // 0x71\r
143 { SCAN_F23, 0x00, 0x00 }, // 0x72\r
144 { SCAN_F24, 0x00, 0x00 }, // 0x73\r
145 { SCAN_MUTE, 0x00, 0x00 }, // 0x7F\r
146 { SCAN_VOLUME_UP, 0x00, 0x00 }, // 0x80\r
147 { SCAN_VOLUME_DOWN, 0x00, 0x00 }, // 0x81\r
ed838d0c 148};\r
149\r
150STATIC KB_MODIFIER KB_Mod[8] = {\r
151 { MOD_CONTROL_L, 0xe0 }, // 11100000\r
152 { MOD_CONTROL_R, 0xe4 }, // 11100100\r
153 { MOD_SHIFT_L, 0xe1 }, // 11100001\r
154 { MOD_SHIFT_R, 0xe5 }, // 11100101\r
155 { MOD_ALT_L, 0xe2 }, // 11100010\r
156 { MOD_ALT_R, 0xe6 }, // 11100110\r
157 { MOD_WIN_L, 0xe3 }, // 11100011\r
66aa04e4 158 { MOD_WIN_R, 0xe7 }, // 11100111 \r
ed838d0c 159};\r
160\r
161\r
162\r
163/**\r
164 Uses USB I/O to check whether the device is a USB Keyboard device.\r
165\r
166 UsbIo: Points to a USB I/O protocol instance.\r
167\r
168\r
169**/\r
170BOOLEAN\r
171IsUSBKeyboard (\r
172 IN EFI_USB_IO_PROTOCOL *UsbIo\r
173 )\r
174{\r
175 EFI_STATUS Status;\r
176 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;\r
177\r
178 //\r
179 // Get the Default interface descriptor, currently we\r
180 // assume it is interface 1\r
181 //\r
182 Status = UsbIo->UsbGetInterfaceDescriptor (\r
183 UsbIo,\r
184 &InterfaceDescriptor\r
185 );\r
186\r
187 if (EFI_ERROR (Status)) {\r
188 return FALSE;\r
189 }\r
190\r
191 if (InterfaceDescriptor.InterfaceClass == CLASS_HID &&\r
192 InterfaceDescriptor.InterfaceSubClass == SUBCLASS_BOOT &&\r
193 InterfaceDescriptor.InterfaceProtocol == PROTOCOL_KEYBOARD\r
194 ) {\r
195\r
196 return TRUE;\r
197 }\r
198\r
199 return FALSE;\r
200}\r
201\r
202\r
203\r
204/**\r
205 Initialize USB Keyboard device and all private data structures.\r
206\r
207 UsbKeyboardDevice The USB_KB_DEV instance.\r
208\r
209 @retval EFI_SUCCESS Success\r
210 @retval EFI_DEVICE_ERROR Hardware Error\r
211\r
212**/\r
213EFI_STATUS\r
214InitUSBKeyboard (\r
215 IN USB_KB_DEV *UsbKeyboardDevice\r
216 )\r
217{\r
218 UINT8 ConfigValue;\r
219 UINT8 Protocol;\r
220 UINT8 ReportId;\r
221 UINT8 Duration;\r
222 EFI_STATUS Status;\r
223 UINT32 TransferResult;\r
ed838d0c 224\r
225 KbdReportStatusCode (\r
226 UsbKeyboardDevice->DevicePath,\r
227 EFI_PROGRESS_CODE,\r
228 PcdGet32 (PcdStatusCodeValueKeyboardSelfTest)\r
229 );\r
230\r
231 InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer));\r
232\r
233 //\r
234 // default configurations\r
235 //\r
236 ConfigValue = 0x01;\r
237\r
238 //\r
239 // Uses default configuration to configure the USB Keyboard device.\r
240 //\r
241 Status = UsbSetConfiguration (\r
242 UsbKeyboardDevice->UsbIo,\r
243 (UINT16) ConfigValue,\r
244 &TransferResult\r
245 );\r
246 if (EFI_ERROR (Status)) {\r
247 //\r
248 // If configuration could not be set here, it means\r
249 // the keyboard interface has some errors and could\r
250 // not be initialized\r
251 //\r
252 KbdReportStatusCode (\r
253 UsbKeyboardDevice->DevicePath,\r
254 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
255 PcdGet32 (PcdStatusCodeValueKeyboardInterfaceError)\r
256 );\r
257\r
258 return EFI_DEVICE_ERROR;\r
259 }\r
260\r
261 UsbGetProtocolRequest (\r
262 UsbKeyboardDevice->UsbIo,\r
263 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,\r
264 &Protocol\r
265 );\r
266 //\r
267 // Sets boot protocol for the USB Keyboard.\r
268 // This driver only supports boot protocol.\r
269 // !!BugBug: How about the device that does not support boot protocol?\r
270 //\r
271 if (Protocol != BOOT_PROTOCOL) {\r
272 UsbSetProtocolRequest (\r
273 UsbKeyboardDevice->UsbIo,\r
274 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,\r
275 BOOT_PROTOCOL\r
276 );\r
277 }\r
278 //\r
279 // the duration is indefinite, so the endpoint will inhibit reporting forever,\r
280 // and only reporting when a change is detected in the report data.\r
281 //\r
282\r
283 //\r
284 // idle value for all report ID\r
285 //\r
286 ReportId = 0;\r
287 //\r
288 // idle forever until there is a key pressed and released.\r
289 //\r
290 Duration = 0;\r
291 UsbSetIdleRequest (\r
292 UsbKeyboardDevice->UsbIo,\r
293 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,\r
294 ReportId,\r
295 Duration\r
296 );\r
297\r
298 UsbKeyboardDevice->CtrlOn = 0;\r
299 UsbKeyboardDevice->AltOn = 0;\r
300 UsbKeyboardDevice->ShiftOn = 0;\r
301 UsbKeyboardDevice->NumLockOn = 0;\r
302 UsbKeyboardDevice->CapsOn = 0;\r
303 UsbKeyboardDevice->ScrollOn = 0;\r
66aa04e4 304 \r
305 UsbKeyboardDevice->LeftCtrlOn = 0;\r
306 UsbKeyboardDevice->LeftAltOn = 0;\r
307 UsbKeyboardDevice->LeftShiftOn = 0; \r
308 UsbKeyboardDevice->LeftLogoOn = 0; \r
309 UsbKeyboardDevice->RightCtrlOn = 0;\r
310 UsbKeyboardDevice->RightAltOn = 0;\r
311 UsbKeyboardDevice->RightShiftOn = 0; \r
312 UsbKeyboardDevice->RightLogoOn = 0; \r
313 UsbKeyboardDevice->MenuKeyOn = 0;\r
314 UsbKeyboardDevice->SysReqOn = 0; \r
ed838d0c 315\r
316 //\r
317 // Sync the initial state of lights\r
318 //\r
319 SetKeyLED (UsbKeyboardDevice);\r
320\r
321 ZeroMem (UsbKeyboardDevice->LastKeyCodeArray, sizeof (UINT8) * 8);\r
322\r
323 //\r
324 // Set a timer for repeat keys' generation.\r
325 //\r
326 if (UsbKeyboardDevice->RepeatTimer) {\r
327 gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);\r
328 UsbKeyboardDevice->RepeatTimer = 0;\r
329 }\r
330\r
331 Status = gBS->CreateEvent (\r
332 EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
333 TPL_NOTIFY,\r
334 USBKeyboardRepeatHandler,\r
335 UsbKeyboardDevice,\r
336 &UsbKeyboardDevice->RepeatTimer\r
337 );\r
338\r
339 if (UsbKeyboardDevice->DelayedRecoveryEvent) {\r
340 gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);\r
341 UsbKeyboardDevice->DelayedRecoveryEvent = 0;\r
342 }\r
343\r
344 Status = gBS->CreateEvent (\r
345 EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
346 TPL_NOTIFY,\r
347 USBKeyboardRecoveryHandler,\r
348 UsbKeyboardDevice,\r
349 &UsbKeyboardDevice->DelayedRecoveryEvent\r
350 );\r
351\r
352 return EFI_SUCCESS;\r
353}\r
354\r
355\r
356/**\r
357 Handler function for USB Keyboard's asynchronous interrupt transfer.\r
358\r
359 Data A pointer to a buffer that is filled with key data which is\r
360 retrieved via asynchronous interrupt transfer.\r
361 DataLength Indicates the size of the data buffer.\r
362 Context Pointing to USB_KB_DEV instance.\r
363 Result Indicates the result of the asynchronous interrupt transfer.\r
364\r
365 @retval EFI_SUCCESS Success\r
366 @retval EFI_DEVICE_ERROR Hardware Error\r
367\r
368**/\r
369EFI_STATUS\r
370EFIAPI\r
371KeyboardHandler (\r
372 IN VOID *Data,\r
373 IN UINTN DataLength,\r
374 IN VOID *Context,\r
375 IN UINT32 Result\r
376 )\r
377{\r
378 USB_KB_DEV *UsbKeyboardDevice;\r
379 EFI_USB_IO_PROTOCOL *UsbIo;\r
380 UINT8 *CurKeyCodeBuffer;\r
381 UINT8 *OldKeyCodeBuffer;\r
382 UINT8 CurModifierMap;\r
383 UINT8 OldModifierMap;\r
384 UINT8 Index;\r
385 UINT8 Index2;\r
386 BOOLEAN Down;\r
ed838d0c 387 BOOLEAN KeyRelease;\r
388 BOOLEAN KeyPress;\r
389 UINT8 SavedTail;\r
390 USB_KEY UsbKey;\r
391 UINT8 NewRepeatKey;\r
392 UINT32 UsbStatus;\r
ed838d0c 393\r
394 ASSERT (Context);\r
395\r
396 NewRepeatKey = 0;\r
ed838d0c 397 UsbKeyboardDevice = (USB_KB_DEV *) Context;\r
398 UsbIo = UsbKeyboardDevice->UsbIo;\r
399\r
400 //\r
401 // Analyzes the Result and performs corresponding action.\r
402 //\r
403 if (Result != EFI_USB_NOERROR) {\r
404 //\r
405 // Some errors happen during the process\r
406 //\r
407 KbdReportStatusCode (\r
408 UsbKeyboardDevice->DevicePath,\r
409 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
410 PcdGet32 (PcdStatusCodeValueKeyboardInputError)\r
411 );\r
412\r
413 //\r
414 // stop the repeat key generation if any\r
415 //\r
416 UsbKeyboardDevice->RepeatKey = 0;\r
417\r
418 gBS->SetTimer (\r
419 UsbKeyboardDevice->RepeatTimer,\r
420 TimerCancel,\r
421 USBKBD_REPEAT_RATE\r
422 );\r
423\r
424 if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {\r
425 UsbClearEndpointHalt (\r
426 UsbIo,\r
427 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,\r
428 &UsbStatus\r
429 );\r
430 }\r
431\r
432 //\r
433 // Delete & Submit this interrupt again\r
434 //\r
435\r
c52fa98c 436 UsbIo->UsbAsyncInterruptTransfer (\r
ed838d0c 437 UsbIo,\r
438 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,\r
439 FALSE,\r
440 0,\r
441 0,\r
442 NULL,\r
443 NULL\r
444 );\r
445\r
446 gBS->SetTimer (\r
447 UsbKeyboardDevice->DelayedRecoveryEvent,\r
448 TimerRelative,\r
449 EFI_USB_INTERRUPT_DELAY\r
450 );\r
451\r
452 return EFI_DEVICE_ERROR;\r
453 }\r
454\r
455 if (DataLength == 0 || Data == NULL) {\r
456 return EFI_SUCCESS;\r
457 }\r
458\r
459 CurKeyCodeBuffer = (UINT8 *) Data;\r
460 OldKeyCodeBuffer = UsbKeyboardDevice->LastKeyCodeArray;\r
461\r
462 //\r
463 // checks for new key stroke.\r
464 // if no new key got, return immediately.\r
465 //\r
466 for (Index = 0; Index < 8; Index++) {\r
467 if (OldKeyCodeBuffer[Index] != CurKeyCodeBuffer[Index]) {\r
468 break;\r
469 }\r
470 }\r
471\r
472 if (Index == 8) {\r
473 return EFI_SUCCESS;\r
474 }\r
475\r
476 //\r
477 // Parse the modifier key\r
478 //\r
479 CurModifierMap = CurKeyCodeBuffer[0];\r
480 OldModifierMap = OldKeyCodeBuffer[0];\r
481\r
482 //\r
483 // handle modifier key's pressing or releasing situation.\r
484 //\r
485 for (Index = 0; Index < 8; Index++) {\r
486\r
487 if ((CurModifierMap & KB_Mod[Index].Mask) != (OldModifierMap & KB_Mod[Index].Mask)) {\r
488 //\r
489 // if current modifier key is up, then\r
490 // CurModifierMap & KB_Mod[Index].Mask = 0;\r
491 // otherwize it is a non-zero value.\r
492 // Inserts the pressed modifier key into key buffer.\r
493 //\r
494 Down = (UINT8) (CurModifierMap & KB_Mod[Index].Mask);\r
495 InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), KB_Mod[Index].Key, Down);\r
496 }\r
497 }\r
498\r
499 //\r
500 // handle normal key's releasing situation\r
501 //\r
502 KeyRelease = FALSE;\r
503 for (Index = 2; Index < 8; Index++) {\r
504\r
505 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index])) {\r
506 continue;\r
507 }\r
508\r
509 KeyRelease = TRUE;\r
510 for (Index2 = 2; Index2 < 8; Index2++) {\r
511\r
512 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index2])) {\r
513 continue;\r
514 }\r
515\r
516 if (OldKeyCodeBuffer[Index] == CurKeyCodeBuffer[Index2]) {\r
517 KeyRelease = FALSE;\r
518 break;\r
519 }\r
520 }\r
521\r
522 if (KeyRelease) {\r
523 InsertKeyCode (\r
524 &(UsbKeyboardDevice->KeyboardBuffer),\r
525 OldKeyCodeBuffer[Index],\r
526 0\r
527 );\r
528 //\r
529 // the original reapeat key is released.\r
530 //\r
531 if (OldKeyCodeBuffer[Index] == UsbKeyboardDevice->RepeatKey) {\r
532 UsbKeyboardDevice->RepeatKey = 0;\r
533 }\r
534 }\r
535 }\r
536\r
537 //\r
538 // original repeat key is released, cancel the repeat timer\r
539 //\r
540 if (UsbKeyboardDevice->RepeatKey == 0) {\r
541 gBS->SetTimer (\r
542 UsbKeyboardDevice->RepeatTimer,\r
543 TimerCancel,\r
544 USBKBD_REPEAT_RATE\r
545 );\r
546 }\r
547\r
548 //\r
549 // handle normal key's pressing situation\r
550 //\r
551 KeyPress = FALSE;\r
552 for (Index = 2; Index < 8; Index++) {\r
553\r
554 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index])) {\r
555 continue;\r
556 }\r
557\r
558 KeyPress = TRUE;\r
559 for (Index2 = 2; Index2 < 8; Index2++) {\r
560\r
561 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index2])) {\r
562 continue;\r
563 }\r
564\r
565 if (CurKeyCodeBuffer[Index] == OldKeyCodeBuffer[Index2]) {\r
566 KeyPress = FALSE;\r
567 break;\r
568 }\r
569 }\r
570\r
571 if (KeyPress) {\r
572 InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), CurKeyCodeBuffer[Index], 1);\r
573 //\r
574 // NumLock pressed or CapsLock pressed\r
575 //\r
576 if (CurKeyCodeBuffer[Index] == 0x53 || CurKeyCodeBuffer[Index] == 0x39) {\r
577 UsbKeyboardDevice->RepeatKey = 0;\r
578 } else {\r
579 NewRepeatKey = CurKeyCodeBuffer[Index];\r
580 //\r
581 // do not repeat the original repeated key\r
582 //\r
583 UsbKeyboardDevice->RepeatKey = 0;\r
584 }\r
585 }\r
586 }\r
587\r
588 //\r
589 // Update LastKeycodeArray[] buffer in the\r
590 // Usb Keyboard Device data structure.\r
591 //\r
592 for (Index = 0; Index < 8; Index++) {\r
593 UsbKeyboardDevice->LastKeyCodeArray[Index] = CurKeyCodeBuffer[Index];\r
594 }\r
595\r
596 //\r
597 // pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence\r
598 // and judge whether it will invoke reset event.\r
599 //\r
600 SavedTail = UsbKeyboardDevice->KeyboardBuffer.bTail;\r
601 Index = UsbKeyboardDevice->KeyboardBuffer.bHead;\r
602 while (Index != SavedTail) {\r
603 RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey);\r
604\r
605 switch (UsbKey.KeyCode) {\r
606\r
607 case 0xe0:\r
608 case 0xe4:\r
609 if (UsbKey.Down) {\r
610 UsbKeyboardDevice->CtrlOn = 1;\r
611 } else {\r
612 UsbKeyboardDevice->CtrlOn = 0;\r
613 }\r
614 break;\r
615\r
616 case 0xe2:\r
617 case 0xe6:\r
618 if (UsbKey.Down) {\r
619 UsbKeyboardDevice->AltOn = 1;\r
620 } else {\r
621 UsbKeyboardDevice->AltOn = 0;\r
622 }\r
623 break;\r
624\r
625 //\r
626 // Del Key Code\r
627 //\r
628 case 0x4c:\r
629 case 0x63:\r
630 if (UsbKey.Down) {\r
631 if (UsbKeyboardDevice->CtrlOn && UsbKeyboardDevice->AltOn) {\r
632 gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
633 }\r
634 }\r
635 break;\r
636\r
637 default:\r
638 break;\r
639 }\r
640\r
641 //\r
642 // insert the key back to the buffer.\r
643 // so the key sequence will not be destroyed.\r
644 //\r
645 InsertKeyCode (\r
646 &(UsbKeyboardDevice->KeyboardBuffer),\r
647 UsbKey.KeyCode,\r
648 UsbKey.Down\r
649 );\r
650 Index = UsbKeyboardDevice->KeyboardBuffer.bHead;\r
651\r
652 }\r
653 //\r
654 // If have new key pressed, update the RepeatKey value, and set the\r
655 // timer to repeate delay timer\r
656 //\r
657 if (NewRepeatKey != 0) {\r
658 //\r
659 // sets trigger time to "Repeat Delay Time",\r
660 // to trigger the repeat timer when the key is hold long\r
661 // enough time.\r
662 //\r
663 gBS->SetTimer (\r
664 UsbKeyboardDevice->RepeatTimer,\r
665 TimerRelative,\r
666 USBKBD_REPEAT_DELAY\r
667 );\r
668 UsbKeyboardDevice->RepeatKey = NewRepeatKey;\r
669 }\r
670\r
671 return EFI_SUCCESS;\r
672}\r
673\r
674\r
675/**\r
676 Retrieves a key character after parsing the raw data in keyboard buffer.\r
677\r
678 UsbKeyboardDevice The USB_KB_DEV instance.\r
679 KeyChar Points to the Key character after key parsing.\r
680\r
681 @retval EFI_SUCCESS Success\r
682 @retval EFI_NOT_READY Device is not ready\r
683\r
684**/\r
685EFI_STATUS\r
686USBParseKey (\r
687 IN OUT USB_KB_DEV *UsbKeyboardDevice,\r
688 OUT UINT8 *KeyChar\r
689 )\r
690{\r
691 USB_KEY UsbKey;\r
692\r
693 *KeyChar = 0;\r
694\r
695 while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice->KeyboardBuffer)) {\r
696 //\r
697 // pops one raw data off.\r
698 //\r
699 RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey);\r
700\r
701 if (!UsbKey.Down) {\r
702 switch (UsbKey.KeyCode) {\r
703\r
66aa04e4 704 //\r
705 // CTRL release\r
706 //\r
ed838d0c 707 case 0xe0:\r
66aa04e4 708 UsbKeyboardDevice->LeftCtrlOn = 0;\r
709 UsbKeyboardDevice->CtrlOn = 0;\r
710 break;\r
ed838d0c 711 case 0xe4:\r
66aa04e4 712 UsbKeyboardDevice->RightCtrlOn = 0;\r
ed838d0c 713 UsbKeyboardDevice->CtrlOn = 0;\r
714 break;\r
715\r
66aa04e4 716 //\r
717 // Shift release\r
718 //\r
ed838d0c 719 case 0xe1:\r
66aa04e4 720 UsbKeyboardDevice->LeftShiftOn = 0;\r
721 UsbKeyboardDevice->ShiftOn = 0;\r
722 break;\r
ed838d0c 723 case 0xe5:\r
66aa04e4 724 UsbKeyboardDevice->RightShiftOn = 0;\r
ed838d0c 725 UsbKeyboardDevice->ShiftOn = 0;\r
726 break;\r
727\r
66aa04e4 728 //\r
729 // Alt release\r
730 //\r
ed838d0c 731 case 0xe2:\r
66aa04e4 732 UsbKeyboardDevice->LeftAltOn = 0;\r
733 UsbKeyboardDevice->AltOn = 0;\r
734 break;\r
ed838d0c 735 case 0xe6:\r
66aa04e4 736 UsbKeyboardDevice->RightAltOn = 0;\r
ed838d0c 737 UsbKeyboardDevice->AltOn = 0;\r
738 break;\r
739\r
66aa04e4 740 //\r
741 // Logo release\r
742 //\r
743 case 0xe3:\r
744 UsbKeyboardDevice->LeftLogoOn = 0;\r
745 break;\r
746 case 0xe7:\r
747 UsbKeyboardDevice->RightLogoOn = 0;\r
748 break;\r
749\r
750 //\r
751 // Menu key (App/Apps) release\r
752 //\r
753 case 0x65:\r
754 UsbKeyboardDevice->MenuKeyOn = 0;\r
755 break;\r
756\r
757 //\r
758 // SysReq release\r
759 //\r
760 case 0x46:\r
761 UsbKeyboardDevice->SysReqOn = 0;\r
762 break;\r
ed838d0c 763 default:\r
764 break;\r
765 }\r
766\r
767 continue;\r
768 }\r
769\r
770 //\r
771 // Analyzes key pressing situation\r
772 //\r
773 switch (UsbKey.KeyCode) {\r
774\r
775 case 0xe0:\r
66aa04e4 776 UsbKeyboardDevice->LeftCtrlOn = 1;\r
777 UsbKeyboardDevice->CtrlOn = 1;\r
778 continue; \r
779 break;\r
ed838d0c 780 case 0xe4:\r
66aa04e4 781 UsbKeyboardDevice->RightCtrlOn = 1;\r
ed838d0c 782 UsbKeyboardDevice->CtrlOn = 1;\r
783 continue;\r
784 break;\r
785\r
66aa04e4 786 //\r
787 // Shift press\r
788 //\r
ed838d0c 789 case 0xe1:\r
66aa04e4 790 UsbKeyboardDevice->LeftShiftOn = 1;\r
791 UsbKeyboardDevice->ShiftOn = 1;\r
792 continue;\r
793 break;\r
ed838d0c 794 case 0xe5:\r
66aa04e4 795 UsbKeyboardDevice->RightShiftOn = 1; \r
ed838d0c 796 UsbKeyboardDevice->ShiftOn = 1;\r
797 continue;\r
798 break;\r
799\r
66aa04e4 800 //\r
801 // Alt press\r
802 //\r
ed838d0c 803 case 0xe2:\r
66aa04e4 804 UsbKeyboardDevice->LeftAltOn = 1;\r
805 UsbKeyboardDevice->AltOn = 1;\r
806 continue;\r
807 break;\r
ed838d0c 808 case 0xe6:\r
66aa04e4 809 UsbKeyboardDevice->RightAltOn = 1; \r
ed838d0c 810 UsbKeyboardDevice->AltOn = 1;\r
811 continue;\r
812 break;\r
813\r
66aa04e4 814 //\r
815 // Logo press\r
816 //\r
ed838d0c 817 case 0xe3:\r
66aa04e4 818 UsbKeyboardDevice->LeftLogoOn = 1;\r
819 continue; \r
820 break;\r
ed838d0c 821 case 0xe7:\r
66aa04e4 822 UsbKeyboardDevice->RightLogoOn = 1;\r
ed838d0c 823 continue;\r
824 break;\r
825\r
ed838d0c 826 //\r
66aa04e4 827 // Menu key (App/Apps) press\r
828 //\r
829 case 0x65:\r
830 UsbKeyboardDevice->MenuKeyOn = 1;\r
831 continue; \r
832 break;\r
833\r
834 //\r
835 // SysReq press\r
ed838d0c 836 //\r
66aa04e4 837 case 0x46:\r
838 UsbKeyboardDevice->SysReqOn = 1;\r
839 continue; \r
840 break;\r
841\r
842 case 0x53:\r
843 UsbKeyboardDevice->NumLockOn ^= 1;\r
844 //\r
845 // Turn on the NumLock light on KB\r
846 //\r
ed838d0c 847 SetKeyLED (UsbKeyboardDevice);\r
848 continue;\r
849 break;\r
850\r
851 case 0x39:\r
852 UsbKeyboardDevice->CapsOn ^= 1;\r
66aa04e4 853 //\r
854 // Turn on the CapsLock light on KB\r
855 //\r
ed838d0c 856 SetKeyLED (UsbKeyboardDevice);\r
857 continue;\r
858 break;\r
859\r
860 case 0x47:\r
861 UsbKeyboardDevice->ScrollOn ^= 1;\r
66aa04e4 862 //\r
863 // Turn on the ScrollLock light on KB\r
864 //\r
ed838d0c 865 SetKeyLED (UsbKeyboardDevice);\r
866 continue;\r
867 break;\r
868\r
869 //\r
870 // PrintScreen,Pause,Application,Power\r
871 // keys are not valid EFI key\r
872 //\r
873\r
ed838d0c 874 //\r
66aa04e4 875 // PrintScreen/SysRq key and Application key\r
876 // Should be handled by UEFI2.1 compliant code\r
877\r
ed838d0c 878 case 0x48:\r
879 //\r
880 // fall through\r
881 //\r
ed838d0c 882 case 0x66:\r
883 //\r
884 // fall through\r
885 //\r
886 continue;\r
887 break;\r
888\r
889 default:\r
890 break;\r
891 }\r
892\r
893 //\r
894 // When encountered Del Key...\r
895 //\r
896 if (UsbKey.KeyCode == 0x4c || UsbKey.KeyCode == 0x63) {\r
897 if (UsbKeyboardDevice->CtrlOn && UsbKeyboardDevice->AltOn) {\r
898 gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
899 }\r
900 }\r
901\r
902 *KeyChar = UsbKey.KeyCode;\r
903 return EFI_SUCCESS;\r
904 }\r
905\r
906 return EFI_NOT_READY;\r
907\r
908}\r
909\r
910\r
911\r
912/**\r
913 Converts USB Keyboard code to EFI Scan Code.\r
914\r
915 UsbKeyboardDevice The USB_KB_DEV instance.\r
916 KeyChar Indicates the key code that will be interpreted.\r
917 Key A pointer to a buffer that is filled in with\r
918 the keystroke information for the key that\r
919 was pressed.\r
920\r
921 @retval EFI_NOT_READY Device is not ready\r
922 @retval EFI_SUCCESS Success\r
923\r
924**/\r
925EFI_STATUS\r
926USBKeyCodeToEFIScanCode (\r
927 IN USB_KB_DEV *UsbKeyboardDevice,\r
928 IN UINT8 KeyChar,\r
929 OUT EFI_INPUT_KEY *Key\r
930 )\r
931{\r
932 UINT8 Index;\r
933\r
934 if (!USBKBD_VALID_KEYCODE (KeyChar)) {\r
935 return EFI_NOT_READY;\r
936 }\r
937\r
938 //\r
939 // valid USB Key Code starts from 4\r
940 //\r
941 Index = (UINT8) (KeyChar - 4);\r
942\r
943 if (Index >= USB_KEYCODE_MAX_MAKE) {\r
944 return EFI_NOT_READY;\r
945 }\r
946\r
66aa04e4 947 //\r
948 // Undefined entries from 0x74 to 0x7E\r
949 //\r
950 if (KeyChar > USB_KEYCODE_MAX_MAKE) {\r
951 Index = (UINT8) (Index - 11);\r
952 }\r
953\r
ed838d0c 954 Key->ScanCode = KeyConvertionTable[Index][0];\r
955\r
956 if (UsbKeyboardDevice->ShiftOn) {\r
957\r
958 Key->UnicodeChar = KeyConvertionTable[Index][2];\r
66aa04e4 959 //\r
960 // Need not return associated shift state if a class of printable characters that\r
961 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'\r
962 //\r
963 if (Key->UnicodeChar >= 'A' && Key->UnicodeChar <= 'Z') {\r
964 UsbKeyboardDevice->LeftShiftOn = 0;\r
965 UsbKeyboardDevice->RightShiftOn = 0;\r
966 }\r
ed838d0c 967\r
968 } else {\r
969\r
970 Key->UnicodeChar = KeyConvertionTable[Index][1];\r
971 }\r
972\r
973 if (UsbKeyboardDevice->CapsOn) {\r
974\r
975 if (Key->UnicodeChar >= 'a' && Key->UnicodeChar <= 'z') {\r
976\r
977 Key->UnicodeChar = KeyConvertionTable[Index][2];\r
978\r
979 } else if (Key->UnicodeChar >= 'A' && Key->UnicodeChar <= 'Z') {\r
980\r
981 Key->UnicodeChar = KeyConvertionTable[Index][1];\r
982\r
983 }\r
984 }\r
1f771698 985 //\r
986 // Translate the CTRL-Alpha characters to their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A)\r
987 //\r
988 if (UsbKeyboardDevice->CtrlOn) {\r
989 if (Key->UnicodeChar >= 'a' && Key->UnicodeChar <= 'z') {\r
990 Key->UnicodeChar = (UINT16) (Key->UnicodeChar - 'a' + 1);\r
991 } else if (Key->UnicodeChar >= 'A' && Key->UnicodeChar <= 'Z') {\r
992 Key->UnicodeChar = (UINT16) (Key->UnicodeChar - 'A' + 1);\r
993 }\r
994 }\r
995 \r
996 \r
ed838d0c 997 if (KeyChar >= 0x59 && KeyChar <= 0x63) {\r
998\r
999 if (UsbKeyboardDevice->NumLockOn && !UsbKeyboardDevice->ShiftOn) {\r
1000\r
1001 Key->ScanCode = SCAN_NULL;\r
1002\r
1003 } else {\r
1004\r
1005 Key->UnicodeChar = 0x00;\r
1006 }\r
1007 }\r
1008\r
1009 if (Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) {\r
1010 return EFI_NOT_READY;\r
1011 }\r
1012\r
66aa04e4 1013\r
1014 //\r
1015 // Save Shift/Toggle state\r
1016 //\r
1017 if (UsbKeyboardDevice->LeftCtrlOn == 1) {\r
1018 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;\r
1019 }\r
1020 if (UsbKeyboardDevice->RightCtrlOn == 1) {\r
1021 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;\r
1022 }\r
1023 if (UsbKeyboardDevice->LeftAltOn == 1) {\r
1024 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED;\r
1025 }\r
1026 if (UsbKeyboardDevice->RightAltOn == 1) {\r
1027 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED;\r
1028 }\r
1029 if (UsbKeyboardDevice->LeftShiftOn == 1) {\r
1030 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;\r
1031 }\r
1032 if (UsbKeyboardDevice->RightShiftOn == 1) {\r
1033 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;\r
1034 }\r
1035 if (UsbKeyboardDevice->LeftLogoOn == 1) {\r
1036 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;\r
1037 }\r
1038 if (UsbKeyboardDevice->RightLogoOn == 1) {\r
1039 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;\r
1040 }\r
1041 if (UsbKeyboardDevice->MenuKeyOn == 1) {\r
1042 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;\r
1043 }\r
1044 if (UsbKeyboardDevice->SysReqOn == 1) {\r
1045 UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;\r
1046 } \r
1047\r
1048 if (UsbKeyboardDevice->ScrollOn == 1) {\r
1049 UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
1050 }\r
1051 if (UsbKeyboardDevice->NumLockOn == 1) {\r
1052 UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;\r
1053 }\r
1054 if (UsbKeyboardDevice->CapsOn == 1) {\r
1055 UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
1056 }\r
1057\r
ed838d0c 1058 return EFI_SUCCESS;\r
1059\r
1060}\r
1061\r
1062\r
1063\r
1064/**\r
1065 Resets USB Keyboard Buffer.\r
1066\r
1067 @param KeyboardBuffer Points to the USB Keyboard Buffer.\r
1068\r
1069 @retval EFI_SUCCESS Success\r
1070\r
1071**/\r
1072EFI_STATUS\r
1073InitUSBKeyBuffer (\r
1074 IN OUT USB_KB_BUFFER *KeyboardBuffer\r
1075 )\r
1076{\r
1077 ZeroMem (KeyboardBuffer, sizeof (USB_KB_BUFFER));\r
1078\r
1079 KeyboardBuffer->bHead = KeyboardBuffer->bTail;\r
1080\r
1081 return EFI_SUCCESS;\r
1082}\r
1083\r
1084\r
1085/**\r
1086 Check whether USB Keyboard buffer is empty.\r
1087\r
1088 @param KeyboardBuffer USB Keyboard Buffer.\r
1089\r
1090\r
1091**/\r
1092BOOLEAN\r
1093IsUSBKeyboardBufferEmpty (\r
1094 IN USB_KB_BUFFER *KeyboardBuffer\r
1095 )\r
1096{\r
1097 //\r
1098 // meet FIFO empty condition\r
1099 //\r
1100 return (BOOLEAN) (KeyboardBuffer->bHead == KeyboardBuffer->bTail);\r
1101}\r
1102\r
1103\r
1104\r
1105/**\r
1106 Check whether USB Keyboard buffer is full.\r
1107\r
1108 @param KeyboardBuffer USB Keyboard Buffer.\r
1109\r
1110\r
1111**/\r
1112BOOLEAN\r
1113IsUSBKeyboardBufferFull (\r
1114 IN USB_KB_BUFFER *KeyboardBuffer\r
1115 )\r
1116{\r
1117 return (BOOLEAN)(((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1)) ==\r
1118 KeyboardBuffer->bHead);\r
1119}\r
1120\r
1121\r
1122\r
1123/**\r
1124 Inserts a key code into keyboard buffer.\r
1125\r
1126 @param KeyboardBuffer Points to the USB Keyboard Buffer.\r
1127 @param Key Key code\r
1128 @param Down Special key\r
1129\r
1130 @retval EFI_SUCCESS Success\r
1131\r
1132**/\r
1133EFI_STATUS\r
1134InsertKeyCode (\r
1135 IN OUT USB_KB_BUFFER *KeyboardBuffer,\r
1136 IN UINT8 Key,\r
1137 IN UINT8 Down\r
1138 )\r
1139{\r
1140 USB_KEY UsbKey;\r
1141\r
1142 //\r
1143 // if keyboard buffer is full, throw the\r
1144 // first key out of the keyboard buffer.\r
1145 //\r
1146 if (IsUSBKeyboardBufferFull (KeyboardBuffer)) {\r
1147 RemoveKeyCode (KeyboardBuffer, &UsbKey);\r
1148 }\r
1149\r
1150 KeyboardBuffer->buffer[KeyboardBuffer->bTail].KeyCode = Key;\r
1151 KeyboardBuffer->buffer[KeyboardBuffer->bTail].Down = Down;\r
1152\r
1153 //\r
1154 // adjust the tail pointer of the FIFO keyboard buffer.\r
1155 //\r
1156 KeyboardBuffer->bTail = (UINT8) ((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1));\r
1157\r
1158 return EFI_SUCCESS;\r
1159}\r
1160\r
1161\r
1162/**\r
1163 Pops a key code off from keyboard buffer.\r
1164\r
1165 @param KeyboardBuffer Points to the USB Keyboard Buffer.\r
1166 @param UsbKey Points to the buffer that contains a usb key code.\r
1167\r
1168 @retval EFI_SUCCESS Success\r
1169 @retval EFI_DEVICE_ERROR Hardware Error\r
1170\r
1171**/\r
1172EFI_STATUS\r
1173RemoveKeyCode (\r
1174 IN OUT USB_KB_BUFFER *KeyboardBuffer,\r
1175 OUT USB_KEY *UsbKey\r
1176 )\r
1177{\r
1178 if (IsUSBKeyboardBufferEmpty (KeyboardBuffer)) {\r
1179 return EFI_DEVICE_ERROR;\r
1180 }\r
1181\r
1182 UsbKey->KeyCode = KeyboardBuffer->buffer[KeyboardBuffer->bHead].KeyCode;\r
1183 UsbKey->Down = KeyboardBuffer->buffer[KeyboardBuffer->bHead].Down;\r
1184\r
1185 //\r
1186 // adjust the head pointer of the FIFO keyboard buffer.\r
1187 //\r
1188 KeyboardBuffer->bHead = (UINT8) ((KeyboardBuffer->bHead + 1) % (MAX_KEY_ALLOWED + 1));\r
1189\r
1190 return EFI_SUCCESS;\r
1191}\r
1192\r
1193\r
1194/**\r
1195 Sets USB Keyboard LED state.\r
1196\r
1197 @param UsbKeyboardDevice The USB_KB_DEV instance.\r
1198\r
1199 @retval EFI_SUCCESS Success\r
1200\r
1201**/\r
1202EFI_STATUS\r
1203SetKeyLED (\r
1204 IN USB_KB_DEV *UsbKeyboardDevice\r
1205 )\r
1206{\r
1207 LED_MAP Led;\r
1208 UINT8 ReportId;\r
1209\r
1210 //\r
1211 // Set each field in Led map.\r
1212 //\r
1213 Led.NumLock = (UINT8) UsbKeyboardDevice->NumLockOn;\r
1214 Led.CapsLock = (UINT8) UsbKeyboardDevice->CapsOn;\r
1215 Led.ScrollLock = (UINT8) UsbKeyboardDevice->ScrollOn;\r
1216 Led.Resrvd = 0;\r
1217\r
1218 ReportId = 0;\r
1219 //\r
1220 // call Set Report Request to lighten the LED.\r
1221 //\r
1222 UsbSetReportRequest (\r
1223 UsbKeyboardDevice->UsbIo,\r
1224 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,\r
1225 ReportId,\r
1226 HID_OUTPUT_REPORT,\r
1227 1,\r
1228 (UINT8 *) &Led\r
1229 );\r
1230\r
1231 return EFI_SUCCESS;\r
1232}\r
1233\r
1234\r
1235/**\r
1236 Timer handler for Repeat Key timer.\r
1237\r
1238 @param Event The Repeat Key event.\r
1239 @param Context Points to the USB_KB_DEV instance.\r
1240\r
1241\r
1242**/\r
1243VOID\r
1244EFIAPI\r
1245USBKeyboardRepeatHandler (\r
1246 IN EFI_EVENT Event,\r
1247 IN VOID *Context\r
1248 )\r
1249{\r
1250 USB_KB_DEV *UsbKeyboardDevice;\r
1251\r
1252 UsbKeyboardDevice = (USB_KB_DEV *) Context;\r
1253\r
1254 //\r
1255 // Do nothing when there is no repeat key.\r
1256 //\r
1257 if (UsbKeyboardDevice->RepeatKey != 0) {\r
1258 //\r
1259 // Inserts one Repeat key into keyboard buffer,\r
1260 //\r
1261 InsertKeyCode (\r
1262 &(UsbKeyboardDevice->KeyboardBuffer),\r
1263 UsbKeyboardDevice->RepeatKey,\r
1264 1\r
1265 );\r
1266\r
1267 //\r
1268 // set repeate rate for repeat key generation.\r
1269 //\r
1270 gBS->SetTimer (\r
1271 UsbKeyboardDevice->RepeatTimer,\r
1272 TimerRelative,\r
1273 USBKBD_REPEAT_RATE\r
1274 );\r
1275\r
1276 }\r
1277}\r
1278\r
1279\r
1280/**\r
1281 Timer handler for Delayed Recovery timer.\r
1282\r
1283 @param Event The Delayed Recovery event.\r
1284 @param Context Points to the USB_KB_DEV instance.\r
1285\r
1286\r
1287**/\r
1288VOID\r
1289EFIAPI\r
1290USBKeyboardRecoveryHandler (\r
1291 IN EFI_EVENT Event,\r
1292 IN VOID *Context\r
1293 )\r
1294{\r
1295\r
1296 USB_KB_DEV *UsbKeyboardDevice;\r
1297 EFI_USB_IO_PROTOCOL *UsbIo;\r
1298 UINT8 PacketSize;\r
1299\r
1300 UsbKeyboardDevice = (USB_KB_DEV *) Context;\r
1301\r
1302 UsbIo = UsbKeyboardDevice->UsbIo;\r
1303\r
1304 PacketSize = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize);\r
1305\r
1306 UsbIo->UsbAsyncInterruptTransfer (\r
1307 UsbIo,\r
1308 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,\r
1309 TRUE,\r
1310 UsbKeyboardDevice->IntEndpointDescriptor.Interval,\r
1311 PacketSize,\r
1312 KeyboardHandler,\r
1313 UsbKeyboardDevice\r
1314 );\r
1315}\r