/** @file
  USB Mouse Driver that manages USB mouse and produces Absolute Pointer Protocol.

Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#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 Protocol, initializes 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));
  if (UsbMouseAbsolutePointerDevice == NULL) {
    ASSERT (UsbMouseAbsolutePointerDevice != NULL);
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }

  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 IN
  //
  Found = FALSE;
  for (Index = 0; Index < EndpointNumber; Index++) {
    UsbIo->UsbGetEndpointDescriptor (
             UsbIo,
             Index,
             &EndpointDescriptor
             );

    if (((EndpointDescriptor.Attributes & (BIT0 | BIT1)) == USB_ENDPOINT_INTERRUPT) &&
        ((EndpointDescriptor.EndpointAddress & USB_ENDPOINT_DIR_IN) != 0))
    {
      //
      // 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);
  if (ReportDesc == NULL) {
    ASSERT (ReportDesc != NULL);
    FreePool (Buf);
    return EFI_OUT_OF_RESOURCES;
  }

  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 = 1024;
  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;
  }

  //
  // 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)
  //
  if (DataLength < 3) {
    return EFI_DEVICE_ERROR;
  }

  UsbMouseAbsolutePointerDevice->StateChanged = TRUE;

  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 + 3),
          (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
           );
}
