1. Add Partial Keystroke Support in Ps2Kb drivers. See the Uefi2.3.1a chapter 11.2

2. Fix the bug of "In Ps2Keyboard the CAPs LOCK's LED should NOT be light when user press the SysReq key".
3. Fix the bug of "The PS2Keyboard driver outputs wrong EFI_INPUT_KEY value for PrintScr/SysRq keystroke"

Signed-off-by: qianouyang
Reviewed-by: niruiyu vanjeff




git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12495 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
qianouyang 2011-09-30 07:29:42 +00:00
parent 3765794ca3
commit 5829afe3e4
4 changed files with 264 additions and 212 deletions

View File

@ -624,26 +624,6 @@ GetScancodeBufHead (
return EFI_SUCCESS;
}
/**
Push one byte to the scancode buffer.
@param Queue Pointer to instance of SCAN_CODE_QUEUE.
@param Scancode The byte to push.
**/
VOID
PushScancodeBufTail (
IN SCAN_CODE_QUEUE *Queue,
IN UINT8 Scancode
)
{
if (GetScancodeBufCount (Queue) == KEYBOARD_SCAN_CODE_MAX_COUNT - 1) {
return;
}
Queue->Buffer[Queue->Tail] = Scancode;
Queue->Tail = (Queue->Tail + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT;
}
/**
Read & remove several bytes from the scancode buffer.
@ -660,7 +640,7 @@ EFI_STATUS
PopScancodeBufHead (
IN SCAN_CODE_QUEUE *Queue,
IN UINTN Count,
OUT UINT8 *Buf
OUT UINT8 *Buf OPTIONAL
)
{
UINTN Index;
@ -675,12 +655,34 @@ PopScancodeBufHead (
// Retrieve and remove the values
//
for (Index = 0; Index < Count; Index++, Queue->Head = (Queue->Head + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT) {
if (Buf != NULL) {
Buf[Index] = Queue->Buffer[Queue->Head];
}
}
return EFI_SUCCESS;
}
/**
Push one byte to the scancode buffer.
@param Queue Pointer to instance of SCAN_CODE_QUEUE.
@param Scancode The byte to push.
**/
VOID
PushScancodeBufTail (
IN SCAN_CODE_QUEUE *Queue,
IN UINT8 Scancode
)
{
if (GetScancodeBufCount (Queue) == KEYBOARD_SCAN_CODE_MAX_COUNT - 1) {
PopScancodeBufHead (Queue, 1, NULL);
}
Queue->Buffer[Queue->Tail] = Scancode;
Queue->Tail = (Queue->Tail + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT;
}
/**
Read data register .
@ -1249,12 +1251,15 @@ KeyGetchar (
case SCANCODE_LEFT_SHIFT_MAKE:
//
// To avoid recognize PRNT_SCRN key as a L_SHIFT key
// because PRNT_SCRN key generates E0 followed by L_SHIFT scan code
// because PRNT_SCRN key generates E0 followed by L_SHIFT scan code.
// If it the second byte of the PRNT_ScRN skip it.
//
if (!Extend0) {
ConsoleIn->LeftShift = TRUE;
}
break;
}
continue;
case SCANCODE_LEFT_SHIFT_BREAK:
if (!Extend0) {
ConsoleIn->LeftShift = FALSE;
@ -1358,14 +1363,14 @@ KeyGetchar (
| (ConsoleIn->RightLogo ? EFI_RIGHT_LOGO_PRESSED : 0)
| (ConsoleIn->Menu ? EFI_MENU_KEY_PRESSED : 0)
| (ConsoleIn->SysReq ? EFI_SYS_REQ_PRESSED : 0)
)
;
);
KeyData.KeyState.KeyToggleState = (EFI_KEY_TOGGLE_STATE) (EFI_TOGGLE_STATE_VALID
| (ConsoleIn->CapsLock ? EFI_CAPS_LOCK_ACTIVE : 0)
| (ConsoleIn->NumLock ? EFI_NUM_LOCK_ACTIVE : 0)
| (ConsoleIn->ScrollLock ? EFI_SCROLL_LOCK_ACTIVE : 0)
)
;
| (ConsoleIn->IsSupportPartialKey ? EFI_KEY_STATE_EXPOSED : 0)
);
KeyData.Key.ScanCode = SCAN_NULL;
KeyData.Key.UnicodeChar = CHAR_NULL;
@ -1440,12 +1445,15 @@ KeyGetchar (
KeyData.Key.UnicodeChar = CHAR_NULL;
}
}
//
// If the key can not be converted then just return.
//
if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {
if (!ConsoleIn->IsSupportPartialKey) {
return ;
}
}
//
// Invoke notification functions if exist
@ -1679,6 +1687,7 @@ InitKeyboard (
ConsoleIn->Menu = FALSE;
ConsoleIn->SysReq = FALSE;
ConsoleIn->IsSupportPartialKey = FALSE;
//
// For reseting keyboard is not mandatory before booting OS and sometimes keyboard responses very slow,
// and to support KB hot plug, we need to let the InitKB succeed no matter whether there is a KB device connected

View File

@ -32,7 +32,33 @@ IsEfikeyBufEmpty (
return (BOOLEAN) (Queue->Head == Queue->Tail);
}
/**
Read & remove one key data from the EFI key buffer.
@param Queue Pointer to instance of EFI_KEY_QUEUE.
@param KeyData Receive the key data.
@retval EFI_SUCCESS The key data is popped successfully.
@retval EFI_NOT_READY There is no key data available.
**/
EFI_STATUS
PopEfikeyBufHead (
IN EFI_KEY_QUEUE *Queue,
OUT EFI_KEY_DATA *KeyData OPTIONAL
)
{
if (IsEfikeyBufEmpty (Queue)) {
return EFI_NOT_READY;
}
//
// Retrieve and remove the values
//
if (KeyData != NULL) {
CopyMem (KeyData, &Queue->Buffer[Queue->Head], sizeof (EFI_KEY_DATA));
}
Queue->Head = (Queue->Head + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;
return EFI_SUCCESS;
}
/**
Push one key data to the EFI key buffer.
@ -47,39 +73,15 @@ PushEfikeyBufTail (
)
{
if ((Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT == Queue->Head) {
return;
//
// If Queue is full, pop the one from head.
//
PopEfikeyBufHead (Queue, NULL);
}
CopyMem (&Queue->Buffer[Queue->Tail], KeyData, sizeof (EFI_KEY_DATA));
Queue->Tail = (Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;
}
/**
Read & remove one key data from the EFI key buffer.
@param Queue Pointer to instance of EFI_KEY_QUEUE.
@param KeyData Receive the key data.
@retval EFI_SUCCESS The key data is popped successfully.
@retval EFI_NOT_READY There is no key data available.
**/
EFI_STATUS
PopEfikeyBufHead (
IN EFI_KEY_QUEUE *Queue,
OUT EFI_KEY_DATA *KeyData
)
{
if (IsEfikeyBufEmpty (Queue)) {
return EFI_NOT_READY;
}
//
// Retrieve and remove the values
//
CopyMem (KeyData, &Queue->Buffer[Queue->Head], sizeof (EFI_KEY_DATA));
Queue->Head = (Queue->Head + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;
return EFI_SUCCESS;
}
/**
Judge whether is a registed key
@ -266,14 +268,29 @@ KeyboardReadKeyStroke (
EFI_KEY_DATA KeyData;
ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
//
// Considering if the partial keystroke is enabled, there maybe a partial
// keystroke in the queue, so here skip the partial keystroke and get the
// next key from the queue
//
while (1) {
//
// If there is no pending key, then return.
//
Status = KeyboardReadKeyStrokeWorker (ConsoleIn, &KeyData);
if (EFI_ERROR (Status)) {
return Status;
}
//
// If it is partial keystroke, skip it.
//
if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {
continue;
}
CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
return EFI_SUCCESS;
}
}
/**
@ -293,6 +310,7 @@ KeyboardWaitForKey (
{
EFI_TPL OldTpl;
KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
EFI_KEY_DATA KeyData;
ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context;
@ -305,11 +323,26 @@ KeyboardWaitForKey (
if (!ConsoleIn->KeyboardErr) {
//
// Someone is waiting on the keyboard event, if there's
// a key pending, signal the event
// WaitforKey doesn't suppor the partial key.
// Considering if the partial keystroke is enabled, there maybe a partial
// keystroke in the queue, so here skip the partial keystroke and get the
// next key from the queue
//
while (!IsEfikeyBufEmpty (&ConsoleIn->EfiKeyQueue)) {
CopyMem (
&KeyData,
&(ConsoleIn->EfiKeyQueue.Buffer[ConsoleIn->EfiKeyQueue.Head]),
sizeof (EFI_KEY_DATA)
);
if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {
PopEfikeyBufHead (&ConsoleIn->EfiKeyQueue, &KeyData);
continue;
}
//
// if there is pending value key, signal the event.
//
if (!IsEfikeyBufEmpty (&ConsoleIn->EfiKeyQueue)) {
gBS->SignalEvent (Event);
break;
}
}
//
@ -398,7 +431,6 @@ KeyboardReadKeyStrokeEx (
ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
return KeyboardReadKeyStrokeWorker (ConsoleInDev, KeyData);
}
/**
@ -454,6 +486,7 @@ KeyboardSetState (
ConsoleInDev->ScrollLock = FALSE;
ConsoleInDev->NumLock = FALSE;
ConsoleInDev->CapsLock = FALSE;
ConsoleInDev->IsSupportPartialKey = FALSE;
if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {
ConsoleInDev->ScrollLock = TRUE;
@ -464,6 +497,9 @@ KeyboardSetState (
if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {
ConsoleInDev->CapsLock = TRUE;
}
if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) {
ConsoleInDev->IsSupportPartialKey = TRUE;
}
Status = UpdateStatusLights (ConsoleInDev);
if (EFI_ERROR (Status)) {

View File

@ -99,6 +99,7 @@ typedef struct {
BOOLEAN NumLock;
BOOLEAN ScrollLock;
BOOLEAN IsSupportPartialKey;
//
// Queue storing key scancodes
//
@ -546,4 +547,5 @@ IsKeyRegistered (
IN EFI_KEY_DATA *RegsiteredData,
IN EFI_KEY_DATA *InputData
);
#endif

View File

@ -2171,7 +2171,12 @@ BiosKeyboardSetState (
return EFI_INVALID_PARAMETER;
}
if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) {
//
// Thunk keyboard driver doesn't support partial keystroke.
//
if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID ||
(*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED
) {
return EFI_UNSUPPORTED;
}