Code Scrub for UsbKbDxe module.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@6871 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
xli24
2008-12-05 09:19:10 +00:00
parent 0c95b03bcd
commit 5899f27e06
4 changed files with 571 additions and 631 deletions

View File

@@ -1,5 +1,4 @@
/** @file /** @file
USB Keyboard Driver that includes the implementation of interface. USB Keyboard Driver that includes the implementation of interface.
Copyright (c) 2004 - 2008, Intel Corporation Copyright (c) 2004 - 2008, Intel Corporation
@@ -16,185 +15,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "EfiKey.h" #include "EfiKey.h"
#include "KeyBoard.h" #include "KeyBoard.h"
/**
The Usb Keyboard Driver Entry Point.
@param ImageHandle The driver image handle.
@param SystemTable The system table.
@return EFI_SUCCESS The component name protocol is installed.
@return Others Failed to install.
**/
EFI_STATUS
EFIAPI
USBKeyboardDriverBindingEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
Check whether USB keyboard driver support this device.
@param This The USB keyboard driver binding protocol.
@param Controller The controller handle to check.
@param RemainingDevicePath The remaining device path.
@retval EFI_SUCCESS The driver supports this controller.
@retval EFI_UNSUPPORTED This device isn't supported.
**/
EFI_STATUS
EFIAPI
USBKeyboardDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
/**
Start running driver on the controller.
@param This The USB keyboard driver binding instance.
@param Controller The controller to check.
@param RemainingDevicePath The remaining device patch.
@retval EFI_SUCCESS The controller is controlled by the usb keyboard driver.
@return Other The keyboard driver doesn't support this controller.
**/
EFI_STATUS
EFIAPI
USBKeyboardDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
/**
Stop handle the controller by this USB keyboard driver.
@param This The USB keyboard driver binding protocol.
@param Controller The controller to release.
@param NumberOfChildren The number of handles in ChildHandleBuffer.
@param ChildHandleBuffer The array of child handle.
@retval EFI_SUCCESS The controller or children are stopped.
@retval EFI_DEVICE_ERROR Failed to stop the driver.
**/
EFI_STATUS
EFIAPI
USBKeyboardDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
/**
Reset Usb Keyboard.
@param This The protocol instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
@param ExtendedVerification Whether completely reset keyboard or not.
@retval EFI_SUCCESS Reset keyboard successfully.
@retval EFI_DEVICE_ERROR Reset keyboard failed.
**/
EFI_STATUS
EFIAPI
USBKeyboardReset (
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
);
/**
Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke() function.
@param This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.
@param Key A pointer to a buffer that is filled in with the keystroke
information for the key that was pressed.
@retval EFI_SUCCESS Read key stroke successfully.
@retval Other Read key stroke failed.
**/
EFI_STATUS
EFIAPI
USBKeyboardReadKeyStroke (
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
OUT EFI_INPUT_KEY *Key
);
/**
Handler function for WaitForKey event.
@param Event Event to be signaled when a key is pressed.
@param Context Points to USB_KB_DEV instance.
@return None.
**/
VOID
EFIAPI
USBKeyboardWaitForKey (
IN EFI_EVENT Event,
IN VOID *Context
);
/**
Check whether there is key pending.
@param UsbKeyboardDevice The USB_KB_DEV instance.
@retval EFI_SUCCESS Have key pending to read.
@retval Other Parse key failed.
**/
EFI_STATUS
EFIAPI
USBKeyboardCheckForKey (
IN USB_KB_DEV *UsbKeyboardDevice
);
EFI_GUID gEfiUsbKeyboardDriverGuid = {
0xa05f5f78, 0xfb3, 0x4d10, {0x90, 0x90, 0xac, 0x4, 0x6e, 0xeb, 0x7c, 0x3c}
};
/**
Free keyboard notify list.
@param ListHead The list head.
@retval EFI_SUCCESS Free the notify list successfully.
@retval EFI_INVALID_PARAMETER ListHead is invalid.
**/
EFI_STATUS
EFIAPI
KbdFreeNotifyList (
IN OUT LIST_ENTRY *ListHead
);
/**
Whether the pressed key matches a registered key or not.
@param RegsiteredData A pointer to a buffer that is filled in with the keystroke
state data for the key that was registered.
@param InputData A pointer to a buffer that is filled in with the keystroke
state data for the key that was pressed.
@retval TRUE Key pressed matches a registered key.
@retval FLASE Match failed.
**/
BOOLEAN
EFIAPI
IsKeyRegistered (
IN EFI_KEY_DATA *RegsiteredData,
IN EFI_KEY_DATA *InputData
);
// //
// USB Keyboard Driver Global Variables // USB Keyboard Driver Global Variables
// //
@@ -208,13 +28,15 @@ EFI_DRIVER_BINDING_PROTOCOL gUsbKeyboardDriverBinding = {
}; };
/** /**
The Usb Keyboard Driver Entry Point. Entrypoint of USB Keyboard Driver.
@param ImageHandle The driver image handle. This function is the entrypoint of USB Keyboard Driver. It installs Driver Binding
@param SystemTable The system table. Protocols together with Component Name Protocols.
@return EFI_SUCCESS The component name protocol is installed. @param ImageHandle The firmware allocated handle for the EFI image.
@return Others Failed to install. @param SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
**/ **/
EFI_STATUS EFI_STATUS
@@ -224,25 +46,31 @@ USBKeyboardDriverBindingEntryPoint (
IN EFI_SYSTEM_TABLE *SystemTable IN EFI_SYSTEM_TABLE *SystemTable
) )
{ {
return EfiLibInstallDriverBindingComponentName2 ( EFI_STATUS Status;
ImageHandle,
SystemTable, Status = EfiLibInstallDriverBindingComponentName2 (
&gUsbKeyboardDriverBinding, ImageHandle,
ImageHandle, SystemTable,
&gUsbKeyboardComponentName, &gUsbKeyboardDriverBinding,
&gUsbKeyboardComponentName2 ImageHandle,
); &gUsbKeyboardComponentName,
&gUsbKeyboardComponentName2
);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
} }
/** /**
Check whether USB keyboard driver support this device. Check whether USB keyboard driver supports this device.
@param This The USB keyboard driver binding protocol. @param This The USB keyboard driver binding protocol.
@param Controller The controller handle to check. @param Controller The controller handle to check.
@param RemainingDevicePath The remaining device path. @param RemainingDevicePath The remaining device path.
@retval EFI_SUCCESS The driver supports this controller. @retval EFI_SUCCESS The driver supports this controller.
@retval EFI_UNSUPPORTED This device isn't supported. @retval other This device isn't supported.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
@@ -252,27 +80,26 @@ USBKeyboardDriverBindingSupported (
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
) )
{ {
EFI_STATUS OpenStatus;
EFI_USB_IO_PROTOCOL *UsbIo;
EFI_STATUS Status; EFI_STATUS Status;
EFI_USB_IO_PROTOCOL *UsbIo;
// //
// Check if USB_IO protocol is attached on the controller handle. // Check if USB I/O Protocol is attached on the controller handle.
// //
OpenStatus = gBS->OpenProtocol ( Status = gBS->OpenProtocol (
Controller, Controller,
&gEfiUsbIoProtocolGuid, &gEfiUsbIoProtocolGuid,
(VOID **) &UsbIo, (VOID **) &UsbIo,
This->DriverBindingHandle, This->DriverBindingHandle,
Controller, Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER EFI_OPEN_PROTOCOL_BY_DRIVER
); );
if (EFI_ERROR (OpenStatus)) { if (EFI_ERROR (Status)) {
return OpenStatus; return Status;
} }
// //
// Use the USB I/O protocol interface to check whether the Controller is // Use the USB I/O Protocol interface to check whether the Controller is
// the Keyboard controller that can be managed by this driver. // the Keyboard controller that can be managed by this driver.
// //
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
@@ -282,11 +109,11 @@ USBKeyboardDriverBindingSupported (
} }
gBS->CloseProtocol ( gBS->CloseProtocol (
Controller, Controller,
&gEfiUsbIoProtocolGuid, &gEfiUsbIoProtocolGuid,
This->DriverBindingHandle, This->DriverBindingHandle,
Controller Controller
); );
return Status; return Status;
} }
@@ -295,11 +122,13 @@ USBKeyboardDriverBindingSupported (
Start running driver on the controller. Start running driver on the controller.
@param This The USB keyboard driver binding instance. @param This The USB keyboard driver binding instance.
@param Controller The controller to check. @param Controller Handle of device to bind driver to.
@param RemainingDevicePath The remaining device patch. @param RemainingDevicePath Optional parameter use to pick a specific child
device to start.
@retval EFI_SUCCESS The controller is controlled by the usb keyboard driver. @retval EFI_SUCCESS The controller is controlled by the usb keyboard driver.
@return Other The keyboard driver doesn't support this controller. @retval EFI_UNSUPPORTED No interrupt endpoint can be found.
@retval Other The keyboard driver cannot support this controller.
**/ **/
EFI_STATUS EFI_STATUS
@@ -321,11 +150,8 @@ USBKeyboardDriverBindingStart (
UINT8 PacketSize; UINT8 PacketSize;
BOOLEAN Found; BOOLEAN Found;
UsbKeyboardDevice = NULL;
Found = FALSE;
// //
// Open USB_IO Protocol // Open USB I/O Protocol
// //
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol (
Controller, Controller,
@@ -340,15 +166,8 @@ USBKeyboardDriverBindingStart (
} }
UsbKeyboardDevice = AllocateZeroPool (sizeof (USB_KB_DEV)); UsbKeyboardDevice = AllocateZeroPool (sizeof (USB_KB_DEV));
if (UsbKeyboardDevice == NULL) { ASSERT (UsbKeyboardDevice != NULL);
gBS->CloseProtocol (
Controller,
&gEfiUsbIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_OUT_OF_RESOURCES;
}
// //
// Get the Device Path Protocol on Controller's handle // Get the Device Path Protocol on Controller's handle
// //
@@ -362,31 +181,24 @@ USBKeyboardDriverBindingStart (
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
gBS->FreePool (UsbKeyboardDevice); goto ErrorExit;
gBS->CloseProtocol (
Controller,
&gEfiUsbIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return Status;
} }
// //
// Report that the usb keyboard is being enabled // Report that the USB keyboard is being enabled
// //
KbdReportStatusCode ( REPORT_STATUS_CODE_WITH_DEVICE_PATH (
UsbKeyboardDevice->DevicePath,
EFI_PROGRESS_CODE, EFI_PROGRESS_CODE,
PcdGet32 (PcdStatusCodeValueKeyboardEnable) PcdGet32 (PcdStatusCodeValueKeyboardEnable),
UsbKeyboardDevice->DevicePath
); );
// //
// This is pretty close to keyboard detection, so log progress // This is pretty close to keyboard detection, so log progress
// //
KbdReportStatusCode ( REPORT_STATUS_CODE_WITH_DEVICE_PATH (
UsbKeyboardDevice->DevicePath,
EFI_PROGRESS_CODE, EFI_PROGRESS_CODE,
PcdGet32 (PcdStatusCodeValueKeyboardPresenceDetect) PcdGet32 (PcdStatusCodeValueKeyboardPresenceDetect),
UsbKeyboardDevice->DevicePath
); );
// //
@@ -398,26 +210,31 @@ USBKeyboardDriverBindingStart (
// Get interface & endpoint descriptor // Get interface & endpoint descriptor
// //
UsbIo->UsbGetInterfaceDescriptor ( UsbIo->UsbGetInterfaceDescriptor (
UsbIo, UsbIo,
&UsbKeyboardDevice->InterfaceDescriptor &UsbKeyboardDevice->InterfaceDescriptor
); );
EndpointNumber = UsbKeyboardDevice->InterfaceDescriptor.NumEndpoints; EndpointNumber = UsbKeyboardDevice->InterfaceDescriptor.NumEndpoints;
//
// Traverse endpoints to find interrupt endpoints
//
Found = FALSE;
for (Index = 0; Index < EndpointNumber; Index++) { for (Index = 0; Index < EndpointNumber; Index++) {
UsbIo->UsbGetEndpointDescriptor ( UsbIo->UsbGetEndpointDescriptor (
UsbIo, UsbIo,
Index, Index,
&EndpointDescriptor &EndpointDescriptor
); );
if ((EndpointDescriptor.Attributes & 0x03) == 0x03) { if ((EndpointDescriptor.Attributes & 0x03) == USB_ENDPOINT_INTERRUPT) {
// //
// We only care interrupt endpoint here // We only care interrupt endpoint here
// //
CopyMem(&UsbKeyboardDevice->IntEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor)); CopyMem(&UsbKeyboardDevice->IntEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor));
Found = TRUE; Found = TRUE;
break;
} }
} }
@@ -425,14 +242,8 @@ USBKeyboardDriverBindingStart (
// //
// No interrupt endpoint found, then return unsupported. // No interrupt endpoint found, then return unsupported.
// //
gBS->FreePool (UsbKeyboardDevice); Status = EFI_UNSUPPORTED;
gBS->CloseProtocol ( goto ErrorExit;
Controller,
&gEfiUsbIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_UNSUPPORTED;
} }
UsbKeyboardDevice->Signature = USB_KB_DEV_SIGNATURE; UsbKeyboardDevice->Signature = USB_KB_DEV_SIGNATURE;
@@ -459,11 +270,6 @@ USBKeyboardDriverBindingStart (
goto ErrorExit; goto ErrorExit;
} }
Status = InitKeyboardLayout (UsbKeyboardDevice);
if (EFI_ERROR (Status)) {
goto ErrorExit;
}
Status = gBS->CreateEvent ( Status = gBS->CreateEvent (
EVT_NOTIFY_WAIT, EVT_NOTIFY_WAIT,
TPL_NOTIFY, TPL_NOTIFY,
@@ -473,20 +279,18 @@ USBKeyboardDriverBindingStart (
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
gBS->FreePool (UsbKeyboardDevice); goto ErrorExit;
gBS->CloseProtocol ( }
Controller,
&gEfiUsbIoProtocolGuid, Status = InitKeyboardLayout (UsbKeyboardDevice);
This->DriverBindingHandle, if (EFI_ERROR (Status)) {
Controller goto ErrorExit;
);
return Status;
} }
// //
// Install simple txt in protocol interface // Install Simple Text Input Protocol and Simple Text Input Ex Protocol
// for the usb keyboard device. // for the USB keyboard device.
// Usb keyboard is a hot plug device, and expected to work immediately // USB keyboard is a hot plug device, and expected to work immediately
// when plugging into system, so a HotPlugDeviceGuid is installed onto // when plugging into system, so a HotPlugDeviceGuid is installed onto
// the usb keyboard device handle, to distinguish it from other conventional // the usb keyboard device handle, to distinguish it from other conventional
// console devices. // console devices.
@@ -502,19 +306,11 @@ USBKeyboardDriverBindingStart (
NULL NULL
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey); goto ErrorExit;
gBS->FreePool (UsbKeyboardDevice);
gBS->CloseProtocol (
Controller,
&gEfiUsbIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return Status;
} }
// //
// Reset USB Keyboard Device // Reset USB Keyboard Device exhaustively.
// //
Status = UsbKeyboardDevice->SimpleInput.Reset ( Status = UsbKeyboardDevice->SimpleInput.Reset (
&UsbKeyboardDevice->SimpleInput, &UsbKeyboardDevice->SimpleInput,
@@ -531,18 +327,11 @@ USBKeyboardDriverBindingStart (
NULL, NULL,
NULL NULL
); );
gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey); goto ErrorExit;
gBS->FreePool (UsbKeyboardDevice);
gBS->CloseProtocol (
Controller,
&gEfiUsbIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return Status;
} }
// //
// submit async interrupt transfer // Submit Asynchronous Interrupt Transfer to manage this device.
// //
EndpointAddr = UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress; EndpointAddr = UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress;
PollingInterval = UsbKeyboardDevice->IntEndpointDescriptor.Interval; PollingInterval = UsbKeyboardDevice->IntEndpointDescriptor.Interval;
@@ -559,7 +348,6 @@ USBKeyboardDriverBindingStart (
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
gBS->UninstallMultipleProtocolInterfaces ( gBS->UninstallMultipleProtocolInterfaces (
Controller, Controller,
&gEfiSimpleTextInProtocolGuid, &gEfiSimpleTextInProtocolGuid,
@@ -570,15 +358,7 @@ USBKeyboardDriverBindingStart (
NULL, NULL,
NULL NULL
); );
gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey); goto ErrorExit;
gBS->FreePool (UsbKeyboardDevice);
gBS->CloseProtocol (
Controller,
&gEfiUsbIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return Status;
} }
UsbKeyboardDevice->ControllerNameTable = NULL; UsbKeyboardDevice->ControllerNameTable = NULL;
@@ -597,9 +377,11 @@ USBKeyboardDriverBindingStart (
FALSE FALSE
); );
return EFI_SUCCESS; return EFI_SUCCESS;
//
// Error handler
//
ErrorExit: ErrorExit:
if (UsbKeyboardDevice != NULL) { if (UsbKeyboardDevice != NULL) {
if (UsbKeyboardDevice->SimpleInput.WaitForKey != NULL) { if (UsbKeyboardDevice->SimpleInput.WaitForKey != NULL) {
@@ -608,7 +390,6 @@ ErrorExit:
if (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx != NULL) { if (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx != NULL) {
gBS->CloseEvent (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx); gBS->CloseEvent (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx);
} }
KbdFreeNotifyList (&UsbKeyboardDevice->NotifyList);
gBS->FreePool (UsbKeyboardDevice); gBS->FreePool (UsbKeyboardDevice);
UsbKeyboardDevice = NULL; UsbKeyboardDevice = NULL;
} }
@@ -624,7 +405,7 @@ ErrorExit:
/** /**
Stop handle the controller by this USB keyboard driver. Stop handling the controller by this USB keyboard driver.
@param This The USB keyboard driver binding protocol. @param This The USB keyboard driver binding protocol.
@param Controller The controller to release. @param Controller The controller to release.
@@ -632,6 +413,8 @@ ErrorExit:
@param ChildHandleBuffer The array of child handle. @param ChildHandleBuffer The array of child handle.
@retval EFI_SUCCESS The controller or children are stopped. @retval EFI_SUCCESS The controller or children are stopped.
@retval EFI_UNSUPPORTED Simple Text In Protocol or Simple Text In Ex Protocol
is not installed on Controller.
@retval EFI_DEVICE_ERROR Failed to stop the driver. @retval EFI_DEVICE_ERROR Failed to stop the driver.
**/ **/
@@ -644,9 +427,9 @@ USBKeyboardDriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer IN EFI_HANDLE *ChildHandleBuffer
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleInput; EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleInput;
USB_KB_DEV *UsbKeyboardDevice; USB_KB_DEV *UsbKeyboardDevice;
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol (
Controller, Controller,
@@ -659,6 +442,7 @@ USBKeyboardDriverBindingStop (
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol (
Controller, Controller,
&gEfiSimpleTextInputExProtocolGuid, &gEfiSimpleTextInputExProtocolGuid,
@@ -675,25 +459,17 @@ USBKeyboardDriverBindingStop (
// //
UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (SimpleInput); UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (SimpleInput);
gBS->CloseProtocol (
Controller,
&gEfiSimpleTextInProtocolGuid,
This->DriverBindingHandle,
Controller
);
// //
// Uninstall the Asyn Interrupt Transfer from this device // The key data input from this device will be disabled.
// will disable the key data input from this device
// //
KbdReportStatusCode ( REPORT_STATUS_CODE_WITH_DEVICE_PATH (
UsbKeyboardDevice->DevicePath,
EFI_PROGRESS_CODE, EFI_PROGRESS_CODE,
PcdGet32 (PcdStatusCodeValueKeyboardDisable) PcdGet32 (PcdStatusCodeValueKeyboardDisable),
UsbKeyboardDevice->DevicePath
); );
// //
// Destroy asynchronous interrupt transfer // Delete the Asynchronous Interrupt Transfer from this device
// //
UsbKeyboardDevice->UsbIo->UsbAsyncInterruptTransfer ( UsbKeyboardDevice->UsbIo->UsbAsyncInterruptTransfer (
UsbKeyboardDevice->UsbIo, UsbKeyboardDevice->UsbIo,
@@ -706,11 +482,11 @@ USBKeyboardDriverBindingStop (
); );
gBS->CloseProtocol ( gBS->CloseProtocol (
Controller, Controller,
&gEfiUsbIoProtocolGuid, &gEfiUsbIoProtocolGuid,
This->DriverBindingHandle, This->DriverBindingHandle,
Controller Controller
); );
Status = gBS->UninstallMultipleProtocolInterfaces ( Status = gBS->UninstallMultipleProtocolInterfaces (
Controller, Controller,
@@ -723,7 +499,7 @@ USBKeyboardDriverBindingStop (
NULL NULL
); );
// //
// free all the resources. // Free all resources.
// //
gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer); gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);
gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent); gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);
@@ -741,12 +517,10 @@ USBKeyboardDriverBindingStop (
gBS->FreePool (UsbKeyboardDevice); gBS->FreePool (UsbKeyboardDevice);
return Status; return Status;
} }
/** /**
Reads the next keystroke from the input device. The WaitForKey Event can Internal function to read the next keystroke from the input device.
be used to test for existance of a keystroke via WaitForEvent () call.
@param UsbKeyboardDevice Usb keyboard's private structure. @param UsbKeyboardDevice Usb keyboard's private structure.
@param KeyData A pointer to a buffer that is filled in with the keystroke @param KeyData A pointer to a buffer that is filled in with the keystroke
@@ -766,7 +540,6 @@ USBKeyboardReadKeyStrokeWorker (
OUT EFI_KEY_DATA *KeyData OUT EFI_KEY_DATA *KeyData
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINT8 KeyChar; UINT8 KeyChar;
LIST_ENTRY *Link; LIST_ENTRY *Link;
@@ -778,39 +551,47 @@ USBKeyboardReadKeyStrokeWorker (
} }
// //
// if there is no saved ASCII byte, fetch it // If there is no saved ASCII byte, fetch it
// by calling USBKeyboardCheckForKey(). // by calling USBKeyboardCheckForKey().
// //
if (UsbKeyboardDevice->CurKeyChar == 0) { if (UsbKeyboardDevice->CurKeyChar == 0) {
Status = USBKeyboardCheckForKey (UsbKeyboardDevice); Status = USBKeyboardCheckForKey (UsbKeyboardDevice);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return EFI_NOT_READY;
} }
} }
KeyData->Key.UnicodeChar = 0; KeyData->Key.UnicodeChar = 0;
KeyData->Key.ScanCode = SCAN_NULL; KeyData->Key.ScanCode = SCAN_NULL;
//
// Store the key char read by USBKeyboardCheckForKey() and clear it.
//
KeyChar = UsbKeyboardDevice->CurKeyChar; KeyChar = UsbKeyboardDevice->CurKeyChar;
UsbKeyboardDevice->CurKeyChar = 0; UsbKeyboardDevice->CurKeyChar = 0;
// //
// Translate saved ASCII byte into EFI_INPUT_KEY // Translate saved ASCII byte into EFI_INPUT_KEY
// //
Status = USBKeyCodeToEFIScanCode (UsbKeyboardDevice, KeyChar, &KeyData->Key); Status = UsbKeyCodeToEfiInputKey (UsbKeyboardDevice, KeyChar, &KeyData->Key);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return 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)); CopyMem (&KeyData->KeyState, &UsbKeyboardDevice->KeyState, sizeof (KeyData->KeyState));
UsbKeyboardDevice->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID; UsbKeyboardDevice->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
UsbKeyboardDevice->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID; UsbKeyboardDevice->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
// //
//Switch the control value to their original characters. In USBKeyCodeToEFIScanCode() the CTRL-Alpha characters have been switched to // Switch the control value to their original characters.
// their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A), here switch them back for notification function. // 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)); CopyMem (&OriginalKeyData, KeyData, sizeof (EFI_KEY_DATA));
if (UsbKeyboardDevice->CtrlOn != 0) { if (UsbKeyboardDevice->CtrlOn != 0) {
@@ -824,15 +605,12 @@ USBKeyboardReadKeyStrokeWorker (
} }
// //
// Invoke notification functions if exist // Invoke notification functions if the key is registered.
// //
for (Link = UsbKeyboardDevice->NotifyList.ForwardLink; Link != &UsbKeyboardDevice->NotifyList; Link = Link->ForwardLink) { for (Link = GetFirstNode (&UsbKeyboardDevice->NotifyList);
CurrentNotify = CR ( !IsNull (&UsbKeyboardDevice->NotifyList, Link);
Link, Link = GetNextNode (&UsbKeyboardDevice->NotifyList, Link)) {
KEYBOARD_CONSOLE_IN_EX_NOTIFY, CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
NotifyEntry,
USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
if (IsKeyRegistered (&CurrentNotify->KeyData, &OriginalKeyData)) { if (IsKeyRegistered (&CurrentNotify->KeyData, &OriginalKeyData)) {
CurrentNotify->KeyNotificationFn (&OriginalKeyData); CurrentNotify->KeyNotificationFn (&OriginalKeyData);
} }
@@ -843,20 +621,27 @@ USBKeyboardReadKeyStrokeWorker (
} }
/** /**
Reset Usb Keyboard. Reset USB Keyboard.
There are 2 types of reset for USB keyboard.
For non-exhaustive reset, only keyboard buffer is cleared.
For exhaustive reset, in addition to clearance of keyboard buffer, the hardware status
is also re-initialized.
@param This The protocol instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL. @param This The protocol instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
@param ExtendedVerification Whether completely reset keyboard or not. @param ExtendedVerification Indicates if exhaustive reset is used.
TRUE for exhaustive reset.
FALSE for non-exhaustive reset.
@retval EFI_SUCCESS Reset keyboard successfully. @retval EFI_SUCCESS Keyboard is reset successfully.
@retval EFI_DEVICE_ERROR Reset keyboard failed. @retval EFI_DEVICE_ERROR Failed to reset keyboard.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
USBKeyboardReset ( USBKeyboardReset (
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
IN BOOLEAN ExtendedVerification IN BOOLEAN ExtendedVerification
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@@ -864,35 +649,35 @@ USBKeyboardReset (
UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This); UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);
KbdReportStatusCode ( REPORT_STATUS_CODE_WITH_DEVICE_PATH (
UsbKeyboardDevice->DevicePath,
EFI_PROGRESS_CODE, EFI_PROGRESS_CODE,
PcdGet32 (PcdStatusCodeValueKeyboardReset) PcdGet32 (PcdStatusCodeValueKeyboardReset),
UsbKeyboardDevice->DevicePath
); );
// //
// Non Exhaustive reset: // Non-exhaustive reset:
// only reset private data structures. // only reset private data structures.
// //
if (!ExtendedVerification) { if (!ExtendedVerification) {
// REPORT_STATUS_CODE_WITH_DEVICE_PATH (
// Clear the key buffer of this Usb keyboard
//
KbdReportStatusCode (
UsbKeyboardDevice->DevicePath,
EFI_PROGRESS_CODE, EFI_PROGRESS_CODE,
PcdGet32 (PcdStatusCodeValueKeyboardClearBuffer) PcdGet32 (PcdStatusCodeValueKeyboardClearBuffer),
UsbKeyboardDevice->DevicePath
); );
//
// Clear the key buffer of this USB keyboard
//
InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer)); InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer));
UsbKeyboardDevice->CurKeyChar = 0; UsbKeyboardDevice->CurKeyChar = 0;
return EFI_SUCCESS; return EFI_SUCCESS;
} }
// //
// Exhaustive reset // Exhaustive reset
// //
Status = InitUSBKeyboard (UsbKeyboardDevice); Status = InitUSBKeyboard (UsbKeyboardDevice);
UsbKeyboardDevice->CurKeyChar = 0; UsbKeyboardDevice->CurKeyChar = 0;
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
@@ -917,7 +702,7 @@ EFI_STATUS
EFIAPI EFIAPI
USBKeyboardReadKeyStroke ( USBKeyboardReadKeyStroke (
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
OUT EFI_INPUT_KEY *Key OUT EFI_INPUT_KEY *Key
) )
{ {
USB_KB_DEV *UsbKeyboardDevice; USB_KB_DEV *UsbKeyboardDevice;
@@ -944,7 +729,6 @@ USBKeyboardReadKeyStroke (
@param Event Event to be signaled when a key is pressed. @param Event Event to be signaled when a key is pressed.
@param Context Points to USB_KB_DEV instance. @param Context Points to USB_KB_DEV instance.
@return None.
**/ **/
VOID VOID
EFIAPI EFIAPI
@@ -958,13 +742,15 @@ USBKeyboardWaitForKey (
UsbKeyboardDevice = (USB_KB_DEV *) Context; UsbKeyboardDevice = (USB_KB_DEV *) Context;
if (UsbKeyboardDevice->CurKeyChar == 0) { if (UsbKeyboardDevice->CurKeyChar == 0) {
if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice))) { if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice))) {
//
// If no pending key, simply return.
//
return ; return ;
} }
} }
// //
// If has key pending, signal the event. // If there is pending key, signal the event.
// //
gBS->SignalEvent (Event); gBS->SignalEvent (Event);
} }
@@ -975,8 +761,8 @@ USBKeyboardWaitForKey (
@param UsbKeyboardDevice The USB_KB_DEV instance. @param UsbKeyboardDevice The USB_KB_DEV instance.
@retval EFI_SUCCESS Have key pending to read. @retval EFI_SUCCESS There is pending key to read.
@retval Other Parse key failed. @retval EFI_NOT_READY No pending key to read.
**/ **/
EFI_STATUS EFI_STATUS
@@ -994,39 +780,13 @@ USBKeyboardCheckForKey (
// //
Status = USBParseKey (UsbKeyboardDevice, &KeyChar); Status = USBParseKey (UsbKeyboardDevice, &KeyChar);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return EFI_NOT_READY;
} }
UsbKeyboardDevice->CurKeyChar = KeyChar; UsbKeyboardDevice->CurKeyChar = KeyChar;
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Report Status Code in Usb Keyboard Driver.
@param DevicePath Use this to get Device Path.
@param CodeType Status Code Type.
@param CodeValue Status Code Value.
@return None.
**/
VOID
EFIAPI
KbdReportStatusCode (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN EFI_STATUS_CODE_TYPE CodeType,
IN EFI_STATUS_CODE_VALUE Value
)
{
REPORT_STATUS_CODE_WITH_DEVICE_PATH (
CodeType,
Value,
DevicePath
);
}
/** /**
Free keyboard notify list. Free keyboard notify list.
@@ -1274,7 +1034,9 @@ USBKeyboardRegisterKeyNotify (
// //
// Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered. // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
// //
for (Link = UsbKeyboardDevice->NotifyList.ForwardLink; Link != &UsbKeyboardDevice->NotifyList; Link = Link->ForwardLink) { for (Link = GetFirstNode (&UsbKeyboardDevice->NotifyList);
!IsNull (&UsbKeyboardDevice->NotifyList, Link);
Link = GetNextNode (&UsbKeyboardDevice->NotifyList, Link)) {
CurrentNotify = CR ( CurrentNotify = CR (
Link, Link,
KEYBOARD_CONSOLE_IN_EX_NOTIFY, KEYBOARD_CONSOLE_IN_EX_NOTIFY,
@@ -1349,6 +1111,9 @@ USBKeyboardUnregisterKeyNotify (
UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This); UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);
//
// Check if NotificationHandle is returned from RegisterKeyNotify().
//
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol (
NotificationHandle, NotificationHandle,
&gSimpleTextInExNotifyGuid, &gSimpleTextInExNotifyGuid,
@@ -1361,7 +1126,12 @@ USBKeyboardUnregisterKeyNotify (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
for (Link = UsbKeyboardDevice->NotifyList.ForwardLink; Link != &UsbKeyboardDevice->NotifyList; Link = Link->ForwardLink) { //
// Traverse notify list of USB keyboard and remove the entry of NotificationHandle.
//
for (Link = GetFirstNode (&UsbKeyboardDevice->NotifyList);
!IsNull (&UsbKeyboardDevice->NotifyList, Link);
Link = GetNextNode (&UsbKeyboardDevice->NotifyList, Link)) {
CurrentNotify = CR ( CurrentNotify = CR (
Link, Link,
KEYBOARD_CONSOLE_IN_EX_NOTIFY, KEYBOARD_CONSOLE_IN_EX_NOTIFY,

View File

@@ -1,6 +1,5 @@
/** @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 Copyright (c) 2004 - 2008, Intel Corporation
All rights reserved. This program and the accompanying materials All rights reserved. This program and the accompanying materials
@@ -37,6 +36,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/PcdLib.h> #include <Library/PcdLib.h>
#include <Library/UefiUsbLib.h> #include <Library/UefiUsbLib.h>
#include <Library/BaseLib.h> #include <Library/BaseLib.h>
#include <Library/UefiUsbLib.h>
#include <IndustryStandard/Usb.h> #include <IndustryStandard/Usb.h>
@@ -59,9 +59,9 @@ typedef struct {
} USB_KEY; } USB_KEY;
typedef struct { typedef struct {
USB_KEY buffer[MAX_KEY_ALLOWED + 1]; USB_KEY Buffer[MAX_KEY_ALLOWED + 1];
UINT8 bHead; UINT8 BufferHead;
UINT8 bTail; UINT8 BufferTail;
} USB_KB_BUFFER; } USB_KB_BUFFER;
#define USB_KB_DEV_SIGNATURE EFI_SIGNATURE_32 ('u', 'k', 'b', 'd') #define USB_KB_DEV_SIGNATURE EFI_SIGNATURE_32 ('u', 'k', 'b', 'd')
@@ -95,57 +95,60 @@ typedef struct {
#define USB_NS_KEY_FORM_FROM_LINK(a) CR (a, USB_NS_KEY, Link, USB_NS_KEY_SIGNATURE) #define USB_NS_KEY_FORM_FROM_LINK(a) CR (a, USB_NS_KEY, Link, USB_NS_KEY_SIGNATURE)
///
/// Structure to describe USB keyboard device
///
typedef struct { typedef struct {
UINTN Signature; UINTN Signature;
EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_EVENT DelayedRecoveryEvent; EFI_EVENT DelayedRecoveryEvent;
EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleInput; EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleInput;
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL SimpleInputEx; EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL SimpleInputEx;
EFI_USB_IO_PROTOCOL *UsbIo; EFI_USB_IO_PROTOCOL *UsbIo;
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_KB_BUFFER KeyboardBuffer;
UINT8 CtrlOn; UINT8 CtrlOn;
UINT8 AltOn; UINT8 AltOn;
UINT8 ShiftOn; UINT8 ShiftOn;
UINT8 NumLockOn; UINT8 NumLockOn;
UINT8 CapsOn; UINT8 CapsOn;
UINT8 ScrollOn; UINT8 ScrollOn;
UINT8 LastKeyCodeArray[8]; UINT8 LastKeyCodeArray[8];
UINT8 CurKeyChar; UINT8 CurKeyChar;
UINT8 RepeatKey; UINT8 RepeatKey;
EFI_EVENT RepeatTimer; EFI_EVENT RepeatTimer;
EFI_UNICODE_STRING_TABLE *ControllerNameTable; EFI_UNICODE_STRING_TABLE *ControllerNameTable;
UINT8 LeftCtrlOn; UINT8 LeftCtrlOn;
UINT8 LeftAltOn; UINT8 LeftAltOn;
UINT8 LeftShiftOn; UINT8 LeftShiftOn;
UINT8 LeftLogoOn; UINT8 LeftLogoOn;
UINT8 RightCtrlOn; UINT8 RightCtrlOn;
UINT8 RightAltOn; UINT8 RightAltOn;
UINT8 RightShiftOn; UINT8 RightShiftOn;
UINT8 RightLogoOn; UINT8 RightLogoOn;
UINT8 MenuKeyOn; UINT8 MenuKeyOn;
UINT8 SysReqOn; UINT8 SysReqOn;
UINT8 AltGrOn; UINT8 AltGrOn;
EFI_KEY_STATE KeyState; EFI_KEY_STATE KeyState;
// //
// Notification function list // Notification function list
// //
LIST_ENTRY NotifyList; LIST_ENTRY NotifyList;
// //
// Non-spacing key list // Non-spacing key list
// //
LIST_ENTRY NsKeyList; LIST_ENTRY NsKeyList;
USB_NS_KEY *CurrentNsKey; USB_NS_KEY *CurrentNsKey;
EFI_KEY_DESCRIPTOR *KeyConvertionTable; EFI_KEY_DESCRIPTOR *KeyConvertionTable;
EFI_EVENT KeyboardLayoutEvent; EFI_EVENT KeyboardLayoutEvent;
} USB_KB_DEV; } USB_KB_DEV;
// //
@@ -154,27 +157,8 @@ typedef struct {
extern EFI_DRIVER_BINDING_PROTOCOL gUsbKeyboardDriverBinding; extern EFI_DRIVER_BINDING_PROTOCOL gUsbKeyboardDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gUsbKeyboardComponentName; extern EFI_COMPONENT_NAME_PROTOCOL gUsbKeyboardComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gUsbKeyboardComponentName2; extern EFI_COMPONENT_NAME2_PROTOCOL gUsbKeyboardComponentName2;
extern EFI_GUID gEfiUsbKeyboardDriverGuid;
extern EFI_GUID gSimpleTextInExNotifyGuid; extern EFI_GUID gSimpleTextInExNotifyGuid;
/**
Report Status Code in Usb Keyboard Driver.
@param DevicePath Use this to get Device Path.
@param CodeType Status Code Type.
@param CodeValue Status Code Value.
@return None.
**/
VOID
EFIAPI
KbdReportStatusCode (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN EFI_STATUS_CODE_TYPE CodeType,
IN EFI_STATUS_CODE_VALUE Value
);
#define USB_KB_DEV_FROM_THIS(a) \ #define USB_KB_DEV_FROM_THIS(a) \
CR(a, USB_KB_DEV, SimpleInput, USB_KB_DEV_SIGNATURE) CR(a, USB_KB_DEV, SimpleInput, USB_KB_DEV_SIGNATURE)
#define TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS(a) \ #define TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS(a) \
@@ -206,6 +190,117 @@ typedef struct {
UINT8 Resrvd : 5; UINT8 Resrvd : 5;
} LED_MAP; } LED_MAP;
//
// Functions of Driver Binding Protocol
//
/**
Check whether USB keyboard driver supports this device.
@param This The USB keyboard driver binding protocol.
@param Controller The controller handle to check.
@param RemainingDevicePath The remaining device path.
@retval EFI_SUCCESS The driver supports this controller.
@retval other This device isn't supported.
**/
EFI_STATUS
EFIAPI
USBKeyboardDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
/**
Start running driver on the controller.
@param This The USB keyboard driver binding instance.
@param Controller Handle of device to bind driver to.
@param RemainingDevicePath Optional parameter use to pick a specific child
device to start.
@retval EFI_SUCCESS The controller is controlled by the usb keyboard driver.
@retval EFI_UNSUPPORTED No interrupt endpoint can be found.
@retval Other The keyboard driver cannot support this controller.
**/
EFI_STATUS
EFIAPI
USBKeyboardDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
/**
Stop handling the controller by this USB keyboard driver.
@param This The USB keyboard driver binding protocol.
@param Controller The controller to release.
@param NumberOfChildren The number of handles in ChildHandleBuffer.
@param ChildHandleBuffer The array of child handle.
@retval EFI_SUCCESS The controller or children are stopped.
@retval EFI_UNSUPPORTED Simple Text In Protocol or Simple Text In Ex Protocol
is not installed on Controller.
@retval EFI_DEVICE_ERROR Failed to stop the driver.
**/
EFI_STATUS
EFIAPI
USBKeyboardDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
//
// Functions of Simple Text Input Protocol
//
/**
Reset USB Keyboard.
There are 2 types of reset for USB keyboard.
For non-exhaustive reset, only keyboard buffer is cleared.
For exhaustive reset, in addition to clearance of keyboard buffer, the hardware status
is also re-initialized.
@param This The protocol instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
@param ExtendedVerification Indicates if exhaustive reset is used.
TRUE for exhaustive reset.
FALSE for non-exhaustive reset.
@retval EFI_SUCCESS Keyboard is reset successfully.
@retval EFI_DEVICE_ERROR Failed to reset keyboard.
**/
EFI_STATUS
EFIAPI
USBKeyboardReset (
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
);
/**
Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke() function.
@param This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.
@param Key A pointer to a buffer that is filled in with the keystroke
information for the key that was pressed.
@retval EFI_SUCCESS Read key stroke successfully.
@retval Other Read key stroke failed.
**/
EFI_STATUS
EFIAPI
USBKeyboardReadKeyStroke (
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
OUT EFI_INPUT_KEY *Key
);
// //
// Simple Text Input Ex protocol functions // Simple Text Input Ex protocol functions
// //
@@ -309,5 +404,68 @@ USBKeyboardUnregisterKeyNotify (
IN EFI_HANDLE NotificationHandle IN EFI_HANDLE NotificationHandle
); );
/**
Handler function for WaitForKey event.
@param Event Event to be signaled when a key is pressed.
@param Context Points to USB_KB_DEV instance.
**/
VOID
EFIAPI
USBKeyboardWaitForKey (
IN EFI_EVENT Event,
IN VOID *Context
);
/**
Free keyboard notify list.
@param ListHead The list head.
@retval EFI_SUCCESS Free the notify list successfully.
@retval EFI_INVALID_PARAMETER ListHead is invalid.
**/
EFI_STATUS
EFIAPI
KbdFreeNotifyList (
IN OUT LIST_ENTRY *ListHead
);
/**
Check whether there is key pending.
@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 USB_KB_DEV *UsbKeyboardDevice
);
/**
Whether the pressed key matches a registered key or not.
@param RegsiteredData A pointer to a buffer that is filled in with the keystroke
state data for the key that was registered.
@param InputData A pointer to a buffer that is filled in with the keystroke
state data for the key that was pressed.
@retval TRUE Key pressed matches a registered key.
@retval FLASE Match failed.
**/
BOOLEAN
EFIAPI
IsKeyRegistered (
IN EFI_KEY_DATA *RegsiteredData,
IN EFI_KEY_DATA *InputData
);
#endif #endif

View File

@@ -1,5 +1,4 @@
/** @file /** @file
Helper functions for USB Keyboard Driver. Helper functions for USB Keyboard Driver.
Copyright (c) 2004 - 2008, Intel Corporation Copyright (c) 2004 - 2008, Intel Corporation
@@ -14,7 +13,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/ **/
#include "KeyBoard.h" #include "KeyBoard.h"
#include <Library/UefiUsbLib.h>
// //
// Static English keyboard layout // Static English keyboard layout
@@ -295,12 +293,10 @@ KB_MODIFIER KB_Mod[8] = {
{ MOD_WIN_R, 0xe7 }, // 11100111 { MOD_WIN_R, 0xe7 }, // 11100111
}; };
/** /**
Initialize KeyConvertionTable by using default keyboard layout. Initialize KeyConvertionTable by using default keyboard layout.
@param UsbKeyboardDevice The USB_KB_DEV instance. @param UsbKeyboardDevice The USB_KB_DEV instance.
@retval None.
**/ **/
VOID VOID
@@ -330,12 +326,10 @@ LoadDefaultKeyboardLayout (
} }
} }
/** /**
Uses USB I/O to check whether the device is a USB Keyboard device. Uses USB I/O to check whether the device is a USB Keyboard device.
@param UsbIo Points to a USB I/O protocol instance. @param UsbIo Points to a USB I/O protocol instance.
@retval None
**/ **/
BOOLEAN BOOLEAN
@@ -374,7 +368,7 @@ IsUSBKeyboard (
/** /**
Get current keyboard layout from HII database. Get current keyboard layout from HII database.
@retval Pointer to EFI_HII_KEYBOARD_LAYOUT. @return Pointer to EFI_HII_KEYBOARD_LAYOUT.
**/ **/
EFI_HII_KEYBOARD_LAYOUT * EFI_HII_KEYBOARD_LAYOUT *
@@ -437,6 +431,7 @@ GetCurrentKeyboardLayout (
@param ScanCode USB scan code. @param ScanCode USB scan code.
@return The Key descriptor in KeyConvertionTable. @return The Key descriptor in KeyConvertionTable.
NULL means not found.
**/ **/
EFI_KEY_DESCRIPTOR * EFI_KEY_DESCRIPTOR *
@@ -467,8 +462,8 @@ GetKeyDescriptor (
@param UsbKeyboardDevice The USB_KB_DEV instance. @param UsbKeyboardDevice The USB_KB_DEV instance.
@param KeyDescriptor Key descriptor. @param KeyDescriptor Key descriptor.
@retval NULL Key list is empty. @return The Non-Spacing key corresponding to KeyDescriptor
@return Other The Non-Spacing key. NULL means not found.
**/ **/
USB_NS_KEY * USB_NS_KEY *
@@ -566,12 +561,15 @@ SetKeyboardLayoutEvent (
} }
// //
// Allocate resource for KeyConvertionTable // Re-allocate resource for KeyConvertionTable
// //
ReleaseKeyboardLayoutResources (UsbKeyboardDevice); ReleaseKeyboardLayoutResources (UsbKeyboardDevice);
UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((USB_KEYCODE_MAX_MAKE + 8) * sizeof (EFI_KEY_DESCRIPTOR)); UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((USB_KEYCODE_MAX_MAKE + 8) * sizeof (EFI_KEY_DESCRIPTOR));
ASSERT (UsbKeyboardDevice->KeyConvertionTable != NULL); ASSERT (UsbKeyboardDevice->KeyConvertionTable != NULL);
//
// Traverse the list of key descriptors following the header of EFI_HII_KEYBOARD_LAYOUT
//
KeyDescriptor = (EFI_KEY_DESCRIPTOR *) (((UINT8 *) KeyboardLayout) + sizeof (EFI_HII_KEYBOARD_LAYOUT)); KeyDescriptor = (EFI_KEY_DESCRIPTOR *) (((UINT8 *) KeyboardLayout) + sizeof (EFI_HII_KEYBOARD_LAYOUT));
for (Index = 0; Index < KeyboardLayout->DescriptorCount; Index++) { for (Index = 0; Index < KeyboardLayout->DescriptorCount; Index++) {
// //
@@ -580,7 +578,7 @@ SetKeyboardLayoutEvent (
CopyMem (&TempKey, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR)); CopyMem (&TempKey, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));
// //
// Fill the key into KeyConvertionTable (which use USB Scan Code as index) // Fill the key into KeyConvertionTable, whose index is calculated from USB scan code.
// //
ScanCode = UsbScanCodeConvertionTable [(UINT8) (TempKey.Key)]; ScanCode = UsbScanCodeConvertionTable [(UINT8) (TempKey.Key)];
TableEntry = GetKeyDescriptor (UsbKeyboardDevice, ScanCode); TableEntry = GetKeyDescriptor (UsbKeyboardDevice, ScanCode);
@@ -588,7 +586,7 @@ SetKeyboardLayoutEvent (
if (TempKey.Modifier == EFI_NS_KEY_MODIFIER) { if (TempKey.Modifier == EFI_NS_KEY_MODIFIER) {
// //
// Non-spacing key // For non-spacing key, create the list with a non-spacing key followed by physical keys.
// //
UsbNsKey = AllocatePool (sizeof (USB_NS_KEY)); UsbNsKey = AllocatePool (sizeof (USB_NS_KEY));
ASSERT (UsbNsKey != NULL); ASSERT (UsbNsKey != NULL);
@@ -692,7 +690,8 @@ InitKeyboardLayout (
UsbKeyboardDevice->KeyboardLayoutEvent = NULL; UsbKeyboardDevice->KeyboardLayoutEvent = NULL;
// //
// Register SET_KEYBOARD_LAYOUT_EVENT notification // Register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group,
// which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout.
// //
Status = gBS->CreateEventEx ( Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL, EVT_NOTIFY_SIGNAL,
@@ -706,26 +705,26 @@ InitKeyboardLayout (
return Status; return Status;
} }
//
// Try to get current keyboard layout from HII database
//
KeyboardLayout = GetCurrentKeyboardLayout (); KeyboardLayout = GetCurrentKeyboardLayout ();
if (KeyboardLayout != NULL) { if (KeyboardLayout != NULL) {
// //
// Force to initialize the keyboard layout // If current keyboard layout is successfully retrieved from HII database,
// force to initialize the keyboard layout.
// //
gBS->SignalEvent (UsbKeyboardDevice->KeyboardLayoutEvent); gBS->SignalEvent (UsbKeyboardDevice->KeyboardLayoutEvent);
} else { } else {
if (FeaturePcdGet (PcdDisableDefaultKeyboardLayoutInUsbKbDriver)) { if (FeaturePcdGet (PcdDisableDefaultKeyboardLayoutInUsbKbDriver)) {
//
// If no keyboard layout can be retrieved from HII database, and default layout
// is disabled, then return EFI_NOT_READY.
//
return EFI_NOT_READY; return EFI_NOT_READY;
} else {
//
// Fail to get keyboard layout from HII database,
// use default keyboard layout
//
LoadDefaultKeyboardLayout (UsbKeyboardDevice);
} }
//
// If no keyboard layout can be retrieved from HII database, and default layout
// is enabled, then load the default keyboard layout.
//
LoadDefaultKeyboardLayout (UsbKeyboardDevice);
} }
return EFI_SUCCESS; return EFI_SUCCESS;
@@ -754,10 +753,10 @@ InitUSBKeyboard (
EFI_STATUS Status; EFI_STATUS Status;
UINT32 TransferResult; UINT32 TransferResult;
KbdReportStatusCode ( REPORT_STATUS_CODE_WITH_DEVICE_PATH (
UsbKeyboardDevice->DevicePath,
EFI_PROGRESS_CODE, EFI_PROGRESS_CODE,
PcdGet32 (PcdStatusCodeValueKeyboardSelfTest) PcdGet32 (PcdStatusCodeValueKeyboardSelfTest),
UsbKeyboardDevice->DevicePath
); );
InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer)); InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer));
@@ -771,20 +770,20 @@ InitUSBKeyboard (
// Uses default configuration to configure the USB Keyboard device. // Uses default configuration to configure the USB Keyboard device.
// //
Status = UsbSetConfiguration ( Status = UsbSetConfiguration (
UsbKeyboardDevice->UsbIo, UsbKeyboardDevice->UsbIo,
(UINT16) ConfigValue, (UINT16) ConfigValue,
&TransferResult &TransferResult
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
// //
// If configuration could not be set here, it means // If configuration could not be set here, it means
// the keyboard interface has some errors and could // the keyboard interface has some errors and could
// not be initialized // not be initialized
// //
KbdReportStatusCode ( REPORT_STATUS_CODE_WITH_DEVICE_PATH (
UsbKeyboardDevice->DevicePath,
EFI_ERROR_CODE | EFI_ERROR_MINOR, EFI_ERROR_CODE | EFI_ERROR_MINOR,
PcdGet32 (PcdStatusCodeValueKeyboardInterfaceError) PcdGet32 (PcdStatusCodeValueKeyboardInterfaceError),
UsbKeyboardDevice->DevicePath
); );
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
@@ -796,9 +795,9 @@ InitUSBKeyboard (
&Protocol &Protocol
); );
// //
// Sets boot protocol for the USB Keyboard. // Set boot protocol for the USB Keyboard.
// This driver only supports boot protocol. // This driver only supports boot protocol.
// !!BugBug: How about the device that does not support boot protocol? // The device that does not support boot protocol is not supported.
// //
if (Protocol != BOOT_PROTOCOL) { if (Protocol != BOOT_PROTOCOL) {
UsbSetProtocolRequest ( UsbSetProtocolRequest (
@@ -807,17 +806,15 @@ InitUSBKeyboard (
BOOT_PROTOCOL BOOT_PROTOCOL
); );
} }
//
// the duration is indefinite, so the endpoint will inhibit reporting forever,
// and only reporting when a change is detected in the report data.
//
// //
// idle value for all report ID // ReportId is zero, which means the idle rate applies to all input reports.
// //
ReportId = 0; ReportId = 0;
// //
// idle forever until there is a key pressed and released. // Duration is zero, which means the duration is indefinite.
// so the endpoint will inhibit reporting forever,
// and only reporting when a change is detected in the report data.
// //
Duration = 0; Duration = 0;
UsbSetIdleRequest ( UsbSetIdleRequest (
@@ -861,7 +858,7 @@ InitUSBKeyboard (
// //
if (UsbKeyboardDevice->RepeatTimer != NULL) { if (UsbKeyboardDevice->RepeatTimer != NULL) {
gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer); gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);
UsbKeyboardDevice->RepeatTimer = 0; UsbKeyboardDevice->RepeatTimer = NULL;
} }
Status = gBS->CreateEvent ( Status = gBS->CreateEvent (
@@ -874,7 +871,7 @@ InitUSBKeyboard (
if (UsbKeyboardDevice->DelayedRecoveryEvent != NULL) { if (UsbKeyboardDevice->DelayedRecoveryEvent != NULL) {
gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent); gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);
UsbKeyboardDevice->DelayedRecoveryEvent = 0; UsbKeyboardDevice->DelayedRecoveryEvent = NULL;
} }
Status = gBS->CreateEvent ( Status = gBS->CreateEvent (
@@ -928,7 +925,7 @@ KeyboardHandler (
UINT32 UsbStatus; UINT32 UsbStatus;
EFI_KEY_DESCRIPTOR *KeyDescriptor; EFI_KEY_DESCRIPTOR *KeyDescriptor;
ASSERT (Context); ASSERT (Context != NULL);
NewRepeatKey = 0; NewRepeatKey = 0;
UsbKeyboardDevice = (USB_KB_DEV *) Context; UsbKeyboardDevice = (USB_KB_DEV *) Context;
@@ -941,10 +938,10 @@ KeyboardHandler (
// //
// Some errors happen during the process // Some errors happen during the process
// //
KbdReportStatusCode ( REPORT_STATUS_CODE_WITH_DEVICE_PATH (
UsbKeyboardDevice->DevicePath,
EFI_ERROR_CODE | EFI_ERROR_MINOR, EFI_ERROR_CODE | EFI_ERROR_MINOR,
PcdGet32 (PcdStatusCodeValueKeyboardInputError) PcdGet32 (PcdStatusCodeValueKeyboardInputError),
UsbKeyboardDevice->DevicePath
); );
// //
@@ -968,37 +965,48 @@ KeyboardHandler (
// //
// Delete & Submit this interrupt again // Delete & Submit this interrupt again
// Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt.
// //
UsbIo->UsbAsyncInterruptTransfer ( UsbIo->UsbAsyncInterruptTransfer (
UsbIo, UsbIo,
UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress, UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,
FALSE, FALSE,
0, 0,
0, 0,
NULL, NULL,
NULL NULL
); );
//
// EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling
//
gBS->SetTimer ( gBS->SetTimer (
UsbKeyboardDevice->DelayedRecoveryEvent, UsbKeyboardDevice->DelayedRecoveryEvent,
TimerRelative, TimerRelative,
EFI_USB_INTERRUPT_DELAY EFI_USB_INTERRUPT_DELAY
); );
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
//
// If no error and no data, just return EFI_SUCCESS.
//
if (DataLength == 0 || Data == NULL) { if (DataLength == 0 || Data == NULL) {
return EFI_SUCCESS; return EFI_SUCCESS;
} }
//
// Following code checks current keyboard input report against old key code buffer.
// According to USB HID Firmware Specification, the report consists of 8 bytes.
// Byte 0 is map of Modifier keys.
// Byte 1 is reserved.
// Bytes 2 to 7 are keycodes.
//
CurKeyCodeBuffer = (UINT8 *) Data; CurKeyCodeBuffer = (UINT8 *) Data;
OldKeyCodeBuffer = UsbKeyboardDevice->LastKeyCodeArray; OldKeyCodeBuffer = UsbKeyboardDevice->LastKeyCodeArray;
// //
// checks for new key stroke. // Checks for new key stroke.
// if no new key got, return immediately.
// //
for (Index = 0; Index < 8; Index++) { for (Index = 0; Index < 8; Index++) {
if (OldKeyCodeBuffer[Index] != CurKeyCodeBuffer[Index]) { if (OldKeyCodeBuffer[Index] != CurKeyCodeBuffer[Index]) {
@@ -1006,26 +1014,29 @@ KeyboardHandler (
} }
} }
//
// If no new key, return EFI_SUCCESS immediately.
//
if (Index == 8) { if (Index == 8) {
return EFI_SUCCESS; return EFI_SUCCESS;
} }
// //
// Parse the modifier key // Parse the modifier key, which is the first byte of keyboard input report.
// //
CurModifierMap = CurKeyCodeBuffer[0]; CurModifierMap = CurKeyCodeBuffer[0];
OldModifierMap = OldKeyCodeBuffer[0]; OldModifierMap = OldKeyCodeBuffer[0];
// //
// handle modifier key's pressing or releasing situation. // Handle modifier key's pressing or releasing situation.
// //
for (Index = 0; Index < 8; Index++) { for (Index = 0; Index < 8; Index++) {
if ((CurModifierMap & KB_Mod[Index].Mask) != (OldModifierMap & KB_Mod[Index].Mask)) { if ((CurModifierMap & KB_Mod[Index].Mask) != (OldModifierMap & KB_Mod[Index].Mask)) {
// //
// if current modifier key is up, then // If current modifier key is up, then
// CurModifierMap & KB_Mod[Index].Mask = 0; // CurModifierMap & KB_Mod[Index].Mask = 0;
// otherwize it is a non-zero value. // otherwise it is a non-zero value.
// Inserts the pressed modifier key into key buffer. // Inserts the pressed modifier key into key buffer.
// //
Down = (UINT8) (CurModifierMap & KB_Mod[Index].Mask); Down = (UINT8) (CurModifierMap & KB_Mod[Index].Mask);
@@ -1034,7 +1045,8 @@ KeyboardHandler (
} }
// //
// handle normal key's releasing situation // Handle normal key's releasing situation
// Bytes 2 to 7 are normal keycodes
// //
KeyRelease = FALSE; KeyRelease = FALSE;
for (Index = 2; Index < 8; Index++) { for (Index = 2; Index < 8; Index++) {
@@ -1042,7 +1054,10 @@ KeyboardHandler (
if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index])) { if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index])) {
continue; continue;
} }
//
// For any key in old keycode buffer, if it is not in current keycode buffer,
// then it is released. Otherwise, it is not released.
//
KeyRelease = TRUE; KeyRelease = TRUE;
for (Index2 = 2; Index2 < 8; Index2++) { for (Index2 = 2; Index2 < 8; Index2++) {
@@ -1063,7 +1078,7 @@ KeyboardHandler (
0 0
); );
// //
// the original reapeat key is released. // The original repeat key is released.
// //
if (OldKeyCodeBuffer[Index] == UsbKeyboardDevice->RepeatKey) { if (OldKeyCodeBuffer[Index] == UsbKeyboardDevice->RepeatKey) {
UsbKeyboardDevice->RepeatKey = 0; UsbKeyboardDevice->RepeatKey = 0;
@@ -1072,18 +1087,18 @@ KeyboardHandler (
} }
// //
// original repeat key is released, cancel the repeat timer // If original repeat key is released, cancel the repeat timer
// //
if (UsbKeyboardDevice->RepeatKey == 0) { if (UsbKeyboardDevice->RepeatKey == 0) {
gBS->SetTimer ( gBS->SetTimer (
UsbKeyboardDevice->RepeatTimer, UsbKeyboardDevice->RepeatTimer,
TimerCancel, TimerCancel,
USBKBD_REPEAT_RATE USBKBD_REPEAT_RATE
); );
} }
// //
// handle normal key's pressing situation // Handle normal key's pressing situation
// //
KeyPress = FALSE; KeyPress = FALSE;
for (Index = 2; Index < 8; Index++) { for (Index = 2; Index < 8; Index++) {
@@ -1091,7 +1106,10 @@ KeyboardHandler (
if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index])) { if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index])) {
continue; continue;
} }
//
// For any key in current keycode buffer, if it is not in old keycode buffer,
// then it is pressed. Otherwise, it is not pressed.
//
KeyPress = TRUE; KeyPress = TRUE;
for (Index2 = 2; Index2 < 8; Index2++) { for (Index2 = 2; Index2 < 8; Index2++) {
@@ -1107,17 +1125,21 @@ KeyboardHandler (
if (KeyPress) { if (KeyPress) {
InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), CurKeyCodeBuffer[Index], 1); InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), CurKeyCodeBuffer[Index], 1);
// //
// NumLock pressed or CapsLock pressed // Handle repeat key
// //
KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, CurKeyCodeBuffer[Index]); KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, CurKeyCodeBuffer[Index]);
if (KeyDescriptor->Modifier == EFI_NUM_LOCK_MODIFIER || KeyDescriptor->Modifier == EFI_CAPS_LOCK_MODIFIER) { if (KeyDescriptor->Modifier == EFI_NUM_LOCK_MODIFIER || KeyDescriptor->Modifier == EFI_CAPS_LOCK_MODIFIER) {
//
// For NumLock or CapsLock pressed, there is no need to handle repeat key for them.
//
UsbKeyboardDevice->RepeatKey = 0; UsbKeyboardDevice->RepeatKey = 0;
} else { } else {
//
// Prepare new repeat key, and clear the original one.
//
NewRepeatKey = CurKeyCodeBuffer[Index]; NewRepeatKey = CurKeyCodeBuffer[Index];
//
// do not repeat the original repeated key
//
UsbKeyboardDevice->RepeatKey = 0; UsbKeyboardDevice->RepeatKey = 0;
} }
} }
@@ -1132,11 +1154,11 @@ KeyboardHandler (
} }
// //
// pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence // Pre-process KeyboardBuffer. Pop out the Ctrl, Alt, Del key in sequence
// and judge whether it will invoke reset event. // and judge whether it will invoke reset event.
// //
SavedTail = UsbKeyboardDevice->KeyboardBuffer.bTail; SavedTail = UsbKeyboardDevice->KeyboardBuffer.BufferTail;
Index = UsbKeyboardDevice->KeyboardBuffer.bHead; Index = UsbKeyboardDevice->KeyboardBuffer.BufferHead;
while (Index != SavedTail) { while (Index != SavedTail) {
RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey); RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey);
@@ -1171,7 +1193,7 @@ KeyboardHandler (
break; break;
// //
// Del Key Code // For Del Key, check if Ctrl + Alt + Del occurs for reset.
// //
case EFI_DELETE_MODIFIER: case EFI_DELETE_MODIFIER:
if (UsbKey.Down != 0) { if (UsbKey.Down != 0) {
@@ -1186,7 +1208,7 @@ KeyboardHandler (
} }
// //
// insert the key back to the buffer. // Insert the key back to the buffer,
// so the key sequence will not be destroyed. // so the key sequence will not be destroyed.
// //
InsertKeyCode ( InsertKeyCode (
@@ -1194,7 +1216,7 @@ KeyboardHandler (
UsbKey.KeyCode, UsbKey.KeyCode,
UsbKey.Down UsbKey.Down
); );
Index = UsbKeyboardDevice->KeyboardBuffer.bHead; Index = UsbKeyboardDevice->KeyboardBuffer.BufferHead;
} }
// //
@@ -1203,7 +1225,7 @@ KeyboardHandler (
// //
if (NewRepeatKey != 0) { if (NewRepeatKey != 0) {
// //
// sets trigger time to "Repeat Delay Time", // Sets trigger time to "Repeat Delay Time",
// to trigger the repeat timer when the key is hold long // to trigger the repeat timer when the key is hold long
// enough time. // enough time.
// //
@@ -1243,12 +1265,15 @@ USBParseKey (
while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice->KeyboardBuffer)) { while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice->KeyboardBuffer)) {
// //
// pops one raw data off. // Pops one raw data off.
// //
RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey); RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey);
KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode); KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode);
if (UsbKey.Down == 0) { if (UsbKey.Down == 0) {
//
// Key is released.
//
switch (KeyDescriptor->Modifier) { switch (KeyDescriptor->Modifier) {
// //
@@ -1417,7 +1442,7 @@ USBParseKey (
case EFI_NUM_LOCK_MODIFIER: case EFI_NUM_LOCK_MODIFIER:
UsbKeyboardDevice->NumLockOn ^= 1; UsbKeyboardDevice->NumLockOn ^= 1;
// //
// Turn on the NumLock light on KB // Set the NumLock light on keyboard
// //
SetKeyLED (UsbKeyboardDevice); SetKeyLED (UsbKeyboardDevice);
continue; continue;
@@ -1426,7 +1451,7 @@ USBParseKey (
case EFI_CAPS_LOCK_MODIFIER: case EFI_CAPS_LOCK_MODIFIER:
UsbKeyboardDevice->CapsOn ^= 1; UsbKeyboardDevice->CapsOn ^= 1;
// //
// Turn on the CapsLock light on KB // Set the CapsLock light on keyboard
// //
SetKeyLED (UsbKeyboardDevice); SetKeyLED (UsbKeyboardDevice);
continue; continue;
@@ -1435,22 +1460,22 @@ USBParseKey (
case EFI_SCROLL_LOCK_MODIFIER: case EFI_SCROLL_LOCK_MODIFIER:
UsbKeyboardDevice->ScrollOn ^= 1; UsbKeyboardDevice->ScrollOn ^= 1;
// //
// Turn on the ScrollLock light on KB // Set the ScrollLock light on keyboard
// //
SetKeyLED (UsbKeyboardDevice); SetKeyLED (UsbKeyboardDevice);
continue; continue;
break; break;
// //
// F11,F12,PrintScreen,Pause/Break // F11, F12, PrintScreen, Pause/Break
// could not be retrieved via SimpleTxtInEx protocol // could not be retrieved via SimpleTextInEx protocol
// //
case EFI_FUNCTION_KEY_ELEVEN_MODIFIER: case EFI_FUNCTION_KEY_ELEVEN_MODIFIER:
case EFI_FUNCTION_KEY_TWELVE_MODIFIER: case EFI_FUNCTION_KEY_TWELVE_MODIFIER:
case EFI_PAUSE_MODIFIER: case EFI_PAUSE_MODIFIER:
case EFI_BREAK_MODIFIER: case EFI_BREAK_MODIFIER:
// //
// fall through // Fall through
// //
continue; continue;
break; break;
@@ -1460,7 +1485,7 @@ USBParseKey (
} }
// //
// When encountered Del Key... // When encountering Ctrl + Alt + Del, then warm reset.
// //
if (KeyDescriptor->Modifier == EFI_DELETE_MODIFIER) { if (KeyDescriptor->Modifier == EFI_DELETE_MODIFIER) {
if ((UsbKeyboardDevice->CtrlOn != 0) && (UsbKeyboardDevice->AltOn != 0)) { if ((UsbKeyboardDevice->CtrlOn != 0) && (UsbKeyboardDevice->AltOn != 0)) {
@@ -1477,7 +1502,7 @@ USBParseKey (
/** /**
Converts USB Keyboard code to EFI Scan Code. Converts USB Keyboard code to EFI_INPUT_KEY.
@param UsbKeyboardDevice The USB_KB_DEV instance. @param UsbKeyboardDevice The USB_KB_DEV instance.
@param KeyChar Indicates the key code that will be interpreted. @param KeyChar Indicates the key code that will be interpreted.
@@ -1491,7 +1516,7 @@ USBParseKey (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
USBKeyCodeToEFIScanCode ( UsbKeyCodeToEfiInputKey (
IN USB_KB_DEV *UsbKeyboardDevice, IN USB_KB_DEV *UsbKeyboardDevice,
IN UINT8 KeyChar, IN UINT8 KeyChar,
OUT EFI_INPUT_KEY *Key OUT EFI_INPUT_KEY *Key
@@ -1505,7 +1530,7 @@ USBKeyCodeToEFIScanCode (
} }
// //
// valid USB Key Code starts from 4 // Valid USB Key Code starts from 4, so it's safe to minus 4.
// //
Index = (UINT8) (KeyChar - 4); Index = (UINT8) (KeyChar - 4);
@@ -1515,18 +1540,19 @@ USBKeyCodeToEFIScanCode (
KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, KeyChar); KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, KeyChar);
//
// Check for Non-spacing key
//
if (KeyDescriptor->Modifier == EFI_NS_KEY_MODIFIER) { if (KeyDescriptor->Modifier == EFI_NS_KEY_MODIFIER) {
//
// If this is a dead key with EFI_NS_KEY_MODIFIER, then record it and return.
//
UsbKeyboardDevice->CurrentNsKey = FindUsbNsKey (UsbKeyboardDevice, KeyDescriptor); UsbKeyboardDevice->CurrentNsKey = FindUsbNsKey (UsbKeyboardDevice, KeyDescriptor);
return EFI_NOT_READY; return EFI_NOT_READY;
} }
//
// Check whether this keystroke follows a Non-spacing key
//
if (UsbKeyboardDevice->CurrentNsKey != NULL) { if (UsbKeyboardDevice->CurrentNsKey != NULL) {
//
// If this keystroke follows a non-spacing key, then find the descriptor for corresponding
// physical key.
//
KeyDescriptor = FindPhysicalKey (UsbKeyboardDevice->CurrentNsKey, KeyDescriptor); KeyDescriptor = FindPhysicalKey (UsbKeyboardDevice->CurrentNsKey, KeyDescriptor);
UsbKeyboardDevice->CurrentNsKey = NULL; UsbKeyboardDevice->CurrentNsKey = NULL;
} }
@@ -1534,7 +1560,7 @@ USBKeyCodeToEFIScanCode (
Key->ScanCode = EfiScanCodeConvertionTable[KeyDescriptor->Modifier]; Key->ScanCode = EfiScanCodeConvertionTable[KeyDescriptor->Modifier];
Key->UnicodeChar = KeyDescriptor->Unicode; Key->UnicodeChar = KeyDescriptor->Unicode;
if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_STANDARD_SHIFT) { if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_STANDARD_SHIFT)!= 0) {
if (UsbKeyboardDevice->ShiftOn != 0) { if (UsbKeyboardDevice->ShiftOn != 0) {
Key->UnicodeChar = KeyDescriptor->ShiftedUnicode; Key->UnicodeChar = KeyDescriptor->ShiftedUnicode;
@@ -1542,7 +1568,7 @@ USBKeyCodeToEFIScanCode (
// 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
// are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F' // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
// //
if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) { if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) != 0) {
UsbKeyboardDevice->LeftShiftOn = 0; UsbKeyboardDevice->LeftShiftOn = 0;
UsbKeyboardDevice->RightShiftOn = 0; UsbKeyboardDevice->RightShiftOn = 0;
} }
@@ -1562,7 +1588,7 @@ USBKeyCodeToEFIScanCode (
} }
} }
if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) { if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) != 0) {
if (UsbKeyboardDevice->CapsOn != 0) { if (UsbKeyboardDevice->CapsOn != 0) {
if (Key->UnicodeChar == KeyDescriptor->Unicode) { if (Key->UnicodeChar == KeyDescriptor->Unicode) {
@@ -1578,7 +1604,8 @@ USBKeyCodeToEFIScanCode (
} }
// //
// Translate the CTRL-Alpha characters to their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A) // Translate the CTRL-Alpha characters to their corresponding control value
// (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
// //
if (UsbKeyboardDevice->CtrlOn != 0) { if (UsbKeyboardDevice->CtrlOn != 0) {
if (Key->UnicodeChar >= 'a' && Key->UnicodeChar <= 'z') { if (Key->UnicodeChar >= 'a' && Key->UnicodeChar <= 'z') {
@@ -1589,11 +1616,13 @@ USBKeyCodeToEFIScanCode (
} }
if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_NUM_LOCK) { if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_NUM_LOCK) {
//
// For key affected by NumLock, if NumLock is on and Shift is not pressed, then it means
// normal key, instead of original control key. So the ScanCode should be cleaned.
// Otherwise, it means control key, so preserve the EFI Scan Code and clear the unicode keycode.
//
if ((UsbKeyboardDevice->NumLockOn != 0) && (UsbKeyboardDevice->ShiftOn == 0)) { if ((UsbKeyboardDevice->NumLockOn != 0) && (UsbKeyboardDevice->ShiftOn == 0)) {
Key->ScanCode = SCAN_NULL; Key->ScanCode = SCAN_NULL;
} else { } else {
Key->UnicodeChar = 0x00; Key->UnicodeChar = 0x00;
} }
@@ -1607,6 +1636,9 @@ USBKeyCodeToEFIScanCode (
Key->UnicodeChar = 0x00; Key->UnicodeChar = 0x00;
} }
//
// Not valid for key without both unicode key code and EFI Scan Code.
//
if (Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) { if (Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) {
return EFI_NOT_READY; return EFI_NOT_READY;
} }
@@ -1666,10 +1698,8 @@ USBKeyCodeToEFIScanCode (
@param KeyboardBuffer Points to the USB Keyboard Buffer. @param KeyboardBuffer Points to the USB Keyboard Buffer.
@retval EFI_SUCCESS Init key buffer successfully.
**/ **/
EFI_STATUS VOID
EFIAPI EFIAPI
InitUSBKeyBuffer ( InitUSBKeyBuffer (
IN OUT USB_KB_BUFFER *KeyboardBuffer IN OUT USB_KB_BUFFER *KeyboardBuffer
@@ -1677,9 +1707,7 @@ InitUSBKeyBuffer (
{ {
ZeroMem (KeyboardBuffer, sizeof (USB_KB_BUFFER)); ZeroMem (KeyboardBuffer, sizeof (USB_KB_BUFFER));
KeyboardBuffer->bHead = KeyboardBuffer->bTail; KeyboardBuffer->BufferHead = KeyboardBuffer->BufferTail;
return EFI_SUCCESS;
} }
@@ -1701,7 +1729,7 @@ IsUSBKeyboardBufferEmpty (
// //
// meet FIFO empty condition // meet FIFO empty condition
// //
return (BOOLEAN) (KeyboardBuffer->bHead == KeyboardBuffer->bTail); return (BOOLEAN) (KeyboardBuffer->BufferHead == KeyboardBuffer->BufferTail);
} }
@@ -1720,8 +1748,7 @@ IsUSBKeyboardBufferFull (
IN USB_KB_BUFFER *KeyboardBuffer IN USB_KB_BUFFER *KeyboardBuffer
) )
{ {
return (BOOLEAN)(((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1)) == return (BOOLEAN)(((KeyboardBuffer->BufferTail + 1) % (MAX_KEY_ALLOWED + 1)) == KeyboardBuffer->BufferHead);
KeyboardBuffer->bHead);
} }
@@ -1732,10 +1759,8 @@ IsUSBKeyboardBufferFull (
@param Key Key code @param Key Key code
@param Down Special key @param Down Special key
@retval EFI_SUCCESS Success
**/ **/
EFI_STATUS VOID
EFIAPI EFIAPI
InsertKeyCode ( InsertKeyCode (
IN OUT USB_KB_BUFFER *KeyboardBuffer, IN OUT USB_KB_BUFFER *KeyboardBuffer,
@@ -1753,15 +1778,13 @@ InsertKeyCode (
RemoveKeyCode (KeyboardBuffer, &UsbKey); RemoveKeyCode (KeyboardBuffer, &UsbKey);
} }
KeyboardBuffer->buffer[KeyboardBuffer->bTail].KeyCode = Key; KeyboardBuffer->Buffer[KeyboardBuffer->BufferTail].KeyCode = Key;
KeyboardBuffer->buffer[KeyboardBuffer->bTail].Down = Down; 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->bTail = (UINT8) ((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1)); KeyboardBuffer->BufferTail = (UINT8) ((KeyboardBuffer->BufferTail + 1) % (MAX_KEY_ALLOWED + 1));
return EFI_SUCCESS;
} }
@@ -1771,8 +1794,8 @@ InsertKeyCode (
@param KeyboardBuffer Points to the USB Keyboard Buffer. @param KeyboardBuffer Points to the USB Keyboard Buffer.
@param UsbKey Points to the buffer that contains a usb key code. @param UsbKey Points to the buffer that contains a usb key code.
@retval EFI_SUCCESS Success @retval EFI_SUCCESS Key code Successfully poped from keyboard buffer.
@retval EFI_DEVICE_ERROR Hardware Error @retval EFI_DEVICE_ERROR Keyboard buffer is empty.
**/ **/
EFI_STATUS EFI_STATUS
@@ -1786,13 +1809,13 @@ RemoveKeyCode (
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
UsbKey->KeyCode = KeyboardBuffer->buffer[KeyboardBuffer->bHead].KeyCode; UsbKey->KeyCode = KeyboardBuffer->Buffer[KeyboardBuffer->BufferHead].KeyCode;
UsbKey->Down = KeyboardBuffer->buffer[KeyboardBuffer->bHead].Down; 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->bHead = (UINT8) ((KeyboardBuffer->bHead + 1) % (MAX_KEY_ALLOWED + 1)); KeyboardBuffer->BufferHead = (UINT8) ((KeyboardBuffer->BufferHead + 1) % (MAX_KEY_ALLOWED + 1));
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@@ -1803,10 +1826,8 @@ RemoveKeyCode (
@param UsbKeyboardDevice The USB_KB_DEV instance. @param UsbKeyboardDevice The USB_KB_DEV instance.
@retval EFI_SUCCESS Success
**/ **/
EFI_STATUS VOID
EFIAPI EFIAPI
SetKeyLED ( SetKeyLED (
IN USB_KB_DEV *UsbKeyboardDevice IN USB_KB_DEV *UsbKeyboardDevice
@@ -1825,7 +1846,7 @@ SetKeyLED (
ReportId = 0; ReportId = 0;
// //
// call Set Report Request to lighten the LED. // Call Set_Report Request to lighten the LED.
// //
UsbSetReportRequest ( UsbSetReportRequest (
UsbKeyboardDevice->UsbIo, UsbKeyboardDevice->UsbIo,
@@ -1835,8 +1856,6 @@ SetKeyLED (
1, 1,
(UINT8 *) &Led (UINT8 *) &Led
); );
return EFI_SUCCESS;
} }
@@ -1846,7 +1865,6 @@ SetKeyLED (
@param Event The Repeat Key event. @param Event The Repeat Key event.
@param Context Points to the USB_KB_DEV instance. @param Context Points to the USB_KB_DEV instance.
**/ **/
VOID VOID
EFIAPI EFIAPI
@@ -1873,14 +1891,13 @@ USBKeyboardRepeatHandler (
); );
// //
// set repeate rate for repeat key generation. // Set repeate rate for next repeat key generation.
// //
gBS->SetTimer ( gBS->SetTimer (
UsbKeyboardDevice->RepeatTimer, UsbKeyboardDevice->RepeatTimer,
TimerRelative, TimerRelative,
USBKBD_REPEAT_RATE USBKBD_REPEAT_RATE
); );
} }
} }
@@ -1891,7 +1908,6 @@ USBKeyboardRepeatHandler (
@param Event The Delayed Recovery event. @param Event The Delayed Recovery event.
@param Context Points to the USB_KB_DEV instance. @param Context Points to the USB_KB_DEV instance.
**/ **/
VOID VOID
EFIAPI EFIAPI
@@ -1911,13 +1927,16 @@ USBKeyboardRecoveryHandler (
PacketSize = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize); PacketSize = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize);
//
// Re-submit Asynchronous Interrupt Transfer for recovery.
//
UsbIo->UsbAsyncInterruptTransfer ( UsbIo->UsbAsyncInterruptTransfer (
UsbIo, UsbIo,
UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress, UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,
TRUE, TRUE,
UsbKeyboardDevice->IntEndpointDescriptor.Interval, UsbKeyboardDevice->IntEndpointDescriptor.Interval,
PacketSize, PacketSize,
KeyboardHandler, KeyboardHandler,
UsbKeyboardDevice UsbKeyboardDevice
); );
} }

View File

@@ -1,5 +1,4 @@
/** @file /** @file
Function prototype for USB Keyboard Driver. Function prototype for USB Keyboard Driver.
Copyright (c) 2004 - 2008, Intel Corporation Copyright (c) 2004 - 2008, Intel Corporation
@@ -143,7 +142,7 @@ USBParseKey (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
USBKeyCodeToEFIScanCode ( UsbKeyCodeToEfiInputKey (
IN USB_KB_DEV *UsbKeyboardDevice, IN USB_KB_DEV *UsbKeyboardDevice,
IN UINT8 KeyChar, IN UINT8 KeyChar,
OUT EFI_INPUT_KEY *Key OUT EFI_INPUT_KEY *Key
@@ -154,10 +153,8 @@ USBKeyCodeToEFIScanCode (
@param KeyboardBuffer Points to the USB Keyboard Buffer. @param KeyboardBuffer Points to the USB Keyboard Buffer.
@retval EFI_SUCCESS Init key buffer successfully.
**/ **/
EFI_STATUS VOID
EFIAPI EFIAPI
InitUSBKeyBuffer ( InitUSBKeyBuffer (
IN OUT USB_KB_BUFFER *KeyboardBuffer IN OUT USB_KB_BUFFER *KeyboardBuffer
@@ -200,10 +197,8 @@ IsUSBKeyboardBufferFull (
@param Key Key code @param Key Key code
@param Down Special key @param Down Special key
@retval EFI_SUCCESS Success
**/ **/
EFI_STATUS VOID
EFIAPI EFIAPI
InsertKeyCode ( InsertKeyCode (
IN OUT USB_KB_BUFFER *KeyboardBuffer, IN OUT USB_KB_BUFFER *KeyboardBuffer,
@@ -248,10 +243,8 @@ USBKeyboardRepeatHandler (
@param UsbKeyboardDevice The USB_KB_DEV instance. @param UsbKeyboardDevice The USB_KB_DEV instance.
@retval EFI_SUCCESS Success
**/ **/
EFI_STATUS VOID
EFIAPI EFIAPI
SetKeyLED ( SetKeyLED (
IN USB_KB_DEV *UsbKeyboardDevice IN USB_KB_DEV *UsbKeyboardDevice