diff --git a/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/ComponentName.c b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/ComponentName.c new file mode 100644 index 0000000000..3e71f4e748 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/ComponentName.c @@ -0,0 +1,377 @@ +/** @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: + + UsbMouseAbsolutePointerComponentName.c + +Abstract: + + +**/ + +#include "UsbMouseAbsolutePointer.h" +#include + +// +// EFI Component Name Functions +// +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name 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. Language is specified + in RFC 3066 or ISO 639-2 language code format. + + @param DriverName[out] 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. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +UsbMouseAbsolutePointerComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] 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. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name 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. Language is specified in + RFC 3066 or ISO 639-2 language code format. + + @param ControllerName[out] 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. + + @retval 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. + + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +UsbMouseAbsolutePointerComponentNameGetControllerName ( + 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 +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gUsbMouseAbsolutePointerComponentName = { + UsbMouseAbsolutePointerComponentNameGetDriverName, + UsbMouseAbsolutePointerComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gUsbMouseAbsolutePointerComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) UsbMouseAbsolutePointerComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) UsbMouseAbsolutePointerComponentNameGetControllerName, + "en" +}; + + + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUsbMouseAbsolutePointerDriverNameTable[] = { + { "eng;en", L"Usb Mouse Simulate TouchPad Driver" }, + { NULL , NULL } +}; + + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name 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. Language is specified + in RFC 3066 or ISO 639-2 language code format. + + @param DriverName[out] 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. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +UsbMouseAbsolutePointerComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mUsbMouseAbsolutePointerDriverNameTable, + DriverName, + (BOOLEAN)(This == &gUsbMouseAbsolutePointerComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] 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. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name 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. Language is specified in + RFC 3066 or ISO 639-2 language code format. + + @param ControllerName[out] 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. + + @retval 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. + + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +UsbMouseAbsolutePointerComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDev; + EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointerProtocol; + 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, + gUsbMouseAbsolutePointerDriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (!EFI_ERROR (Status)) { + gBS->CloseProtocol ( + ControllerHandle, + &gEfiUsbIoProtocolGuid, + gUsbMouseAbsolutePointerDriverBinding.DriverBindingHandle, + ControllerHandle + ); + + return EFI_UNSUPPORTED; + } + + if (Status != EFI_ALREADY_STARTED) { + return EFI_UNSUPPORTED; + } + // + // Get the device context + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiAbsolutePointerProtocolGuid, + (VOID **) &AbsolutePointerProtocol, + gUsbMouseAbsolutePointerDriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + UsbMouseAbsolutePointerDev = USB_MOUSE_ABSOLUTE_POINTER_DEV_FROM_MOUSE_PROTOCOL (AbsolutePointerProtocol); + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + UsbMouseAbsolutePointerDev->ControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gUsbMouseAbsolutePointerComponentName) + ); + +} diff --git a/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointer.c b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointer.c new file mode 100644 index 0000000000..af68e610a3 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointer.c @@ -0,0 +1,1025 @@ +/** @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: + + UsbMouseAbsolutePointer.c + + Abstract: + + +**/ + +#include "UsbMouseAbsolutePointer.h" + +#include +#include + +#include "mousehid.h" + +// +// Prototypes +// Driver model protocol interface +// +EFI_STATUS +EFIAPI +USBMouseAbsolutePointerDriverBindingEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_STATUS +EFIAPI +USBMouseAbsolutePointerDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +EFI_STATUS +EFIAPI +USBMouseAbsolutePointerDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +EFI_STATUS +EFIAPI +USBMouseAbsolutePointerDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ); + +EFI_GUID gEfiUsbMouseAbsolutePointerDriverGuid = { + 0xa579f729, 0xa71d, 0x4b45, { 0xbe, 0xd7, 0xd, 0xb0, 0xa8, 0x7c, 0x3e, 0x8d } +}; + +EFI_DRIVER_BINDING_PROTOCOL gUsbMouseAbsolutePointerDriverBinding = { + USBMouseAbsolutePointerDriverBindingSupported, + USBMouseAbsolutePointerDriverBindingStart, + USBMouseAbsolutePointerDriverBindingStop, + 0x1, + NULL, + NULL +}; + +// +// helper functions +// +STATIC +BOOLEAN +IsUsbMouseAbsolutePointer ( + IN EFI_USB_IO_PROTOCOL *UsbIo + ); + +STATIC +EFI_STATUS +InitializeUsbMouseAbsolutePointerDevice ( + IN USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDev + ); + +STATIC +VOID +EFIAPI +UsbMouseAbsolutePointerWaitForInput ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +// +// Mouse interrupt handler +// +STATIC +EFI_STATUS +EFIAPI +OnMouseAbsolutePointerInterruptComplete ( + IN VOID *Data, + IN UINTN DataLength, + IN VOID *Context, + IN UINT32 Result + ); + +// +// Mouse simulate TouchPad, Using AbsolutePointer Protocol +// +STATIC +EFI_STATUS +EFIAPI +GetMouseAbsolutePointerState ( + IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, + OUT EFI_ABSOLUTE_POINTER_STATE *MouseAbsolutePointerState + ); + +STATIC +EFI_STATUS +EFIAPI +UsbMouseAbsolutePointerReset ( + IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +// +// Driver start here +// +EFI_STATUS +EFIAPI +USBMouseAbsolutePointerDriverBindingEntryPoint ( + 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 EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &gUsbMouseAbsolutePointerDriverBinding, + ImageHandle, + &gUsbMouseAbsolutePointerComponentName, + &gUsbMouseAbsolutePointerComponentName2 + ); +} + + +/** + 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 +USBMouseAbsolutePointerDriverBindingSupported ( + 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, + (VOID **) &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 (!IsUsbMouseAbsolutePointer (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 +USBMouseAbsolutePointerDriverBindingStart ( + 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_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDevice; + UINT8 EndpointNumber; + UINT8 Index; + UINT8 EndpointAddr; + UINT8 PollingInterval; + UINT8 PacketSize; + + UsbMouseAbsolutePointerDevice = NULL; + Status = EFI_SUCCESS; + + Status = gBS->OpenProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + (VOID **) &UsbIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + + UsbMouseAbsolutePointerDevice = AllocateZeroPool (sizeof (USB_MOUSE_ABSOLUTE_POINTER_DEV)); + if (UsbMouseAbsolutePointerDevice == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + + UsbMouseAbsolutePointerDevice->UsbIo = UsbIo; + + UsbMouseAbsolutePointerDevice->Signature = USB_MOUSE_ABSOLUTE_POINTER_DEV_SIGNATURE; + + UsbMouseAbsolutePointerDevice->InterfaceDescriptor = AllocatePool (sizeof (EFI_USB_INTERFACE_DESCRIPTOR)); + + if (UsbMouseAbsolutePointerDevice->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 **) &UsbMouseAbsolutePointerDevice->DevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + // + // Get interface & endpoint descriptor + // + UsbIo->UsbGetInterfaceDescriptor ( + UsbIo, + UsbMouseAbsolutePointerDevice->InterfaceDescriptor + ); + + EndpointNumber = UsbMouseAbsolutePointerDevice->InterfaceDescriptor->NumEndpoints; + + for (Index = 0; Index < EndpointNumber; Index++) { + UsbIo->UsbGetEndpointDescriptor ( + UsbIo, + Index, + EndpointDesc + ); + + if ((EndpointDesc->Attributes & 0x03) == 0x03) { + + // + // We only care interrupt endpoint here + // + UsbMouseAbsolutePointerDevice->IntEndpointDescriptor = EndpointDesc; + } + } + + if (UsbMouseAbsolutePointerDevice->IntEndpointDescriptor == NULL) { + // + // No interrupt endpoint, then error + // + Status = EFI_UNSUPPORTED; + goto ErrorExit; + } + + Status = InitializeUsbMouseAbsolutePointerDevice (UsbMouseAbsolutePointerDevice); + if (EFI_ERROR (Status)) { + MouseAbsolutePointerReportStatusCode ( + UsbMouseAbsolutePointerDevice->DevicePath, + EFI_ERROR_CODE | EFI_ERROR_MINOR, + PcdGet32 (PcdStatusCodeValueMouseInterfaceError) + ); + + goto ErrorExit; + } + + UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol.GetState = GetMouseAbsolutePointerState; + UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol.Reset = UsbMouseAbsolutePointerReset; + UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol.Mode = &UsbMouseAbsolutePointerDevice->AbsolutePointerMode; + + Status = gBS->CreateEvent ( + EVT_NOTIFY_WAIT, + TPL_NOTIFY, + UsbMouseAbsolutePointerWaitForInput, + UsbMouseAbsolutePointerDevice, + &((UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol).WaitForInput) + ); + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + + Status = gBS->InstallProtocolInterface ( + &Controller, + &gEfiAbsolutePointerProtocolGuid, + EFI_NATIVE_INTERFACE, + &UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol + ); + + 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 + // + + MouseAbsolutePointerReportStatusCode ( + UsbMouseAbsolutePointerDevice->DevicePath, + EFI_PROGRESS_CODE, + PcdGet32 (PcdStatusCodeValueMouseEnable) + ); + + // + // submit async interrupt transfer + // + EndpointAddr = UsbMouseAbsolutePointerDevice->IntEndpointDescriptor->EndpointAddress; + PollingInterval = UsbMouseAbsolutePointerDevice->IntEndpointDescriptor->Interval; + PacketSize = (UINT8) (UsbMouseAbsolutePointerDevice->IntEndpointDescriptor->MaxPacketSize); + + Status = UsbIo->UsbAsyncInterruptTransfer ( + UsbIo, + EndpointAddr, + TRUE, + PollingInterval, + PacketSize, + OnMouseAbsolutePointerInterruptComplete, + UsbMouseAbsolutePointerDevice + ); + + if (!EFI_ERROR (Status)) { + + UsbMouseAbsolutePointerDevice->ControllerNameTable = NULL; + AddUnicodeString2 ( + "eng", + gUsbMouseAbsolutePointerComponentName.SupportedLanguages, + &UsbMouseAbsolutePointerDevice->ControllerNameTable, + L"Generic Usb Mouse Simulate TouchPad", + TRUE + ); + AddUnicodeString2 ( + "en", + gUsbMouseAbsolutePointerComponentName2.SupportedLanguages, + &UsbMouseAbsolutePointerDevice->ControllerNameTable, + L"Generic Usb Mouse Simulate TouchPad2", + FALSE + ); + + return EFI_SUCCESS; + } + + // + // If submit error, uninstall that interface + // + Status = EFI_DEVICE_ERROR; + + gBS->UninstallProtocolInterface ( + Controller, + &gEfiAbsolutePointerProtocolGuid, + &UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol + ); + +ErrorExit: + if (EFI_ERROR (Status)) { + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + if (UsbMouseAbsolutePointerDevice != NULL) { + if (UsbMouseAbsolutePointerDevice->InterfaceDescriptor != NULL) { + gBS->FreePool (UsbMouseAbsolutePointerDevice->InterfaceDescriptor); + } + + if (UsbMouseAbsolutePointerDevice->IntEndpointDescriptor != NULL) { + gBS->FreePool (UsbMouseAbsolutePointerDevice->IntEndpointDescriptor); + } + + if ((UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol).WaitForInput != NULL) { + gBS->CloseEvent ((UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol).WaitForInput); + } + + gBS->FreePool (UsbMouseAbsolutePointerDevice); + UsbMouseAbsolutePointerDevice = 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 +USBMouseAbsolutePointerDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_STATUS Status; + USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDevice; + EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointerProtocol; + EFI_USB_IO_PROTOCOL *UsbIo; + + // + // Get our context back. + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiAbsolutePointerProtocolGuid, + (VOID **) &AbsolutePointerProtocol, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + UsbMouseAbsolutePointerDevice = USB_MOUSE_ABSOLUTE_POINTER_DEV_FROM_MOUSE_PROTOCOL (AbsolutePointerProtocol); + + gBS->CloseProtocol ( + Controller, + &gEfiAbsolutePointerProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + UsbIo = UsbMouseAbsolutePointerDevice->UsbIo; + + // + // Uninstall the Asyn Interrupt Transfer from this device + // will disable the mouse data input from this device + // + MouseAbsolutePointerReportStatusCode ( + UsbMouseAbsolutePointerDevice->DevicePath, + EFI_PROGRESS_CODE, + PcdGet32 (PcdStatusCodeValueMouseDisable) + ); + + // + // Delete Mouse Async Interrupt Transfer + // + UsbIo->UsbAsyncInterruptTransfer ( + UsbIo, + UsbMouseAbsolutePointerDevice->IntEndpointDescriptor->EndpointAddress, + FALSE, + UsbMouseAbsolutePointerDevice->IntEndpointDescriptor->Interval, + 0, + NULL, + NULL + ); + + gBS->CloseEvent (UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol.WaitForInput); + + if (UsbMouseAbsolutePointerDevice->DelayedRecoveryEvent) { + gBS->CloseEvent (UsbMouseAbsolutePointerDevice->DelayedRecoveryEvent); + UsbMouseAbsolutePointerDevice->DelayedRecoveryEvent = 0; + } + + Status = gBS->UninstallProtocolInterface ( + Controller, + &gEfiAbsolutePointerProtocolGuid, + &UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + gBS->CloseProtocol ( + Controller, + &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + gBS->FreePool (UsbMouseAbsolutePointerDevice->InterfaceDescriptor); + gBS->FreePool (UsbMouseAbsolutePointerDevice->IntEndpointDescriptor); + + if (UsbMouseAbsolutePointerDevice->ControllerNameTable) { + FreeUnicodeStringTable (UsbMouseAbsolutePointerDevice->ControllerNameTable); + } + + gBS->FreePool (UsbMouseAbsolutePointerDevice); + + 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 +IsUsbMouseAbsolutePointer ( + 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 Simulate TouchPad Device. + + @param UsbMouseAbsolutePointerDev 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 +InitializeUsbMouseAbsolutePointerDevice ( + IN USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDev + ) +{ + EFI_USB_IO_PROTOCOL *UsbIo; + UINT8 Protocol; + EFI_STATUS Status; + EFI_USB_HID_DESCRIPTOR MouseHidDesc; + UINT8 *ReportDesc; + + UsbIo = UsbMouseAbsolutePointerDev->UsbIo; + + // + // Get HID descriptor + // + Status = UsbGetHidDescriptor ( + UsbIo, + UsbMouseAbsolutePointerDev->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, + UsbMouseAbsolutePointerDev->InterfaceDescriptor->InterfaceNumber, + MouseHidDesc.HidClassDesc[0].DescriptorLength, + ReportDesc + ); + + if (EFI_ERROR (Status)) { + gBS->FreePool (ReportDesc); + return Status; + } + + // + // Parse report descriptor + // + Status = ParseMouseReportDescriptor ( + UsbMouseAbsolutePointerDev, + ReportDesc, + MouseHidDesc.HidClassDesc[0].DescriptorLength + ); + + if (EFI_ERROR (Status)) { + gBS->FreePool (ReportDesc); + return Status; + } + + UsbMouseAbsolutePointerDev->AbsolutePointerMode.AbsoluteMaxX = 1024; + UsbMouseAbsolutePointerDev->AbsolutePointerMode.AbsoluteMaxY = 1024; + UsbMouseAbsolutePointerDev->AbsolutePointerMode.AbsoluteMaxZ = 0; + UsbMouseAbsolutePointerDev->AbsolutePointerMode.AbsoluteMinX = 0; + UsbMouseAbsolutePointerDev->AbsolutePointerMode.AbsoluteMinY = 0; + UsbMouseAbsolutePointerDev->AbsolutePointerMode.AbsoluteMinZ = 0; + UsbMouseAbsolutePointerDev->AbsolutePointerMode.Attributes = 0x3; + + // + // 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 (UsbMouseAbsolutePointerDev->DelayedRecoveryEvent) { + gBS->CloseEvent (UsbMouseAbsolutePointerDev->DelayedRecoveryEvent); + UsbMouseAbsolutePointerDev->DelayedRecoveryEvent = 0; + } + + Status = gBS->CreateEvent ( + EVT_TIMER | EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + USBMouseAbsolutePointerRecoveryHandler, + UsbMouseAbsolutePointerDev, + &UsbMouseAbsolutePointerDev->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 +OnMouseAbsolutePointerInterruptComplete ( + IN VOID *Data, + IN UINTN DataLength, + IN VOID *Context, + IN UINT32 Result + ) +{ + USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDevice; + EFI_USB_IO_PROTOCOL *UsbIo; + UINT8 EndpointAddr; + UINT32 UsbResult; + + UsbMouseAbsolutePointerDevice = (USB_MOUSE_ABSOLUTE_POINTER_DEV *) Context; + UsbIo = UsbMouseAbsolutePointerDevice->UsbIo; + + if (Result != EFI_USB_NOERROR) { + // + // Some errors happen during the process + // + MouseAbsolutePointerReportStatusCode ( + UsbMouseAbsolutePointerDevice->DevicePath, + EFI_ERROR_CODE | EFI_ERROR_MINOR, + PcdGet32 (PcdStatusCodeValueMouseInputError) + ); + + if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) { + EndpointAddr = UsbMouseAbsolutePointerDevice->IntEndpointDescriptor->EndpointAddress; + + UsbClearEndpointHalt ( + UsbIo, + EndpointAddr, + &UsbResult + ); + } + + UsbIo->UsbAsyncInterruptTransfer ( + UsbIo, + UsbMouseAbsolutePointerDevice->IntEndpointDescriptor->EndpointAddress, + FALSE, + 0, + 0, + NULL, + NULL + ); + + gBS->SetTimer ( + UsbMouseAbsolutePointerDevice->DelayedRecoveryEvent, + TimerRelative, + EFI_USB_INTERRUPT_DELAY + ); + return EFI_DEVICE_ERROR; + } + + if (DataLength == 0 || Data == NULL) { + return EFI_SUCCESS; + } + + // + //Check mouse Data + // + UsbMouseAbsolutePointerDevice->AbsolutePointerStateChanged = TRUE; + UsbMouseAbsolutePointerDevice->AbsolutePointerState.CurrentX += *((INT8 *) Data + 1); + UsbMouseAbsolutePointerDevice->AbsolutePointerState.CurrentY += *((INT8 *) Data + 2); + if (DataLength > 3) { + UsbMouseAbsolutePointerDevice->AbsolutePointerState.CurrentZ += *((INT8 *) Data + 3); + } + UsbMouseAbsolutePointerDevice->AbsolutePointerState.ActiveButtons = *(UINT8 *)Data & 0x3; + + return EFI_SUCCESS; +} + +/** + Get the mouse state, see ABSOLUTE 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 +GetMouseAbsolutePointerState ( + IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, + OUT EFI_ABSOLUTE_POINTER_STATE *MouseAbsolutePointerState + ) +{ + USB_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev; + + if (MouseAbsolutePointerState == NULL) { + return EFI_DEVICE_ERROR; + } + + MouseAbsolutePointerDev = USB_MOUSE_ABSOLUTE_POINTER_DEV_FROM_MOUSE_PROTOCOL (This); + + if (!MouseAbsolutePointerDev->AbsolutePointerStateChanged) { + return EFI_NOT_READY; + } + + CopyMem ( + MouseAbsolutePointerState, + &MouseAbsolutePointerDev->AbsolutePointerState, + sizeof (EFI_ABSOLUTE_POINTER_STATE) + ); + + // + // Clear previous move state + // + MouseAbsolutePointerDev->AbsolutePointerState.CurrentX = 0; + MouseAbsolutePointerDev->AbsolutePointerState.CurrentY = 0; + MouseAbsolutePointerDev->AbsolutePointerState.CurrentZ = 0; + MouseAbsolutePointerDev->AbsolutePointerState.ActiveButtons = 0; + + MouseAbsolutePointerDev->AbsolutePointerStateChanged = FALSE; + + return EFI_SUCCESS; +} + + +/** + Reset the mouse device, see ABSOLUTE POINTER PROTOCOL. + + @param This Protocol instance pointer. + @param ExtendedVerification Ignored here/ + + @return EFI_SUCCESS + +**/ +STATIC +EFI_STATUS +EFIAPI +UsbMouseAbsolutePointerReset ( + IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDevice; + + UsbMouseAbsolutePointerDevice = USB_MOUSE_ABSOLUTE_POINTER_DEV_FROM_MOUSE_PROTOCOL (This); + + MouseAbsolutePointerReportStatusCode ( + UsbMouseAbsolutePointerDevice->DevicePath, + EFI_PROGRESS_CODE, + PcdGet32 (PcdStatusCodeValueMouseReset) + ); + + ZeroMem ( + &UsbMouseAbsolutePointerDevice->AbsolutePointerState, + sizeof (EFI_ABSOLUTE_POINTER_STATE) + ); + UsbMouseAbsolutePointerDevice->AbsolutePointerStateChanged = FALSE; + + return EFI_SUCCESS; +} + +/** + Event notification function for ABSOLUTE_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 +UsbMouseAbsolutePointerWaitForInput ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDev; + + UsbMouseAbsolutePointerDev = (USB_MOUSE_ABSOLUTE_POINTER_DEV *) Context; + + // + // Someone is waiting on the mouse event, if there's + // input from mouse, signal the event + // + if (UsbMouseAbsolutePointerDev->AbsolutePointerStateChanged) { + 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 +USBMouseAbsolutePointerRecoveryHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDev; + EFI_USB_IO_PROTOCOL *UsbIo; + + UsbMouseAbsolutePointerDev = (USB_MOUSE_ABSOLUTE_POINTER_DEV *) Context; + + UsbIo = UsbMouseAbsolutePointerDev->UsbIo; + + UsbIo->UsbAsyncInterruptTransfer ( + UsbIo, + UsbMouseAbsolutePointerDev->IntEndpointDescriptor->EndpointAddress, + TRUE, + UsbMouseAbsolutePointerDev->IntEndpointDescriptor->Interval, + UsbMouseAbsolutePointerDev->IntEndpointDescriptor->MaxPacketSize, + OnMouseAbsolutePointerInterruptComplete, + UsbMouseAbsolutePointerDev + ); +} + + +/** + 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 +MouseAbsolutePointerReportStatusCode ( + 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/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointer.h b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointer.h new file mode 100644 index 0000000000..9c7d22f6cc --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointer.h @@ -0,0 +1,106 @@ +/** @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: + + UsbMouseAbsolutePointer.h + + Abstract: + + +**/ + +#ifndef _USB_MOUSE_ABSOLUTE_POINTER_H +#define _USB_MOUSE_ABSOLUTE_POINTER_H + + +#include + +#include +#include +#include + +#include +#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_ABSOLUTE_POINTER_DEV_SIGNATURE EFI_SIGNATURE_32 ('u', 'm', 's', 't') + +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_ABSOLUTE_POINTER_PROTOCOL AbsolutePointerProtocol; + EFI_ABSOLUTE_POINTER_STATE AbsolutePointerState; + EFI_ABSOLUTE_POINTER_MODE AbsolutePointerMode; + BOOLEAN AbsolutePointerStateChanged; + + PRIVATE_DATA PrivateData; + EFI_UNICODE_STRING_TABLE *ControllerNameTable; +} USB_MOUSE_ABSOLUTE_POINTER_DEV; + +#define USB_MOUSE_ABSOLUTE_POINTER_DEV_FROM_MOUSE_PROTOCOL(a) \ + CR(a, USB_MOUSE_ABSOLUTE_POINTER_DEV, AbsolutePointerProtocol, USB_MOUSE_ABSOLUTE_POINTER_DEV_SIGNATURE) + +VOID +EFIAPI +USBMouseAbsolutePointerRecoveryHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +// +// Global Variables +// +extern EFI_DRIVER_BINDING_PROTOCOL gUsbMouseAbsolutePointerDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gUsbMouseAbsolutePointerComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gUsbMouseAbsolutePointerComponentName2; +extern EFI_GUID gEfiUsbMouseAbsolutePointerDriverGuid; + +VOID +MouseAbsolutePointerReportStatusCode ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN EFI_STATUS_CODE_TYPE CodeType, + IN EFI_STATUS_CODE_VALUE Value + ); + +#endif diff --git a/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointerDxe.inf b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointerDxe.inf new file mode 100644 index 0000000000..14f7298a7c --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointerDxe.inf @@ -0,0 +1,67 @@ +#/** @file +# Component name for module UsbMouseAbsolutePointerDxe +# +# FIX ME! +# 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. +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UsbMouseAbsolutePointerDxe + FILE_GUID = 4EA43463-747C-46eb-97FB-B0E5C5F05306 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = USBMouseAbsolutePointerDriverBindingEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources.common] + mousehid.h + ComponentName.c + UsbMouseAbsolutePointer.c + mousehid.c + UsbMouseAbsolutePointer.h + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + MemoryAllocationLib + UefiLib + UefiBootServicesTableLib + UefiDriverEntryPoint + BaseMemoryLib + ReportStatusCodeLib + PcdLib + UsbLib + +[Protocols] + gEfiUsbIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiAbsolutePointerProtocolGuid # PROTOCOL ALWAYS_CONSUMED + +[FixedPcd] + gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueMouseInterfaceError + gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueMouseEnable + gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueMouseDisable + gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueMouseInputError + gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueMouseReset + + diff --git a/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointerDxe.msa b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointerDxe.msa new file mode 100644 index 0000000000..5ab61542b0 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointerDxe.msa @@ -0,0 +1,73 @@ + + + UsbMouseAbsolutePointerDxe + DXE_DRIVER + 4EA43463-747C-46eb-97FB-B0E5C5F05306 + 1.0 + Component name for module UsbMouseAbsolutePointer + FIX ME! + 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + UsbMouseAbsolutePointerDxe + + + + ReportStatusCodeLib + + + BaseMemoryLib + + + UefiDriverEntryPoint + + + UefiBootServicesTableLib + + + UefiLib + + + MemoryAllocationLib + + + + UsbMouseAbsolutePointer.h + mousehid.c + UsbMouseAbsolutePointer.c + ComponentName.c + mousehid.h + + + + + + + + gEfiAbsolutePointerProtocolGuid + + + gEfiDevicePathProtocolGuid + + + gEfiUsbIoProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + USBMouseAbsolutePointerDriverBindingEntryPoint + + + \ No newline at end of file diff --git a/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/mousehid.c b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/mousehid.c new file mode 100644 index 0000000000..1d2721c310 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/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 UsbMouseAbsolutePointer USB_MOUSE_ABSOLUTE_POINTER_DEV + @param LocalItem Local Item + + +**/ +STATIC +VOID +ParseLocalItem ( + IN USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointer, + 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 (UsbMouseAbsolutePointer->PrivateData.ButtonDetected) { + UsbMouseAbsolutePointer->PrivateData.ButtonMinIndex = (UINT8) Data; + } + + return ; + + case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: + { + if (UsbMouseAbsolutePointer->PrivateData.ButtonDetected) { + UsbMouseAbsolutePointer->PrivateData.ButtonMaxIndex = (UINT8) Data; + } + + return ; + } + } +} + +STATIC +VOID +ParseGlobalItem ( + IN USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointer, + 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 + // + UsbMouseAbsolutePointer->PrivateData.ButtonDetected = TRUE; + return ; + } + break; + } + + } +} + + + +/** + Parse Main Item + + @param UsbMouseAbsolutePointer USB_MOUSE_ABSOLUTE_POINTER_DEV + @param MainItem HID_ITEM to parse + + @return VOID + +**/ +STATIC +VOID +ParseMainItem ( + IN USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointer, + IN HID_ITEM *MainItem + ) +{ + // + // we don't care any main items, just skip + // + return ; +} + + +/** + Parse Hid Item + + @param UsbMouseAbsolutePointer USB_MOUSE_ABSOLUTE_POINTER_DEV + @param HidItem HidItem to parse + + @return VOID + +**/ +STATIC +VOID +ParseHidItem ( + IN USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointer, + IN HID_ITEM *HidItem + ) +{ + switch (HidItem->Type) { + + case HID_ITEM_TYPE_MAIN: + // + // For Main Item, parse main item + // + ParseMainItem (UsbMouseAbsolutePointer, HidItem); + break; + + case HID_ITEM_TYPE_GLOBAL: + // + // For global Item, parse global item + // + ParseGlobalItem (UsbMouseAbsolutePointer, HidItem); + break; + + case HID_ITEM_TYPE_LOCAL: + // + // For Local Item, parse local item + // + ParseLocalItem (UsbMouseAbsolutePointer, 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_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointer, + 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 (UsbMouseAbsolutePointer, &HidItem); + + ptr = GetNextItem (ptr, DescriptorEnd, &HidItem); + } + + UsbMouseAbsolutePointer->NumberOfButtons = (UINT8) (UsbMouseAbsolutePointer->PrivateData.ButtonMaxIndex - UsbMouseAbsolutePointer->PrivateData.ButtonMinIndex + 1); + UsbMouseAbsolutePointer->XLogicMax = UsbMouseAbsolutePointer->YLogicMax = 1023; + UsbMouseAbsolutePointer->XLogicMin = UsbMouseAbsolutePointer->YLogicMin = -1023; + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/mousehid.h b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/mousehid.h new file mode 100644 index 0000000000..4c4a2332ca --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/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 "UsbMouseAbsolutePointer.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_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointer, + IN UINT8 *ReportDescriptor, + IN UINTN ReportSize + ); + +#endif