/** @file
  The XHCI controller driver.

(C) Copyright 2023 Hewlett Packard Enterprise Development LP<BR>
Copyright (c) 2011 - 2023, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Xhci.h"

//
// Two arrays used to translate the XHCI port state (change)
// to the UEFI protocol's port state (change).
//
USB_PORT_STATE_MAP  mUsbPortStateMap[] = {
  { XHC_PORTSC_CCS,   USB_PORT_STAT_CONNECTION  },
  { XHC_PORTSC_PED,   USB_PORT_STAT_ENABLE      },
  { XHC_PORTSC_OCA,   USB_PORT_STAT_OVERCURRENT },
  { XHC_PORTSC_RESET, USB_PORT_STAT_RESET       }
};

USB_PORT_STATE_MAP  mUsbPortChangeMap[] = {
  { XHC_PORTSC_CSC, USB_PORT_STAT_C_CONNECTION  },
  { XHC_PORTSC_PEC, USB_PORT_STAT_C_ENABLE      },
  { XHC_PORTSC_OCC, USB_PORT_STAT_C_OVERCURRENT },
  { XHC_PORTSC_PRC, USB_PORT_STAT_C_RESET       }
};

USB_CLEAR_PORT_MAP  mUsbClearPortChangeMap[] = {
  { XHC_PORTSC_CSC, EfiUsbPortConnectChange     },
  { XHC_PORTSC_PEC, EfiUsbPortEnableChange      },
  { XHC_PORTSC_OCC, EfiUsbPortOverCurrentChange },
  { XHC_PORTSC_PRC, EfiUsbPortResetChange       }
};

USB_PORT_STATE_MAP  mUsbHubPortStateMap[] = {
  { XHC_HUB_PORTSC_CCS,   USB_PORT_STAT_CONNECTION  },
  { XHC_HUB_PORTSC_PED,   USB_PORT_STAT_ENABLE      },
  { XHC_HUB_PORTSC_OCA,   USB_PORT_STAT_OVERCURRENT },
  { XHC_HUB_PORTSC_RESET, USB_PORT_STAT_RESET       }
};

USB_PORT_STATE_MAP  mUsbHubPortChangeMap[] = {
  { XHC_HUB_PORTSC_CSC, USB_PORT_STAT_C_CONNECTION  },
  { XHC_HUB_PORTSC_PEC, USB_PORT_STAT_C_ENABLE      },
  { XHC_HUB_PORTSC_OCC, USB_PORT_STAT_C_OVERCURRENT },
  { XHC_HUB_PORTSC_PRC, USB_PORT_STAT_C_RESET       }
};

USB_CLEAR_PORT_MAP  mUsbHubClearPortChangeMap[] = {
  { XHC_HUB_PORTSC_CSC,  EfiUsbPortConnectChange     },
  { XHC_HUB_PORTSC_PEC,  EfiUsbPortEnableChange      },
  { XHC_HUB_PORTSC_OCC,  EfiUsbPortOverCurrentChange },
  { XHC_HUB_PORTSC_PRC,  EfiUsbPortResetChange       },
  { XHC_HUB_PORTSC_BHRC, Usb3PortBHPortResetChange   }
};

EFI_DRIVER_BINDING_PROTOCOL  gXhciDriverBinding = {
  XhcDriverBindingSupported,
  XhcDriverBindingStart,
  XhcDriverBindingStop,
  0x30,
  NULL,
  NULL
};

//
// Template for Xhci's Usb2 Host Controller Protocol Instance.
//
EFI_USB2_HC_PROTOCOL  gXhciUsb2HcTemplate = {
  XhcGetCapability,
  XhcReset,
  XhcGetState,
  XhcSetState,
  XhcControlTransfer,
  XhcBulkTransfer,
  XhcAsyncInterruptTransfer,
  XhcSyncInterruptTransfer,
  XhcIsochronousTransfer,
  XhcAsyncIsochronousTransfer,
  XhcGetRootHubPortStatus,
  XhcSetRootHubPortFeature,
  XhcClearRootHubPortFeature,
  0x3,
  0x0
};

static UINT64   mXhciPerformanceCounterStartValue;
static UINT64   mXhciPerformanceCounterEndValue;
static UINT64   mXhciPerformanceCounterFrequency;
static BOOLEAN  mXhciPerformanceCounterValuesCached = FALSE;

/**
  Retrieves the capability of root hub ports.

  @param  This                  The EFI_USB2_HC_PROTOCOL instance.
  @param  MaxSpeed              Max speed supported by the controller.
  @param  PortNumber            Number of the root hub ports.
  @param  Is64BitCapable        Whether the controller supports 64-bit memory
                                addressing.

  @retval EFI_SUCCESS           Host controller capability were retrieved successfully.
  @retval EFI_INVALID_PARAMETER Either of the three capability pointer is NULL.

**/
EFI_STATUS
EFIAPI
XhcGetCapability (
  IN  EFI_USB2_HC_PROTOCOL  *This,
  OUT UINT8                 *MaxSpeed,
  OUT UINT8                 *PortNumber,
  OUT UINT8                 *Is64BitCapable
  )
{
  USB_XHCI_INSTANCE  *Xhc;
  EFI_TPL            OldTpl;

  if ((MaxSpeed == NULL) || (PortNumber == NULL) || (Is64BitCapable == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (XHC_TPL);

  Xhc             = XHC_FROM_THIS (This);
  *MaxSpeed       = EFI_USB_SPEED_SUPER;
  *PortNumber     = (UINT8)(Xhc->HcSParams1.Data.MaxPorts);
  *Is64BitCapable = (UINT8)Xhc->Support64BitDma;
  DEBUG ((DEBUG_INFO, "XhcGetCapability: %d ports, 64 bit %d\n", *PortNumber, *Is64BitCapable));

  gBS->RestoreTPL (OldTpl);

  return EFI_SUCCESS;
}

/**
  Provides software reset for the USB host controller.

  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
  @param  Attributes            A bit mask of the reset operation to perform.

  @retval EFI_SUCCESS           The reset operation succeeded.
  @retval EFI_INVALID_PARAMETER Attributes is not valid.
  @retval EFI_UNSUPPOURTED      The type of reset specified by Attributes is
                                not currently supported by the host controller.
  @retval EFI_DEVICE_ERROR      Host controller isn't halted to reset.

**/
EFI_STATUS
EFIAPI
XhcReset (
  IN EFI_USB2_HC_PROTOCOL  *This,
  IN UINT16                Attributes
  )
{
  USB_XHCI_INSTANCE  *Xhc;
  EFI_STATUS         Status;
  EFI_TPL            OldTpl;

  Xhc = XHC_FROM_THIS (This);

  if (Xhc->DevicePath != NULL) {
    //
    // Report Status Code to indicate reset happens
    //
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_PROGRESS_CODE,
      (EFI_IO_BUS_USB | EFI_IOB_PC_RESET),
      Xhc->DevicePath
      );
  }

  OldTpl = gBS->RaiseTPL (XHC_TPL);

  switch (Attributes) {
    case EFI_USB_HC_RESET_GLOBAL:
    //
    // Flow through, same behavior as Host Controller Reset
    //
    case EFI_USB_HC_RESET_HOST_CONTROLLER:
      if ((Xhc->DebugCapSupOffset != 0xFFFFFFFF) && ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset) & 0xFF) == XHC_CAP_USB_DEBUG) &&
          ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset + XHC_DC_DCCTRL) & BIT0) != 0))
      {
        Status = EFI_SUCCESS;
        goto ON_EXIT;
      }

      //
      // Host Controller must be Halt when Reset it
      //
      if (!XhcIsHalt (Xhc)) {
        Status = XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT);

        if (EFI_ERROR (Status)) {
          Status = EFI_DEVICE_ERROR;
          goto ON_EXIT;
        }
      }

      Status = XhcResetHC (Xhc, XHC_RESET_TIMEOUT);
      ASSERT (!(XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_CNR)));

      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }

      //
      // Clean up the asynchronous transfers, currently only
      // interrupt supports asynchronous operation.
      //
      XhciDelAllAsyncIntTransfers (Xhc);
      XhcFreeSched (Xhc);

      XhcInitSched (Xhc);
      break;

    case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG:
    case EFI_USB_HC_RESET_HOST_WITH_DEBUG:
      Status = EFI_UNSUPPORTED;
      break;

    default:
      Status = EFI_INVALID_PARAMETER;
  }

ON_EXIT:
  DEBUG ((DEBUG_INFO, "XhcReset: status %r\n", Status));
  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Retrieve the current state of the USB host controller.

  @param  This                   This EFI_USB2_HC_PROTOCOL instance.
  @param  State                  Variable to return the current host controller
                                 state.

  @retval EFI_SUCCESS            Host controller state was returned in State.
  @retval EFI_INVALID_PARAMETER  State is NULL.
  @retval EFI_DEVICE_ERROR       An error was encountered while attempting to
                                 retrieve the host controller's current state.

**/
EFI_STATUS
EFIAPI
XhcGetState (
  IN  EFI_USB2_HC_PROTOCOL  *This,
  OUT EFI_USB_HC_STATE      *State
  )
{
  USB_XHCI_INSTANCE  *Xhc;
  EFI_TPL            OldTpl;

  if (State == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (XHC_TPL);

  Xhc = XHC_FROM_THIS (This);

  if (XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT)) {
    *State = EfiUsbHcStateHalt;
  } else {
    *State = EfiUsbHcStateOperational;
  }

  DEBUG ((DEBUG_INFO, "XhcGetState: current state %d\n", *State));
  gBS->RestoreTPL (OldTpl);

  return EFI_SUCCESS;
}

/**
  Sets the USB host controller to a specific state.

  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
  @param  State                 The state of the host controller that will be set.

  @retval EFI_SUCCESS           The USB host controller was successfully placed
                                in the state specified by State.
  @retval EFI_INVALID_PARAMETER State is invalid.
  @retval EFI_DEVICE_ERROR      Failed to set the state due to device error.

**/
EFI_STATUS
EFIAPI
XhcSetState (
  IN EFI_USB2_HC_PROTOCOL  *This,
  IN EFI_USB_HC_STATE      State
  )
{
  USB_XHCI_INSTANCE  *Xhc;
  EFI_STATUS         Status;
  EFI_USB_HC_STATE   CurState;
  EFI_TPL            OldTpl;

  Status = XhcGetState (This, &CurState);

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  if (CurState == State) {
    return EFI_SUCCESS;
  }

  OldTpl = gBS->RaiseTPL (XHC_TPL);

  Xhc = XHC_FROM_THIS (This);

  switch (State) {
    case EfiUsbHcStateHalt:
      Status = XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT);
      break;

    case EfiUsbHcStateOperational:
      if (XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HSE)) {
        Status = EFI_DEVICE_ERROR;
        break;
      }

      //
      // Software must not write a one to this field unless the host controller
      // is in the Halted state. Doing so will yield undefined results.
      // refers to Spec[XHCI1.0-2.3.1]
      //
      if (!XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT)) {
        Status = EFI_DEVICE_ERROR;
        break;
      }

      Status = XhcRunHC (Xhc, XHC_GENERIC_TIMEOUT);
      break;

    case EfiUsbHcStateSuspend:
      Status = EFI_UNSUPPORTED;
      break;

    default:
      Status = EFI_INVALID_PARAMETER;
  }

  DEBUG ((DEBUG_INFO, "XhcSetState: status %r\n", Status));
  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Retrieves the current status of a USB root hub port.

  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
  @param  PortNumber            The root hub port to retrieve the state from.
                                This value is zero-based.
  @param  PortStatus            Variable to receive the port state.

  @retval EFI_SUCCESS           The status of the USB root hub port specified.
                                by PortNumber was returned in PortStatus.
  @retval EFI_INVALID_PARAMETER PortNumber is invalid.
  @retval EFI_DEVICE_ERROR      Can't read register.

**/
EFI_STATUS
EFIAPI
XhcGetRootHubPortStatus (
  IN  EFI_USB2_HC_PROTOCOL  *This,
  IN  UINT8                 PortNumber,
  OUT EFI_USB_PORT_STATUS   *PortStatus
  )
{
  USB_XHCI_INSTANCE  *Xhc;
  UINT32             Offset;
  UINT32             State;
  UINT32             TotalPort;
  UINTN              Index;
  UINTN              MapSize;
  UINT8              PortSpeed;
  EFI_STATUS         Status;
  USB_DEV_ROUTE      ParentRouteChart;
  EFI_TPL            OldTpl;

  if (PortStatus == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (XHC_TPL);

  Xhc    = XHC_FROM_THIS (This);
  Status = EFI_SUCCESS;

  TotalPort = Xhc->HcSParams1.Data.MaxPorts;

  if (PortNumber >= TotalPort) {
    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }

  Offset                       = (UINT32)(XHC_PORTSC_OFFSET + (0x10 * PortNumber));
  PortStatus->PortStatus       = 0;
  PortStatus->PortChangeStatus = 0;

  State = XhcReadOpReg (Xhc, Offset);

  PortSpeed = (State & XHC_PORTSC_PS) >> 10;

  //
  // According to XHCI 1.1 spec November 2017,
  // Section 7.2 xHCI Support Protocol Capability
  //
  if (PortSpeed > 0) {
    PortStatus->PortStatus = XhcCheckUsbPortSpeedUsedPsic (Xhc, PortSpeed, PortNumber);
    // If no match found in ext cap reg, fall back to PORTSC
    if (PortStatus->PortStatus == 0) {
      //
      // According to XHCI 1.1 spec November 2017,
      // bit 10~13 of the root port status register identifies the speed of the attached device.
      //
      switch (PortSpeed) {
        case 2:
          PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;
          break;

        case 3:
          PortStatus->PortStatus |= USB_PORT_STAT_HIGH_SPEED;
          break;

        case 4:
        case 5:
          PortStatus->PortStatus |= USB_PORT_STAT_SUPER_SPEED;
          break;

        default:
          break;
      }
    }
  }

  //
  // Convert the XHCI port/port change state to UEFI status
  //
  MapSize = sizeof (mUsbPortStateMap) / sizeof (USB_PORT_STATE_MAP);

  for (Index = 0; Index < MapSize; Index++) {
    if (XHC_BIT_IS_SET (State, mUsbPortStateMap[Index].HwState)) {
      PortStatus->PortStatus = (UINT16)(PortStatus->PortStatus | mUsbPortStateMap[Index].UefiState);
    }
  }

  //
  // Bit5~8 reflects its current link state.
  //
  if ((State & XHC_PORTSC_PLS) >> 5 == 3) {
    PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;
  }

  MapSize = sizeof (mUsbPortChangeMap) / sizeof (USB_PORT_STATE_MAP);

  for (Index = 0; Index < MapSize; Index++) {
    if (XHC_BIT_IS_SET (State, mUsbPortChangeMap[Index].HwState)) {
      PortStatus->PortChangeStatus = (UINT16)(PortStatus->PortChangeStatus | mUsbPortChangeMap[Index].UefiState);
    }
  }

  MapSize = sizeof (mUsbClearPortChangeMap) / sizeof (USB_CLEAR_PORT_MAP);

  for (Index = 0; Index < MapSize; Index++) {
    if (XHC_BIT_IS_SET (State, mUsbClearPortChangeMap[Index].HwState)) {
      XhcClearRootHubPortFeature (This, PortNumber, (EFI_USB_PORT_FEATURE)mUsbClearPortChangeMap[Index].Selector);
    }
  }

  //
  // Poll the root port status register to enable/disable corresponding device slot if there is a device attached/detached.
  // For those devices behind hub, we get its attach/detach event by hooking Get_Port_Status request at control transfer for those hub.
  //
  ParentRouteChart.Dword = 0;
  Status                 = XhcPollPortStatusChange (Xhc, ParentRouteChart, PortNumber, PortStatus);

  //
  // Force resetting the port by clearing the USB_PORT_STAT_C_RESET bit in PortChangeStatus
  // when XhcPollPortStatusChange fails
  //
  if (EFI_ERROR (Status)) {
    PortStatus->PortChangeStatus &= ~(USB_PORT_STAT_C_RESET);
    Status                        = EFI_SUCCESS;
  }

ON_EXIT:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Sets a feature for the specified root hub port.

  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
  @param  PortNumber            Root hub port to set.
  @param  PortFeature           Feature to set.

  @retval EFI_SUCCESS           The feature specified by PortFeature was set.
  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
  @retval EFI_DEVICE_ERROR      Can't read register.

**/
EFI_STATUS
EFIAPI
XhcSetRootHubPortFeature (
  IN EFI_USB2_HC_PROTOCOL  *This,
  IN UINT8                 PortNumber,
  IN EFI_USB_PORT_FEATURE  PortFeature
  )
{
  USB_XHCI_INSTANCE  *Xhc;
  UINT32             Offset;
  UINT32             State;
  UINT32             TotalPort;
  EFI_STATUS         Status;
  EFI_TPL            OldTpl;

  OldTpl = gBS->RaiseTPL (XHC_TPL);

  Xhc    = XHC_FROM_THIS (This);
  Status = EFI_SUCCESS;

  TotalPort = (Xhc->HcSParams1.Data.MaxPorts);

  if (PortNumber >= TotalPort) {
    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }

  Offset = (UINT32)(XHC_PORTSC_OFFSET + (0x10 * PortNumber));
  State  = XhcReadOpReg (Xhc, Offset);

  //
  // Mask off the port status change bits, these bits are
  // write clean bit
  //
  State &= ~(BIT1 | BIT17 | BIT18 | BIT19 | BIT20 | BIT21 | BIT22 | BIT23);

  switch (PortFeature) {
    case EfiUsbPortEnable:
      //
      // Ports may only be enabled by the xHC. Software cannot enable a port by writing a '1' to this flag.
      // A port may be disabled by software writing a '1' to this flag.
      //
      Status = EFI_SUCCESS;
      break;

    case EfiUsbPortSuspend:
      State |= XHC_PORTSC_LWS;
      XhcWriteOpReg (Xhc, Offset, State);
      State &= ~XHC_PORTSC_PLS;
      State |= (3 << 5);
      XhcWriteOpReg (Xhc, Offset, State);
      break;

    case EfiUsbPortReset:
      DEBUG ((DEBUG_INFO, "XhcUsbPortReset!\n"));
      //
      // Make sure Host Controller not halt before reset it
      //
      if (XhcIsHalt (Xhc)) {
        Status = XhcRunHC (Xhc, XHC_GENERIC_TIMEOUT);

        if (EFI_ERROR (Status)) {
          DEBUG ((DEBUG_INFO, "XhcSetRootHubPortFeature :failed to start HC - %r\n", Status));
          break;
        }
      }

      //
      // 4.3.1 Resetting a Root Hub Port
      // 1) Write the PORTSC register with the Port Reset (PR) bit set to '1'.
      //
      State |= XHC_PORTSC_RESET;
      XhcWriteOpReg (Xhc, Offset, State);
      XhcWaitOpRegBit (Xhc, Offset, XHC_PORTSC_PRC, TRUE, XHC_GENERIC_TIMEOUT);
      break;

    case EfiUsbPortPower:
      //
      // Not supported, ignore the operation
      //
      Status = EFI_SUCCESS;
      break;

    case EfiUsbPortOwner:
      //
      // XHCI root hub port don't has the owner bit, ignore the operation
      //
      Status = EFI_SUCCESS;
      break;

    default:
      Status = EFI_INVALID_PARAMETER;
  }

ON_EXIT:
  DEBUG ((DEBUG_INFO, "XhcSetRootHubPortFeature: status %r\n", Status));
  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Clears a feature for the specified root hub port.

  @param  This                  A pointer to the EFI_USB2_HC_PROTOCOL instance.
  @param  PortNumber            Specifies the root hub port whose feature is
                                requested to be cleared.
  @param  PortFeature           Indicates the feature selector associated with the
                                feature clear request.

  @retval EFI_SUCCESS           The feature specified by PortFeature was cleared
                                for the USB root hub port specified by PortNumber.
  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
  @retval EFI_DEVICE_ERROR      Can't read register.

**/
EFI_STATUS
EFIAPI
XhcClearRootHubPortFeature (
  IN EFI_USB2_HC_PROTOCOL  *This,
  IN UINT8                 PortNumber,
  IN EFI_USB_PORT_FEATURE  PortFeature
  )
{
  USB_XHCI_INSTANCE  *Xhc;
  UINT32             Offset;
  UINT32             State;
  UINT32             TotalPort;
  EFI_STATUS         Status;
  EFI_TPL            OldTpl;

  OldTpl = gBS->RaiseTPL (XHC_TPL);

  Xhc    = XHC_FROM_THIS (This);
  Status = EFI_SUCCESS;

  TotalPort = (Xhc->HcSParams1.Data.MaxPorts);

  if (PortNumber >= TotalPort) {
    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }

  Offset = XHC_PORTSC_OFFSET + (0x10 * PortNumber);

  //
  // Mask off the port status change bits, these bits are
  // write clean bit
  //
  State  = XhcReadOpReg (Xhc, Offset);
  State &= ~(BIT1 | BIT17 | BIT18 | BIT19 | BIT20 | BIT21 | BIT22 | BIT23);

  switch (PortFeature) {
    case EfiUsbPortEnable:
      //
      // Ports may only be enabled by the xHC. Software cannot enable a port by writing a '1' to this flag.
      // A port may be disabled by software writing a '1' to this flag.
      //
      State |= XHC_PORTSC_PED;
      State &= ~XHC_PORTSC_RESET;
      XhcWriteOpReg (Xhc, Offset, State);
      break;

    case EfiUsbPortSuspend:
      State |= XHC_PORTSC_LWS;
      XhcWriteOpReg (Xhc, Offset, State);
      State &= ~XHC_PORTSC_PLS;
      XhcWriteOpReg (Xhc, Offset, State);
      break;

    case EfiUsbPortReset:
      //
      // PORTSC_RESET BIT(4) bit is RW1S attribute, which means Write-1-to-set status:
      // Register bits indicate status when read, a clear bit may be set by
      // writing a '1'. Writing a '0' to RW1S bits has no effect.
      //
      break;

    case EfiUsbPortOwner:
      //
      // XHCI root hub port don't has the owner bit, ignore the operation
      //
      break;

    case EfiUsbPortConnectChange:
      //
      // Clear connect status change
      //
      State |= XHC_PORTSC_CSC;
      XhcWriteOpReg (Xhc, Offset, State);
      break;

    case EfiUsbPortEnableChange:
      //
      // Clear enable status change
      //
      State |= XHC_PORTSC_PEC;
      XhcWriteOpReg (Xhc, Offset, State);
      break;

    case EfiUsbPortOverCurrentChange:
      //
      // Clear PortOverCurrent change
      //
      State |= XHC_PORTSC_OCC;
      XhcWriteOpReg (Xhc, Offset, State);
      break;

    case EfiUsbPortResetChange:
      //
      // Clear Port Reset change
      //
      State |= XHC_PORTSC_PRC;
      XhcWriteOpReg (Xhc, Offset, State);
      break;

    case EfiUsbPortPower:
    case EfiUsbPortSuspendChange:
      //
      // Not supported or not related operation
      //
      break;

    default:
      Status = EFI_INVALID_PARAMETER;
      break;
  }

ON_EXIT:
  DEBUG ((DEBUG_INFO, "XhcClearRootHubPortFeature: status %r\n", Status));
  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Submits a new transaction to a target USB device.

  @param  Xhc                   The XHCI Instance.
  @param  DeviceAddress         The target device address.
  @param  EndPointAddress       Endpoint number and its direction encoded in bit 7
  @param  DeviceSpeed           Target device speed.
  @param  MaximumPacketLength   Maximum packet size the default control transfer
                                endpoint is capable of sending or receiving.
  @param  Type                  The transaction type.
  @param  Request               USB device request to send.
  @param  Data                  Data buffer to be transmitted or received from USB
                                device.
  @param  DataLength            The size (in bytes) of the data buffer.
  @param  Timeout               Indicates the maximum timeout, in millisecond.
  @param  TransferResult        Return the result of this control transfer.

  @retval EFI_SUCCESS           Transfer was completed successfully.
  @retval EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resources.
  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
  @retval EFI_TIMEOUT           Transfer failed due to timeout.
  @retval EFI_DEVICE_ERROR      Transfer failed due to host controller or device error.
**/
EFI_STATUS
XhcTransfer (
  IN     USB_XHCI_INSTANCE       *Xhc,
  IN     UINT8                   DeviceAddress,
  IN     UINT8                   EndPointAddress,
  IN     UINT8                   DeviceSpeed,
  IN     UINTN                   MaximumPacketLength,
  IN     UINTN                   Type,
  IN     EFI_USB_DEVICE_REQUEST  *Request,
  IN OUT VOID                    *Data,
  IN OUT UINTN                   *DataLength,
  IN     UINTN                   Timeout,
  OUT    UINT32                  *TransferResult
  )
{
  EFI_STATUS  Status;
  EFI_STATUS  RecoveryStatus;
  URB         *Urb;

  ASSERT ((Type == XHC_CTRL_TRANSFER) || (Type == XHC_BULK_TRANSFER) || (Type == XHC_INT_TRANSFER_SYNC));
  Urb = XhcCreateUrb (
          Xhc,
          DeviceAddress,
          EndPointAddress,
          DeviceSpeed,
          MaximumPacketLength,
          Type,
          Request,
          Data,
          *DataLength,
          NULL,
          NULL
          );

  if (Urb == NULL) {
    DEBUG ((DEBUG_ERROR, "XhcTransfer[Type=%d]: failed to create URB!\n", Type));
    return EFI_OUT_OF_RESOURCES;
  }

  Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout);

  if (Status == EFI_TIMEOUT) {
    //
    // The transfer timed out. Abort the transfer by dequeueing of the TD.
    //
    RecoveryStatus = XhcDequeueTrbFromEndpoint (Xhc, Urb);
    if (RecoveryStatus == EFI_ALREADY_STARTED) {
      //
      // The URB is finished just before stopping endpoint.
      // Change returning status from EFI_TIMEOUT to EFI_SUCCESS.
      //
      ASSERT (Urb->Result == EFI_USB_NOERROR);
      Status = EFI_SUCCESS;
      DEBUG ((DEBUG_ERROR, "XhcTransfer[Type=%d]: pending URB is finished, Length = %d.\n", Type, Urb->Completed));
    } else if (EFI_ERROR (RecoveryStatus)) {
      DEBUG ((DEBUG_ERROR, "XhcTransfer[Type=%d]: XhcDequeueTrbFromEndpoint failed!\n", Type));
    }
  }

  *TransferResult = Urb->Result;
  *DataLength     = Urb->Completed;

  //
  // Based on XHCI spec 4.8.3, software should do the reset endpoint while USB Transaction occur.
  //
  if ((*TransferResult == EFI_USB_ERR_STALL) || (*TransferResult == EFI_USB_ERR_BABBLE) || (*TransferResult == EDKII_USB_ERR_TRANSACTION)) {
    ASSERT (Status == EFI_DEVICE_ERROR);
    RecoveryStatus = XhcRecoverHaltedEndpoint (Xhc, Urb);
    if (EFI_ERROR (RecoveryStatus)) {
      DEBUG ((DEBUG_ERROR, "XhcTransfer[Type=%d]: XhcRecoverHaltedEndpoint failed!\n", Type));
    }
  }

  Xhc->PciIo->Flush (Xhc->PciIo);
  XhcFreeUrb (Xhc, Urb);
  return Status;
}

/**
  Submits control transfer to a target USB device.

  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
  @param  DeviceAddress         The target device address.
  @param  DeviceSpeed           Target device speed.
  @param  MaximumPacketLength   Maximum packet size the default control transfer
                                endpoint is capable of sending or receiving.
  @param  Request               USB device request to send.
  @param  TransferDirection     Specifies the data direction for the data stage
  @param  Data                  Data buffer to be transmitted or received from USB
                                device.
  @param  DataLength            The size (in bytes) of the data buffer.
  @param  Timeout               Indicates the maximum timeout, in millisecond.
  @param  Translator            Transaction translator to be used by this device.
  @param  TransferResult        Return the result of this control transfer.

  @retval EFI_SUCCESS           Transfer was completed successfully.
  @retval EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resources.
  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
  @retval EFI_TIMEOUT           Transfer failed due to timeout.
  @retval EFI_DEVICE_ERROR      Transfer failed due to host controller or device error.

**/
EFI_STATUS
EFIAPI
XhcControlTransfer (
  IN     EFI_USB2_HC_PROTOCOL                *This,
  IN     UINT8                               DeviceAddress,
  IN     UINT8                               DeviceSpeed,
  IN     UINTN                               MaximumPacketLength,
  IN     EFI_USB_DEVICE_REQUEST              *Request,
  IN     EFI_USB_DATA_DIRECTION              TransferDirection,
  IN OUT VOID                                *Data,
  IN OUT UINTN                               *DataLength,
  IN     UINTN                               Timeout,
  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
  OUT    UINT32                              *TransferResult
  )
{
  USB_XHCI_INSTANCE       *Xhc;
  UINT8                   Endpoint;
  UINT8                   Index;
  UINT8                   DescriptorType;
  UINT8                   SlotId;
  UINT8                   TTT;
  UINT8                   MTT;
  UINT32                  MaxPacket0;
  EFI_USB_HUB_DESCRIPTOR  *HubDesc;
  EFI_TPL                 OldTpl;
  EFI_STATUS              Status;
  UINTN                   MapSize;
  EFI_USB_PORT_STATUS     PortStatus;
  UINT32                  State;
  EFI_USB_DEVICE_REQUEST  ClearPortRequest;
  UINTN                   Len;

  //
  // Validate parameters
  //
  if ((Request == NULL) || (TransferResult == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((TransferDirection != EfiUsbDataIn) &&
      (TransferDirection != EfiUsbDataOut) &&
      (TransferDirection != EfiUsbNoData))
  {
    return EFI_INVALID_PARAMETER;
  }

  if ((TransferDirection == EfiUsbNoData) &&
      ((Data != NULL) || (*DataLength != 0)))
  {
    return EFI_INVALID_PARAMETER;
  }

  if ((TransferDirection != EfiUsbNoData) &&
      ((Data == NULL) || (*DataLength == 0)))
  {
    return EFI_INVALID_PARAMETER;
  }

  if ((MaximumPacketLength != 8)  && (MaximumPacketLength != 16) &&
      (MaximumPacketLength != 32) && (MaximumPacketLength != 64) &&
      (MaximumPacketLength != 512)
      )
  {
    return EFI_INVALID_PARAMETER;
  }

  if ((DeviceSpeed == EFI_USB_SPEED_LOW) && (MaximumPacketLength != 8)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((DeviceSpeed == EFI_USB_SPEED_SUPER) && (MaximumPacketLength != 512)) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (XHC_TPL);

  Xhc = XHC_FROM_THIS (This);

  Status          = EFI_DEVICE_ERROR;
  *TransferResult = EFI_USB_ERR_SYSTEM;
  Len             = 0;

  if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) {
    DEBUG ((DEBUG_ERROR, "XhcControlTransfer: HC halted at entrance\n"));
    goto ON_EXIT;
  }

  //
  // Check if the device is still enabled before every transaction.
  //
  SlotId = XhcBusDevAddrToSlotId (Xhc, DeviceAddress);
  if (SlotId == 0) {
    goto ON_EXIT;
  }

  //
  // Hook the Set_Address request from UsbBus.
  // According to XHCI 1.0 spec, the Set_Address request is replaced by XHCI's Address_Device cmd.
  //
  if ((Request->Request     == USB_REQ_SET_ADDRESS) &&
      (Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, USB_TARGET_DEVICE)))
  {
    //
    // Reset the BusDevAddr field of all disabled entries in UsbDevContext array firstly.
    // This way is used to clean the history to avoid using wrong device address by XhcAsyncInterruptTransfer().
    //
    for (Index = 0; Index < 255; Index++) {
      if (!Xhc->UsbDevContext[Index + 1].Enabled &&
          (Xhc->UsbDevContext[Index + 1].SlotId == 0) &&
          (Xhc->UsbDevContext[Index + 1].BusDevAddr == (UINT8)Request->Value))
      {
        Xhc->UsbDevContext[Index + 1].BusDevAddr = 0;
      }
    }

    if (Xhc->UsbDevContext[SlotId].XhciDevAddr == 0) {
      Status = EFI_DEVICE_ERROR;
      goto ON_EXIT;
    }

    //
    // The actual device address has been assigned by XHCI during initializing the device slot.
    // So we just need establish the mapping relationship between the device address requested from UsbBus
    // and the actual device address assigned by XHCI. The the following invocations through EFI_USB2_HC_PROTOCOL interface
    // can find out the actual device address by it.
    //
    Xhc->UsbDevContext[SlotId].BusDevAddr = (UINT8)Request->Value;
    Status                                = EFI_SUCCESS;
    goto ON_EXIT;
  }

  //
  // Create a new URB, insert it into the asynchronous
  // schedule list, then poll the execution status.
  // Note that we encode the direction in address although default control
  // endpoint is bidirectional. XhcCreateUrb expects this
  // combination of Ep addr and its direction.
  //
  Endpoint = (UINT8)(0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0));
  Status   = XhcTransfer (
               Xhc,
               DeviceAddress,
               Endpoint,
               DeviceSpeed,
               MaximumPacketLength,
               XHC_CTRL_TRANSFER,
               Request,
               Data,
               DataLength,
               Timeout,
               TransferResult
               );

  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Hook Get_Descriptor request from UsbBus as we need evaluate context and configure endpoint.
  // Hook Get_Status request form UsbBus as we need trace device attach/detach event happened at hub.
  // Hook Set_Config request from UsbBus as we need configure device endpoint.
  //
  if ((Request->Request     == USB_REQ_GET_DESCRIPTOR) &&
      ((Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, USB_REQ_TYPE_STANDARD, USB_TARGET_DEVICE)) ||
       ((Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, USB_REQ_TYPE_CLASS, USB_TARGET_DEVICE)))))
  {
    DescriptorType = (UINT8)(Request->Value >> 8);
    if ((DescriptorType == USB_DESC_TYPE_DEVICE) && ((*DataLength == sizeof (EFI_USB_DEVICE_DESCRIPTOR)) || ((DeviceSpeed == EFI_USB_SPEED_FULL) && (*DataLength == 8)))) {
      ASSERT (Data != NULL);
      //
      // Store a copy of device scriptor as hub device need this info to configure endpoint.
      //
      CopyMem (&Xhc->UsbDevContext[SlotId].DevDesc, Data, *DataLength);
      if (Xhc->UsbDevContext[SlotId].DevDesc.BcdUSB >= 0x0300) {
        //
        // If it's a usb3.0 device, then its max packet size is a 2^n.
        //
        MaxPacket0 = 1 << Xhc->UsbDevContext[SlotId].DevDesc.MaxPacketSize0;
      } else {
        MaxPacket0 = Xhc->UsbDevContext[SlotId].DevDesc.MaxPacketSize0;
      }

      Xhc->UsbDevContext[SlotId].ConfDesc = AllocateZeroPool (Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations * sizeof (EFI_USB_CONFIG_DESCRIPTOR *));
      if (Xhc->HcCParams.Data.Csz == 0) {
        Status = XhcEvaluateContext (Xhc, SlotId, MaxPacket0);
      } else {
        Status = XhcEvaluateContext64 (Xhc, SlotId, MaxPacket0);
      }
    } else if (DescriptorType == USB_DESC_TYPE_CONFIG) {
      ASSERT (Data != NULL);
      if (*DataLength == ((UINT16 *)Data)[1]) {
        //
        // Get configuration value from request, Store the configuration descriptor for Configure_Endpoint cmd.
        //
        Index = (UINT8)Request->Value;
        ASSERT (Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations);
        Xhc->UsbDevContext[SlotId].ConfDesc[Index] = AllocateZeroPool (*DataLength);
        CopyMem (Xhc->UsbDevContext[SlotId].ConfDesc[Index], Data, *DataLength);
        //
        // Default to use AlternateSetting 0 for all interfaces.
        //
        Xhc->UsbDevContext[SlotId].ActiveAlternateSetting = AllocateZeroPool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]->NumInterfaces * sizeof (UINT8));
      }
    } else if (((DescriptorType == USB_DESC_TYPE_HUB) ||
                (DescriptorType == USB_DESC_TYPE_HUB_SUPER_SPEED)) && (*DataLength > 2))
    {
      ASSERT (Data != NULL);
      HubDesc = (EFI_USB_HUB_DESCRIPTOR *)Data;
      ASSERT (HubDesc->NumPorts <= 15);
      //
      // The bit 5,6 of HubCharacter field of Hub Descriptor is TTT.
      //
      TTT = (UINT8)((HubDesc->HubCharacter & (BIT5 | BIT6)) >> 5);
      if (Xhc->UsbDevContext[SlotId].DevDesc.DeviceProtocol == 2) {
        //
        // Don't support multi-TT feature for super speed hub now.
        //
        MTT = 0;
        DEBUG ((DEBUG_ERROR, "XHCI: Don't support multi-TT feature for Hub now. (force to disable MTT)\n"));
      } else {
        MTT = 0;
      }

      if (Xhc->HcCParams.Data.Csz == 0) {
        Status = XhcConfigHubContext (Xhc, SlotId, HubDesc->NumPorts, TTT, MTT);
      } else {
        Status = XhcConfigHubContext64 (Xhc, SlotId, HubDesc->NumPorts, TTT, MTT);
      }
    }
  } else if ((Request->Request     == USB_REQ_SET_CONFIG) &&
             (Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, USB_TARGET_DEVICE)))
  {
    //
    // Hook Set_Config request from UsbBus as we need configure device endpoint.
    //
    for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) {
      if (Xhc->UsbDevContext[SlotId].ConfDesc[Index]->ConfigurationValue == (UINT8)Request->Value) {
        if (Xhc->HcCParams.Data.Csz == 0) {
          Status = XhcSetConfigCmd (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Index]);
        } else {
          Status = XhcSetConfigCmd64 (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Index]);
        }

        break;
      }
    }
  } else if ((Request->Request     == USB_REQ_SET_INTERFACE) &&
             (Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, USB_TARGET_INTERFACE)))
  {
    //
    // Hook Set_Interface request from UsbBus as we need configure interface setting.
    // Request->Value indicates AlterlateSetting to set
    // Request->Index indicates Interface to set
    //
    if (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8)Request->Index] != (UINT8)Request->Value) {
      if (Xhc->HcCParams.Data.Csz == 0) {
        Status = XhcSetInterface (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Xhc->UsbDevContext[SlotId].ActiveConfiguration - 1], Request);
      } else {
        Status = XhcSetInterface64 (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Xhc->UsbDevContext[SlotId].ActiveConfiguration - 1], Request);
      }
    }
  } else if ((Request->Request     == USB_REQ_GET_STATUS) &&
             (Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, USB_REQ_TYPE_CLASS, USB_TARGET_OTHER)))
  {
    ASSERT (Data != NULL);
    //
    // Hook Get_Status request from UsbBus to keep track of the port status change.
    //
    State                       = *(UINT32 *)Data;
    PortStatus.PortStatus       = 0;
    PortStatus.PortChangeStatus = 0;

    if (DeviceSpeed == EFI_USB_SPEED_SUPER) {
      //
      // For super speed hub, its bit10~12 presents the attached device speed.
      //
      if ((State & XHC_PORTSC_PS) >> 10 == 0) {
        PortStatus.PortStatus |= USB_PORT_STAT_SUPER_SPEED;
      }
    } else {
      //
      // For high or full/low speed hub, its bit9~10 presents the attached device speed.
      //
      if (XHC_BIT_IS_SET (State, BIT9)) {
        PortStatus.PortStatus |= USB_PORT_STAT_LOW_SPEED;
      } else if (XHC_BIT_IS_SET (State, BIT10)) {
        PortStatus.PortStatus |= USB_PORT_STAT_HIGH_SPEED;
      }
    }

    //
    // Convert the XHCI port/port change state to UEFI status
    //
    MapSize = sizeof (mUsbHubPortStateMap) / sizeof (USB_PORT_STATE_MAP);
    for (Index = 0; Index < MapSize; Index++) {
      if (XHC_BIT_IS_SET (State, mUsbHubPortStateMap[Index].HwState)) {
        PortStatus.PortStatus = (UINT16)(PortStatus.PortStatus | mUsbHubPortStateMap[Index].UefiState);
      }
    }

    MapSize = sizeof (mUsbHubPortChangeMap) / sizeof (USB_PORT_STATE_MAP);
    for (Index = 0; Index < MapSize; Index++) {
      if (XHC_BIT_IS_SET (State, mUsbHubPortChangeMap[Index].HwState)) {
        PortStatus.PortChangeStatus = (UINT16)(PortStatus.PortChangeStatus | mUsbHubPortChangeMap[Index].UefiState);
      }
    }

    MapSize = sizeof (mUsbHubClearPortChangeMap) / sizeof (USB_CLEAR_PORT_MAP);

    for (Index = 0; Index < MapSize; Index++) {
      if (XHC_BIT_IS_SET (State, mUsbHubClearPortChangeMap[Index].HwState)) {
        ZeroMem (&ClearPortRequest, sizeof (EFI_USB_DEVICE_REQUEST));
        ClearPortRequest.RequestType = USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_CLASS, USB_TARGET_OTHER);
        ClearPortRequest.Request     = (UINT8)USB_REQ_CLEAR_FEATURE;
        ClearPortRequest.Value       = mUsbHubClearPortChangeMap[Index].Selector;
        ClearPortRequest.Index       = Request->Index;
        ClearPortRequest.Length      = 0;

        XhcControlTransfer (
          This,
          DeviceAddress,
          DeviceSpeed,
          MaximumPacketLength,
          &ClearPortRequest,
          EfiUsbNoData,
          NULL,
          &Len,
          Timeout,
          Translator,
          TransferResult
          );
      }
    }

    XhcPollPortStatusChange (Xhc, Xhc->UsbDevContext[SlotId].RouteString, (UINT8)Request->Index, &PortStatus);

    *(UINT32 *)Data = *(UINT32 *)&PortStatus;
  }

ON_EXIT:
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "XhcControlTransfer: error - %r, transfer - %x\n", Status, *TransferResult));
  }

  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Submits bulk transfer to a bulk endpoint of a USB device.

  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
  @param  DeviceAddress         Target device address.
  @param  EndPointAddress       Endpoint number and its direction in bit 7.
  @param  DeviceSpeed           Device speed, Low speed device doesn't support bulk
                                transfer.
  @param  MaximumPacketLength   Maximum packet size the endpoint is capable of
                                sending or receiving.
  @param  DataBuffersNumber     Number of data buffers prepared for the transfer.
  @param  Data                  Array of pointers to the buffers of data to transmit
                                from or receive into.
  @param  DataLength            The lenght of the data buffer.
  @param  DataToggle            On input, the initial data toggle for the transfer;
                                On output, it is updated to to next data toggle to
                                use of the subsequent bulk transfer.
  @param  Timeout               Indicates the maximum time, in millisecond, which
                                the transfer is allowed to complete.
  @param  Translator            A pointr to the transaction translator data.
  @param  TransferResult        A pointer to the detailed result information of the
                                bulk transfer.

  @retval EFI_SUCCESS           The transfer was completed successfully.
  @retval EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resource.
  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
  @retval EFI_TIMEOUT           The transfer failed due to timeout.
  @retval EFI_DEVICE_ERROR      The transfer failed due to host controller error.

**/
EFI_STATUS
EFIAPI
XhcBulkTransfer (
  IN     EFI_USB2_HC_PROTOCOL                *This,
  IN     UINT8                               DeviceAddress,
  IN     UINT8                               EndPointAddress,
  IN     UINT8                               DeviceSpeed,
  IN     UINTN                               MaximumPacketLength,
  IN     UINT8                               DataBuffersNumber,
  IN OUT VOID                                *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
  IN OUT UINTN                               *DataLength,
  IN OUT UINT8                               *DataToggle,
  IN     UINTN                               Timeout,
  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
  OUT    UINT32                              *TransferResult
  )
{
  USB_XHCI_INSTANCE  *Xhc;
  UINT8              SlotId;
  EFI_STATUS         Status;
  EFI_TPL            OldTpl;
  UINTN              DebugErrorLevel;

  //
  // Validate the parameters
  //
  if ((DataLength == NULL) || (*DataLength == 0) ||
      (Data == NULL) || (Data[0] == NULL) || (TransferResult == NULL))
  {
    return EFI_INVALID_PARAMETER;
  }

  if ((*DataToggle != 0) && (*DataToggle != 1)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((DeviceSpeed == EFI_USB_SPEED_LOW) ||
      ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) ||
      ((EFI_USB_SPEED_HIGH == DeviceSpeed) && (MaximumPacketLength > 512)) ||
      ((EFI_USB_SPEED_SUPER == DeviceSpeed) && (MaximumPacketLength > 1024)))
  {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (XHC_TPL);

  Xhc = XHC_FROM_THIS (This);

  *TransferResult = EFI_USB_ERR_SYSTEM;
  Status          = EFI_DEVICE_ERROR;

  if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) {
    DEBUG ((DEBUG_ERROR, "XhcBulkTransfer: HC is halted\n"));
    goto ON_EXIT;
  }

  //
  // Check if the device is still enabled before every transaction.
  //
  SlotId = XhcBusDevAddrToSlotId (Xhc, DeviceAddress);
  if (SlotId == 0) {
    goto ON_EXIT;
  }

  //
  // Create a new URB, insert it into the asynchronous
  // schedule list, then poll the execution status.
  //
  Status = XhcTransfer (
             Xhc,
             DeviceAddress,
             EndPointAddress,
             DeviceSpeed,
             MaximumPacketLength,
             XHC_BULK_TRANSFER,
             NULL,
             Data[0],
             DataLength,
             Timeout,
             TransferResult
             );

ON_EXIT:
  if (EFI_ERROR (Status)) {
    if (Status == EFI_TIMEOUT) {
      DebugErrorLevel = DEBUG_VERBOSE;
    } else {
      DebugErrorLevel = DEBUG_ERROR;
    }

    DEBUG ((DebugErrorLevel, "XhcBulkTransfer: error - %r, transfer - %x\n", Status, *TransferResult));
  }

  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Submits an asynchronous interrupt transfer to an
  interrupt endpoint of a USB device.

  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
  @param  DeviceAddress         Target device address.
  @param  EndPointAddress       Endpoint number and its direction encoded in bit 7
  @param  DeviceSpeed           Indicates device speed.
  @param  MaximumPacketLength   Maximum packet size the target endpoint is capable
  @param  IsNewTransfer         If TRUE, to submit an new asynchronous interrupt
                                transfer If FALSE, to remove the specified
                                asynchronous interrupt.
  @param  DataToggle            On input, the initial data toggle to use; on output,
                                it is updated to indicate the next data toggle.
  @param  PollingInterval       The he interval, in milliseconds, that the transfer
                                is polled.
  @param  DataLength            The length of data to receive at the rate specified
                                by  PollingInterval.
  @param  Translator            Transaction translator to use.
  @param  CallBackFunction      Function to call at the rate specified by
                                PollingInterval.
  @param  Context               Context to CallBackFunction.

  @retval EFI_SUCCESS           The request has been successfully submitted or canceled.
  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
  @retval EFI_OUT_OF_RESOURCES  The request failed due to a lack of resources.
  @retval EFI_DEVICE_ERROR      The transfer failed due to host controller error.

**/
EFI_STATUS
EFIAPI
XhcAsyncInterruptTransfer (
  IN     EFI_USB2_HC_PROTOCOL                *This,
  IN     UINT8                               DeviceAddress,
  IN     UINT8                               EndPointAddress,
  IN     UINT8                               DeviceSpeed,
  IN     UINTN                               MaximumPacketLength,
  IN     BOOLEAN                             IsNewTransfer,
  IN OUT UINT8                               *DataToggle,
  IN     UINTN                               PollingInterval,
  IN     UINTN                               DataLength,
  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK     CallBackFunction,
  IN     VOID                                *Context OPTIONAL
  )
{
  USB_XHCI_INSTANCE  *Xhc;
  URB                *Urb;
  EFI_STATUS         Status;
  UINT8              SlotId;
  UINT8              Index;
  EFI_TPL            OldTpl;

  //
  // Validate parameters
  //
  if (!XHCI_IS_DATAIN (EndPointAddress)) {
    return EFI_INVALID_PARAMETER;
  }

  if (IsNewTransfer) {
    if (DataLength == 0) {
      return EFI_INVALID_PARAMETER;
    }

    if ((*DataToggle != 1) && (*DataToggle != 0)) {
      return EFI_INVALID_PARAMETER;
    }

    if ((PollingInterval > 255) || (PollingInterval < 1)) {
      return EFI_INVALID_PARAMETER;
    }
  }

  OldTpl = gBS->RaiseTPL (XHC_TPL);

  Xhc = XHC_FROM_THIS (This);

  //
  // Delete Async interrupt transfer request.
  //
  if (!IsNewTransfer) {
    //
    // The delete request may happen after device is detached.
    //
    for (Index = 0; Index < 255; Index++) {
      if (Xhc->UsbDevContext[Index + 1].BusDevAddr == DeviceAddress) {
        break;
      }
    }

    if (Index == 255) {
      Status = EFI_INVALID_PARAMETER;
      goto ON_EXIT;
    }

    Status = XhciDelAsyncIntTransfer (Xhc, DeviceAddress, EndPointAddress);
    DEBUG ((DEBUG_INFO, "XhcAsyncInterruptTransfer: remove old transfer for addr %d, Status = %r\n", DeviceAddress, Status));
    goto ON_EXIT;
  }

  Status = EFI_SUCCESS;

  if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) {
    DEBUG ((DEBUG_ERROR, "XhcAsyncInterruptTransfer: HC is halt\n"));
    Status = EFI_DEVICE_ERROR;
    goto ON_EXIT;
  }

  //
  // Check if the device is still enabled before every transaction.
  //
  SlotId = XhcBusDevAddrToSlotId (Xhc, DeviceAddress);
  if (SlotId == 0) {
    goto ON_EXIT;
  }

  Urb = XhciInsertAsyncIntTransfer (
          Xhc,
          DeviceAddress,
          EndPointAddress,
          DeviceSpeed,
          MaximumPacketLength,
          DataLength,
          CallBackFunction,
          Context
          );
  if (Urb == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  //
  // Ring the doorbell
  //
  Status = RingIntTransferDoorBell (Xhc, Urb);

ON_EXIT:
  Xhc->PciIo->Flush (Xhc->PciIo);
  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Submits synchronous interrupt transfer to an interrupt endpoint
  of a USB device.

  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
  @param  DeviceAddress         Target device address.
  @param  EndPointAddress       Endpoint number and its direction encoded in bit 7
  @param  DeviceSpeed           Indicates device speed.
  @param  MaximumPacketLength   Maximum packet size the target endpoint is capable
                                of sending or receiving.
  @param  Data                  Buffer of data that will be transmitted to  USB
                                device or received from USB device.
  @param  DataLength            On input, the size, in bytes, of the data buffer; On
                                output, the number of bytes transferred.
  @param  DataToggle            On input, the initial data toggle to use; on output,
                                it is updated to indicate the next data toggle.
  @param  Timeout               Maximum time, in second, to complete.
  @param  Translator            Transaction translator to use.
  @param  TransferResult        Variable to receive the transfer result.

  @return EFI_SUCCESS           The transfer was completed successfully.
  @return EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resource.
  @return EFI_INVALID_PARAMETER Some parameters are invalid.
  @return EFI_TIMEOUT           The transfer failed due to timeout.
  @return EFI_DEVICE_ERROR      The failed due to host controller or device error

**/
EFI_STATUS
EFIAPI
XhcSyncInterruptTransfer (
  IN     EFI_USB2_HC_PROTOCOL                *This,
  IN     UINT8                               DeviceAddress,
  IN     UINT8                               EndPointAddress,
  IN     UINT8                               DeviceSpeed,
  IN     UINTN                               MaximumPacketLength,
  IN OUT VOID                                *Data,
  IN OUT UINTN                               *DataLength,
  IN OUT UINT8                               *DataToggle,
  IN     UINTN                               Timeout,
  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
  OUT    UINT32                              *TransferResult
  )
{
  USB_XHCI_INSTANCE  *Xhc;
  UINT8              SlotId;
  EFI_STATUS         Status;
  EFI_TPL            OldTpl;

  //
  // Validates parameters
  //
  if ((DataLength == NULL) || (*DataLength == 0) ||
      (Data == NULL) || (TransferResult == NULL))
  {
    return EFI_INVALID_PARAMETER;
  }

  if ((*DataToggle != 1) && (*DataToggle != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  if (((DeviceSpeed == EFI_USB_SPEED_LOW) && (MaximumPacketLength != 8))  ||
      ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) ||
      ((DeviceSpeed == EFI_USB_SPEED_HIGH) && (MaximumPacketLength > 3072)))
  {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (XHC_TPL);

  Xhc = XHC_FROM_THIS (This);

  *TransferResult = EFI_USB_ERR_SYSTEM;
  Status          = EFI_DEVICE_ERROR;

  if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) {
    DEBUG ((DEBUG_ERROR, "EhcSyncInterruptTransfer: HC is halt\n"));
    goto ON_EXIT;
  }

  //
  // Check if the device is still enabled before every transaction.
  //
  SlotId = XhcBusDevAddrToSlotId (Xhc, DeviceAddress);
  if (SlotId == 0) {
    goto ON_EXIT;
  }

  Status = XhcTransfer (
             Xhc,
             DeviceAddress,
             EndPointAddress,
             DeviceSpeed,
             MaximumPacketLength,
             XHC_INT_TRANSFER_SYNC,
             NULL,
             Data,
             DataLength,
             Timeout,
             TransferResult
             );

ON_EXIT:
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "XhcSyncInterruptTransfer: error - %r, transfer - %x\n", Status, *TransferResult));
  }

  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Submits isochronous transfer to a target USB device.

  @param  This                 This EFI_USB2_HC_PROTOCOL instance.
  @param  DeviceAddress        Target device address.
  @param  EndPointAddress      End point address with its direction.
  @param  DeviceSpeed          Device speed, Low speed device doesn't support this
                               type.
  @param  MaximumPacketLength  Maximum packet size that the endpoint is capable of
                               sending or receiving.
  @param  DataBuffersNumber    Number of data buffers prepared for the transfer.
  @param  Data                 Array of pointers to the buffers of data that will
                               be transmitted to USB device or received from USB
                               device.
  @param  DataLength           The size, in bytes, of the data buffer.
  @param  Translator           Transaction translator to use.
  @param  TransferResult       Variable to receive the transfer result.

  @return EFI_UNSUPPORTED      Isochronous transfer is unsupported.

**/
EFI_STATUS
EFIAPI
XhcIsochronousTransfer (
  IN     EFI_USB2_HC_PROTOCOL                *This,
  IN     UINT8                               DeviceAddress,
  IN     UINT8                               EndPointAddress,
  IN     UINT8                               DeviceSpeed,
  IN     UINTN                               MaximumPacketLength,
  IN     UINT8                               DataBuffersNumber,
  IN OUT VOID                                *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
  IN     UINTN                               DataLength,
  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
  OUT    UINT32                              *TransferResult
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Submits Async isochronous transfer to a target USB device.

  @param  This                 This EFI_USB2_HC_PROTOCOL instance.
  @param  DeviceAddress        Target device address.
  @param  EndPointAddress      End point address with its direction.
  @param  DeviceSpeed          Device speed, Low speed device doesn't support this
                               type.
  @param  MaximumPacketLength  Maximum packet size that the endpoint is capable of
                               sending or receiving.
  @param  DataBuffersNumber    Number of data buffers prepared for the transfer.
  @param  Data                 Array of pointers to the buffers of data that will
                               be transmitted to USB device or received from USB
                               device.
  @param  DataLength           The size, in bytes, of the data buffer.
  @param  Translator           Transaction translator to use.
  @param  IsochronousCallBack  Function to be called when the transfer complete.
  @param  Context              Context passed to the call back function as
                               parameter.

  @return EFI_UNSUPPORTED      Isochronous transfer isn't supported.

**/
EFI_STATUS
EFIAPI
XhcAsyncIsochronousTransfer (
  IN     EFI_USB2_HC_PROTOCOL                *This,
  IN     UINT8                               DeviceAddress,
  IN     UINT8                               EndPointAddress,
  IN     UINT8                               DeviceSpeed,
  IN     UINTN                               MaximumPacketLength,
  IN     UINT8                               DataBuffersNumber,
  IN OUT VOID                                *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
  IN     UINTN                               DataLength,
  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK     IsochronousCallBack,
  IN     VOID                                *Context
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Entry point for EFI drivers.

  @param  ImageHandle       EFI_HANDLE.
  @param  SystemTable       EFI_SYSTEM_TABLE.

  @retval EFI_SUCCESS       Success.
  @retval Others            Fail.

**/
EFI_STATUS
EFIAPI
XhcDriverEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  return EfiLibInstallDriverBindingComponentName2 (
           ImageHandle,
           SystemTable,
           &gXhciDriverBinding,
           ImageHandle,
           &gXhciComponentName,
           &gXhciComponentName2
           );
}

/**
  Test to see if this driver supports ControllerHandle. Any
  ControllerHandle that has Usb2HcProtocol installed will
  be supported.

  @param  This                 Protocol instance pointer.
  @param  Controller           Handle of device to test.
  @param  RemainingDevicePath  Not used.

  @return EFI_SUCCESS          This driver supports this device.
  @return EFI_UNSUPPORTED      This driver does not support this device.

**/
EFI_STATUS
EFIAPI
XhcDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS           Status;
  EFI_PCI_IO_PROTOCOL  *PciIo;
  USB_CLASSC           UsbClassCReg;

  //
  // Test whether there is PCI IO Protocol attached on the controller handle.
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  (VOID **)&PciIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );

  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  Status = PciIo->Pci.Read (
                        PciIo,
                        EfiPciIoWidthUint8,
                        PCI_CLASSCODE_OFFSET,
                        sizeof (USB_CLASSC) / sizeof (UINT8),
                        &UsbClassCReg
                        );

  if (EFI_ERROR (Status)) {
    Status = EFI_UNSUPPORTED;
    goto ON_EXIT;
  }

  //
  // Test whether the controller belongs to Xhci type
  //
  if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||
      (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||
      (UsbClassCReg.ProgInterface != PCI_IF_XHCI))
  {
    Status = EFI_UNSUPPORTED;
  }

ON_EXIT:
  gBS->CloseProtocol (
         Controller,
         &gEfiPciIoProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  return Status;
}

/**
  Create and initialize a USB_XHCI_INSTANCE structure.

  @param  PciIo                  The PciIo on this device.
  @param  DevicePath             The device path of host controller.
  @param  OriginalPciAttributes  Original PCI attributes.

  @return The allocated and initialized USB_XHCI_INSTANCE structure if created,
          otherwise NULL.

**/
USB_XHCI_INSTANCE *
XhcCreateUsbHc (
  IN EFI_PCI_IO_PROTOCOL       *PciIo,
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  IN UINT64                    OriginalPciAttributes
  )
{
  USB_XHCI_INSTANCE  *Xhc;
  EFI_STATUS         Status;
  UINT32             PageSize;
  UINT16             ExtCapReg;
  UINT8              ReleaseNumber;

  Xhc = AllocateZeroPool (sizeof (USB_XHCI_INSTANCE));

  if (Xhc == NULL) {
    return NULL;
  }

  //
  // Initialize private data structure
  //
  Xhc->Signature             = XHCI_INSTANCE_SIG;
  Xhc->PciIo                 = PciIo;
  Xhc->DevicePath            = DevicePath;
  Xhc->OriginalPciAttributes = OriginalPciAttributes;
  CopyMem (&Xhc->Usb2Hc, &gXhciUsb2HcTemplate, sizeof (EFI_USB2_HC_PROTOCOL));

  Status = PciIo->Pci.Read (
                        PciIo,
                        EfiPciIoWidthUint8,
                        XHC_PCI_SBRN_OFFSET,
                        1,
                        &ReleaseNumber
                        );

  if (!EFI_ERROR (Status)) {
    Xhc->Usb2Hc.MajorRevision = (ReleaseNumber & 0xF0) >> 4;
    Xhc->Usb2Hc.MinorRevision = (ReleaseNumber & 0x0F);
  }

  InitializeListHead (&Xhc->AsyncIntTransfers);

  //
  // Be caution that the Offset passed to XhcReadCapReg() should be Dword align
  //
  Xhc->CapLength        = XhcReadCapReg8 (Xhc, XHC_CAPLENGTH_OFFSET);
  Xhc->HcSParams1.Dword = XhcReadCapReg (Xhc, XHC_HCSPARAMS1_OFFSET);
  Xhc->HcSParams2.Dword = XhcReadCapReg (Xhc, XHC_HCSPARAMS2_OFFSET);
  Xhc->HcCParams.Dword  = XhcReadCapReg (Xhc, XHC_HCCPARAMS_OFFSET);
  Xhc->DBOff            = XhcReadCapReg (Xhc, XHC_DBOFF_OFFSET);
  Xhc->RTSOff           = XhcReadCapReg (Xhc, XHC_RTSOFF_OFFSET);

  //
  // This PageSize field defines the page size supported by the xHC implementation.
  // This xHC supports a page size of 2^(n+12) if bit n is Set. For example,
  // if bit 0 is Set, the xHC supports 4k byte page sizes.
  //
  PageSize = XhcReadOpReg (Xhc, XHC_PAGESIZE_OFFSET);
  if ((PageSize & (~XHC_PAGESIZE_MASK)) != 0) {
    DEBUG ((DEBUG_ERROR, "XhcCreateUsb3Hc: Reserved bits are not 0 for PageSize\n"));
    goto ON_ERROR;
  }

  PageSize     &= XHC_PAGESIZE_MASK;
  Xhc->PageSize = 1 << (HighBitSet32 (PageSize) + 12);

  ExtCapReg              = (UINT16)(Xhc->HcCParams.Data.ExtCapReg);
  Xhc->ExtCapRegBase     = ExtCapReg << 2;
  Xhc->UsbLegSupOffset   = XhcGetCapabilityAddr (Xhc, XHC_CAP_USB_LEGACY);
  Xhc->DebugCapSupOffset = XhcGetCapabilityAddr (Xhc, XHC_CAP_USB_DEBUG);
  Xhc->Usb2SupOffset     = XhcGetSupportedProtocolCapabilityAddr (Xhc, XHC_SUPPORTED_PROTOCOL_DW0_MAJOR_REVISION_USB2);
  Xhc->Usb3SupOffset     = XhcGetSupportedProtocolCapabilityAddr (Xhc, XHC_SUPPORTED_PROTOCOL_DW0_MAJOR_REVISION_USB3);

  DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: Capability length 0x%x\n", Xhc->CapLength));
  DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: HcSParams1 0x%x\n", Xhc->HcSParams1));
  DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: HcSParams2 0x%x\n", Xhc->HcSParams2));
  DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: HcCParams 0x%x\n", Xhc->HcCParams));
  DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: DBOff 0x%x\n", Xhc->DBOff));
  DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: RTSOff 0x%x\n", Xhc->RTSOff));
  DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: UsbLegSupOffset 0x%x\n", Xhc->UsbLegSupOffset));
  DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: DebugCapSupOffset 0x%x\n", Xhc->DebugCapSupOffset));
  DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: Usb2SupOffset 0x%x\n", Xhc->Usb2SupOffset));
  DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: Usb3SupOffset 0x%x\n", Xhc->Usb3SupOffset));

  //
  // Create AsyncRequest Polling Timer
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  XhcMonitorAsyncRequests,
                  Xhc,
                  &Xhc->PollTimer
                  );

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  return Xhc;

ON_ERROR:
  FreePool (Xhc);
  return NULL;
}

/**
  One notified function to stop the Host Controller when gBS->ExitBootServices() called.

  @param  Event                   Pointer to this event
  @param  Context                 Event handler private data

**/
VOID
EFIAPI
XhcExitBootService (
  EFI_EVENT  Event,
  VOID       *Context
  )

{
  USB_XHCI_INSTANCE    *Xhc;
  EFI_PCI_IO_PROTOCOL  *PciIo;

  Xhc   = (USB_XHCI_INSTANCE *)Context;
  PciIo = Xhc->PciIo;

  //
  // Stop AsyncRequest Polling timer then stop the XHCI driver
  // and uninstall the XHCI protocl.
  //
  gBS->SetTimer (Xhc->PollTimer, TimerCancel, 0);
  XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT);

  if (Xhc->PollTimer != NULL) {
    gBS->CloseEvent (Xhc->PollTimer);
  }

  XhcClearBiosOwnership (Xhc);

  //
  // Restore original PCI attributes
  //
  PciIo->Attributes (
           PciIo,
           EfiPciIoAttributeOperationSet,
           Xhc->OriginalPciAttributes,
           NULL
           );
}

/**
  Starting the Usb XHCI Driver.

  @param  This                 Protocol instance pointer.
  @param  Controller           Handle of device to test.
  @param  RemainingDevicePath  Not used.

  @return EFI_SUCCESS          supports this device.
  @return EFI_UNSUPPORTED      do not support this device.
  @return EFI_DEVICE_ERROR     cannot be started due to device Error.
  @return EFI_OUT_OF_RESOURCES cannot allocate resources.

**/
EFI_STATUS
EFIAPI
XhcDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                Status;
  EFI_PCI_IO_PROTOCOL       *PciIo;
  UINT64                    Supports;
  UINT64                    OriginalPciAttributes;
  BOOLEAN                   PciAttributesSaved;
  USB_XHCI_INSTANCE         *Xhc;
  EFI_DEVICE_PATH_PROTOCOL  *HcDevicePath;

  //
  // Open the PciIo Protocol, then enable the USB host controller
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  (VOID **)&PciIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open Device Path Protocol for on USB host controller
  //
  HcDevicePath = NULL;
  Status       = gBS->OpenProtocol (
                        Controller,
                        &gEfiDevicePathProtocolGuid,
                        (VOID **)&HcDevicePath,
                        This->DriverBindingHandle,
                        Controller,
                        EFI_OPEN_PROTOCOL_GET_PROTOCOL
                        );

  PciAttributesSaved = FALSE;
  //
  // Save original PCI attributes
  //
  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationGet,
                    0,
                    &OriginalPciAttributes
                    );

  if (EFI_ERROR (Status)) {
    goto CLOSE_PCIIO;
  }

  PciAttributesSaved = TRUE;

  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationSupported,
                    0,
                    &Supports
                    );
  if (!EFI_ERROR (Status)) {
    Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
    Status    = PciIo->Attributes (
                         PciIo,
                         EfiPciIoAttributeOperationEnable,
                         Supports,
                         NULL
                         );
  }

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "XhcDriverBindingStart: failed to enable controller\n"));
    goto CLOSE_PCIIO;
  }

  //
  // Create then install USB2_HC_PROTOCOL
  //
  Xhc = XhcCreateUsbHc (PciIo, HcDevicePath, OriginalPciAttributes);

  if (Xhc == NULL) {
    DEBUG ((DEBUG_ERROR, "XhcDriverBindingStart: failed to create USB2_HC\n"));
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Enable 64-bit DMA support in the PCI layer if this controller
  // supports it.
  //
  if (Xhc->HcCParams.Data.Ac64 != 0) {
    Status = PciIo->Attributes (
                      PciIo,
                      EfiPciIoAttributeOperationEnable,
                      EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE,
                      NULL
                      );
    if (!EFI_ERROR (Status)) {
      Xhc->Support64BitDma = TRUE;
    } else {
      DEBUG ((
        DEBUG_WARN,
        "%a: failed to enable 64-bit DMA on 64-bit capable controller @ %p (%r)\n",
        __func__,
        Controller,
        Status
        ));
    }
  }

  XhcSetBiosOwnership (Xhc);

  XhcResetHC (Xhc, XHC_RESET_TIMEOUT);
  ASSERT (XhcIsHalt (Xhc));

  //
  // After Chip Hardware Reset wait until the Controller Not Ready (CNR) flag
  // in the USBSTS is '0' before writing any xHC Operational or Runtime registers.
  //
  ASSERT (!(XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_CNR)));

  //
  // Initialize the schedule
  //
  XhcInitSched (Xhc);

  //
  // Start the Host Controller
  //
  XhcRunHC (Xhc, XHC_GENERIC_TIMEOUT);

  //
  // Start the asynchronous interrupt monitor
  //
  Status = gBS->SetTimer (Xhc->PollTimer, TimerPeriodic, XHC_ASYNC_TIMER_INTERVAL);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "XhcDriverBindingStart: failed to start async interrupt monitor\n"));
    XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT);
    goto FREE_POOL;
  }

  //
  // Create event to stop the HC when exit boot service.
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  XhcExitBootService,
                  Xhc,
                  &gEfiEventExitBootServicesGuid,
                  &Xhc->ExitBootServiceEvent
                  );
  if (EFI_ERROR (Status)) {
    goto FREE_POOL;
  }

  //
  // Install the component name protocol, don't fail the start
  // because of something for display.
  //
  AddUnicodeString2 (
    "eng",
    gXhciComponentName.SupportedLanguages,
    &Xhc->ControllerNameTable,
    L"eXtensible Host Controller (USB 3.0)",
    TRUE
    );
  AddUnicodeString2 (
    "en",
    gXhciComponentName2.SupportedLanguages,
    &Xhc->ControllerNameTable,
    L"eXtensible Host Controller (USB 3.0)",
    FALSE
    );

  Status = gBS->InstallProtocolInterface (
                  &Controller,
                  &gEfiUsb2HcProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &Xhc->Usb2Hc
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "XhcDriverBindingStart: failed to install USB2_HC Protocol\n"));
    goto FREE_POOL;
  }

  DEBUG ((DEBUG_INFO, "XhcDriverBindingStart: XHCI started for controller @ %x\n", Controller));
  return EFI_SUCCESS;

FREE_POOL:
  gBS->CloseEvent (Xhc->PollTimer);
  XhcFreeSched (Xhc);
  FreePool (Xhc);

CLOSE_PCIIO:
  if (PciAttributesSaved) {
    //
    // Restore original PCI attributes
    //
    PciIo->Attributes (
             PciIo,
             EfiPciIoAttributeOperationSet,
             OriginalPciAttributes,
             NULL
             );
  }

  gBS->CloseProtocol (
         Controller,
         &gEfiPciIoProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  return Status;
}

/**
  Stop this driver on ControllerHandle. Support stopping any child handles
  created by this driver.

  @param  This                 Protocol instance pointer.
  @param  Controller           Handle of device to stop driver on.
  @param  NumberOfChildren     Number of Children in the ChildHandleBuffer.
  @param  ChildHandleBuffer    List of handles for the children we need to stop.

  @return EFI_SUCCESS          Success.
  @return EFI_DEVICE_ERROR     Fail.

**/
EFI_STATUS
EFIAPI
XhcDriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN UINTN                        NumberOfChildren,
  IN EFI_HANDLE                   *ChildHandleBuffer
  )
{
  EFI_STATUS            Status;
  EFI_USB2_HC_PROTOCOL  *Usb2Hc;
  EFI_PCI_IO_PROTOCOL   *PciIo;
  USB_XHCI_INSTANCE     *Xhc;
  UINT8                 Index;

  //
  // Test whether the Controller handler passed in is a valid
  // Usb controller handle that should be supported, if not,
  // return the error status directly
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiUsb2HcProtocolGuid,
                  (VOID **)&Usb2Hc,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->UninstallProtocolInterface (
                  Controller,
                  &gEfiUsb2HcProtocolGuid,
                  Usb2Hc
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Xhc   = XHC_FROM_THIS (Usb2Hc);
  PciIo = Xhc->PciIo;

  //
  // Stop AsyncRequest Polling timer then stop the XHCI driver
  // and uninstall the XHCI protocl.
  //
  gBS->SetTimer (Xhc->PollTimer, TimerCancel, 0);

  //
  // Disable the device slots occupied by these devices on its downstream ports.
  // Entry 0 is reserved.
  //
  for (Index = 0; Index < 255; Index++) {
    if (!Xhc->UsbDevContext[Index + 1].Enabled ||
        (Xhc->UsbDevContext[Index + 1].SlotId == 0))
    {
      continue;
    }

    if (Xhc->HcCParams.Data.Csz == 0) {
      XhcDisableSlotCmd (Xhc, Xhc->UsbDevContext[Index + 1].SlotId);
    } else {
      XhcDisableSlotCmd64 (Xhc, Xhc->UsbDevContext[Index + 1].SlotId);
    }
  }

  if (Xhc->PollTimer != NULL) {
    gBS->CloseEvent (Xhc->PollTimer);
  }

  if (Xhc->ExitBootServiceEvent != NULL) {
    gBS->CloseEvent (Xhc->ExitBootServiceEvent);
  }

  XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT);
  XhcClearBiosOwnership (Xhc);
  XhciDelAllAsyncIntTransfers (Xhc);
  XhcFreeSched (Xhc);

  if (Xhc->ControllerNameTable) {
    FreeUnicodeStringTable (Xhc->ControllerNameTable);
  }

  //
  // Restore original PCI attributes
  //
  PciIo->Attributes (
           PciIo,
           EfiPciIoAttributeOperationSet,
           Xhc->OriginalPciAttributes,
           NULL
           );

  gBS->CloseProtocol (
         Controller,
         &gEfiPciIoProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  FreePool (Xhc);

  return EFI_SUCCESS;
}

/**
  Converts a time in nanoseconds to a performance counter tick count.

  @param  Time  The time in nanoseconds to be converted to performance counter ticks.
  @return Time in nanoseconds converted to ticks.
**/
UINT64
XhcConvertTimeToTicks (
  IN UINT64  Time
  )
{
  UINT64  Ticks;
  UINT64  Remainder;
  UINT64  Divisor;
  UINTN   Shift;

  // Cache the return values to avoid repeated calls to GetPerformanceCounterProperties ()
  if (!mXhciPerformanceCounterValuesCached) {
    mXhciPerformanceCounterFrequency = GetPerformanceCounterProperties (
                                         &mXhciPerformanceCounterStartValue,
                                         &mXhciPerformanceCounterEndValue
                                         );

    mXhciPerformanceCounterValuesCached = TRUE;
  }

  // Prevent returning a tick value of 0, unless Time is already 0
  if (0 == mXhciPerformanceCounterFrequency) {
    return Time;
  }

  // Nanoseconds per second
  Divisor = 1000000000;

  //
  //           Frequency
  // Ticks = ------------- x Time
  //         1,000,000,000
  //
  Ticks = MultU64x64 (
            DivU64x64Remainder (
              mXhciPerformanceCounterFrequency,
              Divisor,
              &Remainder
              ),
            Time
            );

  //
  // Ensure (Remainder * Time) will not overflow 64-bit.
  //
  // HighBitSet64 (Remainder) + 1 + HighBitSet64 (Time) + 1 <= 64
  //
  Shift     = MAX (0, HighBitSet64 (Remainder) + HighBitSet64 (Time) - 62);
  Remainder = RShiftU64 (Remainder, (UINTN)Shift);
  Divisor   = RShiftU64 (Divisor, (UINTN)Shift);
  Ticks    += DivU64x64Remainder (MultU64x64 (Remainder, Time), Divisor, NULL);

  return Ticks;
}

/**
  Computes and returns the elapsed ticks since PreviousTick. The
  value of PreviousTick is overwritten with the current performance
  counter value.

  @param  PreviousTick    Pointer to PreviousTick count.
  @return The elapsed ticks since PreviousCount. PreviousCount is
          overwritten with the current performance counter value.
**/
UINT64
XhcGetElapsedTicks (
  IN OUT UINT64  *PreviousTick
  )
{
  UINT64  CurrentTick;
  UINT64  Delta;

  CurrentTick = GetPerformanceCounter ();

  //
  // Determine if the counter is counting up or down
  //
  if (mXhciPerformanceCounterStartValue < mXhciPerformanceCounterEndValue) {
    //
    // Counter counts upwards, check for an overflow condition
    //
    if (*PreviousTick > CurrentTick) {
      Delta = (mXhciPerformanceCounterEndValue - *PreviousTick) + CurrentTick;
    } else {
      Delta = CurrentTick - *PreviousTick;
    }
  } else {
    //
    // Counter counts downwards, check for an underflow condition
    //
    if (*PreviousTick < CurrentTick) {
      Delta = (mXhciPerformanceCounterStartValue - CurrentTick) + *PreviousTick;
    } else {
      Delta = *PreviousTick - CurrentTick;
    }
  }

  //
  // Set PreviousTick to CurrentTick
  //
  *PreviousTick = CurrentTick;

  return Delta;
}
