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
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.
18 Helper functions for USB Keyboard Driver
27 // USB Key Code to Efi key mapping table
28 // Format:<efi scan code>, <unicode without shift>, <unicode with shift>
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 =
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
148 IN EFI_USB_IO_PROTOCOL
*UsbIo
153 Uses USB I/O to check whether the device is a USB Keyboard device.
156 UsbIo: Points to a USB I/O protocol instance.
163 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
166 // Get the Default interface descriptor, currently we
167 // assume it is interface 1
169 Status
= UsbIo
->UsbGetInterfaceDescriptor (
174 if (EFI_ERROR (Status
)) {
178 if (InterfaceDescriptor
.InterfaceClass
== CLASS_HID
&&
179 InterfaceDescriptor
.InterfaceSubClass
== SUBCLASS_BOOT
&&
180 InterfaceDescriptor
.InterfaceProtocol
== PROTOCOL_KEYBOARD
192 IN USB_KB_DEV
*UsbKeyboardDevice
197 Initialize USB Keyboard device and all private data structures.
200 UsbKeyboardDevice The USB_KB_DEV instance.
203 EFI_SUCCESS - Success
204 EFI_DEVICE_ERROR - Hardware Error
212 UINT32 TransferResult
;
213 EFI_USB_IO_PROTOCOL
*UsbIo
;
215 UsbIo
= UsbKeyboardDevice
->UsbIo
;
217 KbdReportStatusCode (
218 UsbKeyboardDevice
->DevicePath
,
220 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_KEYBOARD_PC_SELF_TEST
)
223 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
226 // default configurations
231 // Uses default configuration to configure the USB Keyboard device.
233 Status
= UsbSetDeviceConfiguration (
234 UsbKeyboardDevice
->UsbIo
,
235 (UINT16
) ConfigValue
,
238 if (EFI_ERROR (Status
)) {
240 // If configuration could not be set here, it means
241 // the keyboard interface has some errors and could
242 // not be initialized
244 KbdReportStatusCode (
245 UsbKeyboardDevice
->DevicePath
,
246 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
247 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_INTERFACE_ERROR
)
250 return EFI_DEVICE_ERROR
;
253 UsbGetProtocolRequest (
254 UsbKeyboardDevice
->UsbIo
,
255 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
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?
263 if (Protocol
!= BOOT_PROTOCOL
) {
264 UsbSetProtocolRequest (
265 UsbKeyboardDevice
->UsbIo
,
266 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
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.
276 // idle value for all report ID
280 // idle forever until there is a key pressed and released.
284 UsbKeyboardDevice
->UsbIo
,
285 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
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);
298 // Set a timer for repeat keys' generation.
300 if (UsbKeyboardDevice
->RepeatTimer
) {
301 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
302 UsbKeyboardDevice
->RepeatTimer
= 0;
305 Status
= gBS
->CreateEvent (
306 EFI_EVENT_TIMER
| EFI_EVENT_NOTIFY_SIGNAL
,
308 USBKeyboardRepeatHandler
,
310 &UsbKeyboardDevice
->RepeatTimer
313 if (UsbKeyboardDevice
->DelayedRecoveryEvent
) {
314 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
315 UsbKeyboardDevice
->DelayedRecoveryEvent
= 0;
318 Status
= gBS
->CreateEvent (
319 EFI_EVENT_TIMER
| EFI_EVENT_NOTIFY_SIGNAL
,
321 USBKeyboardRecoveryHandler
,
323 &UsbKeyboardDevice
->DelayedRecoveryEvent
340 Handler function for USB Keyboard's asynchronous interrupt transfer.
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.
350 EFI_SUCCESS - Success
351 EFI_DEVICE_ERROR - Hardware Error
354 USB_KB_DEV
*UsbKeyboardDevice
;
355 EFI_USB_IO_PROTOCOL
*UsbIo
;
356 UINT8
*CurKeyCodeBuffer
;
357 UINT8
*OldKeyCodeBuffer
;
358 UINT8 CurModifierMap
;
359 UINT8 OldModifierMap
;
375 DataPtr
= (UINT8
*) Data
;
376 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
377 UsbIo
= UsbKeyboardDevice
->UsbIo
;
380 // Analyzes the Result and performs corresponding action.
382 if (Result
!= EFI_USB_NOERROR
) {
384 // Some errors happen during the process
386 KbdReportStatusCode (
387 UsbKeyboardDevice
->DevicePath
,
388 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
389 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_INPUT_ERROR
)
393 // stop the repeat key generation if any
395 UsbKeyboardDevice
->RepeatKey
= 0;
398 UsbKeyboardDevice
->RepeatTimer
,
403 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
404 UsbClearEndpointHalt (
406 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
412 // Delete & Submit this interrupt again
415 Status
= UsbIo
->UsbAsyncInterruptTransfer (
417 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
426 UsbKeyboardDevice
->DelayedRecoveryEvent
,
428 EFI_USB_INTERRUPT_DELAY
431 return EFI_DEVICE_ERROR
;
434 if (DataLength
== 0 || Data
== NULL
) {
438 CurKeyCodeBuffer
= (UINT8
*) Data
;
439 OldKeyCodeBuffer
= UsbKeyboardDevice
->LastKeyCodeArray
;
442 // checks for new key stroke.
443 // if no new key got, return immediately.
445 for (Index
= 0; Index
< 8; Index
++) {
446 if (OldKeyCodeBuffer
[Index
] != CurKeyCodeBuffer
[Index
]) {
456 // Parse the modifier key
458 CurModifierMap
= CurKeyCodeBuffer
[0];
459 OldModifierMap
= OldKeyCodeBuffer
[0];
462 // handle modifier key's pressing or releasing situation.
464 for (Index
= 0; Index
< 8; Index
++) {
466 if ((CurModifierMap
& KB_Mod
[Index
].Mask
) != (OldModifierMap
& KB_Mod
[Index
].Mask
)) {
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.
473 Down
= (UINT8
) (CurModifierMap
& KB_Mod
[Index
].Mask
);
474 InsertKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), KB_Mod
[Index
].Key
, Down
);
479 // handle normal key's releasing situation
482 for (Index
= 2; Index
< 8; Index
++) {
484 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index
])) {
489 for (Index2
= 2; Index2
< 8; Index2
++) {
491 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index2
])) {
495 if (OldKeyCodeBuffer
[Index
] == CurKeyCodeBuffer
[Index2
]) {
503 &(UsbKeyboardDevice
->KeyboardBuffer
),
504 OldKeyCodeBuffer
[Index
],
508 // the original reapeat key is released.
510 if (OldKeyCodeBuffer
[Index
] == UsbKeyboardDevice
->RepeatKey
) {
511 UsbKeyboardDevice
->RepeatKey
= 0;
517 // original repeat key is released, cancel the repeat timer
519 if (UsbKeyboardDevice
->RepeatKey
== 0) {
521 UsbKeyboardDevice
->RepeatTimer
,
528 // handle normal key's pressing situation
531 for (Index
= 2; Index
< 8; Index
++) {
533 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index
])) {
538 for (Index2
= 2; Index2
< 8; Index2
++) {
540 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index2
])) {
544 if (CurKeyCodeBuffer
[Index
] == OldKeyCodeBuffer
[Index2
]) {
551 InsertKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), CurKeyCodeBuffer
[Index
], 1);
553 // NumLock pressed or CapsLock pressed
555 if (CurKeyCodeBuffer
[Index
] == 0x53 || CurKeyCodeBuffer
[Index
] == 0x39) {
556 UsbKeyboardDevice
->RepeatKey
= 0;
558 NewRepeatKey
= CurKeyCodeBuffer
[Index
];
560 // do not repeat the original repeated key
562 UsbKeyboardDevice
->RepeatKey
= 0;
568 // Update LastKeycodeArray[] buffer in the
569 // Usb Keyboard Device data structure.
571 for (Index
= 0; Index
< 8; Index
++) {
572 UsbKeyboardDevice
->LastKeyCodeArray
[Index
] = CurKeyCodeBuffer
[Index
];
576 // pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence
577 // and judge whether it will invoke reset event.
579 SavedTail
= UsbKeyboardDevice
->KeyboardBuffer
.bTail
;
580 Index
= UsbKeyboardDevice
->KeyboardBuffer
.bHead
;
581 while (Index
!= SavedTail
) {
582 RemoveKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), &UsbKey
);
584 switch (UsbKey
.KeyCode
) {
589 UsbKeyboardDevice
->CtrlOn
= 1;
591 UsbKeyboardDevice
->CtrlOn
= 0;
598 UsbKeyboardDevice
->AltOn
= 1;
600 UsbKeyboardDevice
->AltOn
= 0;
610 if (UsbKeyboardDevice
->CtrlOn
&& UsbKeyboardDevice
->AltOn
) {
611 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
621 // insert the key back to the buffer.
622 // so the key sequence will not be destroyed.
625 &(UsbKeyboardDevice
->KeyboardBuffer
),
629 Index
= UsbKeyboardDevice
->KeyboardBuffer
.bHead
;
633 // If have new key pressed, update the RepeatKey value, and set the
634 // timer to repeate delay timer
636 if (NewRepeatKey
!= 0) {
638 // sets trigger time to "Repeat Delay Time",
639 // to trigger the repeat timer when the key is hold long
643 UsbKeyboardDevice
->RepeatTimer
,
647 UsbKeyboardDevice
->RepeatKey
= NewRepeatKey
;
655 IN OUT USB_KB_DEV
*UsbKeyboardDevice
,
661 Retrieves a key character after parsing the raw data in keyboard buffer.
664 UsbKeyboardDevice The USB_KB_DEV instance.
665 KeyChar Points to the Key character after key parsing.
668 EFI_SUCCESS - Success
669 EFI_NOT_READY - Device is not ready
676 while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice
->KeyboardBuffer
)) {
678 // pops one raw data off.
680 RemoveKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), &UsbKey
);
683 switch (UsbKey
.KeyCode
) {
687 UsbKeyboardDevice
->CtrlOn
= 0;
692 UsbKeyboardDevice
->ShiftOn
= 0;
697 UsbKeyboardDevice
->AltOn
= 0;
708 // Analyzes key pressing situation
710 switch (UsbKey
.KeyCode
) {
714 UsbKeyboardDevice
->CtrlOn
= 1;
720 UsbKeyboardDevice
->ShiftOn
= 1;
726 UsbKeyboardDevice
->AltOn
= 1;
736 UsbKeyboardDevice
->NumLockOn
^= 1;
737 SetKeyLED (UsbKeyboardDevice
);
742 UsbKeyboardDevice
->CapsOn
^= 1;
743 SetKeyLED (UsbKeyboardDevice
);
748 // F11,F12,PrintScreen,ScrollLock,Pause,Application,Power
749 // keys are not valid EFI key
781 // When encountered Del Key...
783 if (UsbKey
.KeyCode
== 0x4c || UsbKey
.KeyCode
== 0x63) {
784 if (UsbKeyboardDevice
->CtrlOn
&& UsbKeyboardDevice
->AltOn
) {
785 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
789 *KeyChar
= UsbKey
.KeyCode
;
793 return EFI_NOT_READY
;
799 USBKeyCodeToEFIScanCode (
800 IN USB_KB_DEV
*UsbKeyboardDevice
,
802 OUT EFI_INPUT_KEY
*Key
807 Converts USB Keyboard code to EFI Scan Code.
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
816 EFI_NOT_READY - Device is not ready
817 EFI_SUCCESS - Success
822 if (!USBKBD_VALID_KEYCODE (KeyChar
)) {
823 return EFI_NOT_READY
;
827 // valid USB Key Code starts from 4
829 Index
= (UINT8
) (KeyChar
- 4);
831 if (Index
>= USB_KEYCODE_MAX_MAKE
) {
832 return EFI_NOT_READY
;
835 Key
->ScanCode
= KeyConvertionTable
[Index
][0];
837 if (UsbKeyboardDevice
->ShiftOn
) {
839 Key
->UnicodeChar
= KeyConvertionTable
[Index
][2];
843 Key
->UnicodeChar
= KeyConvertionTable
[Index
][1];
846 if (UsbKeyboardDevice
->CapsOn
) {
848 if (Key
->UnicodeChar
>= 'a' && Key
->UnicodeChar
<= 'z') {
850 Key
->UnicodeChar
= KeyConvertionTable
[Index
][2];
852 } else if (Key
->UnicodeChar
>= 'A' && Key
->UnicodeChar
<= 'Z') {
854 Key
->UnicodeChar
= KeyConvertionTable
[Index
][1];
859 if (KeyChar
>= 0x59 && KeyChar
<= 0x63) {
861 if (UsbKeyboardDevice
->NumLockOn
&& !UsbKeyboardDevice
->ShiftOn
) {
863 Key
->ScanCode
= SCAN_NULL
;
867 Key
->UnicodeChar
= 0x00;
871 if (Key
->UnicodeChar
== 0 && Key
->ScanCode
== SCAN_NULL
) {
872 return EFI_NOT_READY
;
882 IN OUT USB_KB_BUFFER
*KeyboardBuffer
887 Resets USB Keyboard Buffer.
890 KeyboardBuffer - Points to the USB Keyboard Buffer.
893 EFI_SUCCESS - Success
896 ZeroMem (KeyboardBuffer
, sizeof (USB_KB_BUFFER
));
898 KeyboardBuffer
->bHead
= KeyboardBuffer
->bTail
;
904 IsUSBKeyboardBufferEmpty (
905 IN USB_KB_BUFFER
*KeyboardBuffer
910 Check whether USB Keyboard buffer is empty.
913 KeyboardBuffer - USB Keyboard Buffer.
920 // meet FIFO empty condition
922 return (BOOLEAN
) (KeyboardBuffer
->bHead
== KeyboardBuffer
->bTail
);
927 IsUSBKeyboardBufferFull (
928 IN USB_KB_BUFFER
*KeyboardBuffer
933 Check whether USB Keyboard buffer is full.
936 KeyboardBuffer - USB Keyboard Buffer.
942 return (BOOLEAN
)(((KeyboardBuffer
->bTail
+ 1) % (MAX_KEY_ALLOWED
+ 1)) ==
943 KeyboardBuffer
->bHead
);
949 IN OUT USB_KB_BUFFER
*KeyboardBuffer
,
956 Inserts a key code into keyboard buffer.
959 KeyboardBuffer - Points to the USB Keyboard Buffer.
963 EFI_SUCCESS - Success
969 // if keyboard buffer is full, throw the
970 // first key out of the keyboard buffer.
972 if (IsUSBKeyboardBufferFull (KeyboardBuffer
)) {
973 RemoveKeyCode (KeyboardBuffer
, &UsbKey
);
976 KeyboardBuffer
->buffer
[KeyboardBuffer
->bTail
].KeyCode
= Key
;
977 KeyboardBuffer
->buffer
[KeyboardBuffer
->bTail
].Down
= Down
;
980 // adjust the tail pointer of the FIFO keyboard buffer.
982 KeyboardBuffer
->bTail
= (UINT8
) ((KeyboardBuffer
->bTail
+ 1) % (MAX_KEY_ALLOWED
+ 1));
989 IN OUT USB_KB_BUFFER
*KeyboardBuffer
,
995 Pops a key code off from keyboard buffer.
998 KeyboardBuffer - Points to the USB Keyboard Buffer.
999 UsbKey - Points to the buffer that contains a usb key code.
1002 EFI_SUCCESS - Success
1003 EFI_DEVICE_ERROR - Hardware Error
1006 if (IsUSBKeyboardBufferEmpty (KeyboardBuffer
)) {
1007 return EFI_DEVICE_ERROR
;
1010 UsbKey
->KeyCode
= KeyboardBuffer
->buffer
[KeyboardBuffer
->bHead
].KeyCode
;
1011 UsbKey
->Down
= KeyboardBuffer
->buffer
[KeyboardBuffer
->bHead
].Down
;
1014 // adjust the head pointer of the FIFO keyboard buffer.
1016 KeyboardBuffer
->bHead
= (UINT8
) ((KeyboardBuffer
->bHead
+ 1) % (MAX_KEY_ALLOWED
+ 1));
1023 IN USB_KB_DEV
*UsbKeyboardDevice
1027 Routine Description:
1028 Sets USB Keyboard LED state.
1031 UsbKeyboardDevice - The USB_KB_DEV instance.
1034 EFI_SUCCESS - Success
1041 // Set each field in Led map.
1043 Led
.NumLock
= (UINT8
) UsbKeyboardDevice
->NumLockOn
;
1044 Led
.CapsLock
= (UINT8
) UsbKeyboardDevice
->CapsOn
;
1049 // call Set Report Request to lighten the LED.
1051 UsbSetReportRequest (
1052 UsbKeyboardDevice
->UsbIo
,
1053 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
1065 USBKeyboardRepeatHandler (
1071 Routine Description:
1072 Timer handler for Repeat Key timer.
1075 Event - The Repeat Key event.
1076 Context - Points to the USB_KB_DEV instance.
1082 USB_KB_DEV
*UsbKeyboardDevice
;
1084 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1087 // Do nothing when there is no repeat key.
1089 if (UsbKeyboardDevice
->RepeatKey
!= 0) {
1091 // Inserts one Repeat key into keyboard buffer,
1094 &(UsbKeyboardDevice
->KeyboardBuffer
),
1095 UsbKeyboardDevice
->RepeatKey
,
1100 // set repeate rate for repeat key generation.
1103 UsbKeyboardDevice
->RepeatTimer
,
1113 USBKeyboardRecoveryHandler (
1119 Routine Description:
1120 Timer handler for Delayed Recovery timer.
1123 Event - The Delayed Recovery event.
1124 Context - Points to the USB_KB_DEV instance.
1131 USB_KB_DEV
*UsbKeyboardDevice
;
1132 EFI_USB_IO_PROTOCOL
*UsbIo
;
1135 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1137 UsbIo
= UsbKeyboardDevice
->UsbIo
;
1139 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
1141 UsbIo
->UsbAsyncInterruptTransfer (
1143 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1145 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,