From: vanjeff Date: Thu, 12 Jul 2007 17:31:28 +0000 (+0000) Subject: 1. Import UsbKbDxe and UsbMouseDxe into MdeModulePkg X-Git-Tag: edk2-stable201903~22739 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=ed838d0c5ec4d4f2f1c1898fff1c6c619ff46352 1. Import UsbKbDxe and UsbMouseDxe into MdeModulePkg 2. Updated UefiUsbLib git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3216 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/MdeModulePkg/Bus/Usb/UsbKbDxe/ComponentName.c b/MdeModulePkg/Bus/Usb/UsbKbDxe/ComponentName.c new file mode 100644 index 0000000000..db8fe6b4f6 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbKbDxe/ComponentName.c @@ -0,0 +1,217 @@ +/** @file + +Copyright (c) 2004 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + ComponentName.c + +Abstract: + + +**/ + + +#include "keyboard.h" + +// +// EFI Component Name Functions +// +EFI_STATUS +EFIAPI +UsbKeyboardComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +EFI_STATUS +EFIAPI +UsbKeyboardComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +// +// EFI Component Name Protocol +// +EFI_COMPONENT_NAME_PROTOCOL gUsbKeyboardComponentName = { + UsbKeyboardComponentNameGetDriverName, + UsbKeyboardComponentNameGetControllerName, + "eng" +}; + +STATIC EFI_UNICODE_STRING_TABLE mUsbKeyboardDriverNameTable[] = { + { "eng", L"Usb Keyboard Driver" }, + { NULL , NULL } +}; + + +EFI_STATUS +EFIAPI +UsbKeyboardComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +/*++ + + Routine Description: + Retrieves a Unicode string that is the user readable name of the EFI Driver. + + Arguments: + This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + Language - A pointer to a three character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + DriverName - A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + Returns: + EFI_SUCCESS - The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + EFI_INVALID_PARAMETER - Language is NULL. + EFI_INVALID_PARAMETER - DriverName is NULL. + EFI_UNSUPPORTED - The driver specified by This does not support the + language specified by Language. + +--*/ +{ + return LookupUnicodeString ( + Language, + gUsbKeyboardComponentName.SupportedLanguages, + mUsbKeyboardDriverNameTable, + DriverName + ); +} + +EFI_STATUS +EFIAPI +UsbKeyboardComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +/*++ + + Routine Description: + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + Arguments: + This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + ControllerHandle - The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + ChildHandle - The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + Language - A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + ControllerName - A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language specified + by Language from the point of view of the driver specified + by This. + + Returns: + EFI_SUCCESS - The Unicode string for the user readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE. + EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE. + EFI_INVALID_PARAMETER - Language is NULL. + EFI_INVALID_PARAMETER - ControllerName is NULL. + EFI_UNSUPPORTED - The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + EFI_UNSUPPORTED - The driver specified by This does not support the + language specified by Language. + +--*/ +{ + EFI_STATUS Status; + USB_KB_DEV *UsbKbDev; + EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleTxtIn; + EFI_USB_IO_PROTOCOL *UsbIoProtocol; + // + // This is a device driver, so ChildHandle must be NULL. + // + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + // + // Check Controller's handle + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiUsbIoProtocolGuid, + (VOID **) &UsbIoProtocol, + gUsbKeyboardDriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (!EFI_ERROR (Status)) { + gBS->CloseProtocol ( + ControllerHandle, + &gEfiUsbIoProtocolGuid, + gUsbKeyboardDriverBinding.DriverBindingHandle, + ControllerHandle + ); + + return EFI_UNSUPPORTED; + } + + if (Status != EFI_ALREADY_STARTED) { + return EFI_UNSUPPORTED; + } + // + // Get the device context + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiSimpleTextInProtocolGuid, + (VOID **) &SimpleTxtIn, + gUsbKeyboardDriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + UsbKbDev = USB_KB_DEV_FROM_THIS (SimpleTxtIn); + + return LookupUnicodeString ( + Language, + gUsbKeyboardComponentName.SupportedLanguages, + UsbKbDev->ControllerNameTable, + ControllerName + ); + +} diff --git a/MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf b/MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf new file mode 100644 index 0000000000..dfe7a2cabf --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf @@ -0,0 +1,121 @@ +#/** @file +# Component name for module UsbKb +# +# FIX ME! +# Copyright (c) 2006, Intel Corporation. All right reserved. +# +# All rights reserved. This program and the accompanying materials +# 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 +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UsbKbDxe + FILE_GUID = 2D2E62CF-9ECF-43b7-8219-94E7FC713DFE + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = USBKeyboardDriverBindingEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + efikey.c + efikey.h + keyboard.c + ComponentName.c + keyboard.h + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + MemoryAllocationLib + UefiLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiRuntimeServicesTableLib + BaseMemoryLib + ReportStatusCodeLib + DebugLib + PcdLib + UsbLib + + +################################################################################ +# +# Guid C Name Section - list of Guids that this module uses or produces. +# +################################################################################ + +[Guids] + gEfiHotPlugDeviceGuid # ALWAYS_CONSUMED + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gEfiUsbIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiSimpleTextInProtocolGuid # PROTOCOL ALWAYS_CONSUMED + +################################################################################ +# +# Pcd FIXED_AT_BUILD - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsFixedAtBuild] + PcdStatusCodeValueKeyboardEnable|gEfiMdePkgTokenSpaceGuid + PcdStatusCodeValueKeyboardPresenceDetect|gEfiMdePkgTokenSpaceGuid + PcdStatusCodeValueKeyboardDisable|gEfiMdePkgTokenSpaceGuid + PcdStatusCodeValueKeyboardReset|gEfiMdePkgTokenSpaceGuid + PcdStatusCodeValueKeyboardClearBuffer|gEfiMdePkgTokenSpaceGuid + PcdStatusCodeValueKeyboardSelfTest|gEfiMdePkgTokenSpaceGuid + PcdStatusCodeValueKeyboardInterfaceError|gEfiMdePkgTokenSpaceGuid + PcdStatusCodeValueKeyboardInputError|gEfiMdePkgTokenSpaceGuid \ No newline at end of file diff --git a/MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.msa b/MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.msa new file mode 100644 index 0000000000..b476aef100 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.msa @@ -0,0 +1,84 @@ + + + UsbKbDxe + DXE_DRIVER + 2D2E62CF-9ECF-43b7-8219-94E7FC713DFE + 1.0 + Component name for module UsbKb + FIX ME! + Copyright (c) 2006, Intel Corporation. All right reserved. + All rights reserved. This program and the accompanying materials + 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 + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + UsbKbDxe + + + + DebugLib + + + ReportStatusCodeLib + + + BaseMemoryLib + + + UefiRuntimeServicesTableLib + + + UefiDriverEntryPoint + + + UefiBootServicesTableLib + + + UefiLib + + + MemoryAllocationLib + + + + keyboard.h + ComponentName.c + keyboard.c + efikey.h + efikey.c + + + + + + + + gEfiSimpleTextInProtocolGuid + + + gEfiDevicePathProtocolGuid + + + gEfiUsbIoProtocolGuid + + + + + gEfiHotPlugDeviceGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + USBKeyboardDriverBindingEntryPoint + + + \ No newline at end of file diff --git a/MdeModulePkg/Bus/Usb/UsbKbDxe/efikey.c b/MdeModulePkg/Bus/Usb/UsbKbDxe/efikey.c new file mode 100644 index 0000000000..3ea788cdad --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbKbDxe/efikey.c @@ -0,0 +1,793 @@ +/** @file + +Copyright (c) 2004 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiKey.c + +Abstract: + + USB Keyboard Driver + +Revision History + + +**/ + +#include "efikey.h" +#include "keyboard.h" + +// +// Prototypes +// Driver model protocol interface +// +EFI_STATUS +EFIAPI +USBKeyboardDriverBindingEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_STATUS +EFIAPI +USBKeyboardDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +EFI_STATUS +EFIAPI +USBKeyboardDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +EFI_STATUS +EFIAPI +USBKeyboardDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ); + +// +// Simple Text In Protocol Interface +// +STATIC +EFI_STATUS +EFIAPI +USBKeyboardReset ( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +STATIC +EFI_STATUS +EFIAPI +USBKeyboardReadKeyStroke ( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + OUT EFI_INPUT_KEY *Key + ); + +STATIC +VOID +EFIAPI +USBKeyboardWaitForKey ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +// +// Helper functions +// +STATIC +EFI_STATUS +USBKeyboardCheckForKey ( + IN USB_KB_DEV *UsbKeyboardDevice + ); + +EFI_GUID gEfiUsbKeyboardDriverGuid = { + 0xa05f5f78, 0xfb3, 0x4d10, 0x90, 0x90, 0xac, 0x4, 0x6e, 0xeb, 0x7c, 0x3c +}; + +// +// USB Keyboard Driver Global Variables +// +EFI_DRIVER_BINDING_PROTOCOL gUsbKeyboardDriverBinding = { + USBKeyboardDriverBindingSupported, + USBKeyboardDriverBindingStart, + USBKeyboardDriverBindingStop, + 0xa, + NULL, + NULL +}; + +//@MT: EFI_DRIVER_ENTRY_POINT (USBKeyboardDriverBindingEntryPoint) + +EFI_STATUS +EFIAPI +USBKeyboardDriverBindingEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + + Routine Description: + Driver Entry Point. + + Arguments: + ImageHandle - EFI_HANDLE + SystemTable - EFI_SYSTEM_TABLE + Returns: + EFI_STATUS + +--*/ +{ + return EfiLibInstallAllDriverProtocols ( + ImageHandle, + SystemTable, + &gUsbKeyboardDriverBinding, + ImageHandle, + &gUsbKeyboardComponentName, + NULL, + NULL + ); +} + + + +/** + Supported. + + @param This EFI_DRIVER_BINDING_PROTOCOL + @param Controller Controller handle + @param RemainingDevicePath EFI_DEVICE_PATH_PROTOCOL + EFI_STATUS + +**/ +EFI_STATUS +EFIAPI +USBKeyboardDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS OpenStatus; + EFI_USB_IO_PROTOCOL *UsbIo; + EFI_STATUS Status; + + // + // Check if USB_IO protocol is attached on the controller handle. + // + OpenStatus = gBS->OpenProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + &UsbIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (OpenStatus)) { + return OpenStatus; + } + + // + // Use the USB I/O protocol interface to check whether the Controller is + // the Keyboard controller that can be managed by this driver. + // + Status = EFI_SUCCESS; + + if (!IsUSBKeyboard (UsbIo)) { + Status = EFI_UNSUPPORTED; + } + + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + return Status; +} + + +/** + Start. + + @param This EFI_DRIVER_BINDING_PROTOCOL + @param Controller Controller handle + @param RemainingDevicePath EFI_DEVICE_PATH_PROTOCOL + + @retval EFI_SUCCESS Success + @retval EFI_OUT_OF_RESOURCES Can't allocate memory + @retval EFI_UNSUPPORTED The Start routine fail + +**/ +EFI_STATUS +EFIAPI +USBKeyboardDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_USB_IO_PROTOCOL *UsbIo; + USB_KB_DEV *UsbKeyboardDevice; + UINT8 EndpointNumber; + EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor; + UINT8 Index; + UINT8 EndpointAddr; + UINT8 PollingInterval; + UINT8 PacketSize; + BOOLEAN Found; + + UsbKeyboardDevice = NULL; + Found = FALSE; + + // + // Open USB_IO Protocol + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + &UsbIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + + UsbKeyboardDevice = AllocateZeroPool (sizeof (USB_KB_DEV)); + if (UsbKeyboardDevice == NULL) { + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return EFI_OUT_OF_RESOURCES; + } + // + // Get the Device Path Protocol on Controller's handle + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &UsbKeyboardDevice->DevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + gBS->FreePool (UsbKeyboardDevice); + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return Status; + } + // + // Report that the usb keyboard is being enabled + // + KbdReportStatusCode ( + UsbKeyboardDevice->DevicePath, + EFI_PROGRESS_CODE, + PcdGet32 (PcdStatusCodeValueKeyboardEnable) + ); + + // + // This is pretty close to keyboard detection, so log progress + // + KbdReportStatusCode ( + UsbKeyboardDevice->DevicePath, + EFI_PROGRESS_CODE, + PcdGet32 (PcdStatusCodeValueKeyboardPresenceDetect) + ); + + // + // Initialize UsbKeyboardDevice + // + UsbKeyboardDevice->UsbIo = UsbIo; + + // + // Get interface & endpoint descriptor + // + UsbIo->UsbGetInterfaceDescriptor ( + UsbIo, + &UsbKeyboardDevice->InterfaceDescriptor + ); + + EndpointNumber = UsbKeyboardDevice->InterfaceDescriptor.NumEndpoints; + + for (Index = 0; Index < EndpointNumber; Index++) { + + UsbIo->UsbGetEndpointDescriptor ( + UsbIo, + Index, + &EndpointDescriptor + ); + + if ((EndpointDescriptor.Attributes & 0x03) == 0x03) { + // + // We only care interrupt endpoint here + // + UsbKeyboardDevice->IntEndpointDescriptor = EndpointDescriptor; + Found = TRUE; + } + } + + if (!Found) { + // + // No interrupt endpoint found, then return unsupported. + // + gBS->FreePool (UsbKeyboardDevice); + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return EFI_UNSUPPORTED; + } + + UsbKeyboardDevice->Signature = USB_KB_DEV_SIGNATURE; + UsbKeyboardDevice->SimpleInput.Reset = USBKeyboardReset; + UsbKeyboardDevice->SimpleInput.ReadKeyStroke = USBKeyboardReadKeyStroke; + Status = gBS->CreateEvent ( + EVT_NOTIFY_WAIT, + TPL_NOTIFY, + USBKeyboardWaitForKey, + UsbKeyboardDevice, + &(UsbKeyboardDevice->SimpleInput.WaitForKey) + ); + + if (EFI_ERROR (Status)) { + gBS->FreePool (UsbKeyboardDevice); + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return Status; + } + + // + // Install simple txt in protocol interface + // for the usb keyboard device. + // Usb keyboard is a hot plug device, and expected to work immediately + // when plugging into system, so a HotPlugDeviceGuid is installed onto + // the usb keyboard device handle, to distinguish it from other conventional + // console devices. + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &Controller, + &gEfiSimpleTextInProtocolGuid, + &UsbKeyboardDevice->SimpleInput, + &gEfiHotPlugDeviceGuid, + NULL, + NULL + ); + if (EFI_ERROR (Status)) { + gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey); + gBS->FreePool (UsbKeyboardDevice); + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return Status; + } + + // + // Reset USB Keyboard Device + // + Status = UsbKeyboardDevice->SimpleInput.Reset ( + &UsbKeyboardDevice->SimpleInput, + TRUE + ); + if (EFI_ERROR (Status)) { + gBS->UninstallMultipleProtocolInterfaces ( + Controller, + &gEfiSimpleTextInProtocolGuid, + &UsbKeyboardDevice->SimpleInput, + &gEfiHotPlugDeviceGuid, + NULL, + NULL + ); + gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey); + gBS->FreePool (UsbKeyboardDevice); + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return Status; + } + // + // submit async interrupt transfer + // + EndpointAddr = UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress; + PollingInterval = UsbKeyboardDevice->IntEndpointDescriptor.Interval; + PacketSize = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize); + + Status = UsbIo->UsbAsyncInterruptTransfer ( + UsbIo, + EndpointAddr, + TRUE, + PollingInterval, + PacketSize, + KeyboardHandler, + UsbKeyboardDevice + ); + + if (EFI_ERROR (Status)) { + + gBS->UninstallMultipleProtocolInterfaces ( + Controller, + &gEfiSimpleTextInProtocolGuid, + &UsbKeyboardDevice->SimpleInput, + &gEfiHotPlugDeviceGuid, + NULL, + NULL + ); + gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey); + gBS->FreePool (UsbKeyboardDevice); + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return Status; + } + + UsbKeyboardDevice->ControllerNameTable = NULL; + AddUnicodeString ( + "eng", + gUsbKeyboardComponentName.SupportedLanguages, + &UsbKeyboardDevice->ControllerNameTable, + L"Generic Usb Keyboard" + ); + + return EFI_SUCCESS; +} + + + +/** + Stop. + + @param This EFI_DRIVER_BINDING_PROTOCOL + @param Controller Controller handle + @param NumberOfChildren Child handle number + @param ChildHandleBuffer Child handle buffer + + @retval EFI_SUCCESS Success + @retval EFI_UNSUPPORTED Can't support + +**/ +EFI_STATUS +EFIAPI +USBKeyboardDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_STATUS Status; + EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleInput; + USB_KB_DEV *UsbKeyboardDevice; + EFI_USB_IO_PROTOCOL *UsbIo; + + Status = gBS->OpenProtocol ( + Controller, + &gEfiSimpleTextInProtocolGuid, + &SimpleInput, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + // + // Get USB_KB_DEV instance. + // + UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (SimpleInput); + + gBS->CloseProtocol ( + Controller, + &gEfiSimpleTextInProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + UsbIo = UsbKeyboardDevice->UsbIo; + // + // Uninstall the Asyn Interrupt Transfer from this device + // will disable the key data input from this device + // + KbdReportStatusCode ( + UsbKeyboardDevice->DevicePath, + EFI_PROGRESS_CODE, + PcdGet32 (PcdStatusCodeValueKeyboardDisable) + ); + + // + // Destroy asynchronous interrupt transfer + // + UsbKeyboardDevice->UsbIo->UsbAsyncInterruptTransfer ( + UsbKeyboardDevice->UsbIo, + UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress, + FALSE, + UsbKeyboardDevice->IntEndpointDescriptor.Interval, + 0, + NULL, + NULL + ); + + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + Status = gBS->UninstallMultipleProtocolInterfaces ( + Controller, + &gEfiSimpleTextInProtocolGuid, + &UsbKeyboardDevice->SimpleInput, + &gEfiHotPlugDeviceGuid, + NULL, + NULL + ); + // + // free all the resources. + // + gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer); + gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent); + gBS->CloseEvent ((UsbKeyboardDevice->SimpleInput).WaitForKey); + + if (UsbKeyboardDevice->ControllerNameTable != NULL) { + FreeUnicodeStringTable (UsbKeyboardDevice->ControllerNameTable); + } + + gBS->FreePool (UsbKeyboardDevice); + + return Status; + +} + + + +/** + Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset() function. + + This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance. + ExtendedVerification + Indicates that the driver may perform a more exhaustive + verification operation of the device during reset. + + @retval EFI_SUCCESS Success + @retval EFI_DEVICE_ERROR Hardware Error + +**/ +EFI_STATUS +EFIAPI +USBKeyboardReset ( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + EFI_STATUS Status; + USB_KB_DEV *UsbKeyboardDevice; + EFI_USB_IO_PROTOCOL *UsbIo; + + UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This); + + UsbIo = UsbKeyboardDevice->UsbIo; + + KbdReportStatusCode ( + UsbKeyboardDevice->DevicePath, + EFI_PROGRESS_CODE, + PcdGet32 (PcdStatusCodeValueKeyboardReset) + ); + + // + // Non Exhaustive reset: + // only reset private data structures. + // + if (!ExtendedVerification) { + // + // Clear the key buffer of this Usb keyboard + // + KbdReportStatusCode ( + UsbKeyboardDevice->DevicePath, + EFI_PROGRESS_CODE, + PcdGet32 (PcdStatusCodeValueKeyboardClearBuffer) + ); + + InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer)); + UsbKeyboardDevice->CurKeyChar = 0; + return EFI_SUCCESS; + } + + // + // Exhaustive reset + // + Status = InitUSBKeyboard (UsbKeyboardDevice); + UsbKeyboardDevice->CurKeyChar = 0; + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + + +/** + Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke() function. + + This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance. + Key A pointer to a buffer that is filled in with the keystroke + information for the key that was pressed. + + @retval EFI_SUCCESS Success + +**/ +STATIC +EFI_STATUS +EFIAPI +USBKeyboardReadKeyStroke ( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + OUT EFI_INPUT_KEY *Key + ) +{ + USB_KB_DEV *UsbKeyboardDevice; + EFI_STATUS Status; + UINT8 KeyChar; + + UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This); + + // + // if there is no saved ASCII byte, fetch it + // by calling USBKeyboardCheckForKey(). + // + if (UsbKeyboardDevice->CurKeyChar == 0) { + Status = USBKeyboardCheckForKey (UsbKeyboardDevice); + if (EFI_ERROR (Status)) { + return Status; + } + } + + Key->UnicodeChar = 0; + Key->ScanCode = SCAN_NULL; + + KeyChar = UsbKeyboardDevice->CurKeyChar; + + UsbKeyboardDevice->CurKeyChar = 0; + + // + // Translate saved ASCII byte into EFI_INPUT_KEY + // + Status = USBKeyCodeToEFIScanCode (UsbKeyboardDevice, KeyChar, Key); + + return Status; + +} + + +/** + Handler function for WaitForKey event. + + Event Event to be signaled when a key is pressed. + Context Points to USB_KB_DEV instance. + + @return VOID + +**/ +STATIC +VOID +EFIAPI +USBKeyboardWaitForKey ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + USB_KB_DEV *UsbKeyboardDevice; + + UsbKeyboardDevice = (USB_KB_DEV *) Context; + + if (UsbKeyboardDevice->CurKeyChar == 0) { + + if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice))) { + return ; + } + } + // + // If has key pending, signal the event. + // + gBS->SignalEvent (Event); +} + + + +/** + Check whether there is key pending. + + UsbKeyboardDevice The USB_KB_DEV instance. + + @retval EFI_SUCCESS Success + +**/ +STATIC +EFI_STATUS +USBKeyboardCheckForKey ( + IN USB_KB_DEV *UsbKeyboardDevice + ) +{ + EFI_STATUS Status; + UINT8 KeyChar; + + // + // Fetch raw data from the USB keyboard input, + // and translate it into ASCII data. + // + Status = USBParseKey (UsbKeyboardDevice, &KeyChar); + if (EFI_ERROR (Status)) { + return Status; + } + + UsbKeyboardDevice->CurKeyChar = KeyChar; + return EFI_SUCCESS; +} + + +/** + Report Status Code in Usb Bot Driver + + @param DevicePath Use this to get Device Path + @param CodeType Status Code Type + @param CodeValue Status Code Value + + @return None + +**/ +VOID +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 + ); +} diff --git a/MdeModulePkg/Bus/Usb/UsbKbDxe/efikey.h b/MdeModulePkg/Bus/Usb/UsbKbDxe/efikey.h new file mode 100644 index 0000000000..e93a8665a4 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbKbDxe/efikey.h @@ -0,0 +1,146 @@ +/** @file +Copyright (c) 2004 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiKey.h + +Abstract: + + Header file for USB Keyboard Driver's Data Structures + +Revision History + +**/ +#ifndef _USB_KB_H +#define _USB_KB_H + +// +// The package level header files this module uses +// +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +#define MAX_KEY_ALLOWED 32 + +#define HZ 1000 * 1000 * 10 +#define USBKBD_REPEAT_DELAY ((HZ) / 2) +#define USBKBD_REPEAT_RATE ((HZ) / 50) + +#define CLASS_HID 3 +#define SUBCLASS_BOOT 1 +#define PROTOCOL_KEYBOARD 1 + +#define BOOT_PROTOCOL 0 +#define REPORT_PROTOCOL 1 + +typedef struct { + UINT8 Down; + UINT8 KeyCode; +} USB_KEY; + +typedef struct { + USB_KEY buffer[MAX_KEY_ALLOWED + 1]; + UINT8 bHead; + UINT8 bTail; +} USB_KB_BUFFER; + +#define USB_KB_DEV_SIGNATURE EFI_SIGNATURE_32 ('u', 'k', 'b', 'd') +typedef struct { + UINTN Signature; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_EVENT DelayedRecoveryEvent; + EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleInput; + EFI_USB_IO_PROTOCOL *UsbIo; + + EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor; + EFI_USB_ENDPOINT_DESCRIPTOR IntEndpointDescriptor; + + USB_KB_BUFFER KeyboardBuffer; + UINT8 CtrlOn; + UINT8 AltOn; + UINT8 ShiftOn; + UINT8 NumLockOn; + UINT8 CapsOn; + UINT8 ScrollOn; + UINT8 LastKeyCodeArray[8]; + UINT8 CurKeyChar; + + UINT8 RepeatKey; + EFI_EVENT RepeatTimer; + + EFI_UNICODE_STRING_TABLE *ControllerNameTable; + +} USB_KB_DEV; + +// +// Global Variables +// +extern EFI_DRIVER_BINDING_PROTOCOL gUsbKeyboardDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gUsbKeyboardComponentName; +extern EFI_GUID gEfiUsbKeyboardDriverGuid; + +VOID +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) \ + CR(a, USB_KB_DEV, SimpleInput, USB_KB_DEV_SIGNATURE) + +#define MOD_CONTROL_L 0x01 +#define MOD_CONTROL_R 0x10 +#define MOD_SHIFT_L 0x02 +#define MOD_SHIFT_R 0x20 +#define MOD_ALT_L 0x04 +#define MOD_ALT_R 0x40 +#define MOD_WIN_L 0x08 +#define MOD_WIN_R 0x80 + +typedef struct { + UINT8 Mask; + UINT8 Key; +} KB_MODIFIER; + +#define USB_KEYCODE_MAX_MAKE 0x64 + +#define USBKBD_VALID_KEYCODE(key) ((UINT8) (key) > 3) + +typedef struct { + UINT8 NumLock : 1; + UINT8 CapsLock : 1; + UINT8 ScrollLock : 1; + UINT8 Resrvd : 5; +} LED_MAP; +#endif diff --git a/MdeModulePkg/Bus/Usb/UsbKbDxe/keyboard.c b/MdeModulePkg/Bus/Usb/UsbKbDxe/keyboard.c new file mode 100644 index 0000000000..41286d6866 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbKbDxe/keyboard.c @@ -0,0 +1,1140 @@ +/** @file + +Copyright (c) 2004 - 2005, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + Keyboard.c + +Abstract: + + Helper functions for USB Keyboard Driver + +Revision History + + +**/ + +#include "keyboard.h" +#include +// +// USB Key Code to Efi key mapping table +// Format:, , +// +STATIC +UINT8 KeyConvertionTable[USB_KEYCODE_MAX_MAKE][3] = { + { SCAN_NULL, 'a', 'A' }, // 0x04 + { SCAN_NULL, 'b', 'B' }, // 0x05 + { SCAN_NULL, 'c', 'C' }, // 0x06 + { SCAN_NULL, 'd', 'D' }, // 0x07 + { SCAN_NULL, 'e', 'E' }, // 0x08 + { SCAN_NULL, 'f', 'F' }, // 0x09 + { SCAN_NULL, 'g', 'G' }, // 0x0A + { SCAN_NULL, 'h', 'H' }, // 0x0B + { SCAN_NULL, 'i', 'I' }, // 0x0C + { SCAN_NULL, 'j', 'J' }, // 0x0D + { SCAN_NULL, 'k', 'K' }, // 0x0E + { SCAN_NULL, 'l', 'L' }, // 0x0F + { SCAN_NULL, 'm', 'M' }, // 0x10 + { SCAN_NULL, 'n', 'N' }, // 0x11 + { SCAN_NULL, 'o', 'O' }, // 0x12 + { SCAN_NULL, 'p', 'P' }, // 0x13 + { SCAN_NULL, 'q', 'Q' }, // 0x14 + { SCAN_NULL, 'r', 'R' }, // 0x15 + { SCAN_NULL, 's', 'S' }, // 0x16 + { SCAN_NULL, 't', 'T' }, // 0x17 + { SCAN_NULL, 'u', 'U' }, // 0x18 + { SCAN_NULL, 'v', 'V' }, // 0x19 + { SCAN_NULL, 'w', 'W' }, // 0x1A + { SCAN_NULL, 'x', 'X' }, // 0x1B + { SCAN_NULL, 'y', 'Y' }, // 0x1C + { SCAN_NULL, 'z', 'Z' }, // 0x1D + { SCAN_NULL, '1', '!' }, // 0x1E + { SCAN_NULL, '2', '@' }, // 0x1F + { SCAN_NULL, '3', '#' }, // 0x20 + { SCAN_NULL, '4', '$' }, // 0x21 + { SCAN_NULL, '5', '%' }, // 0x22 + { SCAN_NULL, '6', '^' }, // 0x23 + { SCAN_NULL, '7', '&' }, // 0x24 + { SCAN_NULL, '8', '*' }, // 0x25 + { SCAN_NULL, '9', '(' }, // 0x26 + { SCAN_NULL, '0', ')' }, // 0x27 + { SCAN_NULL, 0x0d, 0x0d }, // 0x28 Enter + { SCAN_ESC, 0x00, 0x00 }, // 0x29 Esc + { SCAN_NULL, 0x08, 0x08 }, // 0x2A Backspace + { SCAN_NULL, 0x09, 0x09 }, // 0x2B Tab + { SCAN_NULL, ' ', ' ' }, // 0x2C Spacebar + { SCAN_NULL, '-', '_' }, // 0x2D + { SCAN_NULL, '=', '+' }, // 0x2E + { SCAN_NULL, '[', '{' }, // 0x2F + { SCAN_NULL, ']', '}' }, // 0x30 + { SCAN_NULL, '\\', '|' }, // 0x31 + { SCAN_NULL, '\\', '|' }, // 0x32 Keyboard US \ and | + { SCAN_NULL, ';', ':' }, // 0x33 + { SCAN_NULL, '\'', '"' }, // 0x34 + { SCAN_NULL, '`', '~' }, // 0x35 Keyboard Grave Accent and Tlide + { SCAN_NULL, ',', '<' }, // 0x36 + { SCAN_NULL, '.', '>' }, // 0x37 + { SCAN_NULL, '/', '?' }, // 0x38 + { SCAN_NULL, 0x00, 0x00 }, // 0x39 CapsLock + { SCAN_F1, 0x00, 0x00 }, // 0x3A + { SCAN_F2, 0x00, 0x00 }, // 0x3B + { SCAN_F3, 0x00, 0x00 }, // 0x3C + { SCAN_F4, 0x00, 0x00 }, // 0x3D + { SCAN_F5, 0x00, 0x00 }, // 0x3E + { SCAN_F6, 0x00, 0x00 }, // 0x3F + { SCAN_F7, 0x00, 0x00 }, // 0x40 + { SCAN_F8, 0x00, 0x00 }, // 0x41 + { SCAN_F9, 0x00, 0x00 }, // 0x42 + { SCAN_F10, 0x00, 0x00 }, // 0x43 + { SCAN_F11, 0x00, 0x00 }, // 0x44 F11 + { SCAN_F12, 0x00, 0x00 }, // 0x45 F12 + { SCAN_NULL, 0x00, 0x00 }, // 0x46 PrintScreen + { SCAN_NULL, 0x00, 0x00 }, // 0x47 Scroll Lock + { SCAN_NULL, 0x00, 0x00 }, // 0x48 Pause + { SCAN_INSERT, 0x00, 0x00 }, // 0x49 + { SCAN_HOME, 0x00, 0x00 }, // 0x4A + { SCAN_PAGE_UP, 0x00, 0x00 }, // 0x4B + { SCAN_DELETE, 0x00, 0x00 }, // 0x4C + { SCAN_END, 0x00, 0x00 }, // 0x4D + { SCAN_PAGE_DOWN, 0x00, 0x00 }, // 0x4E + { SCAN_RIGHT, 0x00, 0x00 }, // 0x4F + { SCAN_LEFT, 0x00, 0x00 }, // 0x50 + { SCAN_DOWN, 0x00, 0x00 }, // 0x51 + { SCAN_UP, 0x00, 0x00 }, // 0x52 + { SCAN_NULL, 0x00, 0x00 }, // 0x53 NumLock + { SCAN_NULL, '/', '/' }, // 0x54 + { SCAN_NULL, '*', '*' }, // 0x55 + { SCAN_NULL, '-', '-' }, // 0x56 + { SCAN_NULL, '+', '+' }, // 0x57 + { SCAN_NULL, 0x0d, 0x0d }, // 0x58 + { SCAN_END, '1', '1' }, // 0x59 + { SCAN_DOWN, '2', '2' }, // 0x5A + { SCAN_PAGE_DOWN, '3', '3' }, // 0x5B + { SCAN_LEFT, '4', '4' }, // 0x5C + { SCAN_NULL, '5', '5' }, // 0x5D + { SCAN_RIGHT, '6', '6' }, // 0x5E + { SCAN_HOME, '7', '7' }, // 0x5F + { SCAN_UP, '8', '8' }, // 0x60 + { SCAN_PAGE_UP, '9', '9' }, // 0x61 + { SCAN_INSERT, '0', '0' }, // 0x62 + { SCAN_DELETE, '.', '.' }, // 0x63 + { SCAN_NULL, '\\', '|' }, // 0x64 Keyboard Non-US \ and | + { SCAN_NULL, 0x00, 0x00 }, // 0x65 Keyboard Application + { SCAN_NULL, 0x00, 0x00 }, // 0x66 Keyboard Power + { SCAN_NULL, '=' , '=' } // 0x67 Keypad = +}; + +STATIC KB_MODIFIER KB_Mod[8] = { + { MOD_CONTROL_L, 0xe0 }, // 11100000 + { MOD_CONTROL_R, 0xe4 }, // 11100100 + { MOD_SHIFT_L, 0xe1 }, // 11100001 + { MOD_SHIFT_R, 0xe5 }, // 11100101 + { MOD_ALT_L, 0xe2 }, // 11100010 + { MOD_ALT_R, 0xe6 }, // 11100110 + { MOD_WIN_L, 0xe3 }, // 11100011 + { MOD_WIN_R, 0xe7 } // 11100111 +}; + + + +/** + Uses USB I/O to check whether the device is a USB Keyboard device. + + UsbIo: Points to a USB I/O protocol instance. + + +**/ +BOOLEAN +IsUSBKeyboard ( + IN EFI_USB_IO_PROTOCOL *UsbIo + ) +{ + EFI_STATUS Status; + EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor; + + // + // Get the Default interface descriptor, currently we + // assume it is interface 1 + // + Status = UsbIo->UsbGetInterfaceDescriptor ( + UsbIo, + &InterfaceDescriptor + ); + + if (EFI_ERROR (Status)) { + return FALSE; + } + + if (InterfaceDescriptor.InterfaceClass == CLASS_HID && + InterfaceDescriptor.InterfaceSubClass == SUBCLASS_BOOT && + InterfaceDescriptor.InterfaceProtocol == PROTOCOL_KEYBOARD + ) { + + return TRUE; + } + + return FALSE; +} + + + +/** + Initialize USB Keyboard device and all private data structures. + + UsbKeyboardDevice The USB_KB_DEV instance. + + @retval EFI_SUCCESS Success + @retval EFI_DEVICE_ERROR Hardware Error + +**/ +EFI_STATUS +InitUSBKeyboard ( + IN USB_KB_DEV *UsbKeyboardDevice + ) +{ + UINT8 ConfigValue; + UINT8 Protocol; + UINT8 ReportId; + UINT8 Duration; + EFI_STATUS Status; + UINT32 TransferResult; + EFI_USB_IO_PROTOCOL *UsbIo; + + UsbIo = UsbKeyboardDevice->UsbIo; + + KbdReportStatusCode ( + UsbKeyboardDevice->DevicePath, + EFI_PROGRESS_CODE, + PcdGet32 (PcdStatusCodeValueKeyboardSelfTest) + ); + + InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer)); + + // + // default configurations + // + ConfigValue = 0x01; + + // + // Uses default configuration to configure the USB Keyboard device. + // + Status = UsbSetConfiguration ( + UsbKeyboardDevice->UsbIo, + (UINT16) ConfigValue, + &TransferResult + ); + if (EFI_ERROR (Status)) { + // + // If configuration could not be set here, it means + // the keyboard interface has some errors and could + // not be initialized + // + KbdReportStatusCode ( + UsbKeyboardDevice->DevicePath, + EFI_ERROR_CODE | EFI_ERROR_MINOR, + PcdGet32 (PcdStatusCodeValueKeyboardInterfaceError) + ); + + return EFI_DEVICE_ERROR; + } + + UsbGetProtocolRequest ( + UsbKeyboardDevice->UsbIo, + UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber, + &Protocol + ); + // + // Sets boot protocol for the USB Keyboard. + // This driver only supports boot protocol. + // !!BugBug: How about the device that does not support boot protocol? + // + if (Protocol != BOOT_PROTOCOL) { + UsbSetProtocolRequest ( + UsbKeyboardDevice->UsbIo, + UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber, + 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 = 0; + // + // idle forever until there is a key pressed and released. + // + Duration = 0; + UsbSetIdleRequest ( + UsbKeyboardDevice->UsbIo, + UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber, + ReportId, + Duration + ); + + UsbKeyboardDevice->CtrlOn = 0; + UsbKeyboardDevice->AltOn = 0; + UsbKeyboardDevice->ShiftOn = 0; + UsbKeyboardDevice->NumLockOn = 0; + UsbKeyboardDevice->CapsOn = 0; + UsbKeyboardDevice->ScrollOn = 0; + + // + // Sync the initial state of lights + // + SetKeyLED (UsbKeyboardDevice); + + ZeroMem (UsbKeyboardDevice->LastKeyCodeArray, sizeof (UINT8) * 8); + + // + // Set a timer for repeat keys' generation. + // + if (UsbKeyboardDevice->RepeatTimer) { + gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer); + UsbKeyboardDevice->RepeatTimer = 0; + } + + Status = gBS->CreateEvent ( + EVT_TIMER | EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + USBKeyboardRepeatHandler, + UsbKeyboardDevice, + &UsbKeyboardDevice->RepeatTimer + ); + + if (UsbKeyboardDevice->DelayedRecoveryEvent) { + gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent); + UsbKeyboardDevice->DelayedRecoveryEvent = 0; + } + + Status = gBS->CreateEvent ( + EVT_TIMER | EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + USBKeyboardRecoveryHandler, + UsbKeyboardDevice, + &UsbKeyboardDevice->DelayedRecoveryEvent + ); + + return EFI_SUCCESS; +} + + +/** + Handler function for USB Keyboard's asynchronous interrupt transfer. + + Data A pointer to a buffer that is filled with key data which is + retrieved via asynchronous interrupt transfer. + DataLength Indicates the size of the data buffer. + Context Pointing to USB_KB_DEV instance. + Result Indicates the result of the asynchronous interrupt transfer. + + @retval EFI_SUCCESS Success + @retval EFI_DEVICE_ERROR Hardware Error + +**/ +EFI_STATUS +EFIAPI +KeyboardHandler ( + IN VOID *Data, + IN UINTN DataLength, + IN VOID *Context, + IN UINT32 Result + ) +{ + USB_KB_DEV *UsbKeyboardDevice; + EFI_USB_IO_PROTOCOL *UsbIo; + UINT8 *CurKeyCodeBuffer; + UINT8 *OldKeyCodeBuffer; + UINT8 CurModifierMap; + UINT8 OldModifierMap; + UINT8 Index; + UINT8 Index2; + BOOLEAN Down; + EFI_STATUS Status; + BOOLEAN KeyRelease; + BOOLEAN KeyPress; + UINT8 SavedTail; + USB_KEY UsbKey; + UINT8 NewRepeatKey; + UINT32 UsbStatus; + UINT8 *DataPtr; + + ASSERT (Context); + + NewRepeatKey = 0; + DataPtr = (UINT8 *) Data; + UsbKeyboardDevice = (USB_KB_DEV *) Context; + UsbIo = UsbKeyboardDevice->UsbIo; + + // + // Analyzes the Result and performs corresponding action. + // + if (Result != EFI_USB_NOERROR) { + // + // Some errors happen during the process + // + KbdReportStatusCode ( + UsbKeyboardDevice->DevicePath, + EFI_ERROR_CODE | EFI_ERROR_MINOR, + PcdGet32 (PcdStatusCodeValueKeyboardInputError) + ); + + // + // stop the repeat key generation if any + // + UsbKeyboardDevice->RepeatKey = 0; + + gBS->SetTimer ( + UsbKeyboardDevice->RepeatTimer, + TimerCancel, + USBKBD_REPEAT_RATE + ); + + if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) { + UsbClearEndpointHalt ( + UsbIo, + UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress, + &UsbStatus + ); + } + + // + // Delete & Submit this interrupt again + // + + Status = UsbIo->UsbAsyncInterruptTransfer ( + UsbIo, + UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress, + FALSE, + 0, + 0, + NULL, + NULL + ); + + gBS->SetTimer ( + UsbKeyboardDevice->DelayedRecoveryEvent, + TimerRelative, + EFI_USB_INTERRUPT_DELAY + ); + + return EFI_DEVICE_ERROR; + } + + if (DataLength == 0 || Data == NULL) { + return EFI_SUCCESS; + } + + CurKeyCodeBuffer = (UINT8 *) Data; + OldKeyCodeBuffer = UsbKeyboardDevice->LastKeyCodeArray; + + // + // checks for new key stroke. + // if no new key got, return immediately. + // + for (Index = 0; Index < 8; Index++) { + if (OldKeyCodeBuffer[Index] != CurKeyCodeBuffer[Index]) { + break; + } + } + + if (Index == 8) { + return EFI_SUCCESS; + } + + // + // Parse the modifier key + // + CurModifierMap = CurKeyCodeBuffer[0]; + OldModifierMap = OldKeyCodeBuffer[0]; + + // + // handle modifier key's pressing or releasing situation. + // + for (Index = 0; Index < 8; Index++) { + + if ((CurModifierMap & KB_Mod[Index].Mask) != (OldModifierMap & KB_Mod[Index].Mask)) { + // + // if current modifier key is up, then + // CurModifierMap & KB_Mod[Index].Mask = 0; + // otherwize it is a non-zero value. + // Inserts the pressed modifier key into key buffer. + // + Down = (UINT8) (CurModifierMap & KB_Mod[Index].Mask); + InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), KB_Mod[Index].Key, Down); + } + } + + // + // handle normal key's releasing situation + // + KeyRelease = FALSE; + for (Index = 2; Index < 8; Index++) { + + if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index])) { + continue; + } + + KeyRelease = TRUE; + for (Index2 = 2; Index2 < 8; Index2++) { + + if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index2])) { + continue; + } + + if (OldKeyCodeBuffer[Index] == CurKeyCodeBuffer[Index2]) { + KeyRelease = FALSE; + break; + } + } + + if (KeyRelease) { + InsertKeyCode ( + &(UsbKeyboardDevice->KeyboardBuffer), + OldKeyCodeBuffer[Index], + 0 + ); + // + // the original reapeat key is released. + // + if (OldKeyCodeBuffer[Index] == UsbKeyboardDevice->RepeatKey) { + UsbKeyboardDevice->RepeatKey = 0; + } + } + } + + // + // original repeat key is released, cancel the repeat timer + // + if (UsbKeyboardDevice->RepeatKey == 0) { + gBS->SetTimer ( + UsbKeyboardDevice->RepeatTimer, + TimerCancel, + USBKBD_REPEAT_RATE + ); + } + + // + // handle normal key's pressing situation + // + KeyPress = FALSE; + for (Index = 2; Index < 8; Index++) { + + if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index])) { + continue; + } + + KeyPress = TRUE; + for (Index2 = 2; Index2 < 8; Index2++) { + + if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index2])) { + continue; + } + + if (CurKeyCodeBuffer[Index] == OldKeyCodeBuffer[Index2]) { + KeyPress = FALSE; + break; + } + } + + if (KeyPress) { + InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), CurKeyCodeBuffer[Index], 1); + // + // NumLock pressed or CapsLock pressed + // + if (CurKeyCodeBuffer[Index] == 0x53 || CurKeyCodeBuffer[Index] == 0x39) { + UsbKeyboardDevice->RepeatKey = 0; + } else { + NewRepeatKey = CurKeyCodeBuffer[Index]; + // + // do not repeat the original repeated key + // + UsbKeyboardDevice->RepeatKey = 0; + } + } + } + + // + // Update LastKeycodeArray[] buffer in the + // Usb Keyboard Device data structure. + // + for (Index = 0; Index < 8; Index++) { + UsbKeyboardDevice->LastKeyCodeArray[Index] = CurKeyCodeBuffer[Index]; + } + + // + // pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence + // and judge whether it will invoke reset event. + // + SavedTail = UsbKeyboardDevice->KeyboardBuffer.bTail; + Index = UsbKeyboardDevice->KeyboardBuffer.bHead; + while (Index != SavedTail) { + RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey); + + switch (UsbKey.KeyCode) { + + case 0xe0: + case 0xe4: + if (UsbKey.Down) { + UsbKeyboardDevice->CtrlOn = 1; + } else { + UsbKeyboardDevice->CtrlOn = 0; + } + break; + + case 0xe2: + case 0xe6: + if (UsbKey.Down) { + UsbKeyboardDevice->AltOn = 1; + } else { + UsbKeyboardDevice->AltOn = 0; + } + break; + + // + // Del Key Code + // + case 0x4c: + case 0x63: + 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.bHead; + + } + // + // If have new key pressed, update the RepeatKey value, and set the + // timer to repeate delay timer + // + if (NewRepeatKey != 0) { + // + // sets trigger time to "Repeat Delay Time", + // to trigger the repeat timer when the key is hold long + // enough time. + // + gBS->SetTimer ( + UsbKeyboardDevice->RepeatTimer, + TimerRelative, + USBKBD_REPEAT_DELAY + ); + UsbKeyboardDevice->RepeatKey = NewRepeatKey; + } + + return EFI_SUCCESS; +} + + +/** + Retrieves a key character after parsing the raw data in keyboard buffer. + + UsbKeyboardDevice The USB_KB_DEV instance. + KeyChar Points to the Key character after key parsing. + + @retval EFI_SUCCESS Success + @retval EFI_NOT_READY Device is not ready + +**/ +EFI_STATUS +USBParseKey ( + IN OUT USB_KB_DEV *UsbKeyboardDevice, + OUT UINT8 *KeyChar + ) +{ + USB_KEY UsbKey; + + *KeyChar = 0; + + while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice->KeyboardBuffer)) { + // + // pops one raw data off. + // + RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey); + + if (!UsbKey.Down) { + switch (UsbKey.KeyCode) { + + case 0xe0: + case 0xe4: + UsbKeyboardDevice->CtrlOn = 0; + break; + + case 0xe1: + case 0xe5: + UsbKeyboardDevice->ShiftOn = 0; + break; + + case 0xe2: + case 0xe6: + UsbKeyboardDevice->AltOn = 0; + break; + + default: + break; + } + + continue; + } + + // + // Analyzes key pressing situation + // + switch (UsbKey.KeyCode) { + + case 0xe0: + case 0xe4: + UsbKeyboardDevice->CtrlOn = 1; + continue; + break; + + case 0xe1: + case 0xe5: + UsbKeyboardDevice->ShiftOn = 1; + continue; + break; + + case 0xe2: + case 0xe6: + UsbKeyboardDevice->AltOn = 1; + continue; + break; + + case 0xe3: + case 0xe7: + continue; + break; + + case 0x53: + UsbKeyboardDevice->NumLockOn ^= 1; + // + // Turn on the NumLock light on KB + // + SetKeyLED (UsbKeyboardDevice); + continue; + break; + + case 0x39: + UsbKeyboardDevice->CapsOn ^= 1; + // + // Turn on the CapsLock light on KB + // + SetKeyLED (UsbKeyboardDevice); + continue; + break; + + case 0x47: + UsbKeyboardDevice->ScrollOn ^= 1; + // + // Turn on the ScrollLock light on KB + // + SetKeyLED (UsbKeyboardDevice); + continue; + break; + + // + // PrintScreen,Pause,Application,Power + // keys are not valid EFI key + // + + case 0x46: + // + // fall through + // + case 0x48: + // + // fall through + // + case 0x65: + // + // fall through + // + case 0x66: + // + // fall through + // + continue; + break; + + default: + break; + } + + // + // When encountered Del Key... + // + if (UsbKey.KeyCode == 0x4c || UsbKey.KeyCode == 0x63) { + if (UsbKeyboardDevice->CtrlOn && UsbKeyboardDevice->AltOn) { + gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL); + } + } + + *KeyChar = UsbKey.KeyCode; + return EFI_SUCCESS; + } + + return EFI_NOT_READY; + +} + + + +/** + Converts USB Keyboard code to EFI Scan Code. + + UsbKeyboardDevice The USB_KB_DEV instance. + KeyChar Indicates the key code that will be interpreted. + Key A pointer to a buffer that is filled in with + the keystroke information for the key that + was pressed. + + @retval EFI_NOT_READY Device is not ready + @retval EFI_SUCCESS Success + +**/ +EFI_STATUS +USBKeyCodeToEFIScanCode ( + IN USB_KB_DEV *UsbKeyboardDevice, + IN UINT8 KeyChar, + OUT EFI_INPUT_KEY *Key + ) +{ + UINT8 Index; + + if (!USBKBD_VALID_KEYCODE (KeyChar)) { + return EFI_NOT_READY; + } + + // + // valid USB Key Code starts from 4 + // + Index = (UINT8) (KeyChar - 4); + + if (Index >= USB_KEYCODE_MAX_MAKE) { + return EFI_NOT_READY; + } + + Key->ScanCode = KeyConvertionTable[Index][0]; + + if (UsbKeyboardDevice->ShiftOn) { + + Key->UnicodeChar = KeyConvertionTable[Index][2]; + + } else { + + Key->UnicodeChar = KeyConvertionTable[Index][1]; + } + + if (UsbKeyboardDevice->CapsOn) { + + if (Key->UnicodeChar >= 'a' && Key->UnicodeChar <= 'z') { + + Key->UnicodeChar = KeyConvertionTable[Index][2]; + + } else if (Key->UnicodeChar >= 'A' && Key->UnicodeChar <= 'Z') { + + Key->UnicodeChar = KeyConvertionTable[Index][1]; + + } + } + + if (KeyChar >= 0x59 && KeyChar <= 0x63) { + + if (UsbKeyboardDevice->NumLockOn && !UsbKeyboardDevice->ShiftOn) { + + Key->ScanCode = SCAN_NULL; + + } else { + + Key->UnicodeChar = 0x00; + } + } + + if (Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) { + return EFI_NOT_READY; + } + + return EFI_SUCCESS; + +} + + + +/** + Resets USB Keyboard Buffer. + + @param KeyboardBuffer Points to the USB Keyboard Buffer. + + @retval EFI_SUCCESS Success + +**/ +EFI_STATUS +InitUSBKeyBuffer ( + IN OUT USB_KB_BUFFER *KeyboardBuffer + ) +{ + ZeroMem (KeyboardBuffer, sizeof (USB_KB_BUFFER)); + + KeyboardBuffer->bHead = KeyboardBuffer->bTail; + + return EFI_SUCCESS; +} + + +/** + Check whether USB Keyboard buffer is empty. + + @param KeyboardBuffer USB Keyboard Buffer. + + +**/ +BOOLEAN +IsUSBKeyboardBufferEmpty ( + IN USB_KB_BUFFER *KeyboardBuffer + ) +{ + // + // meet FIFO empty condition + // + return (BOOLEAN) (KeyboardBuffer->bHead == KeyboardBuffer->bTail); +} + + + +/** + Check whether USB Keyboard buffer is full. + + @param KeyboardBuffer USB Keyboard Buffer. + + +**/ +BOOLEAN +IsUSBKeyboardBufferFull ( + IN USB_KB_BUFFER *KeyboardBuffer + ) +{ + return (BOOLEAN)(((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1)) == + KeyboardBuffer->bHead); +} + + + +/** + Inserts a key code into keyboard buffer. + + @param KeyboardBuffer Points to the USB Keyboard Buffer. + @param Key Key code + @param Down Special key + + @retval EFI_SUCCESS Success + +**/ +EFI_STATUS +InsertKeyCode ( + IN OUT USB_KB_BUFFER *KeyboardBuffer, + IN UINT8 Key, + IN UINT8 Down + ) +{ + USB_KEY UsbKey; + + // + // if keyboard buffer is full, throw the + // first key out of the keyboard buffer. + // + if (IsUSBKeyboardBufferFull (KeyboardBuffer)) { + RemoveKeyCode (KeyboardBuffer, &UsbKey); + } + + KeyboardBuffer->buffer[KeyboardBuffer->bTail].KeyCode = Key; + KeyboardBuffer->buffer[KeyboardBuffer->bTail].Down = Down; + + // + // adjust the tail pointer of the FIFO keyboard buffer. + // + KeyboardBuffer->bTail = (UINT8) ((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1)); + + return EFI_SUCCESS; +} + + +/** + Pops a key code off from keyboard buffer. + + @param KeyboardBuffer Points to the USB Keyboard Buffer. + @param UsbKey Points to the buffer that contains a usb key code. + + @retval EFI_SUCCESS Success + @retval EFI_DEVICE_ERROR Hardware Error + +**/ +EFI_STATUS +RemoveKeyCode ( + IN OUT USB_KB_BUFFER *KeyboardBuffer, + OUT USB_KEY *UsbKey + ) +{ + if (IsUSBKeyboardBufferEmpty (KeyboardBuffer)) { + return EFI_DEVICE_ERROR; + } + + UsbKey->KeyCode = KeyboardBuffer->buffer[KeyboardBuffer->bHead].KeyCode; + UsbKey->Down = KeyboardBuffer->buffer[KeyboardBuffer->bHead].Down; + + // + // adjust the head pointer of the FIFO keyboard buffer. + // + KeyboardBuffer->bHead = (UINT8) ((KeyboardBuffer->bHead + 1) % (MAX_KEY_ALLOWED + 1)); + + return EFI_SUCCESS; +} + + +/** + Sets USB Keyboard LED state. + + @param UsbKeyboardDevice The USB_KB_DEV instance. + + @retval EFI_SUCCESS Success + +**/ +EFI_STATUS +SetKeyLED ( + IN USB_KB_DEV *UsbKeyboardDevice + ) +{ + LED_MAP Led; + UINT8 ReportId; + + // + // Set each field in Led map. + // + Led.NumLock = (UINT8) UsbKeyboardDevice->NumLockOn; + Led.CapsLock = (UINT8) UsbKeyboardDevice->CapsOn; + Led.ScrollLock = (UINT8) UsbKeyboardDevice->ScrollOn; + Led.Resrvd = 0; + + ReportId = 0; + // + // call Set Report Request to lighten the LED. + // + UsbSetReportRequest ( + UsbKeyboardDevice->UsbIo, + UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber, + ReportId, + HID_OUTPUT_REPORT, + 1, + (UINT8 *) &Led + ); + + return EFI_SUCCESS; +} + + +/** + Timer handler for Repeat Key timer. + + @param Event The Repeat Key event. + @param Context Points to the USB_KB_DEV instance. + + +**/ +VOID +EFIAPI +USBKeyboardRepeatHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + USB_KB_DEV *UsbKeyboardDevice; + + UsbKeyboardDevice = (USB_KB_DEV *) Context; + + // + // Do nothing when there is no repeat key. + // + if (UsbKeyboardDevice->RepeatKey != 0) { + // + // Inserts one Repeat key into keyboard buffer, + // + InsertKeyCode ( + &(UsbKeyboardDevice->KeyboardBuffer), + UsbKeyboardDevice->RepeatKey, + 1 + ); + + // + // set repeate rate for repeat key generation. + // + gBS->SetTimer ( + UsbKeyboardDevice->RepeatTimer, + TimerRelative, + USBKBD_REPEAT_RATE + ); + + } +} + + +/** + Timer handler for Delayed Recovery timer. + + @param Event The Delayed Recovery event. + @param Context Points to the USB_KB_DEV instance. + + +**/ +VOID +EFIAPI +USBKeyboardRecoveryHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + + USB_KB_DEV *UsbKeyboardDevice; + EFI_USB_IO_PROTOCOL *UsbIo; + UINT8 PacketSize; + + UsbKeyboardDevice = (USB_KB_DEV *) Context; + + UsbIo = UsbKeyboardDevice->UsbIo; + + PacketSize = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize); + + UsbIo->UsbAsyncInterruptTransfer ( + UsbIo, + UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress, + TRUE, + UsbKeyboardDevice->IntEndpointDescriptor.Interval, + PacketSize, + KeyboardHandler, + UsbKeyboardDevice + ); +} diff --git a/MdeModulePkg/Bus/Usb/UsbKbDxe/keyboard.h b/MdeModulePkg/Bus/Usb/UsbKbDxe/keyboard.h new file mode 100644 index 0000000000..9a8cb0f493 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbKbDxe/keyboard.h @@ -0,0 +1,108 @@ +/** @file +Copyright (c) 2004 - 2005, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + Keyboard.h + +Abstract: + + Function prototype for USB Keyboard Driver + +Revision History + +**/ + +#ifndef _KEYBOARD_H +#define _KEYBOARD_H + + +#include "efikey.h" + +BOOLEAN +IsUSBKeyboard ( + IN EFI_USB_IO_PROTOCOL *UsbIo + ); + +EFI_STATUS +InitUSBKeyboard ( + IN USB_KB_DEV *UsbKeyboardDevice + ); + +EFI_STATUS +EFIAPI +KeyboardHandler ( + IN VOID *Data, + IN UINTN DataLength, + IN VOID *Context, + IN UINT32 Result + ); + +VOID +EFIAPI +USBKeyboardRecoveryHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +EFI_STATUS +USBParseKey ( + IN OUT USB_KB_DEV *UsbKeyboardDevice, + OUT UINT8 *KeyChar + ); + +EFI_STATUS +USBKeyCodeToEFIScanCode ( + IN USB_KB_DEV *UsbKeyboardDevice, + IN UINT8 KeyChar, + OUT EFI_INPUT_KEY *Key + ); + +EFI_STATUS +InitUSBKeyBuffer ( + IN OUT USB_KB_BUFFER *KeyboardBuffer + ); + +BOOLEAN +IsUSBKeyboardBufferEmpty ( + IN USB_KB_BUFFER *KeyboardBuffer + ); + +BOOLEAN +IsUSBKeyboardBufferFull ( + IN USB_KB_BUFFER *KeyboardBuffer + ); + +EFI_STATUS +InsertKeyCode ( + IN OUT USB_KB_BUFFER *KeyboardBuffer, + IN UINT8 Key, + IN UINT8 Down + ); + +EFI_STATUS +RemoveKeyCode ( + IN OUT USB_KB_BUFFER *KeyboardBuffer, + OUT USB_KEY *UsbKey + ); + +VOID +EFIAPI +USBKeyboardRepeatHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +EFI_STATUS +SetKeyLED ( + IN USB_KB_DEV *UsbKeyboardDevice + ); + +#endif diff --git a/MdeModulePkg/Bus/Usb/UsbMouseDxe/ComponentName.c b/MdeModulePkg/Bus/Usb/UsbMouseDxe/ComponentName.c new file mode 100644 index 0000000000..29ea9436cd --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseDxe/ComponentName.c @@ -0,0 +1,219 @@ +/** @file + +Copyright (c) 2004 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + ComponentName.c + +Abstract: + + +**/ + +#include "usbmouse.h" +#include + +// +// EFI Component Name Functions +// +EFI_STATUS +EFIAPI +UsbMouseComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +EFI_STATUS +EFIAPI +UsbMouseComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +// +// EFI Component Name Protocol +// +EFI_COMPONENT_NAME_PROTOCOL gUsbMouseComponentName = { + UsbMouseComponentNameGetDriverName, + UsbMouseComponentNameGetControllerName, + "eng" +}; + + +STATIC EFI_UNICODE_STRING_TABLE mUsbMouseDriverNameTable[] = { + { "eng", L"Usb Mouse Driver" }, + { NULL , NULL } +}; + + +EFI_STATUS +EFIAPI +UsbMouseComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +/*++ + + Routine Description: + Retrieves a Unicode string that is the user readable name of the EFI Driver. + + Arguments: + This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + Language - A pointer to a three character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + DriverName - A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + Returns: + EFI_SUCCESS - The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + EFI_INVALID_PARAMETER - Language is NULL. + EFI_INVALID_PARAMETER - DriverName is NULL. + EFI_UNSUPPORTED - The driver specified by This does not support the + language specified by Language. + +--*/ +{ + return LookupUnicodeString ( + Language, + gUsbMouseComponentName.SupportedLanguages, + mUsbMouseDriverNameTable, + DriverName + ); +} + +EFI_STATUS +EFIAPI +UsbMouseComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +/*++ + + Routine Description: + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + Arguments: + This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + ControllerHandle - The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + ChildHandle - The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + Language - A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + ControllerName - A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language specified + by Language from the point of view of the driver specified + by This. + + Returns: + EFI_SUCCESS - The Unicode string for the user readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE. + EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE. + EFI_INVALID_PARAMETER - Language is NULL. + EFI_INVALID_PARAMETER - ControllerName is NULL. + EFI_UNSUPPORTED - The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + EFI_UNSUPPORTED - The driver specified by This does not support the + language specified by Language. + +--*/ +{ + EFI_STATUS Status; + USB_MOUSE_DEV *UsbMouseDev; + EFI_SIMPLE_POINTER_PROTOCOL *SimplePointerProtocol; + EFI_USB_IO_PROTOCOL *UsbIoProtocol; + + // + // This is a device driver, so ChildHandle must be NULL. + // + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + // + // Check Controller's handle + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiUsbIoProtocolGuid, + (VOID **) &UsbIoProtocol, + gUsbMouseDriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (!EFI_ERROR (Status)) { + gBS->CloseProtocol ( + ControllerHandle, + &gEfiUsbIoProtocolGuid, + gUsbMouseDriverBinding.DriverBindingHandle, + ControllerHandle + ); + + return EFI_UNSUPPORTED; + } + + if (Status != EFI_ALREADY_STARTED) { + return EFI_UNSUPPORTED; + } + // + // Get the device context + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiSimplePointerProtocolGuid, + (VOID **) &SimplePointerProtocol, + gUsbMouseDriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + UsbMouseDev = USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (SimplePointerProtocol); + + return LookupUnicodeString ( + Language, + gUsbMouseComponentName.SupportedLanguages, + UsbMouseDev->ControllerNameTable, + ControllerName + ); + +} diff --git a/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf b/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf new file mode 100644 index 0000000000..01af215fab --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf @@ -0,0 +1,110 @@ +#/** @file +# Component name for module UsbMouse +# +# FIX ME! +# Copyright (c) 2006, Intel Corporation. All right reserved. +# +# All rights reserved. This program and the accompanying materials +# 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 +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UsbMouseDxe + FILE_GUID = 2D2E62AA-9ECF-43b7-8219-94E7FC713DFE + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = USBMouseDriverBindingEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + mousehid.h + ComponentName.c + usbmouse.c + mousehid.c + usbmouse.h + CommonHeader.h + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + MemoryAllocationLib + UefiLib + UefiBootServicesTableLib + UefiDriverEntryPoint + BaseMemoryLib + ReportStatusCodeLib + PcdLib + UsbLib + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gEfiUsbIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiSimplePointerProtocolGuid # PROTOCOL ALWAYS_CONSUMED + +################################################################################ +# +# Pcd FIXED_AT_BUILD - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsFixedAtBuild] + PcdStatusCodeValueMouseInterfaceError|gEfiMdePkgTokenSpaceGuid + PcdStatusCodeValueMouseEnable|gEfiMdePkgTokenSpaceGuid + PcdStatusCodeValueMouseDisable|gEfiMdePkgTokenSpaceGuid + PcdStatusCodeValueMouseInputError|gEfiMdePkgTokenSpaceGuid + PcdStatusCodeValueMouseReset|gEfiMdePkgTokenSpaceGuid + + diff --git a/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.msa b/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.msa new file mode 100644 index 0000000000..cb267d5771 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.msa @@ -0,0 +1,73 @@ + + + UsbMouseDxe + DXE_DRIVER + 2D2E62AA-9ECF-43b7-8219-94E7FC713DFE + 1.0 + Component name for module UsbMouse + FIX ME! + Copyright (c) 2006, Intel Corporation. All right reserved. + All rights reserved. This program and the accompanying materials + 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 + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + UsbMouseDxe + + + + ReportStatusCodeLib + + + BaseMemoryLib + + + UefiDriverEntryPoint + + + UefiBootServicesTableLib + + + UefiLib + + + MemoryAllocationLib + + + + usbmouse.h + mousehid.c + usbmouse.c + ComponentName.c + mousehid.h + + + + + + + + gEfiSimplePointerProtocolGuid + + + gEfiDevicePathProtocolGuid + + + gEfiUsbIoProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + USBMouseDriverBindingEntryPoint + + + \ No newline at end of file diff --git a/MdeModulePkg/Bus/Usb/UsbMouseDxe/mousehid.c b/MdeModulePkg/Bus/Usb/UsbMouseDxe/mousehid.c new file mode 100644 index 0000000000..6490b090c0 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseDxe/mousehid.c @@ -0,0 +1,362 @@ +/** @file + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + Mousehid.c + +Abstract: + Parse mouse hid descriptor + + +**/ + +#include "mousehid.h" + + +// +// Get an item from report descriptor +// + +/** + Get Next Item + + @param StartPos Start Position + @param EndPos End Position + @param HidItem HidItem to return + + @return Position + +**/ +STATIC +UINT8 * +GetNextItem ( + IN UINT8 *StartPos, + IN UINT8 *EndPos, + OUT HID_ITEM *HidItem + ) +{ + UINT8 Temp; + + if ((EndPos - StartPos) <= 0) { + return NULL; + } + + Temp = *StartPos; + StartPos++; + // + // bit 2,3 + // + HidItem->Type = (UINT8) ((Temp >> 2) & 0x03); + // + // bit 4-7 + // + HidItem->Tag = (UINT8) ((Temp >> 4) & 0x0F); + + if (HidItem->Tag == HID_ITEM_TAG_LONG) { + // + // Long Items are not supported by HID rev1.0, + // although we try to parse it. + // + HidItem->Format = HID_ITEM_FORMAT_LONG; + + if ((EndPos - StartPos) >= 2) { + HidItem->Size = *StartPos++; + HidItem->Tag = *StartPos++; + + if ((EndPos - StartPos) >= HidItem->Size) { + HidItem->Data.LongData = StartPos; + StartPos += HidItem->Size; + return StartPos; + } + } + } else { + HidItem->Format = HID_ITEM_FORMAT_SHORT; + // + // bit 0, 1 + // + HidItem->Size = (UINT8) (Temp & 0x03); + switch (HidItem->Size) { + + case 0: + // + // No data + // + return StartPos; + + case 1: + // + // One byte data + // + if ((EndPos - StartPos) >= 1) { + HidItem->Data.U8 = *StartPos++; + return StartPos; + } + + case 2: + // + // Two byte data + // + if ((EndPos - StartPos) >= 2) { + CopyMem (&HidItem->Data.U16, StartPos, sizeof (UINT16)); + StartPos += 2; + return StartPos; + } + + case 3: + // + // 4 byte data, adjust size + // + HidItem->Size++; + if ((EndPos - StartPos) >= 4) { + CopyMem (&HidItem->Data.U32, StartPos, sizeof (UINT32)); + StartPos += 4; + return StartPos; + } + } + } + + return NULL; +} + + +/** + Get Item Data + + @param HidItem HID_ITEM + + @return HidItem Data + +**/ +STATIC +UINT32 +GetItemData ( + IN HID_ITEM *HidItem + ) +{ + // + // Get Data from HID_ITEM structure + // + switch (HidItem->Size) { + + case 1: + return HidItem->Data.U8; + + case 2: + return HidItem->Data.U16; + + case 4: + return HidItem->Data.U32; + } + + return 0; +} + + +/** + Parse Local Item + + @param UsbMouse USB_MOUSE_DEV + @param LocalItem Local Item + + +**/ +STATIC +VOID +ParseLocalItem ( + IN USB_MOUSE_DEV *UsbMouse, + IN HID_ITEM *LocalItem + ) +{ + UINT32 Data; + + if (LocalItem->Size == 0) { + // + // No expected data for local item + // + return ; + } + + Data = GetItemData (LocalItem); + + switch (LocalItem->Tag) { + + case HID_LOCAL_ITEM_TAG_DELIMITER: + // + // we don't support delimiter here + // + return ; + + case HID_LOCAL_ITEM_TAG_USAGE: + return ; + + case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: + if (UsbMouse->PrivateData.ButtonDetected) { + UsbMouse->PrivateData.ButtonMinIndex = (UINT8) Data; + } + + return ; + + case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: + { + if (UsbMouse->PrivateData.ButtonDetected) { + UsbMouse->PrivateData.ButtonMaxIndex = (UINT8) Data; + } + + return ; + } + } +} + +STATIC +VOID +ParseGlobalItem ( + IN USB_MOUSE_DEV *UsbMouse, + IN HID_ITEM *GlobalItem + ) +{ + UINT8 UsagePage; + + switch (GlobalItem->Tag) { + case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: + { + UsagePage = (UINT8) GetItemData (GlobalItem); + + // + // We only care Button Page here + // + if (UsagePage == 0x09) { + // + // Button Page + // + UsbMouse->PrivateData.ButtonDetected = TRUE; + return ; + } + break; + } + + } +} + + + +/** + Parse Main Item + + @param UsbMouse TODO: add argument description + @param MainItem HID_ITEM to parse + + @return VOID + +**/ +STATIC +VOID +ParseMainItem ( + IN USB_MOUSE_DEV *UsbMouse, + IN HID_ITEM *MainItem + ) +{ + // + // we don't care any main items, just skip + // + return ; +} + + +/** + Parse Hid Item + + @param UsbMouse USB_MOUSE_DEV + @param HidItem HidItem to parse + + @return VOID + +**/ +STATIC +VOID +ParseHidItem ( + IN USB_MOUSE_DEV *UsbMouse, + IN HID_ITEM *HidItem + ) +{ + switch (HidItem->Type) { + + case HID_ITEM_TYPE_MAIN: + // + // For Main Item, parse main item + // + ParseMainItem (UsbMouse, HidItem); + break; + + case HID_ITEM_TYPE_GLOBAL: + // + // For global Item, parse global item + // + ParseGlobalItem (UsbMouse, HidItem); + break; + + case HID_ITEM_TYPE_LOCAL: + // + // For Local Item, parse local item + // + ParseLocalItem (UsbMouse, HidItem); + break; + } +} +// +// A simple parse just read some field we are interested in +// + +/** + Parse Mouse Report Descriptor + + @param UsbMouse USB_MOUSE_DEV + @param ReportDescriptor Report descriptor to parse + @param ReportSize Report descriptor size + + @retval EFI_DEVICE_ERROR Report descriptor error + @retval EFI_SUCCESS Success + +**/ +EFI_STATUS +ParseMouseReportDescriptor ( + IN USB_MOUSE_DEV *UsbMouse, + IN UINT8 *ReportDescriptor, + IN UINTN ReportSize + ) +{ + UINT8 *DescriptorEnd; + UINT8 *ptr; + HID_ITEM HidItem; + + DescriptorEnd = ReportDescriptor + ReportSize; + + ptr = GetNextItem (ReportDescriptor, DescriptorEnd, &HidItem); + + while (ptr != NULL) { + if (HidItem.Format != HID_ITEM_FORMAT_SHORT) { + // + // Long Format Item is not supported at current HID revision + // + return EFI_DEVICE_ERROR; + } + + ParseHidItem (UsbMouse, &HidItem); + + ptr = GetNextItem (ptr, DescriptorEnd, &HidItem); + } + + UsbMouse->NumberOfButtons = (UINT8) (UsbMouse->PrivateData.ButtonMaxIndex - UsbMouse->PrivateData.ButtonMinIndex + 1); + UsbMouse->XLogicMax = UsbMouse->YLogicMax = 127; + UsbMouse->XLogicMin = UsbMouse->YLogicMin = -127; + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Bus/Usb/UsbMouseDxe/mousehid.h b/MdeModulePkg/Bus/Usb/UsbMouseDxe/mousehid.h new file mode 100644 index 0000000000..13afc55e63 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseDxe/mousehid.h @@ -0,0 +1,85 @@ +/** @file + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + MouseHid.h + +Abstract: + + +**/ + +#ifndef __MOUSE_HID_H +#define __MOUSE_HID_H + +#include "usbmouse.h" + +// +// HID Item general structure +// +typedef struct _hid_item { + UINT16 Format; + UINT8 Size; + UINT8 Type; + UINT8 Tag; + union { + UINT8 U8; + UINT16 U16; + UINT32 U32; + INT8 I8; + INT16 I16; + INT32 I32; + UINT8 *LongData; + } Data; +} HID_ITEM; + +typedef struct { + UINT16 UsagePage; + INT32 LogicMin; + INT32 LogicMax; + INT32 PhysicalMin; + INT32 PhysicalMax; + UINT16 UnitExp; + UINT16 UINT; + UINT16 ReportId; + UINT16 ReportSize; + UINT16 ReportCount; +} HID_GLOBAL; + +typedef struct { + UINT16 Usage[16]; /* usage array */ + UINT16 UsageIndex; + UINT16 UsageMin; +} HID_LOCAL; + +typedef struct { + UINT16 Type; + UINT16 Usage; +} HID_COLLECTION; + +typedef struct { + HID_GLOBAL Global; + HID_GLOBAL GlobalStack[8]; + UINT32 GlobalStackPtr; + HID_LOCAL Local; + HID_COLLECTION CollectionStack[8]; + UINT32 CollectionStackPtr; +} HID_PARSER; + +EFI_STATUS +ParseMouseReportDescriptor ( + IN USB_MOUSE_DEV *UsbMouse, + IN UINT8 *ReportDescriptor, + IN UINTN ReportSize + ); + +#endif diff --git a/MdeModulePkg/Bus/Usb/UsbMouseDxe/usbmouse.c b/MdeModulePkg/Bus/Usb/UsbMouseDxe/usbmouse.c new file mode 100644 index 0000000000..a4c9e77660 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseDxe/usbmouse.c @@ -0,0 +1,1057 @@ +/** @file + +Copyright (c) 2004 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: + + UsbMouse.c + + Abstract: + + +**/ + +#include "UsbMouse.h" + +#include +#include + + +// +// Driver Consumed Protocol Prototypes +// +//@MT:#include EFI_PROTOCOL_DEFINITION (DriverBinding) +//@MT:#include EFI_PROTOCOL_DEFINITION (UsbIo) + +// +// Driver Produced Protocol Prototypes +// +//@MT:#include EFI_PROTOCOL_DEFINITION (SimplePointer) + +//@MT:#include "UsbDxeLib.h" +//@MT:#include "hid.h" +#include "usbmouse.h" +#include "mousehid.h" + +// +// Prototypes +// Driver model protocol interface +// +EFI_STATUS +EFIAPI +USBMouseDriverBindingEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_STATUS +EFIAPI +USBMouseDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +EFI_STATUS +EFIAPI +USBMouseDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +EFI_STATUS +EFIAPI +USBMouseDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ); + +EFI_GUID gEfiUsbMouseDriverGuid = { + 0x290156b5, 0x6a05, 0x4ac0, 0xb8, 0x0, 0x51, 0x27, 0x55, 0xad, 0x14, 0x29 +}; + +EFI_DRIVER_BINDING_PROTOCOL gUsbMouseDriverBinding = { + USBMouseDriverBindingSupported, + USBMouseDriverBindingStart, + USBMouseDriverBindingStop, + 0xa, + NULL, + NULL +}; + +// +// helper functions +// +STATIC +BOOLEAN +IsUsbMouse ( + IN EFI_USB_IO_PROTOCOL *UsbIo + ); + +STATIC +EFI_STATUS +InitializeUsbMouseDevice ( + IN USB_MOUSE_DEV *UsbMouseDev + ); + +STATIC +VOID +EFIAPI +UsbMouseWaitForInput ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +// +// Mouse interrupt handler +// +STATIC +EFI_STATUS +EFIAPI +OnMouseInterruptComplete ( + IN VOID *Data, + IN UINTN DataLength, + IN VOID *Context, + IN UINT32 Result + ); + +// +// Mouse Protocol +// +STATIC +EFI_STATUS +EFIAPI +GetMouseState ( + IN EFI_SIMPLE_POINTER_PROTOCOL *This, + OUT EFI_SIMPLE_POINTER_STATE *MouseState + ); + +STATIC +EFI_STATUS +EFIAPI +UsbMouseReset ( + IN EFI_SIMPLE_POINTER_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +// +// Driver start here +// +//@MT: EFI_DRIVER_ENTRY_POINT (USBMouseDriverBindingEntryPoint) + +EFI_STATUS +EFIAPI +USBMouseDriverBindingEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + + Routine Description: + Entry point for EFI drivers. + + Arguments: + ImageHandle - EFI_HANDLE + SystemTable - EFI_SYSTEM_TABLE + Returns: + EFI_SUCCESS + others + +--*/ +{ + return EfiLibInstallAllDriverProtocols ( + ImageHandle, + SystemTable, + &gUsbMouseDriverBinding, + ImageHandle, + &gUsbMouseComponentName, + NULL, + NULL + ); +} + + +/** + Test to see if this driver supports ControllerHandle. Any ControllerHandle + that has UsbHcProtocol installed will be supported. + + @param This Protocol instance pointer. + @param Controller Handle of device to test + @param RemainingDevicePath Not used + + @retval EFI_SUCCESS This driver supports this device. + @retval EFI_UNSUPPORTED This driver does not support this device. + +**/ +EFI_STATUS +EFIAPI +USBMouseDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS OpenStatus; + EFI_USB_IO_PROTOCOL *UsbIo; + EFI_STATUS Status; + + OpenStatus = gBS->OpenProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + &UsbIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) { + return EFI_UNSUPPORTED; + } + + if (OpenStatus == EFI_ALREADY_STARTED) { + return EFI_ALREADY_STARTED; + } + + // + // Use the USB I/O protocol interface to see the Controller is + // the Mouse controller that can be managed by this driver. + // + Status = EFI_SUCCESS; + if (!IsUsbMouse (UsbIo)) { + Status = EFI_UNSUPPORTED; + } + + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return Status; +} + + +/** + Starting the Usb Bus Driver + + @param This Protocol instance pointer. + @param Controller Handle of device to test + @param RemainingDevicePath Not used + + @retval EFI_SUCCESS This driver supports this device. + @retval EFI_UNSUPPORTED This driver does not support this device. + @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error + EFI_OUT_OF_RESOURCES- Can't allocate memory + resources + @retval EFI_ALREADY_STARTED Thios driver has been started + +**/ +EFI_STATUS +EFIAPI +USBMouseDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_USB_IO_PROTOCOL *UsbIo; + EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDesc; + USB_MOUSE_DEV *UsbMouseDevice; + UINT8 EndpointNumber; + UINT8 Index; + UINT8 EndpointAddr; + UINT8 PollingInterval; + UINT8 PacketSize; + + UsbMouseDevice = NULL; + Status = EFI_SUCCESS; + + Status = gBS->OpenProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + &UsbIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + + UsbMouseDevice = AllocateZeroPool (sizeof (USB_MOUSE_DEV)); + if (UsbMouseDevice == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + + UsbMouseDevice->UsbIo = UsbIo; + + UsbMouseDevice->Signature = USB_MOUSE_DEV_SIGNATURE; + + UsbMouseDevice->InterfaceDescriptor = AllocatePool (sizeof (EFI_USB_INTERFACE_DESCRIPTOR)); + if (UsbMouseDevice->InterfaceDescriptor == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + + EndpointDesc = AllocatePool (sizeof (EFI_USB_ENDPOINT_DESCRIPTOR)); + if (EndpointDesc == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + // + // Get the Device Path Protocol on Controller's handle + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &UsbMouseDevice->DevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + // + // Get interface & endpoint descriptor + // + UsbIo->UsbGetInterfaceDescriptor ( + UsbIo, + UsbMouseDevice->InterfaceDescriptor + ); + + EndpointNumber = UsbMouseDevice->InterfaceDescriptor->NumEndpoints; + + for (Index = 0; Index < EndpointNumber; Index++) { + UsbIo->UsbGetEndpointDescriptor ( + UsbIo, + Index, + EndpointDesc + ); + + if ((EndpointDesc->Attributes & 0x03) == 0x03) { + + // + // We only care interrupt endpoint here + // + UsbMouseDevice->IntEndpointDescriptor = EndpointDesc; + } + } + + if (UsbMouseDevice->IntEndpointDescriptor == NULL) { + // + // No interrupt endpoint, then error + // + Status = EFI_UNSUPPORTED; + goto ErrorExit; + } + + Status = InitializeUsbMouseDevice (UsbMouseDevice); + if (EFI_ERROR (Status)) { + MouseReportStatusCode ( + UsbMouseDevice->DevicePath, + EFI_ERROR_CODE | EFI_ERROR_MINOR, + PcdGet32 (PcdStatusCodeValueMouseInterfaceError) + ); + + goto ErrorExit; + } + + UsbMouseDevice->SimplePointerProtocol.GetState = GetMouseState; + UsbMouseDevice->SimplePointerProtocol.Reset = UsbMouseReset; + UsbMouseDevice->SimplePointerProtocol.Mode = &UsbMouseDevice->Mode; + + Status = gBS->CreateEvent ( + EVT_NOTIFY_WAIT, + TPL_NOTIFY, + UsbMouseWaitForInput, + UsbMouseDevice, + &((UsbMouseDevice->SimplePointerProtocol).WaitForInput) + ); + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + + Status = gBS->InstallProtocolInterface ( + &Controller, + &gEfiSimplePointerProtocolGuid, + EFI_NATIVE_INTERFACE, + &UsbMouseDevice->SimplePointerProtocol + ); + + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto ErrorExit; + } + + // + // After Enabling Async Interrupt Transfer on this mouse Device + // we will be able to get key data from it. Thus this is deemed as + // the enable action of the mouse + // + + MouseReportStatusCode ( + UsbMouseDevice->DevicePath, + EFI_PROGRESS_CODE, + PcdGet32 (PcdStatusCodeValueMouseEnable) + ); + + // + // submit async interrupt transfer + // + EndpointAddr = UsbMouseDevice->IntEndpointDescriptor->EndpointAddress; + PollingInterval = UsbMouseDevice->IntEndpointDescriptor->Interval; + PacketSize = (UINT8) (UsbMouseDevice->IntEndpointDescriptor->MaxPacketSize); + + Status = UsbIo->UsbAsyncInterruptTransfer ( + UsbIo, + EndpointAddr, + TRUE, + PollingInterval, + PacketSize, + OnMouseInterruptComplete, + UsbMouseDevice + ); + + if (!EFI_ERROR (Status)) { + + UsbMouseDevice->ControllerNameTable = NULL; + AddUnicodeString ( + "eng", + gUsbMouseComponentName.SupportedLanguages, + &UsbMouseDevice->ControllerNameTable, + L"Generic Usb Mouse" + ); + + return EFI_SUCCESS; + } + + // + // If submit error, uninstall that interface + // + Status = EFI_DEVICE_ERROR; + gBS->UninstallProtocolInterface ( + Controller, + &gEfiSimplePointerProtocolGuid, + &UsbMouseDevice->SimplePointerProtocol + ); + +ErrorExit: + if (EFI_ERROR (Status)) { + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + if (UsbMouseDevice != NULL) { + if (UsbMouseDevice->InterfaceDescriptor != NULL) { + gBS->FreePool (UsbMouseDevice->InterfaceDescriptor); + } + + if (UsbMouseDevice->IntEndpointDescriptor != NULL) { + gBS->FreePool (UsbMouseDevice->IntEndpointDescriptor); + } + + if ((UsbMouseDevice->SimplePointerProtocol).WaitForInput != NULL) { + gBS->CloseEvent ((UsbMouseDevice->SimplePointerProtocol).WaitForInput); + } + + gBS->FreePool (UsbMouseDevice); + UsbMouseDevice = NULL; + } + } + + return Status; +} + + +/** + Stop this driver on ControllerHandle. Support stoping any child handles + created by this driver. + + @param This Protocol instance pointer. + @param Controller Handle of device to stop driver on + @param NumberOfChildren Number of Children in the ChildHandleBuffer + @param ChildHandleBuffer List of handles for the children we need to stop. + + @return EFI_SUCCESS + @return EFI_DEVICE_ERROR + @return others + +**/ +EFI_STATUS +EFIAPI +USBMouseDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_STATUS Status; + USB_MOUSE_DEV *UsbMouseDevice; + EFI_SIMPLE_POINTER_PROTOCOL *SimplePointerProtocol; + EFI_USB_IO_PROTOCOL *UsbIo; + + // + // Get our context back. + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiSimplePointerProtocolGuid, + &SimplePointerProtocol, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + UsbMouseDevice = USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (SimplePointerProtocol); + + gBS->CloseProtocol ( + Controller, + &gEfiSimplePointerProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + UsbIo = UsbMouseDevice->UsbIo; + + // + // Uninstall the Asyn Interrupt Transfer from this device + // will disable the mouse data input from this device + // + MouseReportStatusCode ( + UsbMouseDevice->DevicePath, + EFI_PROGRESS_CODE, + PcdGet32 (PcdStatusCodeValueMouseDisable) + ); + + // + // Delete Mouse Async Interrupt Transfer + // + UsbIo->UsbAsyncInterruptTransfer ( + UsbIo, + UsbMouseDevice->IntEndpointDescriptor->EndpointAddress, + FALSE, + UsbMouseDevice->IntEndpointDescriptor->Interval, + 0, + NULL, + NULL + ); + + gBS->CloseEvent (UsbMouseDevice->SimplePointerProtocol.WaitForInput); + + if (UsbMouseDevice->DelayedRecoveryEvent) { + gBS->CloseEvent (UsbMouseDevice->DelayedRecoveryEvent); + UsbMouseDevice->DelayedRecoveryEvent = 0; + } + + Status = gBS->UninstallProtocolInterface ( + Controller, + &gEfiSimplePointerProtocolGuid, + &UsbMouseDevice->SimplePointerProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + gBS->FreePool (UsbMouseDevice->InterfaceDescriptor); + gBS->FreePool (UsbMouseDevice->IntEndpointDescriptor); + + if (UsbMouseDevice->ControllerNameTable) { + FreeUnicodeStringTable (UsbMouseDevice->ControllerNameTable); + } + + gBS->FreePool (UsbMouseDevice); + + return EFI_SUCCESS; + +} + + +/** + Tell if a Usb Controller is a mouse + + @param UsbIo Protocol instance pointer. + + @retval TRUE It is a mouse + @retval FALSE It is not a mouse + +**/ +BOOLEAN +IsUsbMouse ( + IN EFI_USB_IO_PROTOCOL *UsbIo + ) +{ + EFI_STATUS Status; + EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor; + + // + // Get the Default interface descriptor, now we only + // suppose it is interface 1 + // + Status = UsbIo->UsbGetInterfaceDescriptor ( + UsbIo, + &InterfaceDescriptor + ); + + if (EFI_ERROR (Status)) { + return FALSE; + } + + if ((InterfaceDescriptor.InterfaceClass == CLASS_HID) && + (InterfaceDescriptor.InterfaceSubClass == SUBCLASS_BOOT) && + (InterfaceDescriptor.InterfaceProtocol == PROTOCOL_MOUSE) + ) { + return TRUE; + } + + return FALSE; +} + + +/** + Initialize the Usb Mouse Device. + + @param UsbMouseDev Device instance to be initialized + + @retval EFI_SUCCESS Success + @retval EFI_DEVICE_ERROR Init error. EFI_OUT_OF_RESOURCES- Can't allocate + memory + +**/ +STATIC +EFI_STATUS +InitializeUsbMouseDevice ( + IN USB_MOUSE_DEV *UsbMouseDev + ) +{ + EFI_USB_IO_PROTOCOL *UsbIo; + UINT8 Protocol; + EFI_STATUS Status; + EFI_USB_HID_DESCRIPTOR MouseHidDesc; + UINT8 *ReportDesc; + + UsbIo = UsbMouseDev->UsbIo; + + // + // Get HID descriptor + // + Status = UsbGetHidDescriptor ( + UsbIo, + UsbMouseDev->InterfaceDescriptor->InterfaceNumber, + &MouseHidDesc + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get Report descriptor + // + if (MouseHidDesc.HidClassDesc[0].DescriptorType != 0x22) { + return EFI_UNSUPPORTED; + } + + ReportDesc = AllocateZeroPool (MouseHidDesc.HidClassDesc[0].DescriptorLength); + if (ReportDesc == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = UsbGetReportDescriptor ( + UsbIo, + UsbMouseDev->InterfaceDescriptor->InterfaceNumber, + MouseHidDesc.HidClassDesc[0].DescriptorLength, + ReportDesc + ); + + if (EFI_ERROR (Status)) { + gBS->FreePool (ReportDesc); + return Status; + } + + // + // Parse report descriptor + // + Status = ParseMouseReportDescriptor ( + UsbMouseDev, + ReportDesc, + MouseHidDesc.HidClassDesc[0].DescriptorLength + ); + + if (EFI_ERROR (Status)) { + gBS->FreePool (ReportDesc); + return Status; + } + + if (UsbMouseDev->NumberOfButtons >= 1) { + UsbMouseDev->Mode.LeftButton = TRUE; + } + + if (UsbMouseDev->NumberOfButtons > 1) { + UsbMouseDev->Mode.RightButton = TRUE; + } + + UsbMouseDev->Mode.ResolutionX = 8; + UsbMouseDev->Mode.ResolutionY = 8; + UsbMouseDev->Mode.ResolutionZ = 0; + // + // Here we just assume interface 0 is the mouse interface + // + UsbGetProtocolRequest ( + UsbIo, + 0, + &Protocol + ); + + if (Protocol != BOOT_PROTOCOL) { + Status = UsbSetProtocolRequest ( + UsbIo, + 0, + BOOT_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + gBS->FreePool (ReportDesc); + return EFI_DEVICE_ERROR; + } + } + + // + // Set indefinite Idle rate for USB Mouse + // + UsbSetIdleRequest ( + UsbIo, + 0, + 0, + 0 + ); + + gBS->FreePool (ReportDesc); + + if (UsbMouseDev->DelayedRecoveryEvent) { + gBS->CloseEvent (UsbMouseDev->DelayedRecoveryEvent); + UsbMouseDev->DelayedRecoveryEvent = 0; + } + + Status = gBS->CreateEvent ( + EVT_TIMER | EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + USBMouseRecoveryHandler, + UsbMouseDev, + &UsbMouseDev->DelayedRecoveryEvent + ); + + return EFI_SUCCESS; +} + + +/** + It is called whenever there is data received from async interrupt + transfer. + + @param Data Data received. + @param DataLength Length of Data + @param Context Passed in context + @param Result Async Interrupt Transfer result + + @return EFI_SUCCESS + @return EFI_DEVICE_ERROR + +**/ +STATIC +EFI_STATUS +EFIAPI +OnMouseInterruptComplete ( + IN VOID *Data, + IN UINTN DataLength, + IN VOID *Context, + IN UINT32 Result + ) +{ + USB_MOUSE_DEV *UsbMouseDevice; + EFI_USB_IO_PROTOCOL *UsbIo; + UINT8 EndpointAddr; + UINT32 UsbResult; + + UsbMouseDevice = (USB_MOUSE_DEV *) Context; + UsbIo = UsbMouseDevice->UsbIo; + + if (Result != EFI_USB_NOERROR) { + // + // Some errors happen during the process + // + MouseReportStatusCode ( + UsbMouseDevice->DevicePath, + EFI_ERROR_CODE | EFI_ERROR_MINOR, + PcdGet32 (PcdStatusCodeValueMouseInputError) + ); + + if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) { + EndpointAddr = UsbMouseDevice->IntEndpointDescriptor->EndpointAddress; + + UsbClearEndpointHalt ( + UsbIo, + EndpointAddr, + &UsbResult + ); + } + + UsbIo->UsbAsyncInterruptTransfer ( + UsbIo, + UsbMouseDevice->IntEndpointDescriptor->EndpointAddress, + FALSE, + 0, + 0, + NULL, + NULL + ); + + gBS->SetTimer ( + UsbMouseDevice->DelayedRecoveryEvent, + TimerRelative, + EFI_USB_INTERRUPT_DELAY + ); + return EFI_DEVICE_ERROR; + } + + if (DataLength == 0 || Data == NULL) { + return EFI_SUCCESS; + } + + UsbMouseDevice->StateChanged = TRUE; + + // + // Check mouse Data + // + UsbMouseDevice->State.LeftButton = (BOOLEAN) (*(UINT8 *) Data & 0x01); + UsbMouseDevice->State.RightButton = (BOOLEAN) (*(UINT8 *) Data & 0x02); + UsbMouseDevice->State.RelativeMovementX += *((INT8 *) Data + 1); + UsbMouseDevice->State.RelativeMovementY += *((INT8 *) Data + 2); + + if (DataLength > 3) { + UsbMouseDevice->State.RelativeMovementZ += *((INT8 *) Data + 3); + } + + return EFI_SUCCESS; +} + +/* +STATIC VOID +PrintMouseState( + IN EFI_MOUSE_STATE *MouseState + ) +{ + Aprint("(%x: %x, %x)\n", + MouseState->ButtonStates, + MouseState->dx, + MouseState->dy + ); +} +*/ + +/** + Get the mouse state, see SIMPLE POINTER PROTOCOL. + + @param This Protocol instance pointer. + @param MouseState Current mouse state + + @return EFI_SUCCESS + @return EFI_DEVICE_ERROR + @return EFI_NOT_READY + +**/ +STATIC +EFI_STATUS +EFIAPI +GetMouseState ( + IN EFI_SIMPLE_POINTER_PROTOCOL *This, + OUT EFI_SIMPLE_POINTER_STATE *MouseState + ) +{ + USB_MOUSE_DEV *MouseDev; + + if (MouseState == NULL) { + return EFI_DEVICE_ERROR; + } + + MouseDev = USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (This); + + if (!MouseDev->StateChanged) { + return EFI_NOT_READY; + } + + CopyMem ( + MouseState, + &MouseDev->State, + sizeof (EFI_SIMPLE_POINTER_STATE) + ); + + // + // Clear previous move state + // + MouseDev->State.RelativeMovementX = 0; + MouseDev->State.RelativeMovementY = 0; + MouseDev->State.RelativeMovementZ = 0; + + MouseDev->StateChanged = FALSE; + + return EFI_SUCCESS; +} + + +/** + Reset the mouse device, see SIMPLE POINTER PROTOCOL. + + @param This Protocol instance pointer. + @param ExtendedVerification Ignored here/ + + @return EFI_SUCCESS + +**/ +STATIC +EFI_STATUS +EFIAPI +UsbMouseReset ( + IN EFI_SIMPLE_POINTER_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + USB_MOUSE_DEV *UsbMouseDevice; + EFI_USB_IO_PROTOCOL *UsbIo; + + UsbMouseDevice = USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (This); + + UsbIo = UsbMouseDevice->UsbIo; + + MouseReportStatusCode ( + UsbMouseDevice->DevicePath, + EFI_PROGRESS_CODE, + PcdGet32 (PcdStatusCodeValueMouseReset) + + ); + + ZeroMem ( + &UsbMouseDevice->State, + sizeof (EFI_SIMPLE_POINTER_STATE) + ); + UsbMouseDevice->StateChanged = FALSE; + + return EFI_SUCCESS; +} + + +/** + Event notification function for SIMPLE_POINTER.WaitForInput event + Signal the event if there is input from mouse + + @param Event Wait Event + @param Context Passed parameter to event handler + VOID + +**/ +STATIC +VOID +EFIAPI +UsbMouseWaitForInput ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + USB_MOUSE_DEV *UsbMouseDev; + + UsbMouseDev = (USB_MOUSE_DEV *) Context; + + // + // Someone is waiting on the mouse event, if there's + // input from mouse, signal the event + // + if (UsbMouseDev->StateChanged) { + gBS->SignalEvent (Event); + } +} + + +/** + Timer handler for Delayed Recovery timer. + + @param Event The Delayed Recovery event. + @param Context Points to the USB_KB_DEV instance. + + +**/ +VOID +EFIAPI +USBMouseRecoveryHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + USB_MOUSE_DEV *UsbMouseDev; + EFI_USB_IO_PROTOCOL *UsbIo; + + UsbMouseDev = (USB_MOUSE_DEV *) Context; + + UsbIo = UsbMouseDev->UsbIo; + + UsbIo->UsbAsyncInterruptTransfer ( + UsbIo, + UsbMouseDev->IntEndpointDescriptor->EndpointAddress, + TRUE, + UsbMouseDev->IntEndpointDescriptor->Interval, + UsbMouseDev->IntEndpointDescriptor->MaxPacketSize, + OnMouseInterruptComplete, + UsbMouseDev + ); +} + + +/** + Report Status Code in Usb Bot Driver + + @param DevicePath Use this to get Device Path + @param CodeType Status Code Type + @param CodeValue Status Code Value + + @return None + +**/ +VOID +MouseReportStatusCode ( + 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 + ); +} diff --git a/MdeModulePkg/Bus/Usb/UsbMouseDxe/usbmouse.h b/MdeModulePkg/Bus/Usb/UsbMouseDxe/usbmouse.h new file mode 100644 index 0000000000..73cccb0296 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseDxe/usbmouse.h @@ -0,0 +1,108 @@ +/** @file + +Copyright (c) 2004 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: + + UsbMouse.h + + Abstract: + + +**/ + +#ifndef _USB_MOUSE_H +#define _USB_MOUSE_H + +// +// The package level header files this module uses +// +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define CLASS_HID 3 +#define SUBCLASS_BOOT 1 +#define PROTOCOL_MOUSE 2 + +#define BOOT_PROTOCOL 0 +#define REPORT_PROTOCOL 1 + +#define USB_MOUSE_DEV_SIGNATURE EFI_SIGNATURE_32 ('u', 'm', 'o', 'u') + +typedef struct { + BOOLEAN ButtonDetected; + UINT8 ButtonMinIndex; + UINT8 ButtonMaxIndex; + UINT8 Reserved; +} PRIVATE_DATA; + +typedef struct { + UINTN Signature; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_EVENT DelayedRecoveryEvent; + EFI_USB_IO_PROTOCOL *UsbIo; + EFI_USB_INTERFACE_DESCRIPTOR *InterfaceDescriptor; + EFI_USB_ENDPOINT_DESCRIPTOR *IntEndpointDescriptor; + UINT8 NumberOfButtons; + INT32 XLogicMax; + INT32 XLogicMin; + INT32 YLogicMax; + INT32 YLogicMin; + EFI_SIMPLE_POINTER_PROTOCOL SimplePointerProtocol; + EFI_SIMPLE_POINTER_STATE State; + EFI_SIMPLE_POINTER_MODE Mode; + BOOLEAN StateChanged; + PRIVATE_DATA PrivateData; + EFI_UNICODE_STRING_TABLE *ControllerNameTable; +} USB_MOUSE_DEV; + +#define USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL(a) \ + CR(a, USB_MOUSE_DEV, SimplePointerProtocol, USB_MOUSE_DEV_SIGNATURE) + +VOID +EFIAPI +USBMouseRecoveryHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +// +// Global Variables +// +extern EFI_DRIVER_BINDING_PROTOCOL gUsbMouseDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gUsbMouseComponentName; +extern EFI_GUID gEfiUsbMouseDriverGuid; + +VOID +MouseReportStatusCode ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN EFI_STATUS_CODE_TYPE CodeType, + IN EFI_STATUS_CODE_VALUE Value + ); + +#endif diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 9a53b4613a..92242c5425 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -9,7 +9,7 @@ # the terms and conditions of the BSD License which accompanies this distribution. # The full text of the license may be found at # http://opensource.org/licenses/bsd-license.php -# +# # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. # @@ -29,7 +29,7 @@ PACKAGE_VERSION = 0.1 [Includes.common] - Include + Include ################################################################################ # @@ -68,7 +68,7 @@ gEfiPeiPeCoffLoaderGuid = { 0xd8117cff, 0x94a6, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } gEfiPeiCorePrivateGuid = { 0xd641a0f5, 0xcb7c, 0x4846, { 0xa3, 0x80, 0x1d, 0x01, 0xb4, 0xd9, 0xe3, 0xb9 }} gEfiExtendedSalVariableServicesProtocolGuid = {0x4ecb6c53, 0xc641, 0x4370, {0x8c, 0xb2, 0x3b, 0x0e, 0x49, 0x6e, 0x83, 0x78 }} - + ################################################################################ # # Global Protocols Definition section - list of Global Protocols C Name Data @@ -92,7 +92,7 @@ gEfiCustomizedDecompressProtocolGuid = { 0x9A44198E, 0xA4A2, 0x44E6, { 0x8A, 0x1F, 0x39, 0xBE, 0xFD, 0xAC, 0x89, 0x6F }} gEfiCapsuleArchProtocolGuid = { 0x5053697E, 0x2EBC, 0x4819, { 0x90, 0xD9, 0x05, 0x80, 0xDE, 0xEE, 0x57, 0x54 }} gEfiCrc32GuidedSectionExtractionProtocolGuid = { 0xFC1BCDB0, 0x7D31, 0x49aa, {0x93, 0x6A, 0xA4, 0x60, 0x0D, 0x9D, 0xD0, 0x83 } } - + @@ -104,7 +104,7 @@ ################################################################################ [Ppis.common] gPeiBaseMemoryTestPpiGuid = { 0xB6EC423C, 0x21D2, 0x490D, { 0x85, 0xC6, 0xDD, 0x58, 0x64, 0xEA, 0xA6, 0x74 }} - gEfiPeiFvFileLoaderPpiGuid = { 0x7e1f0d85, 0x04ff, 0x4bb2, { 0x86, 0x6a, 0x31, 0xa2, 0x99, 0x6a, 0x48, 0xa8 }} + gEfiPeiFvFileLoaderPpiGuid = { 0x7e1f0d85, 0x04ff, 0x4bb2, { 0x86, 0x6a, 0x31, 0xa2, 0x99, 0x6a, 0x48, 0xa8 }} ##gPeiFlashMapPpiGuid will be removed in future gPeiFlashMapPpiGuid = { 0xf34c2fa0, 0xde88, 0x4270, {0x84, 0x14, 0x96, 0x12, 0x22, 0xf4, 0x52, 0x1c } } @@ -144,6 +144,19 @@ PcdFlashNvStorageFtwSpareSize|0x30000014|gEfiMdeModulePkgTokenSpaceGuid|UINT32|0x0 PcdFlashNvStorageFtwWorkingBase|0x30000010|gEfiMdeModulePkgTokenSpaceGuid|UINT32|0x0 PcdFlashNvStorageFtwWorkingSize|0x30000011|gEfiMdeModulePkgTokenSpaceGuid|UINT32|0x0 + PcdStatusCodeValueMouseInterfaceError|0x30001000|gEfiMdePkgTokenSpaceGuid|UINT32|0x01020005 + PcdStatusCodeValueMouseEnable|0x30001001|gEfiMdePkgTokenSpaceGuid|UINT32|0x01020004 + PcdStatusCodeValueMouseDisable|0x3001002|gEfiMdePkgTokenSpaceGuid|UINT32|0x01020002 + PcdStatusCodeValueKeyboardEnable|0x3001003|gEfiMdePkgTokenSpaceGuid|UINT32|0x01010004 + PcdStatusCodeValueKeyboardDisable|0x3001004|gEfiMdePkgTokenSpaceGuid|UINT32|0x01010002 + PcdStatusCodeValueKeyboardPresenceDetect|0x30001005|gEfiMdePkgTokenSpaceGuid|UINT32|0x01010003 + PcdStatusCodeValueKeyboardReset|0x30001006|gEfiMdePkgTokenSpaceGuid|UINT32|0x01010001 + PcdStatusCodeValueKeyboardClearBuffer|0x30001007|gEfiMdePkgTokenSpaceGuid|UINT32|0x01011000 + PcdStatusCodeValueKeyboardSelfTest|0x30001008|gEfiMdePkgTokenSpaceGuid|UINT32|0x01011001 + PcdStatusCodeValueKeyboardInterfaceError|0x30001009|gEfiMdePkgTokenSpaceGuid|UINT32|0x01010005 + PcdStatusCodeValueKeyboardInputError|0x3000100a|gEfiMdePkgTokenSpaceGuid|UINT32|0x01010007 + PcdStatusCodeValueMouseInputError|0x30001000b|gEfiMdePkgTokenSpaceGuid|UINT32|0x01020007 + PcdStatusCodeValueMouseReset|0x30001000c|gEfiMdePkgTokenSpaceGuid|UINT32|0x01020001 [PcdsDynamic.common] PcdFlashNvStorageVariableBase|0x30000001|gEfiMdeModulePkgTokenSpaceGuid|UINT32|0x0 diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index ee44ee182c..e8ec07c8fe 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -126,6 +126,7 @@ ReportStatusCodeLib|$(WORKSPACE)/IntelFrameworkPkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf ScsiLib|$(WORKSPACE)/MdePkg/Library/UefiScsiLib/UefiScsiLib.inf FrameworkHiiLib|$(WORKSPACE)/IntelFrameworkPkg/Library/FrameworkHiiLib/HiiLib.inf + UsbLib|$(WORKSPACE)/MdePkg/Library/UefiUsbLib/UefiUsbLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] HobLib|$(WORKSPACE)/MdePkg/Library/DxeHobLib/DxeHobLib.inf @@ -356,9 +357,23 @@ PcdStatusCodeValueRemoteConsoleInputError|gEfiMdePkgTokenSpaceGuid|0x01040007 # EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_INPUT_ERROR PcdStatusCodeValueRemoteConsoleOutputError|gEfiMdePkgTokenSpaceGuid|0x01040008 # EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_OUTPUT_ERROR + PcdStatusCodeValueMouseInterfaceError|gEfiMdePkgTokenSpaceGuid|0x01020005 # EFI_PERIPHERAL_MOUSE | EFI_P_EC_INTERFACE_ERROR + PcdStatusCodeValueMouseEnable|gEfiMdePkgTokenSpaceGuid|0x01020004 # EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE + PcdStatusCodeValueMouseDisable|gEfiMdePkgTokenSpaceGuid|0x01020002 # EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE + PcdStatusCodeValueKeyboardEnable|gEfiMdePkgTokenSpaceGuid|0x01010004 # EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE + PcdStatusCodeValueKeyboardPresenceDetect|gEfiMdePkgTokenSpaceGuid|0x01010003 # EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT + PcdStatusCodeValueKeyboardDisable|gEfiMdePkgTokenSpaceGuid|0x01010002 # EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE + PcdStatusCodeValueKeyboardReset|gEfiMdePkgTokenSpaceGuid|0x01010001 # EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET + PcdStatusCodeValueKeyboardClearBuffer|gEfiMdePkgTokenSpaceGuid|0x01011000 # EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER + PcdStatusCodeValueKeyboardSelfTest|gEfiMdePkgTokenSpaceGuid|0x01011001 # EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST + PcdStatusCodeValueKeyboardInterfaceError|gEfiMdePkgTokenSpaceGuid|0x01010005 # EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_INTERFACE_ERROR + PcdStatusCodeValueKeyboardInputError|gEfiMdePkgTokenSpaceGuid|0x01010007 # EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_INPUT_ERROR + PcdStatusCodeValueMouseInputError|gEfiMdePkgTokenSpaceGuid|0x01020007 # EFI_PERIPHERAL_MOUSE | EFI_P_EC_INPUT_ERROR + PcdStatusCodeValueMouseReset|gEfiMdePkgTokenSpaceGuid|0x01020001 # EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET + [PcdsFixedAtBuild.IPF] PcdIoBlockBaseAddressForIpf|gEfiMdePkgTokenSpaceGuid|0x0ffffc000000 - + [PcdsPatchableInModule.common] PcdDebugPrintErrorLevel|gEfiMdePkgTokenSpaceGuid|0x80000000 PcdPciExpressBaseAddress|gEfiMdePkgTokenSpaceGuid|0xE0000000 @@ -407,24 +422,26 @@ $(WORKSPACE)/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.inf $(WORKSPACE)/MdeModulePkg/Universal/DevicePathDxe/DevicePath.inf $(WORKSPACE)/MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.inf - $(WORKSPACE)/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.inf + $(WORKSPACE)/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.inf $(WORKSPACE)/MdeModulePkg/Application/HelloWorld/HelloWorld.inf $(WORKSPACE)/MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf $(WORKSPACE)/MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf $(WORKSPACE)/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf - $(WORKSPACE)/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf + $(WORKSPACE)/MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf + $(WORKSPACE)/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf + $(WORKSPACE)/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf [Components.Ia32] - $(WORKSPACE)/MdeModulePkg/Universal/Capsule/RuntimeDxe/CapsuleRuntime.inf + $(WORKSPACE)/MdeModulePkg/Universal/Capsule/RuntimeDxe/CapsuleRuntime.inf $(WORKSPACE)/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.inf $(WORKSPACE)/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.inf $(WORKSPACE)/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.inf [Components.X64] - $(WORKSPACE)/MdeModulePkg/Universal/Capsule/RuntimeDxe/CapsuleRuntime.inf + $(WORKSPACE)/MdeModulePkg/Universal/Capsule/RuntimeDxe/CapsuleRuntime.inf $(WORKSPACE)/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.inf $(WORKSPACE)/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.inf - $(WORKSPACE)/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.inf + $(WORKSPACE)/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.inf [Components.IPF] diff --git a/MdePkg/Include/Library/UsbLib.h b/MdePkg/Include/Library/UsbLib.h index 291eccbe36..1438328c9b 100644 --- a/MdePkg/Include/Library/UsbLib.h +++ b/MdePkg/Include/Library/UsbLib.h @@ -1,6 +1,5 @@ /** @file - Common Dxe Libarary for USB - Add Constants & structure definitions for Usb HID + Common Dxe Libarary for USB Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials @@ -18,6 +17,50 @@ #define __USB_DXE_LIB_H__ #include + +// +// Standard device request and request type +// By [Spec-USB20/Chapter-9.4] +// +#define USB_DEV_GET_STATUS 0x00 +#define USB_DEV_GET_STATUS_REQ_TYPE_D 0x80 // Receiver : Device +#define USB_DEV_GET_STATUS_REQ_TYPE_I 0x81 // Receiver : Interface +#define USB_DEV_GET_STATUS_REQ_TYPE_E 0x82 // Receiver : Endpoint + +#define USB_DEV_CLEAR_FEATURE 0x01 +#define USB_DEV_CLEAR_FEATURE_REQ_TYPE_D 0x00 // Receiver : Device +#define USB_DEV_CLEAR_FEATURE_REQ_TYPE_I 0x01 // Receiver : Interface +#define USB_DEV_CLEAR_FEATURE_REQ_TYPE_E 0x02 // Receiver : Endpoint + +#define USB_DEV_SET_FEATURE 0x03 +#define USB_DEV_SET_FEATURE_REQ_TYPE_D 0x00 // Receiver : Device +#define USB_DEV_SET_FEATURE_REQ_TYPE_I 0x01 // Receiver : Interface +#define USB_DEV_SET_FEATURE_REQ_TYPE_E 0x02 // Receiver : Endpoint + +#define USB_DEV_SET_ADDRESS 0x05 +#define USB_DEV_SET_ADDRESS_REQ_TYPE 0x00 + +#define USB_DEV_GET_DESCRIPTOR 0x06 +#define USB_DEV_GET_DESCRIPTOR_REQ_TYPE 0x80 + +#define USB_DEV_SET_DESCRIPTOR 0x07 +#define USB_DEV_SET_DESCRIPTOR_REQ_TYPE 0x00 + +#define USB_DEV_GET_CONFIGURATION 0x08 +#define USB_DEV_GET_CONFIGURATION_REQ_TYPE 0x80 + +#define USB_DEV_SET_CONFIGURATION 0x09 +#define USB_DEV_SET_CONFIGURATION_REQ_TYPE 0x00 + +#define USB_DEV_GET_INTERFACE 0x0A +#define USB_DEV_GET_INTERFACE_REQ_TYPE 0x81 + +#define USB_DEV_SET_INTERFACE 0x0B +#define USB_DEV_SET_INTERFACE_REQ_TYPE 0x01 + +#define USB_DEV_SYNCH_FRAME 0x0C +#define USB_DEV_SYNCH_FRAME_REQ_TYPE 0x82 + // // define the timeout time as 3ms // @@ -233,9 +276,11 @@ UsbGetReportRequest ( IN UINT8 *Report ); -// -// Get Device Descriptor -// +typedef enum { + EfiUsbEndpointHalt, + EfiUsbDeviceRemoteWakeup +} EFI_USB_STANDARD_FEATURE_SELECTOR; + EFI_STATUS UsbGetDescriptor ( IN EFI_USB_IO_PROTOCOL *UsbIo, @@ -246,9 +291,6 @@ UsbGetDescriptor ( OUT UINT32 *Status ); -// -// Set Device Descriptor -// EFI_STATUS UsbSetDescriptor ( IN EFI_USB_IO_PROTOCOL *UsbIo, @@ -259,97 +301,70 @@ UsbSetDescriptor ( OUT UINT32 *Status ); -// -// Get device Interface -// EFI_STATUS -UsbGetDeviceInterface ( +UsbGetInterface ( IN EFI_USB_IO_PROTOCOL *UsbIo, IN UINT16 Index, OUT UINT8 *AltSetting, OUT UINT32 *Status ); -// -// Set device interface -// EFI_STATUS -UsbSetDeviceInterface ( +UsbSetInterface ( IN EFI_USB_IO_PROTOCOL *UsbIo, IN UINT16 InterfaceNo, IN UINT16 AltSetting, OUT UINT32 *Status ); -// -// Get device configuration -// EFI_STATUS -UsbGetDeviceConfiguration ( +UsbGetConfiguration ( IN EFI_USB_IO_PROTOCOL *UsbIo, OUT UINT8 *ConfigValue, OUT UINT32 *Status ); -// -// Set device configuration -// EFI_STATUS -UsbSetDeviceConfiguration ( +UsbSetConfiguration ( IN EFI_USB_IO_PROTOCOL *UsbIo, IN UINT16 Value, OUT UINT32 *Status ); -// -// Set Device Feature -// EFI_STATUS -UsbSetDeviceFeature ( +UsbSetFeature ( IN EFI_USB_IO_PROTOCOL *UsbIo, - IN EFI_USB_RECIPIENT Recipient, + IN UINTN Recipient, IN UINT16 Value, IN UINT16 Target, OUT UINT32 *Status ); -// -// Clear Device Feature -// EFI_STATUS -UsbClearDeviceFeature ( +UsbClearFeature ( IN EFI_USB_IO_PROTOCOL *UsbIo, - IN EFI_USB_RECIPIENT Recipient, + IN UINTN Recipient, IN UINT16 Value, IN UINT16 Target, OUT UINT32 *Status ); -// -// Get Device Status -// EFI_STATUS -UsbGetDeviceStatus ( +UsbGetStatus ( IN EFI_USB_IO_PROTOCOL *UsbIo, - IN EFI_USB_RECIPIENT Recipient, + IN UINTN Recipient, IN UINT16 Target, OUT UINT16 *DevStatus, OUT UINT32 *Status ); -// -// The following APIs are not basic library, but they are common used. -// -// -// Usb Get String -// EFI_STATUS -UsbGetString ( +UsbGetHubDescriptor ( IN EFI_USB_IO_PROTOCOL *UsbIo, - IN UINT16 LangID, - IN UINT8 Index, - IN VOID *Buf, - IN UINTN BufSize, + IN UINT16 Value, + IN UINT16 Index, + IN UINT16 DescriptorLength, + OUT VOID *Descriptor, OUT UINT32 *Status ); diff --git a/MdePkg/Library/UefiUsbLib/UefiUsbLib.inf b/MdePkg/Library/UefiUsbLib/UefiUsbLib.inf index e0c46aeb59..adf275772a 100644 --- a/MdePkg/Library/UefiUsbLib/UefiUsbLib.inf +++ b/MdePkg/Library/UefiUsbLib/UefiUsbLib.inf @@ -25,7 +25,7 @@ FILE_GUID = 87eb5df9-722a-4241-ad7f-370d0b3a56d7 MODULE_TYPE = UEFI_DRIVER VERSION_STRING = 1.0 - LIBRARY_CLASS = UsbLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER + LIBRARY_CLASS = UsbLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER EDK_RELEASE_VERSION = 0x00020000 EFI_SPECIFICATION_VERSION = 0x00020000 @@ -45,8 +45,6 @@ [Sources.common] hid.c UsbDxeLib.c - CommonHeader.h - ################################################################################ # diff --git a/MdePkg/Library/UefiUsbLib/UefiUsbLib.msa b/MdePkg/Library/UefiUsbLib/UefiUsbLib.msa index d552426156..1226226327 100644 --- a/MdePkg/Library/UefiUsbLib/UefiUsbLib.msa +++ b/MdePkg/Library/UefiUsbLib/UefiUsbLib.msa @@ -30,6 +30,7 @@ + hid.h UsbDxeLib.c hid.c diff --git a/MdePkg/Library/UefiUsbLib/UsbDxeLib.c b/MdePkg/Library/UefiUsbLib/UsbDxeLib.c index 626fa22290..cb8885396d 100644 --- a/MdePkg/Library/UefiUsbLib/UsbDxeLib.c +++ b/MdePkg/Library/UefiUsbLib/UsbDxeLib.c @@ -1,13 +1,13 @@ -/*++ +/** @file -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +Copyright (c) 2004 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. Module Name: @@ -19,13 +19,34 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. Revision History ---*/ -#include "UefiUsbLibInternal.h" +**/ // -// Get Device Descriptor +// The package level header files this module uses +// +#include +// +// The Library classes this module consumes // +#include +#include + +/** + Usb Get Descriptor + + @param UsbIo EFI_USB_IO_PROTOCOL + @param Value Device Request Value + @param Index Device Request Index + @param DescriptorLength Descriptor Length + @param Descriptor Descriptor buffer to contain result + @param Status Transfer Status + + @retval EFI_INVALID_PARAMETER Parameter is error + @retval EFI_SUCCESS Success + @retval EFI_TIMEOUT Device has no response + +**/ EFI_STATUS UsbGetDescriptor ( IN EFI_USB_IO_PROTOCOL *UsbIo, @@ -35,26 +56,6 @@ UsbGetDescriptor ( OUT VOID *Descriptor, OUT UINT32 *Status ) -/*++ - -Routine Description: - - Usb Get Descriptor - -Arguments: - - UsbIo - EFI_USB_IO_PROTOCOL - Value - Device Request Value - Index - Device Request Index - DescriptorLength - Descriptor Length - Descriptor - Descriptor buffer to contain result - Status - Transfer Status -Returns: - EFI_INVALID_PARAMETER - Parameter is error - EFI_SUCCESS - Success - EFI_TIMEOUT - Device has no response - ---*/ { EFI_USB_DEVICE_REQUEST DevReq; @@ -65,7 +66,7 @@ Returns: ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); DevReq.RequestType = USB_DEV_GET_DESCRIPTOR_REQ_TYPE; - DevReq.Request = USB_DEV_GET_DESCRIPTOR; + DevReq.Request = USB_REQ_GET_DESCRIPTOR; DevReq.Value = Value; DevReq.Index = Index; DevReq.Length = DescriptorLength; @@ -80,9 +81,23 @@ Returns: Status ); } -// -// Set Device Descriptor -// + + +/** + Usb Set Descriptor + + @param UsbIo EFI_USB_IO_PROTOCOL + @param Value Device Request Value + @param Index Device Request Index + @param DescriptorLength Descriptor Length + @param Descriptor Descriptor buffer to set + @param Status Transfer Status + + @retval EFI_INVALID_PARAMETER Parameter is error + @retval EFI_SUCCESS Success + @retval EFI_TIMEOUT Device has no response + +**/ EFI_STATUS UsbSetDescriptor ( IN EFI_USB_IO_PROTOCOL *UsbIo, @@ -92,26 +107,6 @@ UsbSetDescriptor ( IN VOID *Descriptor, OUT UINT32 *Status ) -/*++ - -Routine Description: - - Usb Set Descriptor - -Arguments: - - UsbIo - EFI_USB_IO_PROTOCOL - Value - Device Request Value - Index - Device Request Index - DescriptorLength - Descriptor Length - Descriptor - Descriptor buffer to set - Status - Transfer Status -Returns: - EFI_INVALID_PARAMETER - Parameter is error - EFI_SUCCESS - Success - EFI_TIMEOUT - Device has no response - ---*/ { EFI_USB_DEVICE_REQUEST DevReq; @@ -122,7 +117,7 @@ Returns: ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); DevReq.RequestType = USB_DEV_SET_DESCRIPTOR_REQ_TYPE; - DevReq.Request = USB_DEV_SET_DESCRIPTOR; + DevReq.Request = USB_REQ_SET_DESCRIPTOR; DevReq.Value = Value; DevReq.Index = Index; DevReq.Length = DescriptorLength; @@ -138,37 +133,27 @@ Returns: ); } -// -// Get device Interface -// + +/** + Usb Get Device Interface + + @param UsbIo EFI_USB_IO_PROTOCOL + @param Index Interface index value + @param AltSetting Alternate setting + @param Status Trasnsfer status + + @retval EFI_INVALID_PARAMETER Parameter is error + @retval EFI_SUCCESS Success + @retval EFI_TIMEOUT Device has no response + +**/ EFI_STATUS -UsbGetDeviceInterface ( +UsbGetInterface ( IN EFI_USB_IO_PROTOCOL *UsbIo, IN UINT16 Index, OUT UINT8 *AltSetting, OUT UINT32 *Status ) -/*++ - -Routine Description: - - Usb Get Device Interface - -Arguments: - - UsbIo - EFI_USB_IO_PROTOCOL - Index - Interface index value - AltSetting - Alternate setting - Status - Trasnsfer status - -Returns: - - EFI_INVALID_PARAMETER - Parameter is error - EFI_SUCCESS - Success - EFI_TIMEOUT - Device has no response - - ---*/ { EFI_USB_DEVICE_REQUEST DevReq; @@ -179,7 +164,7 @@ Returns: ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); DevReq.RequestType = USB_DEV_GET_INTERFACE_REQ_TYPE; - DevReq.Request = USB_DEV_GET_INTERFACE; + DevReq.Request = USB_REQ_GET_INTERFACE; DevReq.Index = Index; DevReq.Length = 1; @@ -193,36 +178,28 @@ Returns: Status ); } -// -// Set device interface -// -EFI_STATUS -UsbSetDeviceInterface ( - IN EFI_USB_IO_PROTOCOL *UsbIo, - IN UINT16 InterfaceNo, - IN UINT16 AltSetting, - OUT UINT32 *Status - ) -/*++ -Routine Description: +/** Usb Set Device Interface -Arguments: - - UsbIo - EFI_USB_IO_PROTOCOL - InterfaceNo - Interface Number - AltSetting - Alternate setting - Status - Trasnsfer status + @param UsbIo EFI_USB_IO_PROTOCOL + @param InterfaceNo Interface Number + @param AltSetting Alternate setting + @param Status Trasnsfer status -Returns: + @retval EFI_INVALID_PARAMETER Parameter is error + @retval EFI_SUCCESS Success + @retval EFI_TIMEOUT Device has no response - EFI_INVALID_PARAMETER - Parameter is error - EFI_SUCCESS - Success - EFI_TIMEOUT - Device has no response - ---*/ +**/ +EFI_STATUS +UsbSetInterface ( + IN EFI_USB_IO_PROTOCOL *UsbIo, + IN UINT16 InterfaceNo, + IN UINT16 AltSetting, + OUT UINT32 *Status + ) { EFI_USB_DEVICE_REQUEST DevReq; @@ -233,10 +210,10 @@ Returns: ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); DevReq.RequestType = USB_DEV_SET_INTERFACE_REQ_TYPE; - DevReq.Request = USB_DEV_SET_INTERFACE; + DevReq.Request = USB_REQ_SET_INTERFACE; DevReq.Value = AltSetting; DevReq.Index = InterfaceNo; - + return UsbIo->UsbControlTransfer ( UsbIo, @@ -248,34 +225,26 @@ Returns: Status ); } -// -// Get device configuration -// -EFI_STATUS -UsbGetDeviceConfiguration ( - IN EFI_USB_IO_PROTOCOL *UsbIo, - OUT UINT8 *ConfigValue, - OUT UINT32 *Status - ) -/*++ -Routine Description: +/** Usb Get Device Configuration -Arguments: - - UsbIo - EFI_USB_IO_PROTOCOL - ConfigValue - Config Value - Status - Transfer Status - -Returns: + @param UsbIo EFI_USB_IO_PROTOCOL + @param ConfigValue Config Value + @param Status Transfer Status - EFI_INVALID_PARAMETER - Parameter is error - EFI_SUCCESS - Success - EFI_TIMEOUT - Device has no response + @retval EFI_INVALID_PARAMETER Parameter is error + @retval EFI_SUCCESS Success + @retval EFI_TIMEOUT Device has no response ---*/ +**/ +EFI_STATUS +UsbGetConfiguration ( + IN EFI_USB_IO_PROTOCOL *UsbIo, + OUT UINT8 *ConfigValue, + OUT UINT32 *Status + ) { EFI_USB_DEVICE_REQUEST DevReq; @@ -286,7 +255,7 @@ Returns: ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); DevReq.RequestType = USB_DEV_GET_CONFIGURATION_REQ_TYPE; - DevReq.Request = USB_DEV_GET_CONFIGURATION; + DevReq.Request = USB_REQ_GET_CONFIG; DevReq.Length = 1; return UsbIo->UsbControlTransfer ( @@ -299,34 +268,26 @@ Returns: Status ); } -// -// Set device configuration -// -EFI_STATUS -UsbSetDeviceConfiguration ( - IN EFI_USB_IO_PROTOCOL *UsbIo, - IN UINT16 Value, - OUT UINT32 *Status - ) -/*++ -Routine Description: +/** Usb Set Device Configuration -Arguments: - - UsbIo - EFI_USB_IO_PROTOCOL - Value - Configuration Value to set - Status - Transfer status + @param UsbIo EFI_USB_IO_PROTOCOL + @param Value Configuration Value to set + @param Status Transfer status -Returns: + @retval EFI_INVALID_PARAMETER Parameter is error + @retval EFI_SUCCESS Success + @retval EFI_TIMEOUT Device has no response - EFI_INVALID_PARAMETER - Parameter is error - EFI_SUCCESS - Success - EFI_TIMEOUT - Device has no response - ---*/ +**/ +EFI_STATUS +UsbSetConfiguration ( + IN EFI_USB_IO_PROTOCOL *UsbIo, + IN UINT16 Value, + OUT UINT32 *Status + ) { EFI_USB_DEVICE_REQUEST DevReq; @@ -337,9 +298,9 @@ Returns: ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); DevReq.RequestType = USB_DEV_SET_CONFIGURATION_REQ_TYPE; - DevReq.Request = USB_DEV_SET_CONFIGURATION; + DevReq.Request = USB_REQ_SET_CONFIG; DevReq.Value = Value; - + return UsbIo->UsbControlTransfer ( UsbIo, &DevReq, @@ -350,38 +311,30 @@ Returns: Status ); } -// -// Set Device Feature -// -EFI_STATUS -UsbSetDeviceFeature ( - IN EFI_USB_IO_PROTOCOL *UsbIo, - IN EFI_USB_RECIPIENT Recipient, - IN UINT16 Value, - IN UINT16 Target, - OUT UINT32 *Status - ) -/*++ -Routine Description: +/** Usb Set Device Feature -Arguments: + @param UsbIo EFI_USB_IO_PROTOCOL + @param Recipient Interface/Device/Endpoint + @param Value Request value + @param Target Request Index + @param Status Transfer status - UsbIo - EFI_USB_IO_PROTOCOL - Recipient - Interface/Device/Endpoint - Value - Request value - Target - Request Index - Status - Transfer status + @retval EFI_INVALID_PARAMETER Parameter is error + @retval EFI_SUCCESS Success + @retval EFI_TIMEOUT Device has no response -Returns: - - EFI_INVALID_PARAMETER - Parameter is error - EFI_SUCCESS - Success - EFI_TIMEOUT - Device has no response - ---*/ +**/ +EFI_STATUS +UsbSetFeature ( + IN EFI_USB_IO_PROTOCOL *UsbIo, + IN UINTN Recipient, + IN UINT16 Value, + IN UINT16 Target, + OUT UINT32 *Status + ) { EFI_USB_DEVICE_REQUEST DevReq; @@ -393,22 +346,22 @@ Returns: switch (Recipient) { - case EfiUsbDevice: - DevReq.RequestType = 0x00; + case USB_TARGET_DEVICE: + DevReq.RequestType = USB_DEV_SET_FEATURE_REQ_TYPE_D; break; - case EfiUsbInterface: - DevReq.RequestType = 0x01; + case USB_TARGET_INTERFACE: + DevReq.RequestType = USB_DEV_SET_FEATURE_REQ_TYPE_I; break; - case EfiUsbEndpoint: - DevReq.RequestType = 0x02; + case USB_TARGET_ENDPOINT: + DevReq.RequestType = USB_DEV_SET_FEATURE_REQ_TYPE_E; break; } // // Fill device request, see USB1.1 spec // - DevReq.Request = USB_DEV_SET_FEATURE; + DevReq.Request = USB_REQ_SET_FEATURE; DevReq.Value = Value; DevReq.Index = Target; @@ -423,38 +376,30 @@ Returns: Status ); } -// -// Clear Device Feature -// -EFI_STATUS -UsbClearDeviceFeature ( - IN EFI_USB_IO_PROTOCOL *UsbIo, - IN EFI_USB_RECIPIENT Recipient, - IN UINT16 Value, - IN UINT16 Target, - OUT UINT32 *Status - ) -/*++ -Routine Description: +/** Usb Clear Device Feature -Arguments: + @param UsbIo EFI_USB_IO_PROTOCOL + @param Recipient Interface/Device/Endpoint + @param Value Request value + @param Target Request Index + @param Status Transfer status - UsbIo - EFI_USB_IO_PROTOCOL - Recipient - Interface/Device/Endpoint - Value - Request value - Target - Request Index - Status - Transfer status + @retval EFI_INVALID_PARAMETER Parameter is error + @retval EFI_SUCCESS Success + @retval EFI_TIMEOUT Device has no response -Returns: - - EFI_INVALID_PARAMETER - Parameter is error - EFI_SUCCESS - Success - EFI_TIMEOUT - Device has no response - ---*/ +**/ +EFI_STATUS +UsbClearFeature ( + IN EFI_USB_IO_PROTOCOL *UsbIo, + IN UINTN Recipient, + IN UINT16 Value, + IN UINT16 Target, + OUT UINT32 *Status + ) { EFI_USB_DEVICE_REQUEST DevReq; @@ -466,22 +411,22 @@ Returns: switch (Recipient) { - case EfiUsbDevice: - DevReq.RequestType = 0x00; + case USB_TARGET_DEVICE: + DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_D; break; - case EfiUsbInterface: - DevReq.RequestType = 0x01; + case USB_TARGET_INTERFACE: + DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_I; break; - case EfiUsbEndpoint: - DevReq.RequestType = 0x02; + case USB_TARGET_ENDPOINT: + DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_E; break; } // // Fill device request, see USB1.1 spec // - DevReq.Request = USB_DEV_CLEAR_FEATURE; + DevReq.Request = USB_REQ_CLEAR_FEATURE; DevReq.Value = Value; DevReq.Index = Target; @@ -496,38 +441,30 @@ Returns: Status ); } -// -// Get Device Status -// -EFI_STATUS -UsbGetDeviceStatus ( - IN EFI_USB_IO_PROTOCOL *UsbIo, - IN EFI_USB_RECIPIENT Recipient, - IN UINT16 Target, - OUT UINT16 *DevStatus, - OUT UINT32 *Status - ) -/*++ -Routine Description: +/** Usb Get Device Status -Arguments: + @param UsbIo EFI_USB_IO_PROTOCOL + @param Recipient Interface/Device/Endpoint + @param Target Request index + @param DevStatus Device status + @param Status Transfer status - UsbIo - EFI_USB_IO_PROTOCOL - Recipient - Interface/Device/Endpoint - Target - Request index - DevStatus - Device status - Status - Transfer status + @retval EFI_INVALID_PARAMETER Parameter is error + @retval EFI_SUCCESS Success + @retval EFI_TIMEOUT Device has no response -Returns: - - EFI_INVALID_PARAMETER - Parameter is error - EFI_SUCCESS - Success - EFI_TIMEOUT - Device has no response - ---*/ +**/ +EFI_STATUS +UsbGetStatus ( + IN EFI_USB_IO_PROTOCOL *UsbIo, + IN UINTN Recipient, + IN UINT16 Target, + OUT UINT16 *DevStatus, + OUT UINT32 *Status + ) { EFI_USB_DEVICE_REQUEST DevReq; @@ -539,22 +476,22 @@ Returns: switch (Recipient) { - case EfiUsbDevice: - DevReq.RequestType = 0x80; + case USB_TARGET_DEVICE: + DevReq.RequestType = USB_DEV_GET_STATUS_REQ_TYPE_D; break; - case EfiUsbInterface: - DevReq.RequestType = 0x81; + case USB_TARGET_INTERFACE: + DevReq.RequestType = USB_DEV_GET_STATUS_REQ_TYPE_I; break; - case EfiUsbEndpoint: - DevReq.RequestType = 0x82; + case USB_TARGET_ENDPOINT: + DevReq.RequestType = USB_DEV_GET_STATUS_REQ_TYPE_E; break; } // // Fill device request, see USB1.1 spec // - DevReq.Request = USB_DEV_GET_STATUS; + DevReq.Request = USB_REQ_GET_STATUS; DevReq.Value = 0; DevReq.Index = Target; DevReq.Length = 2; @@ -569,86 +506,27 @@ Returns: Status ); } -// -// Usb Get String -// -EFI_STATUS -UsbGetString ( - IN EFI_USB_IO_PROTOCOL *UsbIo, - IN UINT16 LangID, - IN UINT8 Index, - IN VOID *Buf, - IN UINTN BufSize, - OUT UINT32 *Status - ) -/*++ -Routine Description: - Usb Get String -Arguments: +/** + Clear endpoint stall - UsbIo - EFI_USB_IO_PROTOCOL - LangID - Language ID - Index - Request index - Buf - Buffer to store string - BufSize - Buffer size - Status - Transfer status + @param UsbIo EFI_USB_IO_PROTOCOL + @param EndpointNo Endpoint Number + @param Status Transfer Status -Returns: - - EFI_INVALID_PARAMETER - Parameter is error - EFI_SUCCESS - Success - EFI_TIMEOUT - Device has no response - ---*/ -{ - UINT16 Value; - - if (UsbIo == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Fill value, see USB1.1 spec - // - Value = (UINT16) ((USB_DT_STRING << 8) | Index); - - return UsbGetDescriptor ( - UsbIo, - Value, - LangID, - (UINT16) BufSize, - Buf, - Status - ); -} + @retval EFI_NOT_FOUND Can't find the Endpoint + @retval EFI_DEVICE_ERROR Hardware error + @retval EFI_SUCCESS Success +**/ EFI_STATUS UsbClearEndpointHalt ( IN EFI_USB_IO_PROTOCOL *UsbIo, IN UINT8 EndpointNo, OUT UINT32 *Status ) -/*++ - -Routine Description: - - Clear endpoint stall - -Arguments: - - UsbIo - EFI_USB_IO_PROTOCOL - EndpointNo - Endpoint Number - Status - Transfer Status - -Returns: - - EFI_NOT_FOUND - Can't find the Endpoint - EFI_DEVICE_ERROR - Hardware error - EFI_SUCCESS - Success - ---*/ { EFI_STATUS Result; EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor; @@ -689,9 +567,9 @@ Returns: return EFI_NOT_FOUND; } - Result = UsbClearDeviceFeature ( + Result = UsbClearFeature ( UsbIo, - EfiUsbEndpoint, + USB_TARGET_ENDPOINT, EfiUsbEndpointHalt, EndpointDescriptor.EndpointAddress, Status diff --git a/MdePkg/Library/UefiUsbLib/hid.c b/MdePkg/Library/UefiUsbLib/hid.c index a1019a0f2d..3156f63143 100644 --- a/MdePkg/Library/UefiUsbLib/hid.c +++ b/MdePkg/Library/UefiUsbLib/hid.c @@ -1,13 +1,13 @@ -/*++ +/** @file -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. Module Name: @@ -19,36 +19,34 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. Revision History ---*/ -#include "UefiUsbLibInternal.h" +**/ +#include +#include // // Function to get HID descriptor // + +/** + Get Hid Descriptor + + @param UsbIo EFI_USB_IO_PROTOCOL + @param InterfaceNum Hid interface number + @param HidDescriptor Caller allocated buffer to store Usb hid descriptor if + successfully returned. + + @return EFI_SUCCESS + @return EFI_DEVICE_ERROR + @return EFI_TIMEOUT + +**/ EFI_STATUS UsbGetHidDescriptor ( IN EFI_USB_IO_PROTOCOL *UsbIo, IN UINT8 InterfaceNum, OUT EFI_USB_HID_DESCRIPTOR *HidDescriptor ) -/*++ - - Routine Description: - Get Hid Descriptor - - Arguments: - UsbIo - EFI_USB_IO_PROTOCOL - InterfaceNum - Hid interface number - HidDescriptor - Caller allocated buffer to store Usb hid descriptor - if successfully returned. - - Returns: - EFI_SUCCESS - EFI_DEVICE_ERROR - EFI_TIMEOUT - ---*/ { UINT32 Status; EFI_STATUS Result; @@ -76,6 +74,21 @@ UsbGetHidDescriptor ( // // Function to get Report Class descriptor // + +/** + get Report Class descriptor + + @param UsbIo EFI_USB_IO_PROTOCOL. + @param InterfaceNum Report interface number. + @param DescriptorSize Length of DescriptorBuffer. + @param DescriptorBuffer Caller allocated buffer to store Usb report descriptor + if successfully returned. + + @return EFI_SUCCESS + @return EFI_DEVICE_ERROR + @return EFI_TIMEOUT + +**/ EFI_STATUS UsbGetReportDescriptor ( IN EFI_USB_IO_PROTOCOL *UsbIo, @@ -83,24 +96,6 @@ UsbGetReportDescriptor ( IN UINT16 DescriptorSize, OUT UINT8 *DescriptorBuffer ) -/*++ - - Routine Description: - get Report Class descriptor - - Arguments: - UsbIo - EFI_USB_IO_PROTOCOL. - InterfaceNum - Report interface number. - DescriptorSize - Length of DescriptorBuffer. - DescriptorBuffer - Caller allocated buffer to store Usb report descriptor - if successfully returned. - - Returns: - EFI_SUCCESS - EFI_DEVICE_ERROR - EFI_TIMEOUT - ---*/ { UINT32 Status; EFI_STATUS Result; @@ -131,28 +126,25 @@ UsbGetReportDescriptor ( // // Following are HID class request // + +/** + Get Hid Protocol Request + + @param UsbIo EFI_USB_IO_PROTOCOL + @param Interface Which interface the caller wants to get protocol + @param Protocol Protocol value returned. + + @return EFI_SUCCESS + @return EFI_DEVICE_ERROR + @return EFI_TIMEOUT + +**/ EFI_STATUS UsbGetProtocolRequest ( IN EFI_USB_IO_PROTOCOL *UsbIo, IN UINT8 Interface, IN UINT8 *Protocol ) -/*++ - - Routine Description: - Get Hid Protocol Request - - Arguments: - UsbIo - EFI_USB_IO_PROTOCOL - Interface - Which interface the caller wants to get protocol - Protocol - Protocol value returned. - - Returns: - EFI_SUCCESS - EFI_DEVICE_ERROR - EFI_TIMEOUT - ---*/ { UINT32 Status; EFI_STATUS Result; @@ -184,28 +176,25 @@ UsbGetProtocolRequest ( } + +/** + Set Hid Protocol Request + + @param UsbIo EFI_USB_IO_PROTOCOL + @param Interface Which interface the caller wants to set protocol + @param Protocol Protocol value the caller wants to set. + + @return EFI_SUCCESS + @return EFI_DEVICE_ERROR + @return EFI_TIMEOUT + +**/ EFI_STATUS UsbSetProtocolRequest ( IN EFI_USB_IO_PROTOCOL *UsbIo, IN UINT8 Interface, IN UINT8 Protocol ) -/*++ - - Routine Description: - Set Hid Protocol Request - - Arguments: - UsbIo - EFI_USB_IO_PROTOCOL - Interface - Which interface the caller wants to set protocol - Protocol - Protocol value the caller wants to set. - - Returns: - EFI_SUCCESS - EFI_DEVICE_ERROR - EFI_TIMEOUT - ---*/ { UINT32 Status; EFI_STATUS Result; @@ -236,6 +225,20 @@ UsbSetProtocolRequest ( } + +/** + Set Idel request. + + @param UsbIo EFI_USB_IO_PROTOCOL + @param Interface Which interface the caller wants to set. + @param ReportId Which report the caller wants to set. + @param Duration Idle rate the caller wants to set. + + @return EFI_SUCCESS + @return EFI_DEVICE_ERROR + @return EFI_TIMEOUT + +**/ EFI_STATUS UsbSetIdleRequest ( IN EFI_USB_IO_PROTOCOL *UsbIo, @@ -243,23 +246,6 @@ UsbSetIdleRequest ( IN UINT8 ReportId, IN UINT8 Duration ) -/*++ - - Routine Description: - Set Idel request. - - Arguments: - UsbIo - EFI_USB_IO_PROTOCOL - Interface - Which interface the caller wants to set. - ReportId - Which report the caller wants to set. - Duration - Idle rate the caller wants to set. - - Returns: - EFI_SUCCESS - EFI_DEVICE_ERROR - EFI_TIMEOUT - ---*/ { UINT32 Status; EFI_STATUS Result; @@ -289,6 +275,20 @@ UsbSetIdleRequest ( return Result; } + +/** + Get Idel request. + + @param UsbIo EFI_USB_IO_PROTOCOL + @param Interface Which interface the caller wants to get. + @param ReportId Which report the caller wants to get. + @param Duration Idle rate the caller wants to get. + + @return EFI_SUCCESS + @return EFI_DEVICE_ERROR + @return EFI_TIMEOUT + +**/ EFI_STATUS UsbGetIdleRequest ( IN EFI_USB_IO_PROTOCOL *UsbIo, @@ -296,23 +296,6 @@ UsbGetIdleRequest ( IN UINT8 ReportId, OUT UINT8 *Duration ) -/*++ - - Routine Description: - Get Idel request. - - Arguments: - UsbIo - EFI_USB_IO_PROTOCOL - Interface - Which interface the caller wants to get. - ReportId - Which report the caller wants to get. - Duration - Idle rate the caller wants to get. - - Returns: - EFI_SUCCESS - EFI_DEVICE_ERROR - EFI_TIMEOUT - ---*/ { UINT32 Status; EFI_STATUS Result; @@ -344,6 +327,22 @@ UsbGetIdleRequest ( } + +/** + Hid Set Report request. + + @param UsbIo EFI_USB_IO_PROTOCOL + @param Interface Which interface the caller wants to set. + @param ReportId Which report the caller wants to set. + @param ReportType Type of report. + @param ReportLen Length of report descriptor. + @param Report Report Descriptor buffer. + + @return EFI_SUCCESS + @return EFI_DEVICE_ERROR + @return EFI_TIMEOUT + +**/ EFI_STATUS UsbSetReportRequest ( IN EFI_USB_IO_PROTOCOL *UsbIo, @@ -353,25 +352,6 @@ UsbSetReportRequest ( IN UINT16 ReportLen, IN UINT8 *Report ) -/*++ - - Routine Description: - Hid Set Report request. - - Arguments: - UsbIo - EFI_USB_IO_PROTOCOL - Interface - Which interface the caller wants to set. - ReportId - Which report the caller wants to set. - ReportType - Type of report. - ReportLen - Length of report descriptor. - Report - Report Descriptor buffer. - - Returns: - EFI_SUCCESS - EFI_DEVICE_ERROR - EFI_TIMEOUT - ---*/ { UINT32 Status; EFI_STATUS Result; @@ -402,6 +382,22 @@ UsbSetReportRequest ( return Result; } + +/** + Hid Set Report request. + + @param UsbIo EFI_USB_IO_PROTOCOL + @param Interface Which interface the caller wants to set. + @param ReportId Which report the caller wants to set. + @param ReportType Type of report. + @param ReportLen Length of report descriptor. + @param Report Caller allocated buffer to store Report Descriptor. + + @return EFI_SUCCESS + @return EFI_DEVICE_ERROR + @return EFI_TIMEOUT + +**/ EFI_STATUS UsbGetReportRequest ( IN EFI_USB_IO_PROTOCOL *UsbIo, @@ -411,25 +407,6 @@ UsbGetReportRequest ( IN UINT16 ReportLen, IN UINT8 *Report ) -/*++ - - Routine Description: - Hid Set Report request. - - Arguments: - UsbIo - EFI_USB_IO_PROTOCOL - Interface - Which interface the caller wants to set. - ReportId - Which report the caller wants to set. - ReportType - Type of report. - ReportLen - Length of report descriptor. - Report - Caller allocated buffer to store Report Descriptor. - - Returns: - EFI_SUCCESS - EFI_DEVICE_ERROR - EFI_TIMEOUT - ---*/ { UINT32 Status; EFI_STATUS Result;