/** @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));
  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 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);
  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;
  }

  //
  // 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 + 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
           );
}
