Fix the USB keyboard driver to call hotkey callback even no one is calling ReadKeyStroke

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11563 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
niruiyu 2011-04-19 06:52:20 +00:00
parent f0368006b0
commit c1fd2767c1
4 changed files with 317 additions and 414 deletions

View File

@ -2,7 +2,7 @@
USB Keyboard Driver that manages USB keyboard and produces Simple Text Input USB Keyboard Driver that manages USB keyboard and produces Simple Text Input
Protocol and Simple Text Input Ex Protocol. Protocol and Simple Text Input Ex Protocol.
Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR> Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -262,6 +262,20 @@ USBKeyboardDriverBindingStart (
InitializeListHead (&UsbKeyboardDevice->NotifyList); InitializeListHead (&UsbKeyboardDevice->NotifyList);
Status = gBS->CreateEvent (
EVT_TIMER | EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
USBKeyboardTimerHandler,
UsbKeyboardDevice,
&UsbKeyboardDevice->TimerEvent
);
if (!EFI_ERROR (Status)) {
Status = gBS->SetTimer (UsbKeyboardDevice->TimerEvent, TimerPeriodic, KEYBOARD_TIMER_INTERVAL);
}
if (EFI_ERROR (Status)) {
goto ErrorExit;
}
Status = gBS->CreateEvent ( Status = gBS->CreateEvent (
EVT_NOTIFY_WAIT, EVT_NOTIFY_WAIT,
TPL_NOTIFY, TPL_NOTIFY,
@ -391,6 +405,9 @@ USBKeyboardDriverBindingStart (
// //
ErrorExit: ErrorExit:
if (UsbKeyboardDevice != NULL) { if (UsbKeyboardDevice != NULL) {
if (UsbKeyboardDevice->TimerEvent != NULL) {
gBS->CloseEvent (UsbKeyboardDevice->TimerEvent);
}
if (UsbKeyboardDevice->SimpleInput.WaitForKey != NULL) { if (UsbKeyboardDevice->SimpleInput.WaitForKey != NULL) {
gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey); gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);
} }
@ -513,11 +530,12 @@ USBKeyboardDriverBindingStop (
// //
// Free all resources. // Free all resources.
// //
gBS->CloseEvent (UsbKeyboardDevice->TimerEvent);
gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer); gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);
gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent); gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);
gBS->CloseEvent ((UsbKeyboardDevice->SimpleInput).WaitForKey); gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);
gBS->CloseEvent (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx); gBS->CloseEvent (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx);
KbdFreeNotifyList (&UsbKeyboardDevice->NotifyList); KbdFreeNotifyList (&UsbKeyboardDevice->NotifyList);
ReleaseKeyboardLayoutResources (UsbKeyboardDevice); ReleaseKeyboardLayoutResources (UsbKeyboardDevice);
gBS->CloseEvent (UsbKeyboardDevice->KeyboardLayoutEvent); gBS->CloseEvent (UsbKeyboardDevice->KeyboardLayoutEvent);
@ -526,6 +544,9 @@ USBKeyboardDriverBindingStop (
FreeUnicodeStringTable (UsbKeyboardDevice->ControllerNameTable); FreeUnicodeStringTable (UsbKeyboardDevice->ControllerNameTable);
} }
DestroyQueue (&UsbKeyboardDevice->UsbKeyQueue);
DestroyQueue (&UsbKeyboardDevice->EfiKeyQueue);
FreePool (UsbKeyboardDevice); FreePool (UsbKeyboardDevice);
return Status; return Status;
@ -547,89 +568,20 @@ USBKeyboardDriverBindingStop (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI
USBKeyboardReadKeyStrokeWorker ( USBKeyboardReadKeyStrokeWorker (
IN OUT USB_KB_DEV *UsbKeyboardDevice, IN OUT USB_KB_DEV *UsbKeyboardDevice,
OUT EFI_KEY_DATA *KeyData OUT EFI_KEY_DATA *KeyData
) )
{ {
EFI_STATUS Status;
UINT8 KeyCode;
LIST_ENTRY *Link;
LIST_ENTRY *NotifyList;
KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
EFI_KEY_DATA OriginalKeyData;
if (KeyData == NULL) { if (KeyData == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
// if (IsQueueEmpty (&UsbKeyboardDevice->EfiKeyQueue)) {
// If there is no saved USB keycode, fetch it return EFI_NOT_READY;
// by calling USBKeyboardCheckForKey().
//
if (UsbKeyboardDevice->CurKeyCode == 0) {
Status = USBKeyboardCheckForKey (UsbKeyboardDevice);
if (EFI_ERROR (Status)) {
return EFI_NOT_READY;
}
} }
KeyData->Key.UnicodeChar = 0; Dequeue (&UsbKeyboardDevice->EfiKeyQueue, KeyData, sizeof (*KeyData));
KeyData->Key.ScanCode = SCAN_NULL;
//
// Store the current keycode and clear it.
//
KeyCode = UsbKeyboardDevice->CurKeyCode;
UsbKeyboardDevice->CurKeyCode = 0;
//
// Translate saved USB keycode into EFI_INPUT_KEY
//
Status = UsbKeyCodeToEfiInputKey (UsbKeyboardDevice, KeyCode, &KeyData->Key);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get current state of various toggled attributes as well as input modifier values,
// and set them as valid.
//
CopyMem (&KeyData->KeyState, &UsbKeyboardDevice->KeyState, sizeof (KeyData->KeyState));
UsbKeyboardDevice->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
UsbKeyboardDevice->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
//
// Switch the control value to their original characters.
// In UsbKeyCodeToEfiInputKey() the CTRL-Alpha characters have been switched to
// their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A),
// here switch them back for notification function.
//
CopyMem (&OriginalKeyData, KeyData, sizeof (EFI_KEY_DATA));
if (UsbKeyboardDevice->CtrlOn) {
if (OriginalKeyData.Key.UnicodeChar >= 0x01 && OriginalKeyData.Key.UnicodeChar <= 0x1A) {
if (UsbKeyboardDevice->CapsOn) {
OriginalKeyData.Key.UnicodeChar = (CHAR16)(OriginalKeyData.Key.UnicodeChar + 'A' - 1);
} else {
OriginalKeyData.Key.UnicodeChar = (CHAR16)(OriginalKeyData.Key.UnicodeChar + 'a' - 1);
}
}
}
//
// Invoke notification functions if the key is registered.
//
NotifyList = &UsbKeyboardDevice->NotifyList;
for (Link = GetFirstNode (NotifyList);
!IsNull (NotifyList, Link);
Link = GetNextNode (NotifyList, Link)) {
CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
if (IsKeyRegistered (&CurrentNotify->KeyData, &OriginalKeyData)) {
CurrentNotify->KeyNotificationFn (&OriginalKeyData);
}
}
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -680,8 +632,8 @@ USBKeyboardReset (
// //
// Clear the key buffer of this USB keyboard // Clear the key buffer of this USB keyboard
// //
InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer)); InitQueue (&UsbKeyboardDevice->UsbKeyQueue, sizeof (USB_KEY));
UsbKeyboardDevice->CurKeyCode = 0; InitQueue (&UsbKeyboardDevice->EfiKeyQueue, sizeof (EFI_KEY_DATA));
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -690,7 +642,6 @@ USBKeyboardReset (
// Exhaustive reset // Exhaustive reset
// //
Status = InitUSBKeyboard (UsbKeyboardDevice); Status = InitUSBKeyboard (UsbKeyboardDevice);
UsbKeyboardDevice->CurKeyCode = 0;
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
@ -755,50 +706,55 @@ USBKeyboardWaitForKey (
UsbKeyboardDevice = (USB_KB_DEV *) Context; UsbKeyboardDevice = (USB_KB_DEV *) Context;
if (UsbKeyboardDevice->CurKeyCode == 0) { if (!IsQueueEmpty (&UsbKeyboardDevice->EfiKeyQueue)) {
if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice))) { //
// // If there is pending key, signal the event.
// If no pending key, simply return. //
// gBS->SignalEvent (Event);
return ;
}
} }
//
// If there is pending key, signal the event.
//
gBS->SignalEvent (Event);
} }
/** /**
Check whether there is key pending in the keyboard buffer. Timer handler to convert the key from USB.
@param UsbKeyboardDevice The USB_KB_DEV instance.
@retval EFI_SUCCESS There is pending key to read.
@retval EFI_NOT_READY No pending key to read.
@param Event Indicates the event that invoke this function.
@param Context Indicates the calling context.
**/ **/
EFI_STATUS VOID
EFIAPI EFIAPI
USBKeyboardCheckForKey ( USBKeyboardTimerHandler (
IN OUT USB_KB_DEV *UsbKeyboardDevice IN EFI_EVENT Event,
IN VOID *Context
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINT8 KeyCode; USB_KB_DEV *UsbKeyboardDevice;
UINT8 KeyCode;
EFI_KEY_DATA KeyData;
UsbKeyboardDevice = (USB_KB_DEV *) Context;
// //
// Fetch raw data from the USB keyboard buffer, // Fetch raw data from the USB keyboard buffer,
// and translate it into USB keycode. // and translate it into USB keycode.
// //
Status = USBParseKey (UsbKeyboardDevice, &KeyCode); Status = USBParseKey (UsbKeyboardDevice, &KeyCode);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_NOT_READY; return ;
} }
UsbKeyboardDevice->CurKeyCode = KeyCode; //
return EFI_SUCCESS; // Translate saved USB keycode into EFI_INPUT_KEY
//
Status = UsbKeyCodeToEfiInputKey (UsbKeyboardDevice, KeyCode, &KeyData);
if (EFI_ERROR (Status)) {
return ;
}
//
// Insert to the EFI Key queue
//
Enqueue (&UsbKeyboardDevice->EfiKeyQueue, &KeyData, sizeof (KeyData));
} }
/** /**
@ -811,7 +767,6 @@ USBKeyboardCheckForKey (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI
KbdFreeNotifyList ( KbdFreeNotifyList (
IN OUT LIST_ENTRY *NotifyList IN OUT LIST_ENTRY *NotifyList
) )
@ -843,7 +798,6 @@ KbdFreeNotifyList (
**/ **/
BOOLEAN BOOLEAN
EFIAPI
IsKeyRegistered ( IsKeyRegistered (
IN EFI_KEY_DATA *RegsiteredData, IN EFI_KEY_DATA *RegsiteredData,
IN EFI_KEY_DATA *InputData IN EFI_KEY_DATA *InputData
@ -905,8 +859,6 @@ USBKeyboardResetEx (
{ {
EFI_STATUS Status; EFI_STATUS Status;
USB_KB_DEV *UsbKeyboardDevice; USB_KB_DEV *UsbKeyboardDevice;
EFI_TPL OldTpl;
UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This); UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);
@ -915,11 +867,6 @@ USBKeyboardResetEx (
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
UsbKeyboardDevice->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
UsbKeyboardDevice->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
gBS->RestoreTPL (OldTpl);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -986,8 +933,7 @@ USBKeyboardSetState (
UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This); UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);
if (((UsbKeyboardDevice->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) || if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) {
((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID)) {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@ -1011,8 +957,6 @@ USBKeyboardSetState (
SetKeyLED (UsbKeyboardDevice); SetKeyLED (UsbKeyboardDevice);
UsbKeyboardDevice->KeyState.KeyToggleState = *KeyToggleState;
return EFI_SUCCESS; return EFI_SUCCESS;
} }

View File

@ -1,7 +1,7 @@
/** @file /** @file
Header file for USB Keyboard Driver's Data Structures. Header file for USB Keyboard Driver's Data Structures.
Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR> Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -39,6 +39,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <IndustryStandard/Usb.h> #include <IndustryStandard/Usb.h>
#define KEYBOARD_TIMER_INTERVAL 200000 // 0.02s
#define MAX_KEY_ALLOWED 32 #define MAX_KEY_ALLOWED 32
#define HZ 1000 * 1000 * 10 #define HZ 1000 * 1000 * 10
@ -58,10 +60,11 @@ typedef struct {
} USB_KEY; } USB_KEY;
typedef struct { typedef struct {
USB_KEY Buffer[MAX_KEY_ALLOWED + 1]; VOID *Buffer[MAX_KEY_ALLOWED + 1];
UINT8 BufferHead; UINTN Head;
UINT8 BufferTail; UINTN Tail;
} USB_KB_BUFFER; UINTN ItemSize;
} USB_SIMPLE_QUEUE;
#define USB_KB_DEV_SIGNATURE SIGNATURE_32 ('u', 'k', 'b', 'd') #define USB_KB_DEV_SIGNATURE SIGNATURE_32 ('u', 'k', 'b', 'd')
#define USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('u', 'k', 'b', 'x') #define USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('u', 'k', 'b', 'x')
@ -109,7 +112,8 @@ typedef struct {
EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor; EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
EFI_USB_ENDPOINT_DESCRIPTOR IntEndpointDescriptor; EFI_USB_ENDPOINT_DESCRIPTOR IntEndpointDescriptor;
USB_KB_BUFFER KeyboardBuffer; USB_SIMPLE_QUEUE UsbKeyQueue;
USB_SIMPLE_QUEUE EfiKeyQueue;
BOOLEAN CtrlOn; BOOLEAN CtrlOn;
BOOLEAN AltOn; BOOLEAN AltOn;
BOOLEAN ShiftOn; BOOLEAN ShiftOn;
@ -119,6 +123,8 @@ typedef struct {
UINT8 LastKeyCodeArray[8]; UINT8 LastKeyCodeArray[8];
UINT8 CurKeyCode; UINT8 CurKeyCode;
EFI_EVENT TimerEvent;
UINT8 RepeatKey; UINT8 RepeatKey;
EFI_EVENT RepeatTimer; EFI_EVENT RepeatTimer;
@ -135,8 +141,6 @@ typedef struct {
BOOLEAN MenuKeyOn; BOOLEAN MenuKeyOn;
BOOLEAN SysReqOn; BOOLEAN SysReqOn;
BOOLEAN AltGrOn; BOOLEAN AltGrOn;
EFI_KEY_STATE KeyState;
// //
// Notification function list // Notification function list
// //
@ -555,26 +559,10 @@ USBKeyboardWaitForKey (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI
KbdFreeNotifyList ( KbdFreeNotifyList (
IN OUT LIST_ENTRY *NotifyList IN OUT LIST_ENTRY *NotifyList
); );
/**
Check whether there is key pending in the keyboard buffer.
@param UsbKeyboardDevice The USB_KB_DEV instance.
@retval EFI_SUCCESS There is pending key to read.
@retval EFI_NOT_READY No pending key to read.
**/
EFI_STATUS
EFIAPI
USBKeyboardCheckForKey (
IN OUT USB_KB_DEV *UsbKeyboardDevice
);
/** /**
Check whether the pressed key matches a registered key or not. Check whether the pressed key matches a registered key or not.
@ -586,11 +574,23 @@ USBKeyboardCheckForKey (
**/ **/
BOOLEAN BOOLEAN
EFIAPI
IsKeyRegistered ( IsKeyRegistered (
IN EFI_KEY_DATA *RegsiteredData, IN EFI_KEY_DATA *RegsiteredData,
IN EFI_KEY_DATA *InputData IN EFI_KEY_DATA *InputData
); );
/**
Timer handler to convert the key from USB.
@param Event Indicates the event that invoke this function.
@param Context Indicates the calling context.
**/
VOID
EFIAPI
USBKeyboardTimerHandler (
IN EFI_EVENT Event,
IN VOID *Context
);
#endif #endif

View File

@ -1,7 +1,7 @@
/** @file /** @file
Helper functions for USB Keyboard Driver. Helper functions for USB Keyboard Driver.
Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR> Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -310,7 +310,6 @@ UINT8 ModifierValueToEfiScanCodeConvertionTable[] = {
@retval Others Failure to install default keyboard layout. @retval Others Failure to install default keyboard layout.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI
InstallDefaultKeyboardLayout ( InstallDefaultKeyboardLayout (
IN OUT USB_KB_DEV *UsbKeyboardDevice IN OUT USB_KB_DEV *UsbKeyboardDevice
) )
@ -363,7 +362,6 @@ InstallDefaultKeyboardLayout (
**/ **/
BOOLEAN BOOLEAN
EFIAPI
IsUSBKeyboard ( IsUSBKeyboard (
IN EFI_USB_IO_PROTOCOL *UsbIo IN EFI_USB_IO_PROTOCOL *UsbIo
) )
@ -401,7 +399,6 @@ IsUSBKeyboard (
**/ **/
EFI_HII_KEYBOARD_LAYOUT * EFI_HII_KEYBOARD_LAYOUT *
EFIAPI
GetCurrentKeyboardLayout ( GetCurrentKeyboardLayout (
VOID VOID
) )
@ -464,7 +461,6 @@ GetCurrentKeyboardLayout (
**/ **/
EFI_KEY_DESCRIPTOR * EFI_KEY_DESCRIPTOR *
EFIAPI
GetKeyDescriptor ( GetKeyDescriptor (
IN USB_KB_DEV *UsbKeyboardDevice, IN USB_KB_DEV *UsbKeyboardDevice,
IN UINT8 KeyCode IN UINT8 KeyCode
@ -502,7 +498,6 @@ GetKeyDescriptor (
**/ **/
USB_NS_KEY * USB_NS_KEY *
EFIAPI
FindUsbNsKey ( FindUsbNsKey (
IN USB_KB_DEV *UsbKeyboardDevice, IN USB_KB_DEV *UsbKeyboardDevice,
IN EFI_KEY_DESCRIPTOR *KeyDescriptor IN EFI_KEY_DESCRIPTOR *KeyDescriptor
@ -543,7 +538,6 @@ FindUsbNsKey (
**/ **/
EFI_KEY_DESCRIPTOR * EFI_KEY_DESCRIPTOR *
EFIAPI
FindPhysicalKey ( FindPhysicalKey (
IN USB_NS_KEY *UsbNsKey, IN USB_NS_KEY *UsbNsKey,
IN EFI_KEY_DESCRIPTOR *KeyDescriptor IN EFI_KEY_DESCRIPTOR *KeyDescriptor
@ -646,7 +640,7 @@ SetKeyboardLayoutEvent (
// //
KeyCount = 0; KeyCount = 0;
NsKey = KeyDescriptor + 1; NsKey = KeyDescriptor + 1;
for (Index2 = Index + 1; Index2 < KeyboardLayout->DescriptorCount; Index2++) { for (Index2 = (UINT8) Index + 1; Index2 < KeyboardLayout->DescriptorCount; Index2++) {
CopyMem (&TempKey, NsKey, sizeof (EFI_KEY_DESCRIPTOR)); CopyMem (&TempKey, NsKey, sizeof (EFI_KEY_DESCRIPTOR));
if (TempKey.Modifier == EFI_NS_KEY_DEPENDENCY_MODIFIER) { if (TempKey.Modifier == EFI_NS_KEY_DEPENDENCY_MODIFIER) {
KeyCount++; KeyCount++;
@ -691,7 +685,6 @@ SetKeyboardLayoutEvent (
**/ **/
VOID VOID
EFIAPI
ReleaseKeyboardLayoutResources ( ReleaseKeyboardLayoutResources (
IN OUT USB_KB_DEV *UsbKeyboardDevice IN OUT USB_KB_DEV *UsbKeyboardDevice
) )
@ -730,7 +723,6 @@ ReleaseKeyboardLayoutResources (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI
InitKeyboardLayout ( InitKeyboardLayout (
OUT USB_KB_DEV *UsbKeyboardDevice OUT USB_KB_DEV *UsbKeyboardDevice
) )
@ -797,7 +789,6 @@ InitKeyboardLayout (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI
InitUSBKeyboard ( InitUSBKeyboard (
IN OUT USB_KB_DEV *UsbKeyboardDevice IN OUT USB_KB_DEV *UsbKeyboardDevice
) )
@ -815,7 +806,8 @@ InitUSBKeyboard (
UsbKeyboardDevice->DevicePath UsbKeyboardDevice->DevicePath
); );
InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer)); InitQueue (&UsbKeyboardDevice->UsbKeyQueue, sizeof (USB_KEY));
InitQueue (&UsbKeyboardDevice->EfiKeyQueue, sizeof (EFI_KEY_DATA));
// //
// Use the config out of the descriptor // Use the config out of the descriptor
@ -986,12 +978,10 @@ KeyboardHandler (
UINT8 CurModifierMap; UINT8 CurModifierMap;
UINT8 OldModifierMap; UINT8 OldModifierMap;
UINT8 Mask; UINT8 Mask;
UINT8 Index; UINTN Index;
UINT8 Index2; UINT8 Index2;
BOOLEAN Down;
BOOLEAN KeyRelease; BOOLEAN KeyRelease;
BOOLEAN KeyPress; BOOLEAN KeyPress;
UINT8 SavedTail;
USB_KEY UsbKey; USB_KEY UsbKey;
UINT8 NewRepeatKey; UINT8 NewRepeatKey;
UINT32 UsbStatus; UINT32 UsbStatus;
@ -1119,8 +1109,9 @@ KeyboardHandler (
// otherwise it is a non-zero value. // otherwise it is a non-zero value.
// Insert the changed modifier key into key buffer. // Insert the changed modifier key into key buffer.
// //
Down = (BOOLEAN) ((CurModifierMap & Mask) != 0); UsbKey.KeyCode = (UINT8) (0xe0 + Index);
InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), (UINT8) (0xe0 + Index), Down); UsbKey.Down = (BOOLEAN) ((CurModifierMap & Mask) != 0);
Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));
} }
} }
@ -1152,11 +1143,9 @@ KeyboardHandler (
} }
if (KeyRelease) { if (KeyRelease) {
InsertKeyCode ( UsbKey.KeyCode = OldKeyCodeBuffer[Index];
&(UsbKeyboardDevice->KeyboardBuffer), UsbKey.Down = FALSE;
OldKeyCodeBuffer[Index], Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));
FALSE
);
// //
// The original repeat key is released. // The original repeat key is released.
// //
@ -1204,7 +1193,9 @@ KeyboardHandler (
} }
if (KeyPress) { if (KeyPress) {
InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), CurKeyCodeBuffer[Index], TRUE); UsbKey.KeyCode = CurKeyCodeBuffer[Index];
UsbKey.Down = TRUE;
Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));
// //
// Handle repeat key // Handle repeat key
@ -1234,72 +1225,6 @@ KeyboardHandler (
UsbKeyboardDevice->LastKeyCodeArray[Index] = CurKeyCodeBuffer[Index]; UsbKeyboardDevice->LastKeyCodeArray[Index] = CurKeyCodeBuffer[Index];
} }
//
// Pre-process KeyboardBuffer to check if Ctrl + Alt + Del is pressed.
//
SavedTail = UsbKeyboardDevice->KeyboardBuffer.BufferTail;
Index = UsbKeyboardDevice->KeyboardBuffer.BufferHead;
while (Index != SavedTail) {
RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey);
KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode);
ASSERT (KeyDescriptor != NULL);
switch (KeyDescriptor->Modifier) {
case EFI_LEFT_CONTROL_MODIFIER:
case EFI_RIGHT_CONTROL_MODIFIER:
if (UsbKey.Down) {
UsbKeyboardDevice->CtrlOn = TRUE;
} else {
UsbKeyboardDevice->CtrlOn = FALSE;
}
break;
case EFI_LEFT_ALT_MODIFIER:
case EFI_RIGHT_ALT_MODIFIER:
if (UsbKey.Down) {
UsbKeyboardDevice->AltOn = TRUE;
} else {
UsbKeyboardDevice->AltOn = FALSE;
}
break;
case EFI_ALT_GR_MODIFIER:
if (UsbKey.Down) {
UsbKeyboardDevice->AltGrOn = TRUE;
} else {
UsbKeyboardDevice->AltGrOn = FALSE;
}
break;
//
// For Del Key, check if Ctrl + Alt + Del occurs for reset.
//
case EFI_DELETE_MODIFIER:
if (UsbKey.Down) {
if ((UsbKeyboardDevice->CtrlOn) && (UsbKeyboardDevice->AltOn)) {
gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
}
}
break;
default:
break;
}
//
// Insert the key back to the buffer,
// so the key sequence will not be destroyed.
//
InsertKeyCode (
&(UsbKeyboardDevice->KeyboardBuffer),
UsbKey.KeyCode,
UsbKey.Down
);
Index = UsbKeyboardDevice->KeyboardBuffer.BufferHead;
}
// //
// If there is new key pressed, update the RepeatKey value, and set the // If there is new key pressed, update the RepeatKey value, and set the
// timer to repeate delay timer // timer to repeate delay timer
@ -1336,7 +1261,6 @@ KeyboardHandler (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI
USBParseKey ( USBParseKey (
IN OUT USB_KB_DEV *UsbKeyboardDevice, IN OUT USB_KB_DEV *UsbKeyboardDevice,
OUT UINT8 *KeyCode OUT UINT8 *KeyCode
@ -1347,11 +1271,11 @@ USBParseKey (
*KeyCode = 0; *KeyCode = 0;
while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice->KeyboardBuffer)) { while (!IsQueueEmpty (&UsbKeyboardDevice->UsbKeyQueue)) {
// //
// Pops one raw data off. // Pops one raw data off.
// //
RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey); Dequeue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));
KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode); KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode);
ASSERT (KeyDescriptor != NULL); ASSERT (KeyDescriptor != NULL);
@ -1589,7 +1513,7 @@ USBParseKey (
@param UsbKeyboardDevice The USB_KB_DEV instance. @param UsbKeyboardDevice The USB_KB_DEV instance.
@param KeyCode Indicates the key code that will be interpreted. @param KeyCode Indicates the key code that will be interpreted.
@param Key A pointer to a buffer that is filled in with @param KeyData A pointer to a buffer that is filled in with
the keystroke information for the key that the keystroke information for the key that
was pressed. was pressed.
@ -1601,14 +1525,16 @@ USBParseKey (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI
UsbKeyCodeToEfiInputKey ( UsbKeyCodeToEfiInputKey (
IN USB_KB_DEV *UsbKeyboardDevice, IN USB_KB_DEV *UsbKeyboardDevice,
IN UINT8 KeyCode, IN UINT8 KeyCode,
OUT EFI_INPUT_KEY *Key OUT EFI_KEY_DATA *KeyData
) )
{ {
EFI_KEY_DESCRIPTOR *KeyDescriptor; EFI_KEY_DESCRIPTOR *KeyDescriptor;
LIST_ENTRY *Link;
LIST_ENTRY *NotifyList;
KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
// //
// KeyCode must in the range of 0x4 to 0x65 // KeyCode must in the range of 0x4 to 0x65
@ -1647,12 +1573,12 @@ UsbKeyCodeToEfiInputKey (
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
Key->ScanCode = ModifierValueToEfiScanCodeConvertionTable[KeyDescriptor->Modifier]; KeyData->Key.ScanCode = ModifierValueToEfiScanCodeConvertionTable[KeyDescriptor->Modifier];
Key->UnicodeChar = KeyDescriptor->Unicode; KeyData->Key.UnicodeChar = KeyDescriptor->Unicode;
if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_STANDARD_SHIFT)!= 0) { if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_STANDARD_SHIFT)!= 0) {
if (UsbKeyboardDevice->ShiftOn) { if (UsbKeyboardDevice->ShiftOn) {
Key->UnicodeChar = KeyDescriptor->ShiftedUnicode; KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedUnicode;
// //
// Need not return associated shift state if a class of printable characters that // Need not return associated shift state if a class of printable characters that
@ -1664,42 +1590,30 @@ UsbKeyCodeToEfiInputKey (
} }
if (UsbKeyboardDevice->AltGrOn) { if (UsbKeyboardDevice->AltGrOn) {
Key->UnicodeChar = KeyDescriptor->ShiftedAltGrUnicode; KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedAltGrUnicode;
} }
} else { } else {
// //
// Shift off // Shift off
// //
Key->UnicodeChar = KeyDescriptor->Unicode; KeyData->Key.UnicodeChar = KeyDescriptor->Unicode;
if (UsbKeyboardDevice->AltGrOn) { if (UsbKeyboardDevice->AltGrOn) {
Key->UnicodeChar = KeyDescriptor->AltGrUnicode; KeyData->Key.UnicodeChar = KeyDescriptor->AltGrUnicode;
} }
} }
} }
if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) != 0) { if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) != 0) {
if (UsbKeyboardDevice->CapsOn) { if (UsbKeyboardDevice->CapsOn) {
if (Key->UnicodeChar == KeyDescriptor->Unicode) { if (KeyData->Key.UnicodeChar == KeyDescriptor->Unicode) {
Key->UnicodeChar = KeyDescriptor->ShiftedUnicode; KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedUnicode;
} else if (Key->UnicodeChar == KeyDescriptor->ShiftedUnicode) { } else if (KeyData->Key.UnicodeChar == KeyDescriptor->ShiftedUnicode) {
Key->UnicodeChar = KeyDescriptor->Unicode; KeyData->Key.UnicodeChar = KeyDescriptor->Unicode;
} }
} }
} }
//
// Translate the CTRL-Alpha characters to their corresponding control value
// (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
//
if (UsbKeyboardDevice->CtrlOn) {
if (Key->UnicodeChar >= 'a' && Key->UnicodeChar <= 'z') {
Key->UnicodeChar = (UINT8) (Key->UnicodeChar - 'a' + 1);
} else if (Key->UnicodeChar >= 'A' && Key->UnicodeChar <= 'Z') {
Key->UnicodeChar = (UINT8) (Key->UnicodeChar - 'A' + 1);
}
}
if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_NUM_LOCK) != 0) { if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_NUM_LOCK) != 0) {
// //
// For key affected by NumLock, if NumLock is on and Shift is not pressed, then it means // For key affected by NumLock, if NumLock is on and Shift is not pressed, then it means
@ -1707,205 +1621,247 @@ UsbKeyCodeToEfiInputKey (
// Otherwise, it means control key, so preserve the EFI Scan Code and clear the unicode keycode. // Otherwise, it means control key, so preserve the EFI Scan Code and clear the unicode keycode.
// //
if ((UsbKeyboardDevice->NumLockOn) && (!(UsbKeyboardDevice->ShiftOn))) { if ((UsbKeyboardDevice->NumLockOn) && (!(UsbKeyboardDevice->ShiftOn))) {
Key->ScanCode = SCAN_NULL; KeyData->Key.ScanCode = SCAN_NULL;
} else { } else {
Key->UnicodeChar = 0x00; KeyData->Key.UnicodeChar = 0x00;
} }
} }
// //
// Translate Unicode 0x1B (ESC) to EFI Scan Code // Translate Unicode 0x1B (ESC) to EFI Scan Code
// //
if (Key->UnicodeChar == 0x1B && Key->ScanCode == SCAN_NULL) { if (KeyData->Key.UnicodeChar == 0x1B && KeyData->Key.ScanCode == SCAN_NULL) {
Key->ScanCode = SCAN_ESC; KeyData->Key.ScanCode = SCAN_ESC;
Key->UnicodeChar = 0x00; KeyData->Key.UnicodeChar = 0x00;
} }
// //
// Not valid for key without both unicode key code and EFI Scan Code. // Not valid for key without both unicode key code and EFI Scan Code.
// //
if (Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) { if (KeyData->Key.UnicodeChar == 0 && KeyData->Key.ScanCode == SCAN_NULL) {
return EFI_NOT_READY; return EFI_NOT_READY;
} }
// //
// Save Shift/Toggle state // Save Shift/Toggle state
// //
KeyData->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
KeyData->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
if (UsbKeyboardDevice->LeftCtrlOn) { if (UsbKeyboardDevice->LeftCtrlOn) {
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED; KeyData->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;
} }
if (UsbKeyboardDevice->RightCtrlOn) { if (UsbKeyboardDevice->RightCtrlOn) {
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED; KeyData->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;
} }
if (UsbKeyboardDevice->LeftAltOn) { if (UsbKeyboardDevice->LeftAltOn) {
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED; KeyData->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED;
} }
if (UsbKeyboardDevice->RightAltOn) { if (UsbKeyboardDevice->RightAltOn) {
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED; KeyData->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED;
} }
if (UsbKeyboardDevice->LeftShiftOn) { if (UsbKeyboardDevice->LeftShiftOn) {
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED; KeyData->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
} }
if (UsbKeyboardDevice->RightShiftOn) { if (UsbKeyboardDevice->RightShiftOn) {
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED; KeyData->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
} }
if (UsbKeyboardDevice->LeftLogoOn) { if (UsbKeyboardDevice->LeftLogoOn) {
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED; KeyData->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;
} }
if (UsbKeyboardDevice->RightLogoOn) { if (UsbKeyboardDevice->RightLogoOn) {
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED; KeyData->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;
} }
if (UsbKeyboardDevice->MenuKeyOn) { if (UsbKeyboardDevice->MenuKeyOn) {
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED; KeyData->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;
} }
if (UsbKeyboardDevice->SysReqOn) { if (UsbKeyboardDevice->SysReqOn) {
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED; KeyData->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;
} }
if (UsbKeyboardDevice->ScrollOn) { if (UsbKeyboardDevice->ScrollOn) {
UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE; KeyData->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;
} }
if (UsbKeyboardDevice->NumLockOn) { if (UsbKeyboardDevice->NumLockOn) {
UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE; KeyData->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
} }
if (UsbKeyboardDevice->CapsOn) { if (UsbKeyboardDevice->CapsOn) {
UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE; KeyData->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
}
//
// Invoke notification functions if the key is registered.
//
NotifyList = &UsbKeyboardDevice->NotifyList;
for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {
CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
CurrentNotify->KeyNotificationFn (KeyData);
}
}
//
// Translate the CTRL-Alpha characters to their corresponding control value
// (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
//
if (UsbKeyboardDevice->CtrlOn) {
if (KeyData->Key.UnicodeChar >= 'a' && KeyData->Key.UnicodeChar <= 'z') {
KeyData->Key.UnicodeChar = (UINT8) (KeyData->Key.UnicodeChar - 'a' + 1);
} else if (KeyData->Key.UnicodeChar >= 'A' && KeyData->Key.UnicodeChar <= 'Z') {
KeyData->Key.UnicodeChar = (UINT8) (KeyData->Key.UnicodeChar - 'A' + 1);
}
} }
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/** /**
Resets USB keyboard buffer. Create the queue.
@param KeyboardBuffer Points to the USB keyboard buffer. @param Queue Points to the queue.
@param ItemSize Size of the single item.
**/ **/
VOID VOID
EFIAPI InitQueue (
InitUSBKeyBuffer ( IN OUT USB_SIMPLE_QUEUE *Queue,
OUT USB_KB_BUFFER *KeyboardBuffer IN UINTN ItemSize
) )
{ {
ZeroMem (KeyboardBuffer, sizeof (USB_KB_BUFFER)); UINTN Index;
KeyboardBuffer->BufferHead = KeyboardBuffer->BufferTail; Queue->ItemSize = ItemSize;
Queue->Head = 0;
Queue->Tail = 0;
if (Queue->Buffer[0] != NULL) {
FreePool (Queue->Buffer[0]);
}
Queue->Buffer[0] = AllocatePool (sizeof (Queue->Buffer) / sizeof (Queue->Buffer[0]) * ItemSize);
ASSERT (Queue->Buffer[0] != NULL);
for (Index = 1; Index < sizeof (Queue->Buffer) / sizeof (Queue->Buffer[0]); Index++) {
Queue->Buffer[Index] = ((UINT8 *) Queue->Buffer[Index - 1]) + ItemSize;
}
}
/**
Destroy the queue
@param Queue Points to the queue.
**/
VOID
DestroyQueue (
IN OUT USB_SIMPLE_QUEUE *Queue
)
{
FreePool (Queue->Buffer[0]);
} }
/** /**
Check whether USB keyboard buffer is empty. Check whether the queue is empty.
@param KeyboardBuffer USB keyboard buffer @param Queue Points to the queue.
@retval TRUE Keyboard buffer is empty. @retval TRUE Queue is empty.
@retval FALSE Keyboard buffer is not empty. @retval FALSE Queue is not empty.
**/ **/
BOOLEAN BOOLEAN
EFIAPI IsQueueEmpty (
IsUSBKeyboardBufferEmpty ( IN USB_SIMPLE_QUEUE *Queue
IN USB_KB_BUFFER *KeyboardBuffer
) )
{ {
// //
// Meet FIFO empty condition // Meet FIFO empty condition
// //
return (BOOLEAN) (KeyboardBuffer->BufferHead == KeyboardBuffer->BufferTail); return (BOOLEAN) (Queue->Head == Queue->Tail);
} }
/** /**
Check whether USB keyboard buffer is full. Check whether the queue is full.
@param KeyboardBuffer USB keyboard buffer @param Queue Points to the queue.
@retval TRUE Keyboard buffer is full. @retval TRUE Queue is full.
@retval FALSE Keyboard buffer is not full. @retval FALSE Queue is not full.
**/ **/
BOOLEAN BOOLEAN
EFIAPI IsQueueFull (
IsUSBKeyboardBufferFull ( IN USB_SIMPLE_QUEUE *Queue
IN USB_KB_BUFFER *KeyboardBuffer
) )
{ {
return (BOOLEAN)(((KeyboardBuffer->BufferTail + 1) % (MAX_KEY_ALLOWED + 1)) == KeyboardBuffer->BufferHead); return (BOOLEAN) (((Queue->Tail + 1) % (MAX_KEY_ALLOWED + 1)) == Queue->Head);
} }
/** /**
Inserts a keycode into keyboard buffer. Enqueue the item to the queue.
@param KeyboardBuffer Points to the USB keyboard buffer.
@param Key Keycode to insert.
@param Down TRUE means key is pressed.
FALSE means key is released.
@param Queue Points to the queue.
@param Item Points to the item to be enqueued.
@param ItemSize Size of the item.
**/ **/
VOID VOID
EFIAPI Enqueue (
InsertKeyCode ( IN OUT USB_SIMPLE_QUEUE *Queue,
IN OUT USB_KB_BUFFER *KeyboardBuffer, IN VOID *Item,
IN UINT8 Key, IN UINTN ItemSize
IN BOOLEAN Down
) )
{ {
USB_KEY UsbKey; ASSERT (ItemSize == Queue->ItemSize);
// //
// If keyboard buffer is full, throw the // If keyboard buffer is full, throw the
// first key out of the keyboard buffer. // first key out of the keyboard buffer.
// //
if (IsUSBKeyboardBufferFull (KeyboardBuffer)) { if (IsQueueFull (Queue)) {
RemoveKeyCode (KeyboardBuffer, &UsbKey); Queue->Head = (Queue->Head + 1) % (MAX_KEY_ALLOWED + 1);
} }
ASSERT (KeyboardBuffer->BufferTail <= MAX_KEY_ALLOWED); CopyMem (Queue->Buffer[Queue->Tail], Item, ItemSize);
KeyboardBuffer->Buffer[KeyboardBuffer->BufferTail].KeyCode = Key;
KeyboardBuffer->Buffer[KeyboardBuffer->BufferTail].Down = Down;
// //
// Adjust the tail pointer of the FIFO keyboard buffer. // Adjust the tail pointer of the FIFO keyboard buffer.
// //
KeyboardBuffer->BufferTail = (UINT8) ((KeyboardBuffer->BufferTail + 1) % (MAX_KEY_ALLOWED + 1)); Queue->Tail = (Queue->Tail + 1) % (MAX_KEY_ALLOWED + 1);
} }
/** /**
Remove a keycode from keyboard buffer and return it. Dequeue a item from the queue.
@param KeyboardBuffer Points to the USB keyboard buffer. @param Queue Points to the queue.
@param UsbKey Points to the buffer that contains keycode for output. @param Item Receives the item.
@param ItemSize Size of the item.
@retval EFI_SUCCESS Keycode successfully removed from keyboard buffer. @retval EFI_SUCCESS Item was successfully dequeued.
@retval EFI_DEVICE_ERROR Keyboard buffer is empty. @retval EFI_DEVICE_ERROR The queue is empty.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI Dequeue (
RemoveKeyCode ( IN OUT USB_SIMPLE_QUEUE *Queue,
IN OUT USB_KB_BUFFER *KeyboardBuffer, OUT VOID *Item,
OUT USB_KEY *UsbKey IN UINTN ItemSize
) )
{ {
if (IsUSBKeyboardBufferEmpty (KeyboardBuffer)) { ASSERT (Queue->ItemSize == ItemSize);
if (IsQueueEmpty (Queue)) {
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
ASSERT (KeyboardBuffer->BufferHead <= MAX_KEY_ALLOWED); CopyMem (Item, Queue->Buffer[Queue->Head], ItemSize);
UsbKey->KeyCode = KeyboardBuffer->Buffer[KeyboardBuffer->BufferHead].KeyCode;
UsbKey->Down = KeyboardBuffer->Buffer[KeyboardBuffer->BufferHead].Down;
// //
// Adjust the head pointer of the FIFO keyboard buffer. // Adjust the head pointer of the FIFO keyboard buffer.
// //
KeyboardBuffer->BufferHead = (UINT8) ((KeyboardBuffer->BufferHead + 1) % (MAX_KEY_ALLOWED + 1)); Queue->Head = (Queue->Head + 1) % (MAX_KEY_ALLOWED + 1);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -1918,7 +1874,6 @@ RemoveKeyCode (
**/ **/
VOID VOID
EFIAPI
SetKeyLED ( SetKeyLED (
IN USB_KB_DEV *UsbKeyboardDevice IN USB_KB_DEV *UsbKeyboardDevice
) )
@ -1970,6 +1925,7 @@ USBKeyboardRepeatHandler (
) )
{ {
USB_KB_DEV *UsbKeyboardDevice; USB_KB_DEV *UsbKeyboardDevice;
USB_KEY UsbKey;
UsbKeyboardDevice = (USB_KB_DEV *) Context; UsbKeyboardDevice = (USB_KB_DEV *) Context;
@ -1980,11 +1936,9 @@ USBKeyboardRepeatHandler (
// //
// Inserts the repeat key into keyboard buffer, // Inserts the repeat key into keyboard buffer,
// //
InsertKeyCode ( UsbKey.KeyCode = UsbKeyboardDevice->RepeatKey;
&(UsbKeyboardDevice->KeyboardBuffer), UsbKey.Down = TRUE;
UsbKeyboardDevice->RepeatKey, Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));
TRUE
);
// //
// Set repeat rate for next repeat key generation. // Set repeat rate for next repeat key generation.

View File

@ -1,7 +1,7 @@
/** @file /** @file
Function prototype for USB Keyboard Driver. Function prototype for USB Keyboard Driver.
Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR> Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -70,7 +70,6 @@ typedef struct {
**/ **/
BOOLEAN BOOLEAN
EFIAPI
IsUSBKeyboard ( IsUSBKeyboard (
IN EFI_USB_IO_PROTOCOL *UsbIo IN EFI_USB_IO_PROTOCOL *UsbIo
); );
@ -85,7 +84,6 @@ IsUSBKeyboard (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI
InitUSBKeyboard ( InitUSBKeyboard (
IN OUT USB_KB_DEV *UsbKeyboardDevice IN OUT USB_KB_DEV *UsbKeyboardDevice
); );
@ -106,7 +104,6 @@ InitUSBKeyboard (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI
InitKeyboardLayout ( InitKeyboardLayout (
OUT USB_KB_DEV *UsbKeyboardDevice OUT USB_KB_DEV *UsbKeyboardDevice
); );
@ -118,7 +115,6 @@ InitKeyboardLayout (
**/ **/
VOID VOID
EFIAPI
ReleaseKeyboardLayoutResources ( ReleaseKeyboardLayoutResources (
IN OUT USB_KB_DEV *UsbKeyboardDevice IN OUT USB_KB_DEV *UsbKeyboardDevice
); );
@ -184,7 +180,6 @@ USBKeyboardRecoveryHandler (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI
USBParseKey ( USBParseKey (
IN OUT USB_KB_DEV *UsbKeyboardDevice, IN OUT USB_KB_DEV *UsbKeyboardDevice,
OUT UINT8 *KeyCode OUT UINT8 *KeyCode
@ -195,7 +190,7 @@ USBParseKey (
@param UsbKeyboardDevice The USB_KB_DEV instance. @param UsbKeyboardDevice The USB_KB_DEV instance.
@param KeyCode Indicates the key code that will be interpreted. @param KeyCode Indicates the key code that will be interpreted.
@param Key A pointer to a buffer that is filled in with @param KeyData A pointer to a buffer that is filled in with
the keystroke information for the key that the keystroke information for the key that
was pressed. was pressed.
@ -207,87 +202,98 @@ USBParseKey (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI
UsbKeyCodeToEfiInputKey ( UsbKeyCodeToEfiInputKey (
IN USB_KB_DEV *UsbKeyboardDevice, IN USB_KB_DEV *UsbKeyboardDevice,
IN UINT8 KeyCode, IN UINT8 KeyCode,
OUT EFI_INPUT_KEY *Key OUT EFI_KEY_DATA *KeyData
); );
/**
Resets USB keyboard buffer.
@param KeyboardBuffer Points to the USB keyboard buffer. /**
Create the queue.
@param Queue Points to the queue.
@param ItemSize Size of the single item.
**/ **/
VOID VOID
EFIAPI InitQueue (
InitUSBKeyBuffer ( IN OUT USB_SIMPLE_QUEUE *Queue,
OUT USB_KB_BUFFER *KeyboardBuffer IN UINTN ItemSize
); );
/** /**
Check whether USB keyboard buffer is empty. Destroy the queue
@param KeyboardBuffer USB keyboard buffer
@retval TRUE Keyboard buffer is empty.
@retval FALSE Keyboard buffer is not empty.
**/
BOOLEAN
EFIAPI
IsUSBKeyboardBufferEmpty (
IN USB_KB_BUFFER *KeyboardBuffer
);
/**
Check whether USB keyboard buffer is full.
@param KeyboardBuffer USB keyboard buffer
@retval TRUE Keyboard buffer is full.
@retval FALSE Keyboard buffer is not full.
**/
BOOLEAN
EFIAPI
IsUSBKeyboardBufferFull (
IN USB_KB_BUFFER *KeyboardBuffer
);
/**
Inserts a keycode into keyboard buffer.
@param KeyboardBuffer Points to the USB keyboard buffer.
@param Key Keycode to insert.
@param Down TRUE means key is pressed.
FALSE means key is released.
@param Queue Points to the queue.
**/ **/
VOID VOID
EFIAPI DestroyQueue (
InsertKeyCode ( IN OUT USB_SIMPLE_QUEUE *Queue
IN OUT USB_KB_BUFFER *KeyboardBuffer,
IN UINT8 Key,
IN BOOLEAN Down
); );
/** /**
Remove a keycode from keyboard buffer and return it. Check whether the queue is empty.
@param KeyboardBuffer Points to the USB keyboard buffer. @param Queue Points to the queue.
@param UsbKey Points to the buffer that contains keycode for output.
@retval EFI_SUCCESS Keycode successfully removed from keyboard buffer. @retval TRUE Queue is empty.
@retval EFI_DEVICE_ERROR Keyboard buffer is empty. @retval FALSE Queue is not empty.
**/
BOOLEAN
IsQueueEmpty (
IN USB_SIMPLE_QUEUE *Queue
);
/**
Check whether the queue is full.
@param Queue Points to the queue.
@retval TRUE Queue is full.
@retval FALSE Queue is not full.
**/
BOOLEAN
IsQueueFull (
IN USB_SIMPLE_QUEUE *Queue
);
/**
Enqueue the item to the queue.
@param Queue Points to the queue.
@param Item Points to the item to be enqueued.
@param ItemSize Size of the item.
**/
VOID
Enqueue (
IN OUT USB_SIMPLE_QUEUE *Queue,
IN VOID *Item,
IN UINTN ItemSize
);
/**
Dequeue a item from the queue.
@param Queue Points to the queue.
@param Item Receives the item.
@param ItemSize Size of the item.
@retval EFI_SUCCESS Item was successfully dequeued.
@retval EFI_DEVICE_ERROR The queue is empty.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI Dequeue (
RemoveKeyCode ( IN OUT USB_SIMPLE_QUEUE *Queue,
IN OUT USB_KB_BUFFER *KeyboardBuffer, OUT VOID *Item,
OUT USB_KEY *UsbKey IN UINTN ItemSize
); );
/** /**
@ -317,7 +323,6 @@ USBKeyboardRepeatHandler (
**/ **/
VOID VOID
EFIAPI
SetKeyLED ( SetKeyLED (
IN USB_KB_DEV *UsbKeyboardDevice IN USB_KB_DEV *UsbKeyboardDevice
); );