/** @file

  The UHCI driver model and HC protocol routines.

Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Uhci.h"

EFI_DRIVER_BINDING_PROTOCOL  gUhciDriverBinding = {
  UhciDriverBindingSupported,
  UhciDriverBindingStart,
  UhciDriverBindingStop,
  0x20,
  NULL,
  NULL
};

/**
  Provides software reset for the USB host controller according to UEFI 2.0 spec.

  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL instance.
  @param  Attributes             A bit mask of the reset operation to perform.  See
                                 below for a list of the supported bit mask values.

  @return EFI_SUCCESS            The reset operation succeeded.
  @return EFI_INVALID_PARAMETER  Attributes is not valid.
  @return EFI_UNSUPPORTED        This type of reset is not currently supported.
  @return EFI_DEVICE_ERROR       Other errors.

**/
EFI_STATUS
EFIAPI
Uhci2Reset (
  IN EFI_USB2_HC_PROTOCOL  *This,
  IN UINT16                Attributes
  )
{
  USB_HC_DEV  *Uhc;
  EFI_TPL     OldTpl;

  if ((Attributes == EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG) ||
      (Attributes == EFI_USB_HC_RESET_HOST_WITH_DEBUG))
  {
    return EFI_UNSUPPORTED;
  }

  Uhc = UHC_FROM_USB2_HC_PROTO (This);

  if (Uhc->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),
      Uhc->DevicePath
      );
  }

  OldTpl = gBS->RaiseTPL (UHCI_TPL);

  switch (Attributes) {
    case EFI_USB_HC_RESET_GLOBAL:
      //
      // Stop schedule and set the Global Reset bit in the command register
      //
      UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);
      UhciSetRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_GRESET);

      gBS->Stall (UHC_ROOT_PORT_RESET_STALL);

      //
      // Clear the Global Reset bit to zero.
      //
      UhciClearRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_GRESET);

      gBS->Stall (UHC_ROOT_PORT_RECOVERY_STALL);
      break;

    case EFI_USB_HC_RESET_HOST_CONTROLLER:
      //
      // Stop schedule and set Host Controller Reset bit to 1
      //
      UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);
      UhciSetRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_HCRESET);

      gBS->Stall (UHC_ROOT_PORT_RECOVERY_STALL);
      break;

    default:
      goto ON_INVAILD_PARAMETER;
  }

  //
  // Delete all old transactions on the USB bus, then
  // reinitialize the frame list
  //
  UhciFreeAllAsyncReq (Uhc);
  UhciDestoryFrameList (Uhc);
  UhciInitFrameList (Uhc);

  gBS->RestoreTPL (OldTpl);

  return EFI_SUCCESS;

ON_INVAILD_PARAMETER:

  gBS->RestoreTPL (OldTpl);

  return EFI_INVALID_PARAMETER;
}

/**
  Retrieves current state of the USB host controller according to UEFI 2.0 spec.

  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL instance.
  @param  State                  Variable to receive current device state.

  @return EFI_SUCCESS            The state is returned.
  @return EFI_INVALID_PARAMETER  State is not valid.
  @return EFI_DEVICE_ERROR       Other errors.

**/
EFI_STATUS
EFIAPI
Uhci2GetState (
  IN   EFI_USB2_HC_PROTOCOL  *This,
  OUT  EFI_USB_HC_STATE      *State
  )
{
  USB_HC_DEV  *Uhc;
  UINT16      UsbSts;
  UINT16      UsbCmd;

  if (State == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Uhc = UHC_FROM_USB2_HC_PROTO (This);

  UsbCmd = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET);
  UsbSts = UhciReadReg (Uhc->PciIo, USBSTS_OFFSET);

  if ((UsbCmd & USBCMD_EGSM) != 0 ) {
    *State = EfiUsbHcStateSuspend;
  } else if ((UsbSts & USBSTS_HCH) != 0) {
    *State = EfiUsbHcStateHalt;
  } else {
    *State = EfiUsbHcStateOperational;
  }

  return EFI_SUCCESS;
}

/**
  Sets the USB host controller to a specific state according to UEFI 2.0 spec.

  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL instance.
  @param  State                  Indicates the state of the host controller that will
                                 be set.

  @return EFI_SUCCESS            Host controller was successfully placed in the state.
  @return EFI_INVALID_PARAMETER  State is invalid.
  @return EFI_DEVICE_ERROR       Failed to set the state.

**/
EFI_STATUS
EFIAPI
Uhci2SetState (
  IN EFI_USB2_HC_PROTOCOL  *This,
  IN EFI_USB_HC_STATE      State
  )
{
  EFI_USB_HC_STATE  CurState;
  USB_HC_DEV        *Uhc;
  EFI_TPL           OldTpl;
  EFI_STATUS        Status;
  UINT16            UsbCmd;

  Uhc    = UHC_FROM_USB2_HC_PROTO (This);
  Status = Uhci2GetState (This, &CurState);

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  if (CurState == State) {
    return EFI_SUCCESS;
  }

  Status = EFI_SUCCESS;
  OldTpl = gBS->RaiseTPL (UHCI_TPL);

  switch (State) {
    case EfiUsbHcStateHalt:
      Status = UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);
      break;

    case EfiUsbHcStateOperational:
      UsbCmd = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET);

      if (CurState == EfiUsbHcStateHalt) {
        //
        // Set Run/Stop bit to 1, also set the bandwidht reclamation
        // point to 64 bytes
        //
        UsbCmd |= USBCMD_RS | USBCMD_MAXP;
        UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, UsbCmd);
      } else if (CurState == EfiUsbHcStateSuspend) {
        //
        // If FGR(Force Global Resume) bit is 0, set it
        //
        if ((UsbCmd & USBCMD_FGR) == 0) {
          UsbCmd |= USBCMD_FGR;
          UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, UsbCmd);
        }

        //
        // wait 20ms to let resume complete (20ms is specified by UHCI spec)
        //
        gBS->Stall (UHC_FORCE_GLOBAL_RESUME_STALL);

        //
        // Write FGR bit to 0 and EGSM(Enter Global Suspend Mode) bit to 0
        //
        UsbCmd &= ~USBCMD_FGR;
        UsbCmd &= ~USBCMD_EGSM;
        UsbCmd |= USBCMD_RS;
        UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, UsbCmd);
      }

      break;

    case EfiUsbHcStateSuspend:
      Status = Uhci2SetState (This, EfiUsbHcStateHalt);

      if (EFI_ERROR (Status)) {
        Status = EFI_DEVICE_ERROR;
        goto ON_EXIT;
      }

      //
      // Set Enter Global Suspend Mode bit to 1.
      //
      UsbCmd  = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET);
      UsbCmd |= USBCMD_EGSM;
      UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, UsbCmd);
      break;

    default:
      Status = EFI_INVALID_PARAMETER;
      break;
  }

ON_EXIT:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Retrieves capabilities of USB host controller according to UEFI 2.0 spec.

  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL instance.
  @param  MaxSpeed               A pointer to the max speed USB host controller
                                 supports.
  @param  PortNumber             A pointer to the number of root hub ports.
  @param  Is64BitCapable         A pointer to an integer to show whether USB host
                                 controller supports 64-bit memory addressing.

  @return EFI_SUCCESS            capabilities were retrieved successfully.
  @return EFI_INVALID_PARAMETER  MaxSpeed or PortNumber or Is64BitCapable is NULL.
  @return EFI_DEVICE_ERROR       An error was encountered.

**/
EFI_STATUS
EFIAPI
Uhci2GetCapability (
  IN  EFI_USB2_HC_PROTOCOL  *This,
  OUT UINT8                 *MaxSpeed,
  OUT UINT8                 *PortNumber,
  OUT UINT8                 *Is64BitCapable
  )
{
  USB_HC_DEV  *Uhc;
  UINT32      Offset;
  UINT16      PortSC;
  UINT32      Index;

  Uhc = UHC_FROM_USB2_HC_PROTO (This);

  if ((NULL == MaxSpeed) || (NULL == PortNumber) || (NULL == Is64BitCapable)) {
    return EFI_INVALID_PARAMETER;
  }

  *MaxSpeed       = EFI_USB_SPEED_FULL;
  *Is64BitCapable = (UINT8)FALSE;

  *PortNumber = 0;

  for (Index = 0; Index < USB_MAX_ROOTHUB_PORT; Index++) {
    Offset = USBPORTSC_OFFSET + Index * 2;
    PortSC = UhciReadReg (Uhc->PciIo, Offset);

    //
    // Port status's bit 7 is reserved and always returns 1 if
    // the port number is valid. Intel's UHCI (in EHCI controller)
    // returns 0 in this bit if port number is invalid. Also, if
    // PciIo IoRead returns error, 0xFFFF is returned to caller.
    //
    if (((PortSC & 0x80) == 0) || (PortSC == 0xFFFF)) {
      break;
    }

    (*PortNumber)++;
  }

  Uhc->RootPorts = *PortNumber;

  DEBUG ((DEBUG_INFO, "Uhci2GetCapability: %d ports\n", (UINT32)Uhc->RootPorts));
  return EFI_SUCCESS;
}

/**
  Retrieves the current status of a USB root hub port according to UEFI 2.0 spec.

  @param  This                    A pointer to the EFI_USB2_HC_PROTOCOL.
  @param  PortNumber              The port to get status.
  @param  PortStatus              A pointer to the current port status bits and  port
                                  status change bits.

  @return EFI_SUCCESS             status of the USB root hub port was returned in PortStatus.
  @return EFI_INVALID_PARAMETER   PortNumber is invalid.
  @return EFI_DEVICE_ERROR        Can't read register.

**/
EFI_STATUS
EFIAPI
Uhci2GetRootHubPortStatus (
  IN   EFI_USB2_HC_PROTOCOL  *This,
  IN   UINT8                 PortNumber,
  OUT  EFI_USB_PORT_STATUS   *PortStatus
  )
{
  USB_HC_DEV  *Uhc;
  UINT32      Offset;
  UINT16      PortSC;

  Uhc = UHC_FROM_USB2_HC_PROTO (This);

  if (PortStatus == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (PortNumber >= Uhc->RootPorts) {
    return EFI_INVALID_PARAMETER;
  }

  Offset                       = USBPORTSC_OFFSET + PortNumber * 2;
  PortStatus->PortStatus       = 0;
  PortStatus->PortChangeStatus = 0;

  PortSC = UhciReadReg (Uhc->PciIo, Offset);

  if ((PortSC & USBPORTSC_CCS) != 0) {
    PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;
  }

  if ((PortSC & USBPORTSC_PED) != 0) {
    PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;
  }

  if ((PortSC & USBPORTSC_SUSP) != 0) {
    DEBUG ((DEBUG_INFO, "Uhci2GetRootHubPortStatus: port %d is suspended\n", PortNumber));
    PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;
  }

  if ((PortSC & USBPORTSC_PR) != 0) {
    PortStatus->PortStatus |= USB_PORT_STAT_RESET;
  }

  if ((PortSC & USBPORTSC_LSDA) != 0) {
    PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;
  }

  //
  // CHC will always return one in port owner bit
  //
  PortStatus->PortStatus |= USB_PORT_STAT_OWNER;

  if ((PortSC & USBPORTSC_CSC) != 0) {
    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;
  }

  if ((PortSC & USBPORTSC_PEDC) != 0) {
    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;
  }

  return EFI_SUCCESS;
}

/**
  Sets a feature for the specified root hub port according to UEFI 2.0 spec.

  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL.
  @param  PortNumber             Specifies the root hub port whose feature  is
                                 requested to be set.
  @param  PortFeature            Indicates the feature selector associated  with the
                                 feature set request.

  @return EFI_SUCCESS            PortFeature was set for the root port.
  @return EFI_INVALID_PARAMETER  PortNumber is invalid or PortFeature is invalid.
  @return EFI_DEVICE_ERROR       Can't read register.

**/
EFI_STATUS
EFIAPI
Uhci2SetRootHubPortFeature (
  IN EFI_USB2_HC_PROTOCOL  *This,
  IN UINT8                 PortNumber,
  IN EFI_USB_PORT_FEATURE  PortFeature
  )
{
  USB_HC_DEV  *Uhc;
  EFI_TPL     OldTpl;
  UINT32      Offset;
  UINT16      PortSC;
  UINT16      Command;

  Uhc = UHC_FROM_USB2_HC_PROTO (This);

  if (PortNumber >= Uhc->RootPorts) {
    return EFI_INVALID_PARAMETER;
  }

  Offset = USBPORTSC_OFFSET + PortNumber * 2;

  OldTpl = gBS->RaiseTPL (UHCI_TPL);
  PortSC = UhciReadReg (Uhc->PciIo, Offset);

  switch (PortFeature) {
    case EfiUsbPortSuspend:
      Command = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET);
      if ((Command & USBCMD_EGSM) == 0) {
        //
        // if global suspend is not active, can set port suspend
        //
        PortSC &= 0xfff5;
        PortSC |= USBPORTSC_SUSP;
      }

      break;

    case EfiUsbPortReset:
      PortSC &= 0xfff5;
      PortSC |= USBPORTSC_PR;
      break;

    case EfiUsbPortPower:
      //
      // No action
      //
      break;

    case EfiUsbPortEnable:
      PortSC &= 0xfff5;
      PortSC |= USBPORTSC_PED;
      break;

    default:
      gBS->RestoreTPL (OldTpl);
      return EFI_INVALID_PARAMETER;
  }

  UhciWriteReg (Uhc->PciIo, Offset, PortSC);
  gBS->RestoreTPL (OldTpl);

  return EFI_SUCCESS;
}

/**
  Clears a feature for the specified root hub port according to Uefi 2.0 spec.

  @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.

  @return EFI_SUCCESS            PortFeature was cleared for the USB root hub port.
  @return EFI_INVALID_PARAMETER  PortNumber is invalid or PortFeature is invalid.
  @return EFI_DEVICE_ERROR       Can't read register.

**/
EFI_STATUS
EFIAPI
Uhci2ClearRootHubPortFeature (
  IN EFI_USB2_HC_PROTOCOL  *This,
  IN UINT8                 PortNumber,
  IN EFI_USB_PORT_FEATURE  PortFeature
  )
{
  USB_HC_DEV  *Uhc;
  EFI_TPL     OldTpl;
  UINT32      Offset;
  UINT16      PortSC;

  Uhc = UHC_FROM_USB2_HC_PROTO (This);

  if (PortNumber >= Uhc->RootPorts) {
    return EFI_INVALID_PARAMETER;
  }

  Offset = USBPORTSC_OFFSET + PortNumber * 2;

  OldTpl = gBS->RaiseTPL (UHCI_TPL);
  PortSC = UhciReadReg (Uhc->PciIo, Offset);

  switch (PortFeature) {
    case EfiUsbPortEnable:
      PortSC &= 0xfff5;
      PortSC &= ~USBPORTSC_PED;
      break;

    case EfiUsbPortSuspend:
      //
      // Cause a resume on the specified port if in suspend mode.
      //
      PortSC &= 0xfff5;
      PortSC &= ~USBPORTSC_SUSP;
      break;

    case EfiUsbPortPower:
      //
      // No action
      //
      break;

    case EfiUsbPortReset:
      PortSC &= 0xfff5;
      PortSC &= ~USBPORTSC_PR;
      break;

    case EfiUsbPortConnectChange:
      PortSC &= 0xfff5;
      PortSC |= USBPORTSC_CSC;
      break;

    case EfiUsbPortEnableChange:
      PortSC &= 0xfff5;
      PortSC |= USBPORTSC_PEDC;
      break;

    case EfiUsbPortSuspendChange:
      //
      // Root hub does not support this
      //
      break;

    case EfiUsbPortOverCurrentChange:
      //
      // Root hub does not support this
      //
      break;

    case EfiUsbPortResetChange:
      //
      // Root hub does not support this
      //
      break;

    default:
      gBS->RestoreTPL (OldTpl);
      return EFI_INVALID_PARAMETER;
  }

  UhciWriteReg (Uhc->PciIo, Offset, PortSC);
  gBS->RestoreTPL (OldTpl);

  return EFI_SUCCESS;
}

/**
  Submits control transfer to a target USB device according to UEFI 2.0 spec.

  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL instance.
  @param  DeviceAddress          Target device address.
  @param  DeviceSpeed            Device speed.
  @param  MaximumPacketLength    Maximum packet size of the target endpoint.
  @param  Request                USB device request to send.
  @param  TransferDirection      Data direction of the Data stage in control transfer.
  @param  Data                   Data to transmit/receive in data stage.
  @param  DataLength             Length of the data.
  @param  TimeOut                Maximum time, in microseconds, for transfer to complete.
  @param  Translator             Transaction translator to be used by this device.
  @param  TransferResult         Variable to receive the transfer result.

  @return EFI_SUCCESS            The control transfer was completed successfully.
  @return EFI_OUT_OF_RESOURCES   Failed due to lack of resource.
  @return EFI_INVALID_PARAMETER  Some parameters are invalid.
  @return EFI_TIMEOUT            Failed due to timeout.
  @return EFI_DEVICE_ERROR       Failed due to host controller or device error.

**/
EFI_STATUS
EFIAPI
Uhci2ControlTransfer (
  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_HC_DEV      *Uhc;
  UHCI_TD_SW      *TDs;
  EFI_TPL         OldTpl;
  EFI_STATUS      Status;
  UHCI_QH_RESULT  QhResult;
  UINT8           PktId;
  UINT8           *RequestPhy;
  VOID            *RequestMap;
  UINT8           *DataPhy;
  VOID            *DataMap;
  BOOLEAN         IsSlowDevice;
  UINTN           TransferDataLength;

  Uhc        = UHC_FROM_USB2_HC_PROTO (This);
  TDs        = NULL;
  DataPhy    = NULL;
  DataMap    = NULL;
  RequestPhy = NULL;
  RequestMap = NULL;

  IsSlowDevice = (BOOLEAN)((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);

  //
  // Parameters Checking
  //
  if ((Request == NULL) || (TransferResult == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (IsSlowDevice && (MaximumPacketLength != 8)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((MaximumPacketLength != 8) &&  (MaximumPacketLength != 16) &&
      (MaximumPacketLength != 32) && (MaximumPacketLength != 64))
  {
    return EFI_INVALID_PARAMETER;
  }

  if ((TransferDirection != EfiUsbNoData) && ((Data == NULL) || (DataLength == NULL))) {
    return EFI_INVALID_PARAMETER;
  }

  if (TransferDirection == EfiUsbNoData) {
    TransferDataLength = 0;
  } else {
    TransferDataLength = *DataLength;
  }

  *TransferResult = EFI_USB_ERR_SYSTEM;
  Status          = EFI_DEVICE_ERROR;

  //
  // If errors exist that cause host controller halt,
  // clear status then return EFI_DEVICE_ERROR.
  //
  UhciAckAllInterrupt (Uhc);

  if (!UhciIsHcWorking (Uhc->PciIo)) {
    return EFI_DEVICE_ERROR;
  }

  OldTpl = gBS->RaiseTPL (UHCI_TPL);

  //
  // Map the Request and data for bus master access,
  // then create a list of TD for this transfer
  //
  Status = UhciMapUserRequest (Uhc, Request, &RequestPhy, &RequestMap);

  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  Status = UhciMapUserData (Uhc, TransferDirection, Data, DataLength, &PktId, &DataPhy, &DataMap);

  if (EFI_ERROR (Status)) {
    Uhc->PciIo->Unmap (Uhc->PciIo, RequestMap);
    goto ON_EXIT;
  }

  TDs = UhciCreateCtrlTds (
          Uhc,
          DeviceAddress,
          PktId,
          (UINT8 *)Request,
          RequestPhy,
          (UINT8 *)Data,
          DataPhy,
          TransferDataLength,
          (UINT8)MaximumPacketLength,
          IsSlowDevice
          );

  if (TDs == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto UNMAP_DATA;
  }

  //
  // According to the speed of the end point, link
  // the TD to corrosponding queue head, then check
  // the execution result
  //
  UhciLinkTdToQh (Uhc, Uhc->CtrlQh, TDs);
  Status = UhciExecuteTransfer (Uhc, Uhc->CtrlQh, TDs, TimeOut, IsSlowDevice, &QhResult);
  UhciUnlinkTdFromQh (Uhc->CtrlQh, TDs);

  Uhc->PciIo->Flush (Uhc->PciIo);

  if (!EFI_ERROR (Status)) {
    *TransferResult = QhResult.Result;

    if (DataLength != NULL) {
      *DataLength = QhResult.Complete;
    }
  }

  UhciDestoryTds (Uhc, TDs);

UNMAP_DATA:
  Uhc->PciIo->Unmap (Uhc->PciIo, DataMap);
  Uhc->PciIo->Unmap (Uhc->PciIo, RequestMap);

ON_EXIT:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Submits bulk transfer to a bulk endpoint of a USB device.

  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL instance.
  @param  DeviceAddress          Target device address.
  @param  EndPointAddress        Endpoint number and direction.
  @param  DeviceSpeed            Device speed.
  @param  MaximumPacketLength    Maximum packet size of the target endpoint.
  @param  DataBuffersNumber      Number of data buffers prepared for the transfer.
  @param  Data                   Array of pointers to the buffers of data.
  @param  DataLength             On input, size of the data buffer, On output,
                                 actually transferred data size.
  @param  DataToggle             On input, data toggle to use; On output, next data toggle.
  @param  TimeOut                Maximum time out, in microseconds.
  @param  Translator             A pointr to the transaction translator data.
  @param  TransferResult         Variable to receive transfer result.

  @return EFI_SUCCESS            The bulk transfer was completed successfully.
  @return EFI_OUT_OF_RESOURCES   Failed due to lack of resource.
  @return EFI_INVALID_PARAMETER  Some parameters are invalid.
  @return EFI_TIMEOUT            Failed due to timeout.
  @return EFI_DEVICE_ERROR       Failed due to host controller or device error.

**/
EFI_STATUS
EFIAPI
Uhci2BulkTransfer (
  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
  )
{
  EFI_USB_DATA_DIRECTION  Direction;
  EFI_TPL                 OldTpl;
  USB_HC_DEV              *Uhc;
  UHCI_TD_SW              *TDs;
  UHCI_QH_SW              *BulkQh;
  UHCI_QH_RESULT          QhResult;
  EFI_STATUS              Status;
  UINT8                   PktId;
  UINT8                   *DataPhy;
  VOID                    *DataMap;

  Uhc     = UHC_FROM_USB2_HC_PROTO (This);
  DataPhy = NULL;
  DataMap = NULL;

  if (DeviceSpeed == EFI_USB_SPEED_LOW) {
    return EFI_INVALID_PARAMETER;
  }

  if ((DataLength == NULL) || (*DataLength == 0) || (Data == NULL) || (TransferResult == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((*DataToggle != 1) && (*DataToggle != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((MaximumPacketLength != 8) && (MaximumPacketLength != 16) &&
      (MaximumPacketLength != 32) && (MaximumPacketLength != 64))
  {
    return EFI_INVALID_PARAMETER;
  }

  *TransferResult = EFI_USB_ERR_SYSTEM;
  Status          = EFI_OUT_OF_RESOURCES;

  //
  // If has errors that cause host controller halt,
  // then return EFI_DEVICE_ERROR directly.
  //
  UhciAckAllInterrupt (Uhc);

  if (!UhciIsHcWorking (Uhc->PciIo)) {
    return EFI_DEVICE_ERROR;
  }

  OldTpl = gBS->RaiseTPL (UHCI_TPL);

  //
  // Map the source data buffer for bus master access,
  // then create a list of TDs
  //
  if ((EndPointAddress & 0x80) != 0) {
    Direction = EfiUsbDataIn;
  } else {
    Direction = EfiUsbDataOut;
  }

  Status = UhciMapUserData (Uhc, Direction, *Data, DataLength, &PktId, &DataPhy, &DataMap);

  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  Status = EFI_OUT_OF_RESOURCES;
  TDs    = UhciCreateBulkOrIntTds (
             Uhc,
             DeviceAddress,
             EndPointAddress,
             PktId,
             (UINT8 *)*Data,
             DataPhy,
             *DataLength,
             DataToggle,
             (UINT8)MaximumPacketLength,
             FALSE
             );

  if (TDs == NULL) {
    Uhc->PciIo->Unmap (Uhc->PciIo, DataMap);
    goto ON_EXIT;
  }

  //
  // Link the TDs to bulk queue head. According to the platfore
  // defintion of UHCI_NO_BW_RECLAMATION, BulkQh is either configured
  // to do full speed bandwidth reclamation or not.
  //
  BulkQh = Uhc->BulkQh;

  UhciLinkTdToQh (Uhc, BulkQh, TDs);
  Status = UhciExecuteTransfer (Uhc, BulkQh, TDs, TimeOut, FALSE, &QhResult);
  UhciUnlinkTdFromQh (BulkQh, TDs);

  Uhc->PciIo->Flush (Uhc->PciIo);

  if (!EFI_ERROR (Status)) {
    *TransferResult = QhResult.Result;
    *DataToggle     = QhResult.NextToggle;
    *DataLength     = QhResult.Complete;
  }

  UhciDestoryTds (Uhc, TDs);
  Uhc->PciIo->Unmap (Uhc->PciIo, DataMap);

ON_EXIT:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Submits an asynchronous interrupt transfer to an
  interrupt endpoint of a USB device according to UEFI 2.0 spec.

  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL instance.
  @param  DeviceAddress          Target device address.
  @param  EndPointAddress        Endpoint number and direction.
  @param  DeviceSpeed            Device speed.
  @param  MaximumPacketLength    Maximum packet size of the target endpoint.
  @param  IsNewTransfer          If TRUE, submit a new transfer, if FALSE cancel old transfer.
  @param  DataToggle             On input, data toggle to use; On output, next data toggle.
  @param  PollingInterval        Interrupt poll rate in milliseconds.
  @param  DataLength             On input, size of the data buffer, On output,
                                 actually transferred data size.
  @param  Translator             A pointr to the transaction translator data.
  @param  CallBackFunction       Function to call periodically.
  @param  Context                User context.

  @return EFI_SUCCESS            Transfer was submitted.
  @return EFI_INVALID_PARAMETER  Some parameters are invalid.
  @return EFI_OUT_OF_RESOURCES   Failed due to a lack of resources.
  @return EFI_DEVICE_ERROR       Can't read register.

**/
EFI_STATUS
EFIAPI
Uhci2AsyncInterruptTransfer (
  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
  )
{
  USB_HC_DEV  *Uhc;
  BOOLEAN     IsSlowDevice;
  UHCI_QH_SW  *Qh;
  UHCI_TD_SW  *IntTds;
  EFI_TPL     OldTpl;
  EFI_STATUS  Status;
  UINT8       *DataPtr;
  UINT8       *DataPhy;
  UINT8       PktId;

  Uhc     = UHC_FROM_USB2_HC_PROTO (This);
  Qh      = NULL;
  IntTds  = NULL;
  DataPtr = NULL;
  DataPhy = NULL;

  IsSlowDevice = (BOOLEAN)((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);

  if ((EndPointAddress & 0x80) == 0) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Delete Async interrupt transfer request
  //
  if (!IsNewTransfer) {
    OldTpl = gBS->RaiseTPL (UHCI_TPL);
    Status = UhciRemoveAsyncReq (Uhc, DeviceAddress, EndPointAddress, DataToggle);

    gBS->RestoreTPL (OldTpl);
    return Status;
  }

  if ((PollingInterval < 1) || (PollingInterval > 255)) {
    return EFI_INVALID_PARAMETER;
  }

  if (DataLength == 0) {
    return EFI_INVALID_PARAMETER;
  }

  if ((*DataToggle != 1) && (*DataToggle != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // If has errors that cause host controller halt,
  // then return EFI_DEVICE_ERROR directly.
  //
  UhciAckAllInterrupt (Uhc);

  if (!UhciIsHcWorking (Uhc->PciIo)) {
    return EFI_DEVICE_ERROR;
  }

  if ((EndPointAddress & 0x80) == 0) {
    PktId = OUTPUT_PACKET_ID;
  } else {
    PktId = INPUT_PACKET_ID;
  }

  //
  // Allocate and map source data buffer for bus master access.
  //
  DataPtr = UsbHcAllocateMem (Uhc->MemPool, DataLength);

  if (DataPtr == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  DataPhy = (UINT8 *)(UINTN)UsbHcGetPciAddressForHostMem (Uhc->MemPool, DataPtr, DataLength);

  OldTpl = gBS->RaiseTPL (UHCI_TPL);

  Qh = UhciCreateQh (Uhc, PollingInterval);

  if (Qh == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto FREE_DATA;
  }

  IntTds = UhciCreateBulkOrIntTds (
             Uhc,
             DeviceAddress,
             EndPointAddress,
             PktId,
             DataPtr,
             DataPhy,
             DataLength,
             DataToggle,
             (UINT8)MaximumPacketLength,
             IsSlowDevice
             );

  if (IntTds == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto DESTORY_QH;
  }

  UhciLinkTdToQh (Uhc, Qh, IntTds);

  //
  // Save QH-TD structures to async Interrupt transfer list,
  // for monitor interrupt transfer execution routine use.
  //
  Status = UhciCreateAsyncReq (
             Uhc,
             Qh,
             IntTds,
             DeviceAddress,
             EndPointAddress,
             DataLength,
             PollingInterval,
             DataPtr,
             CallBackFunction,
             Context,
             IsSlowDevice
             );

  if (EFI_ERROR (Status)) {
    goto DESTORY_QH;
  }

  UhciLinkQhToFrameList (Uhc, Qh);

  gBS->RestoreTPL (OldTpl);
  return EFI_SUCCESS;

DESTORY_QH:
  UsbHcFreeMem (Uhc->MemPool, Qh, sizeof (UHCI_QH_SW));

FREE_DATA:
  UsbHcFreeMem (Uhc->MemPool, DataPtr, DataLength);
  Uhc->PciIo->Flush (Uhc->PciIo);

  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Submits synchronous interrupt transfer to an interrupt endpoint
  of a USB device according to UEFI 2.0 spec.


  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL instance.
  @param  DeviceAddress          Target device address.
  @param  EndPointAddress        Endpoint number and direction.
  @param  DeviceSpeed            Device speed.
  @param  MaximumPacketLength    Maximum packet size of the target endpoint.
  @param  Data                   Array of pointers to the buffers of data.
  @param  DataLength             On input, size of the data buffer, On output,
                                 actually transferred data size.
  @param  DataToggle             On input, data toggle to use; On output, next data toggle.
  @param  TimeOut                Maximum time out, in microseconds.
  @param  Translator             A pointr to the transaction translator data.
  @param  TransferResult         Variable to receive transfer result.

  @return EFI_SUCCESS            The transfer was completed successfully.
  @return EFI_OUT_OF_RESOURCES   Failed due to lack of resource.
  @return EFI_INVALID_PARAMETER  Some parameters are invalid.
  @return EFI_TIMEOUT            Failed due to timeout.
  @return EFI_DEVICE_ERROR       Failed due to host controller or device error.

**/
EFI_STATUS
EFIAPI
Uhci2SyncInterruptTransfer (
  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
  )
{
  EFI_STATUS      Status;
  USB_HC_DEV      *Uhc;
  UHCI_TD_SW      *TDs;
  UHCI_QH_RESULT  QhResult;
  EFI_TPL         OldTpl;
  UINT8           *DataPhy;
  VOID            *DataMap;
  UINT8           PktId;
  BOOLEAN         IsSlowDevice;

  Uhc     = UHC_FROM_USB2_HC_PROTO (This);
  DataPhy = NULL;
  DataMap = NULL;
  TDs     = NULL;

  if (DeviceSpeed == EFI_USB_SPEED_HIGH) {
    return EFI_INVALID_PARAMETER;
  }

  IsSlowDevice = (BOOLEAN)((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);

  if ((DataLength == NULL) || (Data == NULL) || (TransferResult == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((*DataToggle != 1) && (*DataToggle != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((*DataLength == 0) || (MaximumPacketLength > 64)) {
    return EFI_INVALID_PARAMETER;
  }

  if (IsSlowDevice && (MaximumPacketLength > 8)) {
    return EFI_INVALID_PARAMETER;
  }

  *TransferResult = EFI_USB_ERR_SYSTEM;
  Status          = EFI_DEVICE_ERROR;

  UhciAckAllInterrupt (Uhc);

  if (!UhciIsHcWorking (Uhc->PciIo)) {
    return Status;
  }

  OldTpl = gBS->RaiseTPL (UHCI_TPL);

  //
  // Map the source data buffer for bus master access.
  // Create Tds list, then link it to the UHC's interrupt list
  //
  Status = UhciMapUserData (
             Uhc,
             EfiUsbDataIn,
             Data,
             DataLength,
             &PktId,
             &DataPhy,
             &DataMap
             );

  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  TDs = UhciCreateBulkOrIntTds (
          Uhc,
          DeviceAddress,
          EndPointAddress,
          PktId,
          (UINT8 *)Data,
          DataPhy,
          *DataLength,
          DataToggle,
          (UINT8)MaximumPacketLength,
          IsSlowDevice
          );

  if (TDs == NULL) {
    Uhc->PciIo->Unmap (Uhc->PciIo, DataMap);

    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  UhciLinkTdToQh (Uhc, Uhc->SyncIntQh, TDs);

  Status = UhciExecuteTransfer (Uhc, Uhc->SyncIntQh, TDs, TimeOut, IsSlowDevice, &QhResult);

  UhciUnlinkTdFromQh (Uhc->SyncIntQh, TDs);
  Uhc->PciIo->Flush (Uhc->PciIo);

  if (!EFI_ERROR (Status)) {
    *TransferResult = QhResult.Result;
    *DataToggle     = QhResult.NextToggle;
    *DataLength     = QhResult.Complete;
  }

  UhciDestoryTds (Uhc, TDs);
  Uhc->PciIo->Unmap (Uhc->PciIo, DataMap);

ON_EXIT:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Submits isochronous transfer to a target USB device according to UEFI 2.0 spec.

  @param  This                  A pointer to the EFI_USB2_HC_PROTOCOL instance.
  @param  DeviceAddress         Target device address.
  @param  EndPointAddress       Endpoint number and direction.
  @param  DeviceSpeed           Device speed.
  @param  MaximumPacketLength   Maximum packet size of the target endpoint.
  @param  DataBuffersNumber     Number of data buffers prepared for the transfer.
  @param  Data                  Array of pointers to the buffers of data.
  @param  DataLength            On input, size of the data buffer, On output,
                                actually transferred data size.
  @param  Translator            A pointr to the transaction translator data.
  @param  TransferResult        Variable to receive transfer result.

  @return EFI_UNSUPPORTED

**/
EFI_STATUS
EFIAPI
Uhci2IsochronousTransfer (
  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 according to UEFI 2.0 spec.

  @param  This                  A pointer to the EFI_USB2_HC_PROTOCOL instance.
  @param  DeviceAddress         Target device address.
  @param  EndPointAddress       Endpoint number and direction.
  @param  DeviceSpeed           Device speed.
  @param  MaximumPacketLength   Maximum packet size of the target endpoint.
  @param  DataBuffersNumber     Number of data buffers prepared for the transfer.
  @param  Data                  Array of pointers to the buffers of data.
  @param  DataLength            On input, size of the data buffer, On output,
                                actually transferred data size.
  @param  Translator            A pointr to the transaction translator data.
  @param  IsochronousCallBack   Function to call when the transfer complete.
  @param  Context               Pass to the call back function as parameter.

  @return EFI_UNSUPPORTED

**/
EFI_STATUS
EFIAPI
Uhci2AsyncIsochronousTransfer (
  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      Driver is successfully loaded.
  @return Others           Failed.

**/
EFI_STATUS
EFIAPI
UhciDriverEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  return EfiLibInstallDriverBindingComponentName2 (
           ImageHandle,
           SystemTable,
           &gUhciDriverBinding,
           ImageHandle,
           &gUhciComponentName,
           &gUhciComponentName2
           );
}

/**
  Test to see if this driver supports ControllerHandle. Any
  ControllerHandle that has UsbHcProtocol 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
UhciDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS           OpenStatus;
  EFI_STATUS           Status;
  EFI_PCI_IO_PROTOCOL  *PciIo;
  USB_CLASSC           UsbClassCReg;

  //
  // Test whether there is PCI IO Protocol attached on the controller handle.
  //
  OpenStatus = gBS->OpenProtocol (
                      Controller,
                      &gEfiPciIoProtocolGuid,
                      (VOID **)&PciIo,
                      This->DriverBindingHandle,
                      Controller,
                      EFI_OPEN_PROTOCOL_BY_DRIVER
                      );

  if (EFI_ERROR (OpenStatus)) {
    return OpenStatus;
  }

  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 UHCI type
  //
  if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||
      (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||
      (UsbClassCReg.ProgInterface != PCI_IF_UHCI)
      )
  {
    Status = EFI_UNSUPPORTED;
  }

ON_EXIT:
  gBS->CloseProtocol (
         Controller,
         &gEfiPciIoProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  return Status;
}

/**
  Allocate and initialize the empty UHCI device.

  @param  PciIo                  The PCIIO to use.
  @param  DevicePath             The device path of host controller.
  @param  OriginalPciAttributes  The original PCI attributes.

  @return Allocated UHCI device. If err, return NULL.

**/
USB_HC_DEV *
UhciAllocateDev (
  IN EFI_PCI_IO_PROTOCOL       *PciIo,
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  IN UINT64                    OriginalPciAttributes
  )
{
  USB_HC_DEV  *Uhc;
  EFI_STATUS  Status;

  Uhc = AllocateZeroPool (sizeof (USB_HC_DEV));

  if (Uhc == NULL) {
    return NULL;
  }

  //
  // This driver supports both USB_HC_PROTOCOL and USB2_HC_PROTOCOL.
  // USB_HC_PROTOCOL is for EFI 1.1 backward compability.
  //
  Uhc->Signature                       = USB_HC_DEV_SIGNATURE;
  Uhc->Usb2Hc.GetCapability            = Uhci2GetCapability;
  Uhc->Usb2Hc.Reset                    = Uhci2Reset;
  Uhc->Usb2Hc.GetState                 = Uhci2GetState;
  Uhc->Usb2Hc.SetState                 = Uhci2SetState;
  Uhc->Usb2Hc.ControlTransfer          = Uhci2ControlTransfer;
  Uhc->Usb2Hc.BulkTransfer             = Uhci2BulkTransfer;
  Uhc->Usb2Hc.AsyncInterruptTransfer   = Uhci2AsyncInterruptTransfer;
  Uhc->Usb2Hc.SyncInterruptTransfer    = Uhci2SyncInterruptTransfer;
  Uhc->Usb2Hc.IsochronousTransfer      = Uhci2IsochronousTransfer;
  Uhc->Usb2Hc.AsyncIsochronousTransfer = Uhci2AsyncIsochronousTransfer;
  Uhc->Usb2Hc.GetRootHubPortStatus     = Uhci2GetRootHubPortStatus;
  Uhc->Usb2Hc.SetRootHubPortFeature    = Uhci2SetRootHubPortFeature;
  Uhc->Usb2Hc.ClearRootHubPortFeature  = Uhci2ClearRootHubPortFeature;
  Uhc->Usb2Hc.MajorRevision            = 0x1;
  Uhc->Usb2Hc.MinorRevision            = 0x1;

  Uhc->PciIo                 = PciIo;
  Uhc->DevicePath            = DevicePath;
  Uhc->OriginalPciAttributes = OriginalPciAttributes;
  Uhc->MemPool               = UsbHcInitMemPool (PciIo, TRUE, 0);

  if (Uhc->MemPool == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_ERROR;
  }

  InitializeListHead (&Uhc->AsyncIntList);

  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  UhciMonitorAsyncReqList,
                  Uhc,
                  &Uhc->AsyncIntMonitor
                  );

  if (EFI_ERROR (Status)) {
    UsbHcFreeMemPool (Uhc->MemPool);
    goto ON_ERROR;
  }

  return Uhc;

ON_ERROR:
  FreePool (Uhc);
  return NULL;
}

/**
  Free the UHCI device and release its associated resources.

  @param  Uhc     The UHCI device to release.

**/
VOID
UhciFreeDev (
  IN USB_HC_DEV  *Uhc
  )
{
  if (Uhc->AsyncIntMonitor != NULL) {
    gBS->CloseEvent (Uhc->AsyncIntMonitor);
  }

  if (Uhc->ExitBootServiceEvent != NULL) {
    gBS->CloseEvent (Uhc->ExitBootServiceEvent);
  }

  if (Uhc->MemPool != NULL) {
    UsbHcFreeMemPool (Uhc->MemPool);
  }

  if (Uhc->CtrlNameTable != NULL) {
    FreeUnicodeStringTable (Uhc->CtrlNameTable);
  }

  FreePool (Uhc);
}

/**
  Uninstall all Uhci Interface.

  @param  Controller           Controller handle.
  @param  This                 Protocol instance pointer.

**/
VOID
UhciCleanDevUp (
  IN  EFI_HANDLE            Controller,
  IN  EFI_USB2_HC_PROTOCOL  *This
  )
{
  USB_HC_DEV  *Uhc;
  EFI_STATUS  Status;

  //
  // Uninstall the USB_HC and USB_HC2 protocol, then disable the controller
  //
  Uhc = UHC_FROM_USB2_HC_PROTO (This);

  Status = gBS->UninstallProtocolInterface (
                  Controller,
                  &gEfiUsb2HcProtocolGuid,
                  &Uhc->Usb2Hc
                  );
  if (EFI_ERROR (Status)) {
    return;
  }

  UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);
  UhciFreeAllAsyncReq (Uhc);
  UhciDestoryFrameList (Uhc);

  //
  // Restore original PCI attributes
  //
  Uhc->PciIo->Attributes (
                Uhc->PciIo,
                EfiPciIoAttributeOperationSet,
                Uhc->OriginalPciAttributes,
                NULL
                );

  UhciFreeDev (Uhc);
}

/**
  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
UhcExitBootService (
  EFI_EVENT  Event,
  VOID       *Context
  )
{
  USB_HC_DEV  *Uhc;

  Uhc = (USB_HC_DEV *)Context;

  //
  // Stop the Host Controller
  //
  UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);

  //
  // Reset the Host Controller
  //
  UhciSetRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_HCRESET);
  gBS->Stall (UHC_ROOT_PORT_RECOVERY_STALL);
}

/**
  Starting the Usb UHCI Driver.

  @param  This                 Protocol instance pointer.
  @param  Controller           Handle of device to test.
  @param  RemainingDevicePath  Not used.

  @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.
                               EFI_OUT_OF_RESOURCES- Failed due to resource shortage.

**/
EFI_STATUS
EFIAPI
UhciDriverBindingStart (
  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_HC_DEV                *Uhc;
  UINT64                    Supports;
  UINT64                    OriginalPciAttributes;
  BOOLEAN                   PciAttributesSaved;
  EFI_DEVICE_PATH_PROTOCOL  *HcDevicePath;

  //
  // Open PCIIO, then enable the EHC device and turn off emulation
  //
  Uhc    = NULL;
  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;

  //
  // Robustnesss improvement such as for UoL
  // Default is not required.
  //
  if (FeaturePcdGet (PcdTurnOffUsbLegacySupport)) {
    UhciTurnOffUsbEmulation (PciIo);
  }

  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)) {
    goto CLOSE_PCIIO;
  }

  Uhc = UhciAllocateDev (PciIo, HcDevicePath, OriginalPciAttributes);

  if (Uhc == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto CLOSE_PCIIO;
  }

  //
  // Allocate and Init Host Controller's Frame List Entry
  //
  Status = UhciInitFrameList (Uhc);

  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto FREE_UHC;
  }

  Status = gBS->SetTimer (
                  Uhc->AsyncIntMonitor,
                  TimerPeriodic,
                  UHC_ASYNC_POLL_INTERVAL
                  );

  if (EFI_ERROR (Status)) {
    goto FREE_UHC;
  }

  //
  // Install USB2_HC_PROTOCOL
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  &gEfiUsb2HcProtocolGuid,
                  &Uhc->Usb2Hc,
                  NULL
                  );

  if (EFI_ERROR (Status)) {
    goto FREE_UHC;
  }

  //
  // Create event to stop the HC when exit boot service.
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  UhcExitBootService,
                  Uhc,
                  &gEfiEventExitBootServicesGuid,
                  &Uhc->ExitBootServiceEvent
                  );
  if (EFI_ERROR (Status)) {
    goto UNINSTALL_USBHC;
  }

  //
  // Install the component name protocol
  //
  Uhc->CtrlNameTable = NULL;

  AddUnicodeString2 (
    "eng",
    gUhciComponentName.SupportedLanguages,
    &Uhc->CtrlNameTable,
    L"Usb Universal Host Controller",
    TRUE
    );
  AddUnicodeString2 (
    "en",
    gUhciComponentName2.SupportedLanguages,
    &Uhc->CtrlNameTable,
    L"Usb Universal Host Controller",
    FALSE
    );

  //
  // Start the UHCI hardware, also set its reclamation point to 64 bytes
  //
  UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, USBCMD_RS | USBCMD_MAXP);

  return EFI_SUCCESS;

UNINSTALL_USBHC:
  gBS->UninstallMultipleProtocolInterfaces (
         Controller,
         &gEfiUsb2HcProtocolGuid,
         &Uhc->Usb2Hc,
         NULL
         );

FREE_UHC:
  UhciFreeDev (Uhc);

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
  @return others

**/
EFI_STATUS
EFIAPI
UhciDriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN UINTN                        NumberOfChildren,
  IN EFI_HANDLE                   *ChildHandleBuffer
  )
{
  EFI_USB2_HC_PROTOCOL  *Usb2Hc;
  EFI_STATUS            Status;

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiUsb2HcProtocolGuid,
                  (VOID **)&Usb2Hc,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  //
  // Test whether the Controller handler passed in is a valid
  // Usb controller handle that should be supported, if not,
  // return the error status directly
  //
  if (EFI_ERROR (Status)) {
    return Status;
  }

  UhciCleanDevUp (Controller, Usb2Hc);

  gBS->CloseProtocol (
         Controller,
         &gEfiPciIoProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  return EFI_SUCCESS;
}
