/*++ | |
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. | |
Module Name: | |
UsbMouse.c | |
Abstract: | |
--*/ | |
#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_DRIVER_BINDING_PROTOCOL gUsbMouseDriverBinding = { | |
USBMouseDriverBindingSupported, | |
USBMouseDriverBindingStart, | |
USBMouseDriverBindingStop, | |
0x10, | |
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 | |
); | |
EFI_STATUS | |
EFIAPI | |
USBMouseDriverBindingSupported ( | |
IN EFI_DRIVER_BINDING_PROTOCOL *This, | |
IN EFI_HANDLE Controller, | |
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath | |
) | |
/*++ | |
Routine Description: | |
Test to see if this driver supports ControllerHandle. Any ControllerHandle | |
that has UsbHcProtocol installed will be supported. | |
Arguments: | |
This - Protocol instance pointer. | |
Controller - Handle of device to test | |
RemainingDevicePath - Not used | |
Returns: | |
EFI_SUCCESS - This driver supports this device. | |
EFI_UNSUPPORTED - This driver does not support this device. | |
--*/ | |
{ | |
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 (!IsUsbMouse (UsbIo)) { | |
Status = EFI_UNSUPPORTED; | |
} | |
gBS->CloseProtocol ( | |
Controller, | |
&gEfiUsbIoProtocolGuid, | |
This->DriverBindingHandle, | |
Controller | |
); | |
return Status; | |
} | |
EFI_STATUS | |
EFIAPI | |
USBMouseDriverBindingStart ( | |
IN EFI_DRIVER_BINDING_PROTOCOL *This, | |
IN EFI_HANDLE Controller, | |
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath | |
) | |
/*++ | |
Routine Description: | |
Starting the Usb Bus Driver | |
Arguments: | |
This - Protocol instance pointer. | |
Controller - Handle of device to test | |
RemainingDevicePath - Not used | |
Returns: | |
EFI_SUCCESS - This driver supports this device. | |
EFI_UNSUPPORTED - This driver does not support this device. | |
EFI_DEVICE_ERROR - This driver cannot be started due to device | |
Error | |
EFI_OUT_OF_RESOURCES- Can't allocate memory resources | |
EFI_ALREADY_STARTED - Thios driver has been started | |
--*/ | |
{ | |
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, | |
(VOID **) &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, | |
(EFI_PERIPHERAL_MOUSE | EFI_P_EC_INTERFACE_ERROR) | |
); | |
goto ErrorExit; | |
} | |
UsbMouseDevice->SimplePointerProtocol.GetState = GetMouseState; | |
UsbMouseDevice->SimplePointerProtocol.Reset = UsbMouseReset; | |
UsbMouseDevice->SimplePointerProtocol.Mode = &UsbMouseDevice->Mode; | |
Status = gBS->CreateEvent ( | |
EFI_EVENT_NOTIFY_WAIT, | |
EFI_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, | |
(EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE) | |
); | |
// | |
// 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, | |
(CHAR16 *) 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; | |
} | |
EFI_STATUS | |
EFIAPI | |
USBMouseDriverBindingStop ( | |
IN EFI_DRIVER_BINDING_PROTOCOL *This, | |
IN EFI_HANDLE Controller, | |
IN UINTN NumberOfChildren, | |
IN EFI_HANDLE *ChildHandleBuffer | |
) | |
/*++ | |
Routine Description: | |
Stop this driver on ControllerHandle. Support stoping any child handles | |
created by this driver. | |
Arguments: | |
This - Protocol instance pointer. | |
Controller - Handle of device to stop driver on | |
NumberOfChildren - Number of Children in the ChildHandleBuffer | |
ChildHandleBuffer - List of handles for the children we need to stop. | |
Returns: | |
EFI_SUCCESS | |
EFI_DEVICE_ERROR | |
others | |
--*/ | |
{ | |
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, | |
(VOID **) &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, | |
(EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE) | |
); | |
// | |
// 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; | |
} | |
BOOLEAN | |
IsUsbMouse ( | |
IN EFI_USB_IO_PROTOCOL *UsbIo | |
) | |
/*++ | |
Routine Description: | |
Tell if a Usb Controller is a mouse | |
Arguments: | |
UsbIo - Protocol instance pointer. | |
Returns: | |
TRUE - It is a mouse | |
FALSE - It is not a mouse | |
--*/ | |
{ | |
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; | |
} | |
STATIC | |
EFI_STATUS | |
InitializeUsbMouseDevice ( | |
IN USB_MOUSE_DEV *UsbMouseDev | |
) | |
/*++ | |
Routine Description: | |
Initialize the Usb Mouse Device. | |
Arguments: | |
UsbMouseDev - Device instance to be initialized | |
Returns: | |
EFI_SUCCESS - Success | |
EFI_DEVICE_ERROR - Init error. | |
EFI_OUT_OF_RESOURCES- Can't allocate memory | |
--*/ | |
{ | |
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 ( | |
EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL, | |
EFI_TPL_NOTIFY, | |
USBMouseRecoveryHandler, | |
UsbMouseDev, | |
&UsbMouseDev->DelayedRecoveryEvent | |
); | |
return EFI_SUCCESS; | |
} | |
STATIC | |
EFI_STATUS | |
EFIAPI | |
OnMouseInterruptComplete ( | |
IN VOID *Data, | |
IN UINTN DataLength, | |
IN VOID *Context, | |
IN UINT32 Result | |
) | |
/*++ | |
Routine Description: | |
It is called whenever there is data received from async interrupt | |
transfer. | |
Arguments: | |
Data - Data received. | |
DataLength - Length of Data | |
Context - Passed in context | |
Result - Async Interrupt Transfer result | |
Returns: | |
EFI_SUCCESS | |
EFI_DEVICE_ERROR | |
--*/ | |
{ | |
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, | |
(EFI_PERIPHERAL_MOUSE | EFI_P_EC_INPUT_ERROR) | |
); | |
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 | |
); | |
} | |
*/ | |
STATIC | |
EFI_STATUS | |
EFIAPI | |
GetMouseState ( | |
IN EFI_SIMPLE_POINTER_PROTOCOL *This, | |
OUT EFI_SIMPLE_POINTER_STATE *MouseState | |
) | |
/*++ | |
Routine Description: | |
Get the mouse state, see SIMPLE POINTER PROTOCOL. | |
Arguments: | |
This - Protocol instance pointer. | |
MouseState - Current mouse state | |
Returns: | |
EFI_SUCCESS | |
EFI_DEVICE_ERROR | |
EFI_NOT_READY | |
--*/ | |
{ | |
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; | |
} | |
STATIC | |
EFI_STATUS | |
EFIAPI | |
UsbMouseReset ( | |
IN EFI_SIMPLE_POINTER_PROTOCOL *This, | |
IN BOOLEAN ExtendedVerification | |
) | |
/*++ | |
Routine Description: | |
Reset the mouse device, see SIMPLE POINTER PROTOCOL. | |
Arguments: | |
This - Protocol instance pointer. | |
ExtendedVerification - Ignored here/ | |
Returns: | |
EFI_SUCCESS | |
--*/ | |
{ | |
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, | |
(EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET) | |
); | |
ZeroMem ( | |
&UsbMouseDevice->State, | |
sizeof (EFI_SIMPLE_POINTER_STATE) | |
); | |
UsbMouseDevice->StateChanged = FALSE; | |
return EFI_SUCCESS; | |
} | |
STATIC | |
VOID | |
EFIAPI | |
UsbMouseWaitForInput ( | |
IN EFI_EVENT Event, | |
IN VOID *Context | |
) | |
/*++ | |
Routine Description: | |
Event notification function for SIMPLE_POINTER.WaitForInput event | |
Signal the event if there is input from mouse | |
Arguments: | |
Event - Wait Event | |
Context - Passed parameter to event handler | |
Returns: | |
VOID | |
--*/ | |
{ | |
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); | |
} | |
} | |
VOID | |
EFIAPI | |
USBMouseRecoveryHandler ( | |
IN EFI_EVENT Event, | |
IN VOID *Context | |
) | |
/*++ | |
Routine Description: | |
Timer handler for Delayed Recovery timer. | |
Arguments: | |
Event - The Delayed Recovery event. | |
Context - Points to the USB_KB_DEV instance. | |
Returns: | |
--*/ | |
{ | |
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 | |
); | |
} | |
VOID | |
MouseReportStatusCode ( | |
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, | |
IN EFI_STATUS_CODE_TYPE CodeType, | |
IN EFI_STATUS_CODE_VALUE Value | |
) | |
/*++ | |
Routine Description: | |
Report Status Code in Usb Bot Driver | |
Arguments: | |
DevicePath - Use this to get Device Path | |
CodeType - Status Code Type | |
CodeValue - Status Code Value | |
Returns: | |
None | |
--*/ | |
{ | |
REPORT_STATUS_CODE_WITH_DEVICE_PATH ( | |
CodeType, | |
Value, | |
DevicePath | |
); | |
} |