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