/** @file\r
Helper functions for USB Keyboard Driver.\r
\r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
{EfiKeyD11, '[', '{', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
{EfiKeyD12, ']', '}', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
{EfiKeyD13, '\\', '|', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyC12, '\\', '|', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
{EfiKeyC10, ';', ':', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
{EfiKeyC11, '\'', '"', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
{EfiKeyE0, '`', '~', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
{\r
UINT16 ConfigValue;\r
UINT8 Protocol;\r
- UINT8 ReportId;\r
- UINT8 Duration;\r
EFI_STATUS Status;\r
UINT32 TransferResult;\r
\r
\r
InitQueue (&UsbKeyboardDevice->UsbKeyQueue, sizeof (USB_KEY));\r
InitQueue (&UsbKeyboardDevice->EfiKeyQueue, sizeof (EFI_KEY_DATA));\r
+ InitQueue (&UsbKeyboardDevice->EfiKeyQueueForNotify, sizeof (EFI_KEY_DATA));\r
\r
//\r
// Use the config out of the descriptor\r
);\r
if (EFI_ERROR (Status)) {\r
ConfigValue = 0x01;\r
- }\r
-\r
- //\r
- // Uses default configuration to configure the USB Keyboard device.\r
- //\r
- Status = UsbSetConfiguration (\r
- UsbKeyboardDevice->UsbIo,\r
- ConfigValue,\r
- &TransferResult\r
- );\r
- if (EFI_ERROR (Status)) {\r
//\r
- // If configuration could not be set here, it means\r
- // the keyboard interface has some errors and could\r
- // not be initialized\r
+ // Uses default configuration to configure the USB Keyboard device.\r
//\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_INTERFACE_ERROR),\r
- UsbKeyboardDevice->DevicePath\r
- );\r
+ Status = UsbSetConfiguration (\r
+ UsbKeyboardDevice->UsbIo,\r
+ ConfigValue,\r
+ &TransferResult\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // If configuration could not be set here, it means\r
+ // the keyboard interface has some errors and could\r
+ // not be initialized\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+ (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_INTERFACE_ERROR),\r
+ UsbKeyboardDevice->DevicePath\r
+ );\r
\r
- return EFI_DEVICE_ERROR;\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
}\r
\r
UsbGetProtocolRequest (\r
);\r
}\r
\r
- //\r
- // ReportId is zero, which means the idle rate applies to all input reports.\r
- //\r
- ReportId = 0;\r
- //\r
- // Duration is zero, which means the duration is infinite.\r
- // so the endpoint will inhibit reporting forever,\r
- // and only reporting when a change is detected in the report data.\r
- //\r
- Duration = 0;\r
- UsbSetIdleRequest (\r
- UsbKeyboardDevice->UsbIo,\r
- UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,\r
- ReportId,\r
- Duration\r
- );\r
-\r
UsbKeyboardDevice->CtrlOn = FALSE;\r
UsbKeyboardDevice->AltOn = FALSE;\r
UsbKeyboardDevice->ShiftOn = FALSE;\r
// Handle repeat key\r
//\r
KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, CurKeyCodeBuffer[Index]);\r
- ASSERT (KeyDescriptor != NULL);\r
+ if (KeyDescriptor == NULL) {\r
+ continue;\r
+ }\r
\r
if (KeyDescriptor->Modifier == EFI_NUM_LOCK_MODIFIER || KeyDescriptor->Modifier == EFI_CAPS_LOCK_MODIFIER) {\r
//\r
Dequeue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));\r
\r
KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode);\r
- ASSERT (KeyDescriptor != NULL);\r
-\r
+ if (KeyDescriptor == NULL) {\r
+ continue;\r
+ }\r
if (!UsbKey.Down) {\r
//\r
// Key is released.\r
return EFI_NOT_READY;\r
}\r
\r
+/**\r
+ Initialize the key state.\r
+\r
+ @param UsbKeyboardDevice The USB_KB_DEV instance.\r
+ @param KeyState A pointer to receive the key state information.\r
+**/\r
+VOID\r
+InitializeKeyState (\r
+ IN USB_KB_DEV *UsbKeyboardDevice,\r
+ OUT EFI_KEY_STATE *KeyState\r
+ )\r
+{\r
+ KeyState->KeyShiftState = EFI_SHIFT_STATE_VALID;\r
+ KeyState->KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
+\r
+ if (UsbKeyboardDevice->LeftCtrlOn) {\r
+ KeyState->KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;\r
+ }\r
+ if (UsbKeyboardDevice->RightCtrlOn) {\r
+ KeyState->KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;\r
+ }\r
+ if (UsbKeyboardDevice->LeftAltOn) {\r
+ KeyState->KeyShiftState |= EFI_LEFT_ALT_PRESSED;\r
+ }\r
+ if (UsbKeyboardDevice->RightAltOn) {\r
+ KeyState->KeyShiftState |= EFI_RIGHT_ALT_PRESSED;\r
+ }\r
+ if (UsbKeyboardDevice->LeftShiftOn) {\r
+ KeyState->KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;\r
+ }\r
+ if (UsbKeyboardDevice->RightShiftOn) {\r
+ KeyState->KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;\r
+ }\r
+ if (UsbKeyboardDevice->LeftLogoOn) {\r
+ KeyState->KeyShiftState |= EFI_LEFT_LOGO_PRESSED;\r
+ }\r
+ if (UsbKeyboardDevice->RightLogoOn) {\r
+ KeyState->KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;\r
+ }\r
+ if (UsbKeyboardDevice->MenuKeyOn) {\r
+ KeyState->KeyShiftState |= EFI_MENU_KEY_PRESSED;\r
+ }\r
+ if (UsbKeyboardDevice->SysReqOn) {\r
+ KeyState->KeyShiftState |= EFI_SYS_REQ_PRESSED;\r
+ }\r
+\r
+ if (UsbKeyboardDevice->ScrollOn) {\r
+ KeyState->KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
+ }\r
+ if (UsbKeyboardDevice->NumLockOn) {\r
+ KeyState->KeyToggleState |= EFI_NUM_LOCK_ACTIVE;\r
+ }\r
+ if (UsbKeyboardDevice->CapsOn) {\r
+ KeyState->KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
+ }\r
+ if (UsbKeyboardDevice->IsSupportPartialKey) {\r
+ KeyState->KeyToggleState |= EFI_KEY_STATE_EXPOSED;\r
+ }\r
+}\r
\r
/**\r
Converts USB Keycode ranging from 0x4 to 0x65 to EFI_INPUT_KEY.\r
// KeyCode must in the range of [0x4, 0x65] or [0xe0, 0xe7].\r
//\r
KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, KeyCode);\r
- ASSERT (KeyDescriptor != NULL);\r
+ if (KeyDescriptor == NULL) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
\r
if (KeyDescriptor->Modifier == EFI_NS_KEY_MODIFIER) {\r
//\r
// Need not return associated shift state if a class of printable characters that\r
// are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'\r
//\r
- if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) != 0) {\r
+ if ((KeyDescriptor->Unicode != CHAR_NULL) && (KeyDescriptor->ShiftedUnicode != CHAR_NULL) &&\r
+ (KeyDescriptor->Unicode != KeyDescriptor->ShiftedUnicode)) {\r
UsbKeyboardDevice->LeftShiftOn = FALSE;\r
UsbKeyboardDevice->RightShiftOn = FALSE;\r
}\r
//\r
// Save Shift/Toggle state\r
//\r
- KeyData->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;\r
- KeyData->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
-\r
- if (UsbKeyboardDevice->LeftCtrlOn) {\r
- KeyData->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;\r
- }\r
- if (UsbKeyboardDevice->RightCtrlOn) {\r
- KeyData->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;\r
- }\r
- if (UsbKeyboardDevice->LeftAltOn) {\r
- KeyData->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED;\r
- }\r
- if (UsbKeyboardDevice->RightAltOn) {\r
- KeyData->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED;\r
- }\r
- if (UsbKeyboardDevice->LeftShiftOn) {\r
- KeyData->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;\r
- }\r
- if (UsbKeyboardDevice->RightShiftOn) {\r
- KeyData->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;\r
- }\r
- if (UsbKeyboardDevice->LeftLogoOn) {\r
- KeyData->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;\r
- }\r
- if (UsbKeyboardDevice->RightLogoOn) {\r
- KeyData->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;\r
- }\r
- if (UsbKeyboardDevice->MenuKeyOn) {\r
- KeyData->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;\r
- }\r
- if (UsbKeyboardDevice->SysReqOn) {\r
- KeyData->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;\r
- }\r
+ InitializeKeyState (UsbKeyboardDevice, &KeyData->KeyState);\r
\r
- if (UsbKeyboardDevice->ScrollOn) {\r
- KeyData->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
- }\r
- if (UsbKeyboardDevice->NumLockOn) {\r
- KeyData->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;\r
- }\r
- if (UsbKeyboardDevice->CapsOn) {\r
- KeyData->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
- }\r
- if (UsbKeyboardDevice->IsSupportPartialKey) {\r
- KeyData->KeyState.KeyToggleState |= EFI_KEY_STATE_EXPOSED;\r
- }\r
//\r
- // Invoke notification functions if the key is registered.\r
+ // Signal KeyNotify process event if this key pressed matches any key registered.\r
//\r
NotifyList = &UsbKeyboardDevice->NotifyList;\r
for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {\r
CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE);\r
if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
- CurrentNotify->KeyNotificationFn (KeyData);\r
+ //\r
+ // The key notification function needs to run at TPL_CALLBACK\r
+ // while current TPL is TPL_NOTIFY. It will be invoked in\r
+ // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.\r
+ //\r
+ Enqueue (&UsbKeyboardDevice->EfiKeyQueueForNotify, KeyData, sizeof (*KeyData));\r
+ gBS->SignalEvent (UsbKeyboardDevice->KeyNotifyProcessEvent);\r
}\r
}\r
\r
return EFI_SUCCESS;\r
}\r
\r
-\r
/**\r
Create the queue.\r
\r