/** @file
  USB Mouse Driver that manages USB mouse and produces Absolute Pointer Protocol.

Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
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.

**/

#include "UsbMouseAbsolutePointer.h"

EFI_DRIVER_BINDING_PROTOCOL gUsbMouseAbsolutePointerDriverBinding = {
  USBMouseAbsolutePointerDriverBindingSupported,
  USBMouseAbsolutePointerDriverBindingStart,
  USBMouseAbsolutePointerDriverBindingStop,
  0x1,
  NULL,
  NULL
};

/**
  Entrypoint of USB Mouse Absolute Pointer Driver.

  This function is the entrypoint of USB Mouse Driver. It installs Driver Binding
  Protocols together with Component Name Protocols.

  @param  ImageHandle       The firmware allocated handle for the EFI image.
  @param  SystemTable       A pointer to the EFI System Table.

  @retval EFI_SUCCESS       The entry point is executed successfully.

**/
EFI_STATUS
EFIAPI
USBMouseAbsolutePointerDriverBindingEntryPoint (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
{
  EFI_STATUS              Status;

  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gUsbMouseAbsolutePointerDriverBinding,
             ImageHandle,
             &gUsbMouseAbsolutePointerComponentName,
             &gUsbMouseAbsolutePointerComponentName2
             );
  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;
}


/**
  Check whether USB Mouse Absolute Pointer Driver supports this device.

  @param  This                   The driver binding protocol.
  @param  Controller             The controller handle to check.
  @param  RemainingDevicePath    The remaining device path.

  @retval EFI_SUCCESS            The driver supports this controller.
  @retval other                  This device isn't supported.

**/
EFI_STATUS
EFIAPI
USBMouseAbsolutePointerDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
{
  EFI_STATUS          Status;
  EFI_USB_IO_PROTOCOL *UsbIo;

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiUsbIoProtocolGuid,
                  (VOID **) &UsbIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  //
  // Use the USB I/O Protocol interface to check whether Controller is
  // a mouse device 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;
}


/**
  Starts the mouse device with this driver.

  This function consumes USB I/O Portocol, intializes USB mouse device,
  installs Absolute Pointer Protocol, and submits Asynchronous Interrupt
  Transfer to manage the USB mouse device.

  @param  This                  The driver binding instance.
  @param  Controller            Handle of device to bind driver to.
  @param  RemainingDevicePath   Optional parameter use to pick a specific child
                                device to start.

  @retval EFI_SUCCESS           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.
  @retval EFI_OUT_OF_RESOURCES  Can't allocate memory resources.
  @retval EFI_ALREADY_STARTED   This 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;
  USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDevice;
  UINT8                          EndpointNumber;
  EFI_USB_ENDPOINT_DESCRIPTOR    EndpointDescriptor;
  UINT8                          Index;
  UINT8                          EndpointAddr;
  UINT8                          PollingInterval;
  UINT8                          PacketSize;
  BOOLEAN                        Found;
  EFI_TPL                        OldTpl;

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  //
  // Open USB I/O Protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiUsbIoProtocolGuid,
                  (VOID **) &UsbIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER                  
                  );
  if (EFI_ERROR (Status)) {
    goto ErrorExit1;
  }
  
  UsbMouseAbsolutePointerDevice = AllocateZeroPool (sizeof (USB_MOUSE_ABSOLUTE_POINTER_DEV));
  ASSERT (UsbMouseAbsolutePointerDevice != NULL);

  UsbMouseAbsolutePointerDevice->UsbIo     = UsbIo;
  UsbMouseAbsolutePointerDevice->Signature = USB_MOUSE_ABSOLUTE_POINTER_DEV_SIGNATURE;

  //
  // 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;
  }

  //
  // Report Status Code here since USB mouse will be detected next.
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT),
    UsbMouseAbsolutePointerDevice->DevicePath
    );

  //
  // Get interface & endpoint descriptor
  //
  UsbIo->UsbGetInterfaceDescriptor (
           UsbIo,
           &UsbMouseAbsolutePointerDevice->InterfaceDescriptor
           );

  EndpointNumber = UsbMouseAbsolutePointerDevice->InterfaceDescriptor.NumEndpoints;

  //
  // Traverse endpoints to find interrupt endpoint
  //
  Found = FALSE;
  for (Index = 0; Index < EndpointNumber; Index++) {
    UsbIo->UsbGetEndpointDescriptor (
             UsbIo,
             Index,
             &EndpointDescriptor
             );

    if ((EndpointDescriptor.Attributes & (BIT0 | BIT1)) == USB_ENDPOINT_INTERRUPT) {
      //
      // We only care interrupt endpoint here
      //
      CopyMem (&UsbMouseAbsolutePointerDevice->IntEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor));
      Found = TRUE;
      break;
    }
  }

  if (!Found) {
    //
    // Report Status Code to indicate that there is no USB mouse
    //
    REPORT_STATUS_CODE (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      (EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED)
      );
    //
    // No interrupt endpoint found, then return unsupported.
    //
    Status = EFI_UNSUPPORTED;
    goto ErrorExit;
  }

  //
  // Report Status Code here since USB mouse has be detected.
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_PERIPHERAL_MOUSE | EFI_P_PC_DETECTED),
    UsbMouseAbsolutePointerDevice->DevicePath
    );

  Status = InitializeUsbMouseDevice (UsbMouseAbsolutePointerDevice);
  if (EFI_ERROR (Status)) {
    //
    // Fail to initialize USB mouse device.
    //
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      (EFI_PERIPHERAL_MOUSE | EFI_P_EC_INTERFACE_ERROR),
      UsbMouseAbsolutePointerDevice->DevicePath
      );

    goto ErrorExit;
  }

  //
  // Initialize and install EFI Absolute Pointer Protocol.
  //
  UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol.GetState = GetMouseAbsolutePointerState;
  UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol.Reset	  = UsbMouseAbsolutePointerReset;
  UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol.Mode	  = &UsbMouseAbsolutePointerDevice->Mode;

  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)) {
    goto ErrorExit;
  }

  //
  // The next step would be submitting Asynchronous Interrupt Transfer on this mouse device.
  // After that we will be able to get key data from it. Thus this is deemed as
  // the enable action of the mouse, so report status code accordingly.
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE),
    UsbMouseAbsolutePointerDevice->DevicePath
    );

  //
  // Submit Asynchronous Interrupt Transfer to manage this device.
  //
  EndpointAddr    = UsbMouseAbsolutePointerDevice->IntEndpointDescriptor.EndpointAddress;
  PollingInterval = UsbMouseAbsolutePointerDevice->IntEndpointDescriptor.Interval;
  PacketSize      = (UINT8) (UsbMouseAbsolutePointerDevice->IntEndpointDescriptor.MaxPacketSize);

  Status = UsbIo->UsbAsyncInterruptTransfer (
                    UsbIo,
                    EndpointAddr,
                    TRUE,
                    PollingInterval,
                    PacketSize,
                    OnMouseInterruptComplete,
                    UsbMouseAbsolutePointerDevice
                    );

  if (EFI_ERROR (Status)) {
    //
    // If submit error, uninstall that interface
    //
    gBS->UninstallProtocolInterface (
           Controller,
           &gEfiAbsolutePointerProtocolGuid,
           &UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol
           );
    goto ErrorExit;
  }

  UsbMouseAbsolutePointerDevice->ControllerNameTable = NULL;
  AddUnicodeString2 (
    "eng",
    gUsbMouseAbsolutePointerComponentName.SupportedLanguages,
    &UsbMouseAbsolutePointerDevice->ControllerNameTable,
    L"Generic Usb Mouse Absolute Pointer",
      TRUE
      );
  AddUnicodeString2 (
    "en",
    gUsbMouseAbsolutePointerComponentName2.SupportedLanguages,
    &UsbMouseAbsolutePointerDevice->ControllerNameTable,
    L"Generic Usb Mouse Absolute Pointer",
    FALSE
    );

  gBS->RestoreTPL (OldTpl);
  return EFI_SUCCESS;

//
// Error handler
//
ErrorExit:
  if (EFI_ERROR (Status)) {
    gBS->CloseProtocol (
          Controller,
          &gEfiUsbIoProtocolGuid,
          This->DriverBindingHandle,
          Controller
          );

    if (UsbMouseAbsolutePointerDevice != NULL) {
      if ((UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol).WaitForInput != NULL) {
        gBS->CloseEvent ((UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol).WaitForInput);
      }

      FreePool (UsbMouseAbsolutePointerDevice);
      UsbMouseAbsolutePointerDevice = NULL;
    }
  }

ErrorExit1:
  gBS->RestoreTPL (OldTpl);

  return Status;
}


/**
  Stop the USB mouse device handled by this driver.

  @param  This                   The driver binding protocol.
  @param  Controller             The controller to release.
  @param  NumberOfChildren       The number of handles in ChildHandleBuffer.
  @param  ChildHandleBuffer      The array of child handle.

  @retval EFI_SUCCESS            The device was stopped.
  @retval EFI_UNSUPPORTED        Absolute Pointer Protocol is not installed on Controller.
  @retval Others                 Fail to uninstall protocols attached on the device.

**/
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;

  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);

  UsbIo = UsbMouseAbsolutePointerDevice->UsbIo;

  //
  // The key data input from this device will be disabled.
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE),
    UsbMouseAbsolutePointerDevice->DevicePath
    );

  //
  // Delete the Asynchronous Interrupt Transfer from this device
  //
  UsbIo->UsbAsyncInterruptTransfer (
           UsbIo,
           UsbMouseAbsolutePointerDevice->IntEndpointDescriptor.EndpointAddress,
           FALSE,
           UsbMouseAbsolutePointerDevice->IntEndpointDescriptor.Interval,
           0,
           NULL,
           NULL
           );

  Status = gBS->UninstallProtocolInterface (
                  Controller,
                  &gEfiAbsolutePointerProtocolGuid,
                  &UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  gBS->CloseProtocol (
         Controller,
         &gEfiUsbIoProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  //
  // Free all resources.
  //
  gBS->CloseEvent (UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol.WaitForInput);
  
  if (UsbMouseAbsolutePointerDevice->DelayedRecoveryEvent != NULL) {
    gBS->CloseEvent (UsbMouseAbsolutePointerDevice->DelayedRecoveryEvent);
    UsbMouseAbsolutePointerDevice->DelayedRecoveryEvent = NULL;
  }

  if (UsbMouseAbsolutePointerDevice->ControllerNameTable != NULL) {
    FreeUnicodeStringTable (UsbMouseAbsolutePointerDevice->ControllerNameTable);
  }

  FreePool (UsbMouseAbsolutePointerDevice);

  return EFI_SUCCESS;

}


/**
  Uses USB I/O to check whether the device is a USB mouse device.

  @param  UsbIo    Pointer to a USB I/O protocol instance.

  @retval TRUE     Device is a USB mouse device.
  @retval FALSE    Device is a not USB mouse device.

**/
BOOLEAN
IsUsbMouse (
  IN  EFI_USB_IO_PROTOCOL     *UsbIo
  )
{
  EFI_STATUS                    Status;
  EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;

  //
  // Get the default interface descriptor
  //
  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.

  This function retrieves and parses HID report descriptor, and
  initializes state of USB_MOUSE_ABSOLUTE_POINTER_DEV. Then it sets indefinite idle
  rate for the device. Finally it creates event for delayed recovery,
  which deals with device error.

  @param  UsbMouseAbsolutePointerDev   Device instance to be initialized.

  @retval EFI_SUCCESS                  USB mouse device successfully initialized.
  @retval EFI_UNSUPPORTED              HID descriptor type is not report descriptor.
  @retval Other                        USB mouse device was not initialized successfully.

**/
EFI_STATUS
InitializeUsbMouseDevice (
  IN  USB_MOUSE_ABSOLUTE_POINTER_DEV           *UsbMouseAbsolutePointerDev
  )
{
  EFI_USB_IO_PROTOCOL       *UsbIo;
  UINT8                     Protocol;
  EFI_STATUS                Status;
  EFI_USB_HID_DESCRIPTOR    *MouseHidDesc;
  UINT8                     *ReportDesc;
  EFI_USB_CONFIG_DESCRIPTOR ConfigDesc;
  VOID                      *Buf;
  UINT32                    TransferResult;
  UINT16                    Total;
  USB_DESC_HEAD             *Head;
  BOOLEAN                   Start;

  UsbIo = UsbMouseAbsolutePointerDev->UsbIo;

  //
  // Get the current configuration descriptor. Note that it doesn't include other descriptors.
  //
  Status = UsbIo->UsbGetConfigDescriptor (
                    UsbIo,
                    &ConfigDesc
                    );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // By issuing Get_Descriptor(Configuration) request with total length, we get the Configuration descriptor,
  // all Interface descriptors, all Endpoint descriptors, and the HID descriptor for each interface.
  //
  Buf = AllocateZeroPool (ConfigDesc.TotalLength);
  if (Buf == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = UsbGetDescriptor (
             UsbIo,
             (UINT16)((USB_DESC_TYPE_CONFIG << 8) | (ConfigDesc.ConfigurationValue - 1)),
             0,
             ConfigDesc.TotalLength,
             Buf,
             &TransferResult
             );
  if (EFI_ERROR (Status)) {
    FreePool (Buf);
    return Status;
  }

  Total = 0;
  Start = FALSE;
  Head  = (USB_DESC_HEAD *)Buf;  
  MouseHidDesc = NULL;

  //
  // Get HID descriptor from the receipt of Get_Descriptor(Configuration) request.
  // This algorithm is based on the fact that the HID descriptor shall be interleaved
  // between the interface and endpoint descriptors for HID interfaces.
  //
  while (Total < ConfigDesc.TotalLength) {
    if (Head->Type == USB_DESC_TYPE_INTERFACE) {
      if ((((USB_INTERFACE_DESCRIPTOR *)Head)->InterfaceNumber == UsbMouseAbsolutePointerDev->InterfaceDescriptor.InterfaceNumber) &&
        (((USB_INTERFACE_DESCRIPTOR *)Head)->AlternateSetting == UsbMouseAbsolutePointerDev->InterfaceDescriptor.AlternateSetting)) {
        Start = TRUE;
      }
    }
    if (Start && (Head->Type == USB_DESC_TYPE_ENDPOINT)) {
      break;
    }
    if (Start && (Head->Type == USB_DESC_TYPE_HID)) {
      MouseHidDesc = (EFI_USB_HID_DESCRIPTOR *)Head;
      break;
    }
    Total = Total + (UINT16)Head->Len;
    Head  = (USB_DESC_HEAD*)((UINT8 *)Buf + Total);
  }

  if (MouseHidDesc == NULL) {
    FreePool (Buf);
    return EFI_UNSUPPORTED;
  }

  //
  // Get report descriptor
  //
  if (MouseHidDesc->HidClassDesc[0].DescriptorType != USB_DESC_TYPE_REPORT) {
    FreePool (Buf);
    return EFI_UNSUPPORTED;
  }

  ReportDesc = AllocateZeroPool (MouseHidDesc->HidClassDesc[0].DescriptorLength);
  ASSERT (ReportDesc != NULL);

  Status = UsbGetReportDescriptor (
             UsbIo,
             UsbMouseAbsolutePointerDev->InterfaceDescriptor.InterfaceNumber,
             MouseHidDesc->HidClassDesc[0].DescriptorLength,
             ReportDesc
             );

  if (EFI_ERROR (Status)) {
    FreePool (Buf);
    FreePool (ReportDesc);
    return Status;
  }

  //
  // Parse report descriptor
  //
  Status = ParseMouseReportDescriptor (
             UsbMouseAbsolutePointerDev,
             ReportDesc,
             MouseHidDesc->HidClassDesc[0].DescriptorLength
             );

  if (EFI_ERROR (Status)) {
    FreePool (Buf);
    FreePool (ReportDesc);
    return Status;
  }

  UsbMouseAbsolutePointerDev->Mode.AbsoluteMaxX = 1024;
  UsbMouseAbsolutePointerDev->Mode.AbsoluteMaxY = 1024;
  UsbMouseAbsolutePointerDev->Mode.AbsoluteMaxZ = 0;
  UsbMouseAbsolutePointerDev->Mode.AbsoluteMinX = 0;
  UsbMouseAbsolutePointerDev->Mode.AbsoluteMinY = 0;
  UsbMouseAbsolutePointerDev->Mode.AbsoluteMinZ = 0;
  UsbMouseAbsolutePointerDev->Mode.Attributes   = 0x3;

  //
  // Let the cursor's starting position is in the center of the screen.
  //
  UsbMouseAbsolutePointerDev->State.CurrentX =
    DivU64x32 (UsbMouseAbsolutePointerDev->Mode.AbsoluteMaxX + UsbMouseAbsolutePointerDev->Mode.AbsoluteMinX, 2);
  UsbMouseAbsolutePointerDev->State.CurrentY =
    DivU64x32 (UsbMouseAbsolutePointerDev->Mode.AbsoluteMaxY + UsbMouseAbsolutePointerDev->Mode.AbsoluteMinY, 2);

  //
  // Set boot protocol for the USB mouse.
  // This driver only supports boot protocol.
  //
  UsbGetProtocolRequest (
    UsbIo,
    UsbMouseAbsolutePointerDev->InterfaceDescriptor.InterfaceNumber,
    &Protocol
    );
  if (Protocol != BOOT_PROTOCOL) {
    Status = UsbSetProtocolRequest (
               UsbIo,
               UsbMouseAbsolutePointerDev->InterfaceDescriptor.InterfaceNumber,
               BOOT_PROTOCOL
               );

    if (EFI_ERROR (Status)) {
      FreePool (Buf);
      FreePool (ReportDesc);
      return Status;
    }
  }

  FreePool (Buf);
  FreePool (ReportDesc);

  //
  // Create event for delayed recovery, which deals with device error.
  //
  if (UsbMouseAbsolutePointerDev->DelayedRecoveryEvent != NULL) {
    gBS->CloseEvent (UsbMouseAbsolutePointerDev->DelayedRecoveryEvent);
    UsbMouseAbsolutePointerDev->DelayedRecoveryEvent = 0;
  }

  gBS->CreateEvent (
         EVT_TIMER | EVT_NOTIFY_SIGNAL,
         TPL_NOTIFY,
         USBMouseRecoveryHandler,
         UsbMouseAbsolutePointerDev,
         &UsbMouseAbsolutePointerDev->DelayedRecoveryEvent
         );

  return EFI_SUCCESS;
}


/**
  Handler function for USB mouse's asynchronous interrupt transfer.

  This function is the handler function for USB mouse's asynchronous interrupt transfer
  to manage the mouse. It parses data returned from asynchronous interrupt transfer, and
  get button and movement state.

  @param  Data             A pointer to a buffer that is filled with key data which is
                           retrieved via asynchronous interrupt transfer.
  @param  DataLength       Indicates the size of the data buffer.
  @param  Context          Pointing to USB_KB_DEV instance.
  @param  Result           Indicates the result of the asynchronous interrupt transfer.

  @retval EFI_SUCCESS      Asynchronous interrupt transfer is handled successfully.
  @retval EFI_DEVICE_ERROR Hardware error occurs.

**/
EFI_STATUS
EFIAPI
OnMouseInterruptComplete (
  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
    //
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      (EFI_PERIPHERAL_MOUSE | EFI_P_EC_INPUT_ERROR),
      UsbMouseAbsolutePointerDevice->DevicePath
      );

    if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
      EndpointAddr = UsbMouseAbsolutePointerDevice->IntEndpointDescriptor.EndpointAddress;

      UsbClearEndpointHalt (
        UsbIo,
        EndpointAddr,
        &UsbResult
        );
    }

    //
    // Delete & Submit this interrupt again
    // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt. 
    //
    UsbIo->UsbAsyncInterruptTransfer (
             UsbIo,
             UsbMouseAbsolutePointerDevice->IntEndpointDescriptor.EndpointAddress,
             FALSE,
             0,
             0,
             NULL,
             NULL
             );
    //
    // EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling.
    //
    gBS->SetTimer (
           UsbMouseAbsolutePointerDevice->DelayedRecoveryEvent,
           TimerRelative,
           EFI_USB_INTERRUPT_DELAY
           );
    return EFI_DEVICE_ERROR;
  }

  //
  // If no error and no data, just return EFI_SUCCESS.
  //
  if (DataLength == 0 || Data == NULL) {
    return EFI_SUCCESS;
  }

  UsbMouseAbsolutePointerDevice->StateChanged = TRUE;

  //
  // Check mouse Data
  // USB HID Specification specifies following data format:
  // Byte    Bits    Description
  // 0       0       Button 1
  //         1       Button 2
  //         2       Button 3
  //         4 to 7  Device-specific
  // 1       0 to 7  X displacement
  // 2       0 to 7  Y displacement
  // 3 to n  0 to 7  Device specific (optional)
  //
  UsbMouseAbsolutePointerDevice->State.ActiveButtons = *(UINT8 *) Data & (BIT0 | BIT1 | BIT2);

  UsbMouseAbsolutePointerDevice->State.CurrentX =
    MIN (
      MAX ((INT64) UsbMouseAbsolutePointerDevice->State.CurrentX + *((INT8 *) Data + 1),
           (INT64) UsbMouseAbsolutePointerDevice->Mode.AbsoluteMinX),
      (INT64) UsbMouseAbsolutePointerDevice->Mode.AbsoluteMaxX
      );
  UsbMouseAbsolutePointerDevice->State.CurrentY =
    MIN (
      MAX ((INT64) UsbMouseAbsolutePointerDevice->State.CurrentY + *((INT8 *) Data + 2),
           (INT64) UsbMouseAbsolutePointerDevice->Mode.AbsoluteMinY),
      (INT64) UsbMouseAbsolutePointerDevice->Mode.AbsoluteMaxY
      );
  if (DataLength > 3) {
    UsbMouseAbsolutePointerDevice->State.CurrentZ =
      MIN (
        MAX ((INT64) UsbMouseAbsolutePointerDevice->State.CurrentZ + *((INT8 *) Data + 1),
             (INT64) UsbMouseAbsolutePointerDevice->Mode.AbsoluteMinZ),
        (INT64) UsbMouseAbsolutePointerDevice->Mode.AbsoluteMaxZ
        );
  }

  return EFI_SUCCESS;
}

/**
  Retrieves the current state of a pointer device.

  @param  This                  A pointer to the EFI_ABSOLUTE_POINTER_PROTOCOL instance.                                   
  @param  MouseState            A pointer to the state information on the pointer device.

  @retval EFI_SUCCESS           The state of the pointer device was returned in State.
  @retval EFI_NOT_READY         The state of the pointer device has not changed since the last call to
                                GetState().                                                           
  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to retrieve the pointer device's
                                current state.                                                           
  @retval EFI_INVALID_PARAMETER State is NULL.                                                           

**/
EFI_STATUS
EFIAPI
GetMouseAbsolutePointerState (
  IN   EFI_ABSOLUTE_POINTER_PROTOCOL  *This,
  OUT  EFI_ABSOLUTE_POINTER_STATE     *State
  )
{
  USB_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;

  if (State == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  MouseAbsolutePointerDev = USB_MOUSE_ABSOLUTE_POINTER_DEV_FROM_MOUSE_PROTOCOL (This);

  if (!MouseAbsolutePointerDev->StateChanged) {
    return EFI_NOT_READY;
  }

  //
  // Retrieve mouse state from USB_MOUSE_ABSOLUTE_POINTER_DEV,
  // which was filled by OnMouseInterruptComplete()
  //
  CopyMem (
    State,
    &MouseAbsolutePointerDev->State,
    sizeof (EFI_ABSOLUTE_POINTER_STATE)
    );

  MouseAbsolutePointerDev->StateChanged = FALSE;

  return EFI_SUCCESS;
}


/**
  Resets the pointer device hardware.

  @param  This                  A pointer to the EFI_ABSOLUTE_POINTER_PROTOCOL instance.
  @param  ExtendedVerification  Indicates that the driver may perform a more exhaustive
                                verification operation of the device during reset.

  @retval EFI_SUCCESS           The device was reset.
  @retval EFI_DEVICE_ERROR      The device is not functioning correctly and could not be reset.

**/
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);

  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET),
    UsbMouseAbsolutePointerDevice->DevicePath
    );

  //
  // Clear mouse state.
  //
  ZeroMem (
    &UsbMouseAbsolutePointerDevice->State,
    sizeof (EFI_ABSOLUTE_POINTER_STATE)
    );

  //
  // Let the cursor's starting position is in the center of the screen.
  //
  UsbMouseAbsolutePointerDevice->State.CurrentX =
    DivU64x32 (UsbMouseAbsolutePointerDevice->Mode.AbsoluteMaxX + UsbMouseAbsolutePointerDevice->Mode.AbsoluteMinX, 2);
  UsbMouseAbsolutePointerDevice->State.CurrentY =
    DivU64x32 (UsbMouseAbsolutePointerDevice->Mode.AbsoluteMaxY + UsbMouseAbsolutePointerDevice->Mode.AbsoluteMinY, 2);

  UsbMouseAbsolutePointerDevice->StateChanged = FALSE;

  return EFI_SUCCESS;
}

/**
  Event notification function for EFI_ABSOLUTE_POINTER_PROTOCOL.WaitForInput event.

  @param  Event        Event to be signaled when there's input from mouse.
  @param  Context      Points to USB_MOUSE_ABSOLUTE_POINTER_DEV instance.

**/
VOID
EFIAPI
UsbMouseAbsolutePointerWaitForInput (
  IN  EFI_EVENT               Event,
  IN  VOID                    *Context
  )
{
  USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDev;

  UsbMouseAbsolutePointerDev = (USB_MOUSE_ABSOLUTE_POINTER_DEV *) Context;

  //
  // If there's input from mouse, signal the event.
  //
  if (UsbMouseAbsolutePointerDev->StateChanged) {
    gBS->SignalEvent (Event);
  }
}

/**
  Handler for Delayed Recovery event.

  This function is the handler for Delayed Recovery event triggered
  by timer.
  After a device error occurs, the event would be triggered
  with interval of EFI_USB_INTERRUPT_DELAY. EFI_USB_INTERRUPT_DELAY
  is defined in USB standard for error handling.

  @param  Event                 The Delayed Recovery event.
  @param  Context               Points to the USB_MOUSE_ABSOLUTE_POINTER_DEV instance.

**/
VOID
EFIAPI
USBMouseRecoveryHandler (
  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;

  //
  // Re-submit Asynchronous Interrupt Transfer for recovery.
  //
  UsbIo->UsbAsyncInterruptTransfer (
           UsbIo,
           UsbMouseAbsolutePointerDev->IntEndpointDescriptor.EndpointAddress,
           TRUE,
           UsbMouseAbsolutePointerDev->IntEndpointDescriptor.Interval,
           UsbMouseAbsolutePointerDev->IntEndpointDescriptor.MaxPacketSize,
           OnMouseInterruptComplete,
           UsbMouseAbsolutePointerDev
           );
}
