/** @file
PEIM to produce gPeiUsbHostControllerPpiGuid based on gPeiUsbControllerPpiGuid
which is used to enable recovery function from USB Drivers.

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved. <BR>

SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "UhcPeim.h"

/**
  Stop the host controller.

  @param  Uhc           The UHCI device.
  @param  Timeout       Max time allowed.

  @retval EFI_SUCCESS   The host controller is stopped.
  @retval EFI_TIMEOUT   Failed to stop the host controller.

**/
EFI_STATUS
UhciStopHc (
  IN USB_UHC_DEV  *Uhc,
  IN UINTN        Timeout
  )
{
  UINT16  CommandContent;
  UINT16  UsbSts;
  UINTN   Index;

  CommandContent  = USBReadPortW (Uhc, Uhc->UsbHostControllerBaseAddress + USBCMD);
  CommandContent &= USBCMD_RS;
  USBWritePortW (Uhc, Uhc->UsbHostControllerBaseAddress + USBCMD, CommandContent);

  //
  // ensure the HC is in halt status after send the stop command
  // Timeout is in us unit.
  //
  for (Index = 0; Index < (Timeout / 50) + 1; Index++) {
    UsbSts = USBReadPortW (Uhc, Uhc->UsbHostControllerBaseAddress + USBSTS);

    if ((UsbSts & USBSTS_HCH) == USBSTS_HCH) {
      return EFI_SUCCESS;
    }

    MicroSecondDelay (50);
  }

  return EFI_TIMEOUT;
}

/**
  One notified function to stop the Host Controller at the end of PEI

  @param[in]  PeiServices        Pointer to PEI Services Table.
  @param[in]  NotifyDescriptor   Pointer to the descriptor for the Notification event that
                                 caused this function to execute.
  @param[in]  Ppi                Pointer to the PPI data associated with this function.

  @retval     EFI_SUCCESS  The function completes successfully
  @retval     others
**/
EFI_STATUS
EFIAPI
UhcEndOfPei (
  IN EFI_PEI_SERVICES           **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
  IN VOID                       *Ppi
  )
{
  USB_UHC_DEV  *Uhc;

  Uhc = PEI_RECOVERY_USB_UHC_DEV_FROM_THIS_NOTIFY (NotifyDescriptor);

  //
  // Stop the Host Controller
  //
  UhciStopHc (Uhc, 1000 * 1000);

  return EFI_SUCCESS;
}

/**
  Initializes Usb Host Controller.

  @param  FileHandle  Handle of the file being invoked.
  @param  PeiServices Describes the list of possible PEI Services.

  @retval EFI_SUCCESS            PPI successfully installed.
  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resource.

**/
EFI_STATUS
EFIAPI
UhcPeimEntry (
  IN EFI_PEI_FILE_HANDLE     FileHandle,
  IN CONST EFI_PEI_SERVICES  **PeiServices
  )
{
  PEI_USB_CONTROLLER_PPI  *ChipSetUsbControllerPpi;
  EFI_STATUS              Status;
  UINT8                   Index;
  UINTN                   ControllerType;
  UINTN                   BaseAddress;
  UINTN                   MemPages;
  USB_UHC_DEV             *UhcDev;
  EFI_PHYSICAL_ADDRESS    TempPtr;

  //
  // Shadow this PEIM to run from memory
  //
  if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) {
    return EFI_SUCCESS;
  }

  Status = PeiServicesLocatePpi (
             &gPeiUsbControllerPpiGuid,
             0,
             NULL,
             (VOID **)&ChipSetUsbControllerPpi
             );
  //
  // If failed to locate, it is a bug in dispather as depex has gPeiUsbControllerPpiGuid.
  //
  ASSERT_EFI_ERROR (Status);

  Index = 0;
  while (TRUE) {
    Status = ChipSetUsbControllerPpi->GetUsbController (
                                        (EFI_PEI_SERVICES **)PeiServices,
                                        ChipSetUsbControllerPpi,
                                        Index,
                                        &ControllerType,
                                        &BaseAddress
                                        );
    //
    // When status is error, meant no controller is found
    //
    if (EFI_ERROR (Status)) {
      break;
    }

    //
    // This PEIM is for UHC type controller.
    //
    if (ControllerType != PEI_UHCI_CONTROLLER) {
      Index++;
      continue;
    }

    MemPages = sizeof (USB_UHC_DEV) / EFI_PAGE_SIZE + 1;

    Status = PeiServicesAllocatePages (
               EfiBootServicesData,
               MemPages,
               &TempPtr
               );
    if (EFI_ERROR (Status)) {
      return EFI_OUT_OF_RESOURCES;
    }

    UhcDev            = (USB_UHC_DEV *)((UINTN)TempPtr);
    UhcDev->Signature = USB_UHC_DEV_SIGNATURE;
    IoMmuInit (&UhcDev->IoMmu);
    UhcDev->UsbHostControllerBaseAddress = (UINT32)BaseAddress;

    //
    // Init local memory management service
    //
    Status = InitializeMemoryManagement (UhcDev);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Initialize Uhc's hardware
    //
    Status = InitializeUsbHC (UhcDev);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    UhcDev->UsbHostControllerPpi.ControlTransfer         = UhcControlTransfer;
    UhcDev->UsbHostControllerPpi.BulkTransfer            = UhcBulkTransfer;
    UhcDev->UsbHostControllerPpi.GetRootHubPortNumber    = UhcGetRootHubPortNumber;
    UhcDev->UsbHostControllerPpi.GetRootHubPortStatus    = UhcGetRootHubPortStatus;
    UhcDev->UsbHostControllerPpi.SetRootHubPortFeature   = UhcSetRootHubPortFeature;
    UhcDev->UsbHostControllerPpi.ClearRootHubPortFeature = UhcClearRootHubPortFeature;

    UhcDev->PpiDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
    UhcDev->PpiDescriptor.Guid  = &gPeiUsbHostControllerPpiGuid;
    UhcDev->PpiDescriptor.Ppi   = &UhcDev->UsbHostControllerPpi;

    Status = PeiServicesInstallPpi (&UhcDev->PpiDescriptor);
    if (EFI_ERROR (Status)) {
      Index++;
      continue;
    }

    UhcDev->EndOfPeiNotifyList.Flags  = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
    UhcDev->EndOfPeiNotifyList.Guid   = &gEfiEndOfPeiSignalPpiGuid;
    UhcDev->EndOfPeiNotifyList.Notify = UhcEndOfPei;

    PeiServicesNotifyPpi (&UhcDev->EndOfPeiNotifyList);

    Index++;
  }

  return EFI_SUCCESS;
}

/**
  Submits control transfer to a target USB device.

  @param  PeiServices            The pointer of EFI_PEI_SERVICES.
  @param  This                   The pointer of PEI_USB_HOST_CONTROLLER_PPI.
  @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.
                                 If Timeout is 0, then the caller must wait for the function
                                 to be completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned.
  @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
UhcControlTransfer (
  IN     EFI_PEI_SERVICES             **PeiServices,
  IN     PEI_USB_HOST_CONTROLLER_PPI  *This,
  IN     UINT8                        DeviceAddress,
  IN     UINT8                        DeviceSpeed,
  IN     UINT8                        MaximumPacketLength,
  IN     EFI_USB_DEVICE_REQUEST       *Request,
  IN     EFI_USB_DATA_DIRECTION       TransferDirection,
  IN OUT VOID                         *Data                 OPTIONAL,
  IN OUT UINTN                        *DataLength           OPTIONAL,
  IN     UINTN                        TimeOut,
  OUT    UINT32                       *TransferResult
  )
{
  USB_UHC_DEV  *UhcDev;
  UINT32       StatusReg;
  UINT8        PktID;
  QH_STRUCT    *PtrQH;
  TD_STRUCT    *PtrTD;
  TD_STRUCT    *PtrPreTD;
  TD_STRUCT    *PtrSetupTD;
  TD_STRUCT    *PtrStatusTD;
  EFI_STATUS   Status;
  UINT32       DataLen;
  UINT8        DataToggle;
  UINT8        *RequestPhy;
  VOID         *RequestMap;
  UINT8        *DataPhy;
  VOID         *DataMap;

  UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS (This);

  StatusReg = UhcDev->UsbHostControllerBaseAddress + USBSTS;

  PktID = INPUT_PACKET_ID;

  RequestMap = NULL;

  if ((Request == NULL) || (TransferResult == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // if errors exist that cause host controller halt,
  // then return EFI_DEVICE_ERROR.
  //

  if (!IsStatusOK (UhcDev, StatusReg)) {
    ClearStatusReg (UhcDev, StatusReg);
    *TransferResult = EFI_USB_ERR_SYSTEM;
    return EFI_DEVICE_ERROR;
  }

  ClearStatusReg (UhcDev, StatusReg);

  //
  // Map the Request and data for bus master access,
  // then create a list of TD for this transfer
  //
  Status = UhciMapUserRequest (UhcDev, Request, &RequestPhy, &RequestMap);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = UhciMapUserData (UhcDev, TransferDirection, Data, DataLength, &PktID, &DataPhy, &DataMap);

  if (EFI_ERROR (Status)) {
    if (RequestMap != NULL) {
      IoMmuUnmap (UhcDev->IoMmu, RequestMap);
    }

    return Status;
  }

  //
  // generate Setup Stage TD
  //

  PtrQH = UhcDev->ConfigQH;

  GenSetupStageTD (
    UhcDev,
    DeviceAddress,
    0,
    DeviceSpeed,
    (UINT8 *)Request,
    RequestPhy,
    (UINT8)sizeof (EFI_USB_DEVICE_REQUEST),
    &PtrSetupTD
    );

  //
  // link setup TD structures to QH structure
  //
  LinkTDToQH (PtrQH, PtrSetupTD);

  PtrPreTD = PtrSetupTD;

  //
  //  Data Stage of Control Transfer
  //

  if (TransferDirection == EfiUsbNoData) {
    DataLen = 0;
  } else {
    DataLen = (UINT32)*DataLength;
  }

  DataToggle = 1;

  PtrTD = PtrSetupTD;
  while (DataLen > 0) {
    //
    // create TD structures and link together
    //
    UINT8  PacketSize;

    //
    // PacketSize is the data load size of each TD carries.
    //
    PacketSize = (UINT8)DataLen;
    if (DataLen > MaximumPacketLength) {
      PacketSize = MaximumPacketLength;
    }

    GenDataTD (
      UhcDev,
      DeviceAddress,
      0,
      Data,
      DataPhy,
      PacketSize,
      PktID,
      DataToggle,
      DeviceSpeed,
      &PtrTD
      );

    //
    // Link two TDs in vertical depth
    //
    LinkTDToTD (PtrPreTD, PtrTD);
    PtrPreTD = PtrTD;

    DataToggle ^= 1;
    Data        = (VOID *)((UINT8 *)Data + PacketSize);
    DataPhy    += PacketSize;
    DataLen    -= PacketSize;
  }

  //
  // PtrPreTD points to the last TD before the Setup-Stage TD.
  //
  PtrPreTD = PtrTD;

  //
  // Status Stage of Control Transfer
  //
  if (PktID == OUTPUT_PACKET_ID) {
    PktID = INPUT_PACKET_ID;
  } else {
    PktID = OUTPUT_PACKET_ID;
  }

  //
  // create Status Stage TD structure
  //
  CreateStatusTD (
    UhcDev,
    DeviceAddress,
    0,
    PktID,
    DeviceSpeed,
    &PtrStatusTD
    );

  LinkTDToTD (PtrPreTD, PtrStatusTD);

  //
  // Poll QH-TDs execution and get result.
  // detail status is returned
  //
  Status = ExecuteControlTransfer (
             UhcDev,
             PtrSetupTD,
             DataLength,
             TimeOut,
             TransferResult
             );

  //
  // TRUE means must search other framelistindex
  //
  SetQHVerticalValidorInvalid (PtrQH, FALSE);
  DeleteQueuedTDs (UhcDev, PtrSetupTD);

  //
  // if has errors that cause host controller halt, then return EFI_DEVICE_ERROR directly.
  //
  if (!IsStatusOK (UhcDev, StatusReg)) {
    *TransferResult |= EFI_USB_ERR_SYSTEM;
    Status           = EFI_DEVICE_ERROR;
  }

  ClearStatusReg (UhcDev, StatusReg);

  if (DataMap != NULL) {
    IoMmuUnmap (UhcDev->IoMmu, DataMap);
  }

  if (RequestMap != NULL) {
    IoMmuUnmap (UhcDev->IoMmu, RequestMap);
  }

  return Status;
}

/**
  Submits bulk transfer to a bulk endpoint of a USB device.

  @param  PeiServices           The pointer of EFI_PEI_SERVICES.
  @param  This                  The pointer of PEI_USB_HOST_CONTROLLER_PPI.
  @param  DeviceAddress         Target device address.
  @param  EndPointAddress       Endpoint number and its direction in bit 7.
  @param  MaximumPacketLength   Maximum packet size the endpoint is capable of
                                sending or receiving.
  @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.
                                If Timeout is 0, then the caller must wait for the function
                                to be completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned.
  @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 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
UhcBulkTransfer (
  IN     EFI_PEI_SERVICES             **PeiServices,
  IN     PEI_USB_HOST_CONTROLLER_PPI  *This,
  IN     UINT8                        DeviceAddress,
  IN     UINT8                        EndPointAddress,
  IN     UINT8                        MaximumPacketLength,
  IN OUT VOID                         *Data,
  IN OUT UINTN                        *DataLength,
  IN OUT UINT8                        *DataToggle,
  IN     UINTN                        TimeOut,
  OUT    UINT32                       *TransferResult
  )
{
  USB_UHC_DEV  *UhcDev;
  UINT32       StatusReg;

  UINT32  DataLen;

  QH_STRUCT  *PtrQH;
  TD_STRUCT  *PtrFirstTD;
  TD_STRUCT  *PtrTD;
  TD_STRUCT  *PtrPreTD;

  UINT8  PktID;

  BOOLEAN  IsFirstTD;

  EFI_STATUS  Status;

  EFI_USB_DATA_DIRECTION  TransferDirection;

  BOOLEAN  ShortPacketEnable;

  UINT16  CommandContent;

  UINT8  *DataPhy;
  VOID   *DataMap;

  UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS (This);

  //
  // Enable the maximum packet size (64bytes)
  // that can be used for full speed bandwidth reclamation
  // at the end of a frame.
  //
  CommandContent = USBReadPortW (UhcDev, UhcDev->UsbHostControllerBaseAddress + USBCMD);
  if ((CommandContent & USBCMD_MAXP) != USBCMD_MAXP) {
    CommandContent |= USBCMD_MAXP;
    USBWritePortW (UhcDev, UhcDev->UsbHostControllerBaseAddress + USBCMD, CommandContent);
  }

  StatusReg = UhcDev->UsbHostControllerBaseAddress + USBSTS;

  //
  // these code lines are added here per complier's strict demand
  //
  PktID      = INPUT_PACKET_ID;
  PtrTD      = NULL;
  PtrFirstTD = NULL;
  PtrPreTD   = NULL;
  DataLen    = 0;

  ShortPacketEnable = FALSE;

  if ((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;
  }

  //
  // if has errors that cause host controller halt, then return EFI_DEVICE_ERROR directly.
  //
  if (!IsStatusOK (UhcDev, StatusReg)) {
    ClearStatusReg (UhcDev, StatusReg);
    *TransferResult = EFI_USB_ERR_SYSTEM;
    return EFI_DEVICE_ERROR;
  }

  ClearStatusReg (UhcDev, StatusReg);

  //
  // Map the source data buffer for bus master access,
  // then create a list of TDs
  //
  if ((EndPointAddress & 0x80) != 0) {
    TransferDirection = EfiUsbDataIn;
  } else {
    TransferDirection = EfiUsbDataOut;
  }

  Status = UhciMapUserData (UhcDev, TransferDirection, Data, DataLength, &PktID, &DataPhy, &DataMap);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  DataLen = (UINT32)*DataLength;

  PtrQH = UhcDev->BulkQH;

  IsFirstTD = TRUE;
  while (DataLen > 0) {
    //
    // create TD structures and link together
    //
    UINT8  PacketSize;

    PacketSize = (UINT8)DataLen;
    if (DataLen > MaximumPacketLength) {
      PacketSize = MaximumPacketLength;
    }

    GenDataTD (
      UhcDev,
      DeviceAddress,
      EndPointAddress,
      Data,
      DataPhy,
      PacketSize,
      PktID,
      *DataToggle,
      USB_FULL_SPEED_DEVICE,
      &PtrTD
      );

    //
    // Enable short packet detection.
    // (default action is disabling short packet detection)
    //
    if (ShortPacketEnable) {
      EnableorDisableTDShortPacket (PtrTD, TRUE);
    }

    if (IsFirstTD) {
      PtrFirstTD            = PtrTD;
      PtrFirstTD->PtrNextTD = NULL;
      IsFirstTD             = FALSE;
    } else {
      //
      // Link two TDs in vertical depth
      //
      LinkTDToTD (PtrPreTD, PtrTD);
    }

    PtrPreTD = PtrTD;

    *DataToggle ^= 1;
    Data         = (VOID *)((UINT8 *)Data + PacketSize);
    DataPhy     += PacketSize;
    DataLen     -= PacketSize;
  }

  //
  // link TD structures to QH structure
  //
  LinkTDToQH (PtrQH, PtrFirstTD);

  //
  // Execute QH-TD and get result
  //
  //
  // detail status is put into the Result field in the pIRP
  // the Data Toggle value is also re-updated to the value
  // of the last successful TD
  //
  Status = ExecBulkTransfer (
             UhcDev,
             PtrFirstTD,
             DataLength,
             DataToggle,
             TimeOut,
             TransferResult
             );

  //
  // Delete Bulk transfer TD structure
  //
  DeleteQueuedTDs (UhcDev, PtrFirstTD);

  //
  // if has errors that cause host controller halt, then return EFI_DEVICE_ERROR directly.
  //
  if (!IsStatusOK (UhcDev, StatusReg)) {
    *TransferResult |= EFI_USB_ERR_SYSTEM;
    Status           = EFI_DEVICE_ERROR;
  }

  ClearStatusReg (UhcDev, StatusReg);

  if (DataMap != NULL) {
    IoMmuUnmap (UhcDev->IoMmu, DataMap);
  }

  return Status;
}

/**
  Retrieves the number of root hub ports.

  @param[in]  PeiServices   The pointer to the PEI Services Table.
  @param[in]  This          The pointer to this instance of the
                            PEI_USB_HOST_CONTROLLER_PPI.
  @param[out] PortNumber    The pointer to the number of the root hub ports.

  @retval EFI_SUCCESS           The port number was retrieved successfully.
  @retval EFI_INVALID_PARAMETER PortNumber is NULL.

**/
EFI_STATUS
EFIAPI
UhcGetRootHubPortNumber (
  IN EFI_PEI_SERVICES             **PeiServices,
  IN PEI_USB_HOST_CONTROLLER_PPI  *This,
  OUT UINT8                       *PortNumber
  )
{
  USB_UHC_DEV  *UhcDev;
  UINT32       PSAddr;
  UINT16       RHPortControl;
  UINT32       Index;

  UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS (This);

  if (PortNumber == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *PortNumber = 0;

  for (Index = 0; Index < 2; Index++) {
    PSAddr        = UhcDev->UsbHostControllerBaseAddress + USBPORTSC1 + Index * 2;
    RHPortControl = USBReadPortW (UhcDev, PSAddr);
    //
    // Port Register content is valid
    //
    if (RHPortControl != 0xff) {
      (*PortNumber)++;
    }
  }

  return EFI_SUCCESS;
}

/**
  Retrieves the current status of a USB root hub port.

  @param  PeiServices            The pointer of EFI_PEI_SERVICES.
  @param  This                   The pointer of PEI_USB_HOST_CONTROLLER_PPI.
  @param  PortNumber             The root hub port to retrieve the state from.
  @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.

**/
EFI_STATUS
EFIAPI
UhcGetRootHubPortStatus (
  IN EFI_PEI_SERVICES             **PeiServices,
  IN PEI_USB_HOST_CONTROLLER_PPI  *This,
  IN  UINT8                       PortNumber,
  OUT EFI_USB_PORT_STATUS         *PortStatus
  )
{
  USB_UHC_DEV  *UhcDev;
  UINT32       PSAddr;
  UINT16       RHPortStatus;
  UINT8        TotalPortNumber;

  if (PortStatus == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  UhcGetRootHubPortNumber (PeiServices, This, &TotalPortNumber);
  if (PortNumber > TotalPortNumber) {
    return EFI_INVALID_PARAMETER;
  }

  UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS (This);
  PSAddr = UhcDev->UsbHostControllerBaseAddress + USBPORTSC1 + PortNumber * 2;

  PortStatus->PortStatus       = 0;
  PortStatus->PortChangeStatus = 0;

  RHPortStatus = USBReadPortW (UhcDev, PSAddr);

  //
  // Current Connect Status
  //
  if ((RHPortStatus & USBPORTSC_CCS) != 0) {
    PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;
  }

  //
  // Port Enabled/Disabled
  //
  if ((RHPortStatus & USBPORTSC_PED) != 0) {
    PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;
  }

  //
  // Port Suspend
  //
  if ((RHPortStatus & USBPORTSC_SUSP) != 0) {
    PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;
  }

  //
  // Port Reset
  //
  if ((RHPortStatus & USBPORTSC_PR) != 0) {
    PortStatus->PortStatus |= USB_PORT_STAT_RESET;
  }

  //
  // Low Speed Device Attached
  //
  if ((RHPortStatus & USBPORTSC_LSDA) != 0) {
    PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;
  }

  //
  //   Fill Port Status Change bits
  //
  //
  // Connect Status Change
  //
  if ((RHPortStatus & USBPORTSC_CSC) != 0) {
    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;
  }

  //
  // Port Enabled/Disabled Change
  //
  if ((RHPortStatus & USBPORTSC_PEDC) != 0) {
    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;
  }

  return EFI_SUCCESS;
}

/**
  Sets a feature for the specified root hub port.

  @param  PeiServices           The pointer of EFI_PEI_SERVICES
  @param  This                  The pointer of PEI_USB_HOST_CONTROLLER_PPI
  @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_TIMEOUT            The time out occurred.

**/
EFI_STATUS
EFIAPI
UhcSetRootHubPortFeature (
  IN EFI_PEI_SERVICES             **PeiServices,
  IN PEI_USB_HOST_CONTROLLER_PPI  *This,
  IN UINT8                        PortNumber,
  IN EFI_USB_PORT_FEATURE         PortFeature
  )
{
  USB_UHC_DEV  *UhcDev;
  UINT32       PSAddr;
  UINT32       CommandRegAddr;
  UINT16       RHPortControl;
  UINT8        TotalPortNumber;

  UhcGetRootHubPortNumber (PeiServices, This, &TotalPortNumber);
  if (PortNumber > TotalPortNumber) {
    return EFI_INVALID_PARAMETER;
  }

  UhcDev         = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS (This);
  PSAddr         = UhcDev->UsbHostControllerBaseAddress + USBPORTSC1 + PortNumber * 2;
  CommandRegAddr = UhcDev->UsbHostControllerBaseAddress + USBCMD;

  RHPortControl = USBReadPortW (UhcDev, PSAddr);

  switch (PortFeature) {
    case EfiUsbPortSuspend:
      if ((USBReadPortW (UhcDev, CommandRegAddr) & USBCMD_EGSM) == 0) {
        //
        // if global suspend is not active, can set port suspend
        //
        RHPortControl &= 0xfff5;
        RHPortControl |= USBPORTSC_SUSP;
      }

      break;

    case EfiUsbPortReset:
      RHPortControl &= 0xfff5;
      RHPortControl |= USBPORTSC_PR;
      //
      // Set the reset bit
      //
      break;

    case EfiUsbPortPower:
      break;

    case EfiUsbPortEnable:
      RHPortControl &= 0xfff5;
      RHPortControl |= USBPORTSC_PED;
      break;

    default:
      return EFI_INVALID_PARAMETER;
  }

  USBWritePortW (UhcDev, PSAddr, RHPortControl);

  return EFI_SUCCESS;
}

/**
  Clears a feature for the specified root hub port.

  @param  PeiServices           The pointer of EFI_PEI_SERVICES.
  @param  This                  The pointer of PEI_USB_HOST_CONTROLLER_PPI.
  @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.

**/
EFI_STATUS
EFIAPI
UhcClearRootHubPortFeature (
  IN EFI_PEI_SERVICES             **PeiServices,
  IN PEI_USB_HOST_CONTROLLER_PPI  *This,
  IN UINT8                        PortNumber,
  IN EFI_USB_PORT_FEATURE         PortFeature
  )
{
  USB_UHC_DEV  *UhcDev;
  UINT32       PSAddr;
  UINT16       RHPortControl;
  UINT8        TotalPortNumber;

  UhcGetRootHubPortNumber (PeiServices, This, &TotalPortNumber);

  if (PortNumber > TotalPortNumber) {
    return EFI_INVALID_PARAMETER;
  }

  UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS (This);
  PSAddr = UhcDev->UsbHostControllerBaseAddress + USBPORTSC1 + PortNumber * 2;

  RHPortControl = USBReadPortW (UhcDev, PSAddr);

  switch (PortFeature) {
    //
    // clear PORT_ENABLE feature means disable port.
    //
    case EfiUsbPortEnable:
      RHPortControl &= 0xfff5;
      RHPortControl &= ~USBPORTSC_PED;
      break;

    //
    // clear PORT_SUSPEND feature means resume the port.
    // (cause a resume on the specified port if in suspend mode)
    //
    case EfiUsbPortSuspend:
      RHPortControl &= 0xfff5;
      RHPortControl &= ~USBPORTSC_SUSP;
      break;

    //
    // no operation
    //
    case EfiUsbPortPower:
      break;

    //
    // clear PORT_RESET means clear the reset signal.
    //
    case EfiUsbPortReset:
      RHPortControl &= 0xfff5;
      RHPortControl &= ~USBPORTSC_PR;
      break;

    //
    // clear connect status change
    //
    case EfiUsbPortConnectChange:
      RHPortControl &= 0xfff5;
      RHPortControl |= USBPORTSC_CSC;
      break;

    //
    // clear enable/disable status change
    //
    case EfiUsbPortEnableChange:
      RHPortControl &= 0xfff5;
      RHPortControl |= USBPORTSC_PEDC;
      break;

    //
    // root hub does not support this request
    //
    case EfiUsbPortSuspendChange:
      break;

    //
    // root hub does not support this request
    //
    case EfiUsbPortOverCurrentChange:
      break;

    //
    // root hub does not support this request
    //
    case EfiUsbPortResetChange:
      break;

    default:
      return EFI_INVALID_PARAMETER;
  }

  USBWritePortW (UhcDev, PSAddr, RHPortControl);

  return EFI_SUCCESS;
}

/**
  Initialize UHCI.

  @param  UhcDev                 UHCI Device.

  @retval EFI_SUCCESS            UHCI successfully initialized.
  @retval EFI_OUT_OF_RESOURCES   Resource can not be allocated.

**/
EFI_STATUS
InitializeUsbHC (
  IN USB_UHC_DEV  *UhcDev
  )
{
  EFI_STATUS  Status;
  UINT32      FrameListBaseAddrReg;
  UINT32      CommandReg;
  UINT16      Command;

  //
  // Create and Initialize Frame List For the Host Controller.
  //
  Status = CreateFrameList (UhcDev);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  FrameListBaseAddrReg = UhcDev->UsbHostControllerBaseAddress + USBFLBASEADD;
  CommandReg           = UhcDev->UsbHostControllerBaseAddress + USBCMD;

  //
  // Set Frame List Base Address to the specific register to inform the hardware.
  //
  SetFrameListBaseAddress (UhcDev, FrameListBaseAddrReg, (UINT32)(UINTN)(UhcDev->FrameListEntry));

  Command  = USBReadPortW (UhcDev, CommandReg);
  Command |= USBCMD_GRESET;
  USBWritePortW (UhcDev, CommandReg, Command);

  MicroSecondDelay (50 * 1000);

  Command &= ~USBCMD_GRESET;

  USBWritePortW (UhcDev, CommandReg, Command);

  //
  // UHCI spec page120 reset recovery time
  //
  MicroSecondDelay (20 * 1000);

  //
  // Set Run/Stop bit to 1.
  //
  Command  = USBReadPortW (UhcDev, CommandReg);
  Command |= USBCMD_RS | USBCMD_MAXP;
  USBWritePortW (UhcDev, CommandReg, Command);

  return EFI_SUCCESS;
}

/**
  Create Frame List Structure.

  @param  UhcDev                 UHCI device.

  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.
  @retval EFI_SUCCESS            Success.

**/
EFI_STATUS
CreateFrameList (
  USB_UHC_DEV  *UhcDev
  )
{
  EFI_STATUS            Status;
  EFI_PHYSICAL_ADDRESS  FrameListBaseAddr;
  FRAMELIST_ENTRY       *FrameListPtr;
  UINTN                 Index;

  //
  // The Frame List ocupies 4K bytes,
  // and must be aligned on 4-Kbyte boundaries.
  //
  Status = PeiServicesAllocatePages (
             EfiBootServicesData,
             1,
             &FrameListBaseAddr
             );

  if (Status != EFI_SUCCESS) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Create Control QH and Bulk QH and link them into Framelist Entry
  //
  Status = CreateQH (UhcDev, &UhcDev->ConfigQH);
  if (Status != EFI_SUCCESS) {
    return EFI_OUT_OF_RESOURCES;
  }

  ASSERT (UhcDev->ConfigQH != NULL);

  Status = CreateQH (UhcDev, &UhcDev->BulkQH);
  if (Status != EFI_SUCCESS) {
    return EFI_OUT_OF_RESOURCES;
  }

  ASSERT (UhcDev->BulkQH != NULL);

  //
  // Set the corresponding QH pointer
  //
  SetQHHorizontalLinkPtr (UhcDev->ConfigQH, UhcDev->BulkQH);
  SetQHHorizontalQHorTDSelect (UhcDev->ConfigQH, TRUE);
  SetQHHorizontalValidorInvalid (UhcDev->ConfigQH, TRUE);

  UhcDev->FrameListEntry = (FRAMELIST_ENTRY *)((UINTN)FrameListBaseAddr);

  FrameListPtr = UhcDev->FrameListEntry;

  for (Index = 0; Index < 1024; Index++) {
    FrameListPtr->FrameListPtrTerminate = 0;
    FrameListPtr->FrameListPtr          = (UINT32)(UINTN)UhcDev->ConfigQH >> 4;
    FrameListPtr->FrameListPtrQSelect   = 1;
    FrameListPtr->FrameListRsvd         = 0;
    FrameListPtr++;
  }

  return EFI_SUCCESS;
}

/**
  Read a 16bit width data from Uhc HC IO space register.

  @param  UhcDev  The UHCI device.
  @param  Port    The IO space address of the register.

  @retval the register content read.

**/
UINT16
USBReadPortW (
  IN  USB_UHC_DEV  *UhcDev,
  IN  UINT32       Port
  )
{
  return IoRead16 (Port);
}

/**
  Write a 16bit width data into Uhc HC IO space register.

  @param  UhcDev  The UHCI device.
  @param  Port    The IO space address of the register.
  @param  Data    The data written into the register.

**/
VOID
USBWritePortW (
  IN  USB_UHC_DEV  *UhcDev,
  IN  UINT32       Port,
  IN  UINT16       Data
  )
{
  IoWrite16 (Port, Data);
}

/**
  Write a 32bit width data into Uhc HC IO space register.

  @param  UhcDev  The UHCI device.
  @param  Port    The IO space address of the register.
  @param  Data    The data written into the register.

**/
VOID
USBWritePortDW (
  IN  USB_UHC_DEV  *UhcDev,
  IN  UINT32       Port,
  IN  UINT32       Data
  )
{
  IoWrite32 (Port, Data);
}

/**
  Clear the content of UHCI's Status Register.

  @param  UhcDev       The UHCI device.
  @param  StatusAddr   The IO space address of the register.

**/
VOID
ClearStatusReg (
  IN  USB_UHC_DEV  *UhcDev,
  IN  UINT32       StatusAddr
  )
{
  //
  // Clear the content of UHCI's Status Register
  //
  USBWritePortW (UhcDev, StatusAddr, 0x003F);
}

/**
  Check whether the host controller operates well.

  @param  UhcDev        The UHCI device.
  @param  StatusRegAddr The io address of status register.

  @retval TRUE          Host controller is working.
  @retval FALSE         Host controller is halted or system error.

**/
BOOLEAN
IsStatusOK (
  IN USB_UHC_DEV  *UhcDev,
  IN UINT32       StatusRegAddr
  )
{
  UINT16  StatusValue;

  StatusValue = USBReadPortW (UhcDev, StatusRegAddr);

  if ((StatusValue & (USBSTS_HCPE | USBSTS_HSE | USBSTS_HCH)) != 0) {
    return FALSE;
  } else {
    return TRUE;
  }
}

/**
  Set Frame List Base Address.

  @param  UhcDev           The UHCI device.
  @param  FrameListRegAddr The address of frame list register.
  @param  Addr             The address of frame list table.

**/
VOID
SetFrameListBaseAddress (
  IN USB_UHC_DEV  *UhcDev,
  IN UINT32       FrameListRegAddr,
  IN UINT32       Addr
  )
{
  //
  // Sets value in the USB Frame List Base Address register.
  //
  USBWritePortDW (UhcDev, FrameListRegAddr, (UINT32)(Addr & 0xFFFFF000));
}

/**
  Create QH and initialize.

  @param  UhcDev               The UHCI device.
  @param  PtrQH                Place to store QH_STRUCT pointer.

  @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
  @retval EFI_SUCCESS        Success.

**/
EFI_STATUS
CreateQH (
  IN  USB_UHC_DEV  *UhcDev,
  OUT QH_STRUCT    **PtrQH
  )
{
  EFI_STATUS  Status;

  //
  // allocate align memory for QH_STRUCT
  //
  Status = AllocateTDorQHStruct (UhcDev, sizeof (QH_STRUCT), (void **)PtrQH);
  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // init each field of the QH_STRUCT
  //
  SetQHHorizontalValidorInvalid (*PtrQH, FALSE);
  SetQHVerticalValidorInvalid (*PtrQH, FALSE);

  return EFI_SUCCESS;
}

/**
  Set the horizontal link pointer in QH.

  @param  PtrQH               Place to store QH_STRUCT pointer.
  @param  PtrNext             Place to the next QH_STRUCT.

**/
VOID
SetQHHorizontalLinkPtr (
  IN QH_STRUCT  *PtrQH,
  IN VOID       *PtrNext
  )
{
  //
  // Since the QH_STRUCT is aligned on 16-byte boundaries,
  // Only the highest 28bit of the address is valid
  // (take 32bit address as an example).
  //
  PtrQH->QueueHead.QHHorizontalPtr = (UINT32)(UINTN)PtrNext >> 4;
}

/**
  Set a QH or TD horizontally to be connected with a specific QH.

  @param  PtrQH      Place to store QH_STRUCT pointer.
  @param  IsQH       Specify QH or TD is connected.

**/
VOID
SetQHHorizontalQHorTDSelect (
  IN QH_STRUCT  *PtrQH,
  IN BOOLEAN    IsQH
  )
{
  //
  // if QH is connected, the specified bit is set,
  // if TD is connected, the specified bit is cleared.
  //
  PtrQH->QueueHead.QHHorizontalQSelect = IsQH ? 1 : 0;
}

/**
  Set the horizontal validor bit in QH.

  @param  PtrQH      Place to store QH_STRUCT pointer.
  @param  IsValid    Specify the horizontal linker is valid or not.

**/
VOID
SetQHHorizontalValidorInvalid (
  IN QH_STRUCT  *PtrQH,
  IN BOOLEAN    IsValid
  )
{
  //
  // Valid means the horizontal link pointer is valid,
  // else, it's invalid.
  //
  PtrQH->QueueHead.QHHorizontalTerminate = IsValid ? 0 : 1;
}

/**
  Set the vertical link pointer in QH.

  @param  PtrQH       Place to store QH_STRUCT pointer.
  @param  PtrNext     Place to the next QH_STRUCT.

**/
VOID
SetQHVerticalLinkPtr (
  IN QH_STRUCT  *PtrQH,
  IN VOID       *PtrNext
  )
{
  //
  // Since the QH_STRUCT is aligned on 16-byte boundaries,
  // Only the highest 28bit of the address is valid
  // (take 32bit address as an example).
  //
  PtrQH->QueueHead.QHVerticalPtr = (UINT32)(UINTN)PtrNext >> 4;
}

/**
  Set a QH or TD vertically to be connected with a specific QH.

  @param  PtrQH      Place to store QH_STRUCT pointer.
  @param  IsQH       Specify QH or TD is connected.

**/
VOID
SetQHVerticalQHorTDSelect (
  IN QH_STRUCT  *PtrQH,
  IN BOOLEAN    IsQH
  )
{
  //
  // Set the specified bit if the Vertical Link Pointer pointing to a QH,
  // Clear the specified bit if the Vertical Link Pointer pointing to a TD.
  //
  PtrQH->QueueHead.QHVerticalQSelect = IsQH ? 1 : 0;
}

/**
  Set the vertical validor bit in QH.

  @param  PtrQH      Place to store QH_STRUCT pointer.
  @param  IsValid    Specify the vertical linker is valid or not.

**/
VOID
SetQHVerticalValidorInvalid (
  IN QH_STRUCT  *PtrQH,
  IN BOOLEAN    IsValid
  )
{
  //
  // If TRUE, meaning the Vertical Link Pointer field is valid,
  // else, the field is invalid.
  //
  PtrQH->QueueHead.QHVerticalTerminate = IsValid ? 0 : 1;
}

/**
  Allocate TD or QH Struct.

  @param  UhcDev                 The UHCI device.
  @param  Size                   The size of allocation.
  @param  PtrStruct              Place to store TD_STRUCT pointer.

  @return EFI_SUCCESS            Allocate successfully.
  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resource.

**/
EFI_STATUS
AllocateTDorQHStruct (
  IN  USB_UHC_DEV  *UhcDev,
  IN  UINT32       Size,
  OUT VOID         **PtrStruct
  )
{
  EFI_STATUS  Status;

  Status     = EFI_SUCCESS;
  *PtrStruct = NULL;

  Status = UhcAllocatePool (
             UhcDev,
             (UINT8 **)PtrStruct,
             Size
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  ZeroMem (*PtrStruct, Size);

  return Status;
}

/**
  Create a TD Struct.

  @param  UhcDev                 The UHCI device.
  @param  PtrTD                  Place to store TD_STRUCT pointer.

  @return EFI_SUCCESS            Allocate successfully.
  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resource.

**/
EFI_STATUS
CreateTD (
  IN  USB_UHC_DEV  *UhcDev,
  OUT TD_STRUCT    **PtrTD
  )
{
  EFI_STATUS  Status;

  //
  // create memory for TD_STRUCT, and align the memory.
  //
  Status = AllocateTDorQHStruct (UhcDev, sizeof (TD_STRUCT), (void **)PtrTD);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Make TD ready.
  //
  SetTDLinkPtrValidorInvalid (*PtrTD, FALSE);

  return EFI_SUCCESS;
}

/**
  Generate Setup Stage TD.

  @param  UhcDev       The UHCI device.
  @param  DevAddr      Device address.
  @param  Endpoint     Endpoint number.
  @param  DeviceSpeed  Device Speed.
  @param  DevRequest   CPU memory address of request structure buffer to transfer.
  @param  RequestPhy   PCI memory address of request structure buffer to transfer.
  @param  RequestLen   Request length.
  @param  PtrTD        TD_STRUCT generated.

  @return EFI_SUCCESS            Generate setup stage TD successfully.
  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resource.

**/
EFI_STATUS
GenSetupStageTD (
  IN  USB_UHC_DEV  *UhcDev,
  IN  UINT8        DevAddr,
  IN  UINT8        Endpoint,
  IN  UINT8        DeviceSpeed,
  IN  UINT8        *DevRequest,
  IN  UINT8        *RequestPhy,
  IN  UINT8        RequestLen,
  OUT TD_STRUCT    **PtrTD
  )
{
  TD_STRUCT   *TdStruct;
  EFI_STATUS  Status;

  Status = CreateTD (UhcDev, &TdStruct);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  SetTDLinkPtr (TdStruct, NULL);

  //
  // Depth first fashion
  //
  SetTDLinkPtrDepthorBreadth (TdStruct, TRUE);

  //
  // initialize as the last TD in the QH context,
  // this field will be updated in the TD linkage process.
  //
  SetTDLinkPtrValidorInvalid (TdStruct, FALSE);

  //
  // Disable Short Packet Detection by default
  //
  EnableorDisableTDShortPacket (TdStruct, FALSE);

  //
  // Max error counter is 3, retry 3 times when error encountered.
  //
  SetTDControlErrorCounter (TdStruct, 3);

  //
  // set device speed attribute
  // (TRUE - Slow Device; FALSE - Full Speed Device)
  //
  switch (DeviceSpeed) {
    case USB_SLOW_SPEED_DEVICE:
      SetTDLoworFullSpeedDevice (TdStruct, TRUE);
      break;

    case USB_FULL_SPEED_DEVICE:
      SetTDLoworFullSpeedDevice (TdStruct, FALSE);
      break;
  }

  //
  // Non isochronous transfer TD
  //
  SetTDControlIsochronousorNot (TdStruct, FALSE);

  //
  // Interrupt On Complete bit be set to zero,
  // Disable IOC interrupt.
  //
  SetorClearTDControlIOC (TdStruct, FALSE);

  //
  // Set TD Active bit
  //
  SetTDStatusActiveorInactive (TdStruct, TRUE);

  SetTDTokenMaxLength (TdStruct, RequestLen);

  SetTDTokenDataToggle0 (TdStruct);

  SetTDTokenEndPoint (TdStruct, Endpoint);

  SetTDTokenDeviceAddress (TdStruct, DevAddr);

  SetTDTokenPacketID (TdStruct, SETUP_PACKET_ID);

  TdStruct->PtrTDBuffer    = (UINT8 *)DevRequest;
  TdStruct->TDBufferLength = RequestLen;
  //
  // Set the beginning address of the buffer that will be used
  // during the transaction.
  //
  TdStruct->TDData.TDBufferPtr = (UINT32)(UINTN)RequestPhy;

  *PtrTD = TdStruct;

  return EFI_SUCCESS;
}

/**
  Generate Data Stage TD.

  @param  UhcDev       The UHCI device.
  @param  DevAddr      Device address.
  @param  Endpoint     Endpoint number.
  @param  PtrData      CPU memory address of user data buffer to transfer.
  @param  DataPhy      PCI memory address of user data buffer to transfer.
  @param  Len          Data length.
  @param  PktID        PacketID.
  @param  Toggle       Data toggle value.
  @param  DeviceSpeed  Device Speed.
  @param  PtrTD        TD_STRUCT generated.

  @return EFI_SUCCESS            Generate data stage TD successfully.
  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resource.

**/
EFI_STATUS
GenDataTD (
  IN  USB_UHC_DEV  *UhcDev,
  IN  UINT8        DevAddr,
  IN  UINT8        Endpoint,
  IN  UINT8        *PtrData,
  IN  UINT8        *DataPhy,
  IN  UINT8        Len,
  IN  UINT8        PktID,
  IN  UINT8        Toggle,
  IN  UINT8        DeviceSpeed,
  OUT TD_STRUCT    **PtrTD
  )
{
  TD_STRUCT   *TdStruct;
  EFI_STATUS  Status;

  Status = CreateTD (UhcDev, &TdStruct);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  SetTDLinkPtr (TdStruct, NULL);

  //
  // Depth first fashion
  //
  SetTDLinkPtrDepthorBreadth (TdStruct, TRUE);

  //
  // Link pointer pointing to TD struct
  //
  SetTDLinkPtrQHorTDSelect (TdStruct, FALSE);

  //
  // initialize as the last TD in the QH context,
  // this field will be updated in the TD linkage process.
  //
  SetTDLinkPtrValidorInvalid (TdStruct, FALSE);

  //
  // Disable short packet detect
  //
  EnableorDisableTDShortPacket (TdStruct, FALSE);
  //
  // Max error counter is 3
  //
  SetTDControlErrorCounter (TdStruct, 3);

  //
  // set device speed attribute
  // (TRUE - Slow Device; FALSE - Full Speed Device)
  //
  switch (DeviceSpeed) {
    case USB_SLOW_SPEED_DEVICE:
      SetTDLoworFullSpeedDevice (TdStruct, TRUE);
      break;

    case USB_FULL_SPEED_DEVICE:
      SetTDLoworFullSpeedDevice (TdStruct, FALSE);
      break;
  }

  //
  // Non isochronous transfer TD
  //
  SetTDControlIsochronousorNot (TdStruct, FALSE);

  //
  // Disable Interrupt On Complete
  // Disable IOC interrupt.
  //
  SetorClearTDControlIOC (TdStruct, FALSE);

  //
  // Set Active bit
  //
  SetTDStatusActiveorInactive (TdStruct, TRUE);

  SetTDTokenMaxLength (TdStruct, Len);

  if (Toggle != 0) {
    SetTDTokenDataToggle1 (TdStruct);
  } else {
    SetTDTokenDataToggle0 (TdStruct);
  }

  SetTDTokenEndPoint (TdStruct, Endpoint);

  SetTDTokenDeviceAddress (TdStruct, DevAddr);

  SetTDTokenPacketID (TdStruct, PktID);

  TdStruct->PtrTDBuffer    = (UINT8 *)PtrData;
  TdStruct->TDBufferLength = Len;
  //
  // Set the beginning address of the buffer that will be used
  // during the transaction.
  //
  TdStruct->TDData.TDBufferPtr = (UINT32)(UINTN)DataPhy;

  *PtrTD = TdStruct;

  return EFI_SUCCESS;
}

/**
  Generate Status Stage TD.

  @param  UhcDev       The UHCI device.
  @param  DevAddr      Device address.
  @param  Endpoint     Endpoint number.
  @param  PktID        PacketID.
  @param  DeviceSpeed  Device Speed.
  @param  PtrTD        TD_STRUCT generated.

  @return EFI_SUCCESS            Generate status stage TD successfully.
  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resource.

**/
EFI_STATUS
CreateStatusTD (
  IN  USB_UHC_DEV  *UhcDev,
  IN  UINT8        DevAddr,
  IN  UINT8        Endpoint,
  IN  UINT8        PktID,
  IN  UINT8        DeviceSpeed,
  OUT TD_STRUCT    **PtrTD
  )
{
  TD_STRUCT   *PtrTDStruct;
  EFI_STATUS  Status;

  Status = CreateTD (UhcDev, &PtrTDStruct);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  SetTDLinkPtr (PtrTDStruct, NULL);

  //
  // Depth first fashion
  //
  SetTDLinkPtrDepthorBreadth (PtrTDStruct, TRUE);

  //
  // initialize as the last TD in the QH context,
  // this field will be updated in the TD linkage process.
  //
  SetTDLinkPtrValidorInvalid (PtrTDStruct, FALSE);

  //
  // Disable short packet detect
  //
  EnableorDisableTDShortPacket (PtrTDStruct, FALSE);

  //
  // Max error counter is 3
  //
  SetTDControlErrorCounter (PtrTDStruct, 3);

  //
  // set device speed attribute
  // (TRUE - Slow Device; FALSE - Full Speed Device)
  //
  switch (DeviceSpeed) {
    case USB_SLOW_SPEED_DEVICE:
      SetTDLoworFullSpeedDevice (PtrTDStruct, TRUE);
      break;

    case USB_FULL_SPEED_DEVICE:
      SetTDLoworFullSpeedDevice (PtrTDStruct, FALSE);
      break;
  }

  //
  // Non isochronous transfer TD
  //
  SetTDControlIsochronousorNot (PtrTDStruct, FALSE);

  //
  // Disable Interrupt On Complete
  // Disable IOC interrupt.
  //
  SetorClearTDControlIOC (PtrTDStruct, FALSE);

  //
  // Set TD Active bit
  //
  SetTDStatusActiveorInactive (PtrTDStruct, TRUE);

  SetTDTokenMaxLength (PtrTDStruct, 0);

  SetTDTokenDataToggle1 (PtrTDStruct);

  SetTDTokenEndPoint (PtrTDStruct, Endpoint);

  SetTDTokenDeviceAddress (PtrTDStruct, DevAddr);

  SetTDTokenPacketID (PtrTDStruct, PktID);

  PtrTDStruct->PtrTDBuffer    = NULL;
  PtrTDStruct->TDBufferLength = 0;
  //
  // Set the beginning address of the buffer that will be used
  // during the transaction.
  //
  PtrTDStruct->TDData.TDBufferPtr = 0;

  *PtrTD = PtrTDStruct;

  return EFI_SUCCESS;
}

/**
  Set the link pointer validor bit in TD.

  @param  PtrTDStruct  Place to store TD_STRUCT pointer.
  @param  IsValid      Specify the linker pointer is valid or not.

**/
VOID
SetTDLinkPtrValidorInvalid (
  IN  TD_STRUCT  *PtrTDStruct,
  IN  BOOLEAN    IsValid
  )
{
  //
  // Valid means the link pointer is valid,
  // else, it's invalid.
  //
  PtrTDStruct->TDData.TDLinkPtrTerminate = (IsValid ? 0 : 1);
}

/**
  Set the Link Pointer pointing to a QH or TD.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.
  @param  IsQH          Specify QH or TD is connected.

**/
VOID
SetTDLinkPtrQHorTDSelect (
  IN  TD_STRUCT  *PtrTDStruct,
  IN  BOOLEAN    IsQH
  )
{
  //
  // Indicate whether the Link Pointer pointing to a QH or TD
  //
  PtrTDStruct->TDData.TDLinkPtrQSelect = (IsQH ? 1 : 0);
}

/**
  Set the traverse is depth-first or breadth-first.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.
  @param  IsDepth       Specify the traverse is depth-first or breadth-first.

**/
VOID
SetTDLinkPtrDepthorBreadth (
  IN  TD_STRUCT  *PtrTDStruct,
  IN  BOOLEAN    IsDepth
  )
{
  //
  // If TRUE, indicating the host controller should process in depth first fashion,
  // else, the host controller should process in breadth first fashion
  //
  PtrTDStruct->TDData.TDLinkPtrDepthSelect = (IsDepth ? 1 : 0);
}

/**
  Set TD Link Pointer in TD.

  @param  PtrTDStruct  Place to store TD_STRUCT pointer.
  @param  PtrNext      Place to the next TD_STRUCT.

**/
VOID
SetTDLinkPtr (
  IN  TD_STRUCT  *PtrTDStruct,
  IN  VOID       *PtrNext
  )
{
  //
  // Set TD Link Pointer. Since QH,TD align on 16-byte boundaries,
  // only the highest 28 bits are valid. (if take 32bit address as an example)
  //
  PtrTDStruct->TDData.TDLinkPtr = (UINT32)(UINTN)PtrNext >> 4;
}

/**
  Get TD Link Pointer.

  @param  PtrTDStruct     Place to store TD_STRUCT pointer.

  @retval Get TD Link Pointer in TD.

**/
VOID *
GetTDLinkPtr (
  IN  TD_STRUCT  *PtrTDStruct
  )
{
  //
  // Get TD Link Pointer. Restore it back to 32bit
  // (if take 32bit address as an example)
  //
  return (VOID *)(UINTN)((PtrTDStruct->TDData.TDLinkPtr) << 4);
}

/**
  Enable/Disable short packet detection mechanism.

  @param  PtrTDStruct  Place to store TD_STRUCT pointer.
  @param  IsEnable     Enable or disable short packet detection mechanism.

**/
VOID
EnableorDisableTDShortPacket (
  IN  TD_STRUCT  *PtrTDStruct,
  IN  BOOLEAN    IsEnable
  )
{
  //
  // TRUE means enable short packet detection mechanism.
  //
  PtrTDStruct->TDData.TDStatusSPD = (IsEnable ? 1 : 0);
}

/**
  Set the max error counter in TD.

  @param  PtrTDStruct  Place to store TD_STRUCT pointer.
  @param  MaxErrors    The number of allowable error.

**/
VOID
SetTDControlErrorCounter (
  IN  TD_STRUCT  *PtrTDStruct,
  IN  UINT8      MaxErrors
  )
{
  //
  // valid value of MaxErrors is 0,1,2,3
  //
  if (MaxErrors > 3) {
    MaxErrors = 3;
  }

  PtrTDStruct->TDData.TDStatusErr = MaxErrors;
}

/**
  Set the TD is targeting a low-speed device or not.

  @param  PtrTDStruct       Place to store TD_STRUCT pointer.
  @param  IsLowSpeedDevice  Whether The device is low-speed.

**/
VOID
SetTDLoworFullSpeedDevice (
  IN  TD_STRUCT  *PtrTDStruct,
  IN  BOOLEAN    IsLowSpeedDevice
  )
{
  //
  // TRUE means the TD is targeting at a Low-speed device
  //
  PtrTDStruct->TDData.TDStatusLS = (IsLowSpeedDevice ? 1 : 0);
}

/**
  Set the TD is isochronous transfer type or not.

  @param  PtrTDStruct       Place to store TD_STRUCT pointer.
  @param  IsIsochronous     Whether the transaction isochronous transfer type.

**/
VOID
SetTDControlIsochronousorNot (
  IN  TD_STRUCT  *PtrTDStruct,
  IN  BOOLEAN    IsIsochronous
  )
{
  //
  // TRUE means the TD belongs to Isochronous transfer type.
  //
  PtrTDStruct->TDData.TDStatusIOS = (IsIsochronous ? 1 : 0);
}

/**
  Set if UCHI should issue an interrupt on completion of the frame
  in which this TD is executed

  @param  PtrTDStruct       Place to store TD_STRUCT pointer.
  @param  IsSet             Whether HC should issue an interrupt on completion.

**/
VOID
SetorClearTDControlIOC (
  IN  TD_STRUCT  *PtrTDStruct,
  IN  BOOLEAN    IsSet
  )
{
  //
  // If this bit is set, it indicates that the host controller should issue
  // an interrupt on completion of the frame in which this TD is executed.
  //
  PtrTDStruct->TDData.TDStatusIOC = IsSet ? 1 : 0;
}

/**
  Set if the TD is active and can be executed.

  @param  PtrTDStruct       Place to store TD_STRUCT pointer.
  @param  IsActive          Whether the TD is active and can be executed.

**/
VOID
SetTDStatusActiveorInactive (
  IN  TD_STRUCT  *PtrTDStruct,
  IN  BOOLEAN    IsActive
  )
{
  //
  // If this bit is set, it indicates that the TD is active and can be
  // executed.
  //
  if (IsActive) {
    PtrTDStruct->TDData.TDStatus |= 0x80;
  } else {
    PtrTDStruct->TDData.TDStatus &= 0x7F;
  }
}

/**
  Specifies the maximum number of data bytes allowed for the transfer.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.
  @param  MaxLen        The maximum number of data bytes allowed.

  @retval The allowed maximum number of data.
**/
UINT16
SetTDTokenMaxLength (
  IN  TD_STRUCT  *PtrTDStruct,
  IN  UINT16     MaxLen
  )
{
  //
  // Specifies the maximum number of data bytes allowed for the transfer.
  // the legal value extent is 0 ~ 0x500.
  //
  if (MaxLen > 0x500) {
    MaxLen = 0x500;
  }

  PtrTDStruct->TDData.TDTokenMaxLen = MaxLen - 1;

  return MaxLen;
}

/**
  Set the data toggle bit to DATA1.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.

**/
VOID
SetTDTokenDataToggle1 (
  IN  TD_STRUCT  *PtrTDStruct
  )
{
  //
  // Set the data toggle bit to DATA1
  //
  PtrTDStruct->TDData.TDTokenDataToggle = 1;
}

/**
  Set the data toggle bit to DATA0.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.

**/
VOID
SetTDTokenDataToggle0 (
  IN  TD_STRUCT  *PtrTDStruct
  )
{
  //
  // Set the data toggle bit to DATA0
  //
  PtrTDStruct->TDData.TDTokenDataToggle = 0;
}

/**
  Set EndPoint Number the TD is targeting at.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.
  @param  EndPoint      The Endport number of the target.

**/
VOID
SetTDTokenEndPoint (
  IN  TD_STRUCT  *PtrTDStruct,
  IN  UINTN      EndPoint
  )
{
  //
  // Set EndPoint Number the TD is targeting at.
  //
  PtrTDStruct->TDData.TDTokenEndPt = (UINT8)EndPoint;
}

/**
  Set Device Address the TD is targeting at.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.
  @param  DevAddr       The Device Address of the target.

**/
VOID
SetTDTokenDeviceAddress (
  IN  TD_STRUCT  *PtrTDStruct,
  IN  UINTN      DevAddr
  )
{
  //
  // Set Device Address the TD is targeting at.
  //
  PtrTDStruct->TDData.TDTokenDevAddr = (UINT8)DevAddr;
}

/**
  Set Packet Identification the TD is targeting at.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.
  @param  PacketID      The Packet Identification of the target.

**/
VOID
SetTDTokenPacketID (
  IN  TD_STRUCT  *PtrTDStruct,
  IN  UINT8      PacketID
  )
{
  //
  // Set the Packet Identification to be used for this transaction.
  //
  PtrTDStruct->TDData.TDTokenPID = PacketID;
}

/**
  Detect whether the TD is active.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.

  @retval The TD is active or not.

**/
BOOLEAN
IsTDStatusActive (
  IN  TD_STRUCT  *PtrTDStruct
  )
{
  UINT8  TDStatus;

  //
  // Detect whether the TD is active.
  //
  TDStatus = (UINT8)(PtrTDStruct->TDData.TDStatus);
  return (BOOLEAN)(TDStatus & 0x80);
}

/**
  Detect whether the TD is stalled.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.

  @retval The TD is stalled or not.

**/
BOOLEAN
IsTDStatusStalled (
  IN  TD_STRUCT  *PtrTDStruct
  )
{
  UINT8  TDStatus;

  //
  // Detect whether the device/endpoint addressed by this TD is stalled.
  //
  TDStatus = (UINT8)(PtrTDStruct->TDData.TDStatus);
  return (BOOLEAN)(TDStatus & 0x40);
}

/**
  Detect whether Data Buffer Error is happened.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.

  @retval The Data Buffer Error is happened or not.

**/
BOOLEAN
IsTDStatusBufferError (
  IN  TD_STRUCT  *PtrTDStruct
  )
{
  UINT8  TDStatus;

  //
  // Detect whether Data Buffer Error is happened.
  //
  TDStatus = (UINT8)(PtrTDStruct->TDData.TDStatus);
  return (BOOLEAN)(TDStatus & 0x20);
}

/**
  Detect whether Babble Error is happened.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.

  @retval The Babble Error is happened or not.

**/
BOOLEAN
IsTDStatusBabbleError (
  IN  TD_STRUCT  *PtrTDStruct
  )
{
  UINT8  TDStatus;

  //
  // Detect whether Babble Error is happened.
  //
  TDStatus = (UINT8)(PtrTDStruct->TDData.TDStatus);
  return (BOOLEAN)(TDStatus & 0x10);
}

/**
  Detect whether NAK is received.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.

  @retval The NAK is received or not.

**/
BOOLEAN
IsTDStatusNAKReceived (
  IN  TD_STRUCT  *PtrTDStruct
  )
{
  UINT8  TDStatus;

  //
  // Detect whether NAK is received.
  //
  TDStatus = (UINT8)(PtrTDStruct->TDData.TDStatus);
  return (BOOLEAN)(TDStatus & 0x08);
}

/**
  Detect whether CRC/Time Out Error is encountered.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.

  @retval The CRC/Time Out Error is encountered or not.

**/
BOOLEAN
IsTDStatusCRCTimeOutError (
  IN  TD_STRUCT  *PtrTDStruct
  )
{
  UINT8  TDStatus;

  //
  // Detect whether CRC/Time Out Error is encountered.
  //
  TDStatus = (UINT8)(PtrTDStruct->TDData.TDStatus);
  return (BOOLEAN)(TDStatus & 0x04);
}

/**
  Detect whether Bitstuff Error is received.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.

  @retval The Bitstuff Error is received or not.

**/
BOOLEAN
IsTDStatusBitStuffError (
  IN  TD_STRUCT  *PtrTDStruct
  )
{
  UINT8  TDStatus;

  //
  // Detect whether Bitstuff Error is received.
  //
  TDStatus = (UINT8)(PtrTDStruct->TDData.TDStatus);
  return (BOOLEAN)(TDStatus & 0x02);
}

/**
  Retrieve the actual number of bytes that were tansferred.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.

  @retval The actual number of bytes that were tansferred.

**/
UINT16
GetTDStatusActualLength (
  IN  TD_STRUCT  *PtrTDStruct
  )
{
  //
  // Retrieve the actual number of bytes that were tansferred.
  // the value is encoded as n-1. so return the decoded value.
  //
  return (UINT16)((PtrTDStruct->TDData.TDStatusActualLength) + 1);
}

/**
  Retrieve the information of whether the Link Pointer field is valid or not.

  @param  PtrTDStruct   Place to store TD_STRUCT pointer.

  @retval The linker pointer field is valid or not.

**/
BOOLEAN
GetTDLinkPtrValidorInvalid (
  IN  TD_STRUCT  *PtrTDStruct
  )
{
  //
  // Retrieve the information of whether the Link Pointer field
  // is valid or not.
  //
  if ((PtrTDStruct->TDData.TDLinkPtrTerminate & BIT0) != 0) {
    return FALSE;
  } else {
    return TRUE;
  }
}

/**
  Count TD Number from PtrFirstTD.

  @param  PtrFirstTD   Place to store TD_STRUCT pointer.

  @retval The queued TDs number.

**/
UINTN
CountTDsNumber (
  IN  TD_STRUCT  *PtrFirstTD
  )
{
  UINTN      Number;
  TD_STRUCT  *Ptr;

  //
  // Count the queued TDs number.
  //
  Number = 0;
  Ptr    = PtrFirstTD;
  while (Ptr != 0) {
    Ptr = (TD_STRUCT *)Ptr->PtrNextTD;
    Number++;
  }

  return Number;
}

/**
  Link TD To QH.

  @param  PtrQH   Place to store QH_STRUCT pointer.
  @param  PtrTD   Place to store TD_STRUCT pointer.

**/
VOID
LinkTDToQH (
  IN  QH_STRUCT  *PtrQH,
  IN  TD_STRUCT  *PtrTD
  )
{
  if ((PtrQH == NULL) || (PtrTD == NULL)) {
    return;
  }

  //
  //  Validate QH Vertical Ptr field
  //
  SetQHVerticalValidorInvalid (PtrQH, TRUE);

  //
  //  Vertical Ptr pointing to TD structure
  //
  SetQHVerticalQHorTDSelect (PtrQH, FALSE);

  SetQHVerticalLinkPtr (PtrQH, (VOID *)PtrTD);

  PtrQH->PtrDown = (VOID *)PtrTD;
}

/**
  Link TD To TD.

  @param  PtrPreTD  Place to store TD_STRUCT pointer.
  @param  PtrTD     Place to store TD_STRUCT pointer.

**/
VOID
LinkTDToTD (
  IN  TD_STRUCT  *PtrPreTD,
  IN  TD_STRUCT  *PtrTD
  )
{
  if ((PtrPreTD == NULL) || (PtrTD == NULL)) {
    return;
  }

  //
  // Depth first fashion
  //
  SetTDLinkPtrDepthorBreadth (PtrPreTD, TRUE);

  //
  // Link pointer pointing to TD struct
  //
  SetTDLinkPtrQHorTDSelect (PtrPreTD, FALSE);

  //
  // Validate the link pointer valid bit
  //
  SetTDLinkPtrValidorInvalid (PtrPreTD, TRUE);

  SetTDLinkPtr (PtrPreTD, PtrTD);

  PtrPreTD->PtrNextTD = (VOID *)PtrTD;

  PtrTD->PtrNextTD = NULL;
}

/**
  Execute Control Transfer.

  @param  UhcDev            The UCHI device.
  @param  PtrTD             A pointer to TD_STRUCT data.
  @param  ActualLen         Actual transfer Length.
  @param  TimeOut           TimeOut value.
  @param  TransferResult    Transfer Result.

  @return EFI_DEVICE_ERROR  The transfer failed due to transfer error.
  @return EFI_TIMEOUT       The transfer failed due to time out.
  @return EFI_SUCCESS       The transfer finished OK.

**/
EFI_STATUS
ExecuteControlTransfer (
  IN  USB_UHC_DEV  *UhcDev,
  IN  TD_STRUCT    *PtrTD,
  OUT UINTN        *ActualLen,
  IN  UINTN        TimeOut,
  OUT UINT32       *TransferResult
  )
{
  UINTN    ErrTDPos;
  UINTN    Delay;
  BOOLEAN  InfiniteLoop;

  ErrTDPos        = 0;
  *TransferResult = EFI_USB_NOERROR;
  *ActualLen      = 0;
  InfiniteLoop    = FALSE;

  Delay = TimeOut * STALL_1_MILLI_SECOND;
  //
  // If Timeout is 0, then the caller must wait for the function to be completed
  // until EFI_SUCCESS or EFI_DEVICE_ERROR is returned.
  //
  if (TimeOut == 0) {
    InfiniteLoop = TRUE;
  }

  do {
    CheckTDsResults (PtrTD, TransferResult, &ErrTDPos, ActualLen);

    //
    // TD is inactive, means the control transfer is end.
    //
    if ((*TransferResult & EFI_USB_ERR_NOTEXECUTE) != EFI_USB_ERR_NOTEXECUTE) {
      break;
    }

    MicroSecondDelay (STALL_1_MICRO_SECOND);
    Delay--;
  } while (InfiniteLoop || (Delay != 0));

  if (*TransferResult != EFI_USB_NOERROR) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

/**
  Execute Bulk Transfer.

  @param  UhcDev            The UCHI device.
  @param  PtrTD             A pointer to TD_STRUCT data.
  @param  ActualLen         Actual transfer Length.
  @param  DataToggle        DataToggle value.
  @param  TimeOut           TimeOut value.
  @param  TransferResult    Transfer Result.

  @return EFI_DEVICE_ERROR  The transfer failed due to transfer error.
  @return EFI_TIMEOUT       The transfer failed due to time out.
  @return EFI_SUCCESS       The transfer finished OK.

**/
EFI_STATUS
ExecBulkTransfer (
  IN     USB_UHC_DEV  *UhcDev,
  IN     TD_STRUCT    *PtrTD,
  IN OUT UINTN        *ActualLen,
  IN     UINT8        *DataToggle,
  IN     UINTN        TimeOut,
  OUT    UINT32       *TransferResult
  )
{
  UINTN    ErrTDPos;
  UINTN    ScrollNum;
  UINTN    Delay;
  BOOLEAN  InfiniteLoop;

  ErrTDPos        = 0;
  *TransferResult = EFI_USB_NOERROR;
  *ActualLen      = 0;
  InfiniteLoop    = FALSE;

  Delay = TimeOut * STALL_1_MILLI_SECOND;
  //
  // If Timeout is 0, then the caller must wait for the function to be completed
  // until EFI_SUCCESS or EFI_DEVICE_ERROR is returned.
  //
  if (TimeOut == 0) {
    InfiniteLoop = TRUE;
  }

  do {
    CheckTDsResults (PtrTD, TransferResult, &ErrTDPos, ActualLen);
    //
    // TD is inactive, thus meaning bulk transfer's end.
    //
    if ((*TransferResult & EFI_USB_ERR_NOTEXECUTE) != EFI_USB_ERR_NOTEXECUTE) {
      break;
    }

    MicroSecondDelay (STALL_1_MICRO_SECOND);
    Delay--;
  } while (InfiniteLoop || (Delay != 0));

  //
  // has error
  //
  if (*TransferResult != EFI_USB_NOERROR) {
    //
    // scroll the Data Toggle back to the last success TD
    //
    ScrollNum = CountTDsNumber (PtrTD) - ErrTDPos;
    if ((ScrollNum % 2) != 0) {
      *DataToggle ^= 1;
    }

    //
    // If error, wait 100ms to retry by upper layer
    //
    MicroSecondDelay (100 * 1000);
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

/**
  Delete Queued TDs.

  @param  UhcDev       The UCHI device.
  @param  PtrFirstTD   Place to store TD_STRUCT pointer.

**/
VOID
DeleteQueuedTDs (
  IN USB_UHC_DEV  *UhcDev,
  IN TD_STRUCT    *PtrFirstTD
  )
{
  TD_STRUCT  *Tptr1;

  TD_STRUCT  *Tptr2;

  Tptr1 = PtrFirstTD;
  //
  // Delete all the TDs in a queue.
  //
  while (Tptr1 != NULL) {
    Tptr2 = Tptr1;

    if (!GetTDLinkPtrValidorInvalid (Tptr2)) {
      Tptr1 = NULL;
    } else {
      //
      // has more than one TD in the queue.
      //
      Tptr1 = GetTDLinkPtr (Tptr2);
    }

    UhcFreePool (UhcDev, (UINT8 *)Tptr2, sizeof (TD_STRUCT));
  }

  return;
}

/**
  Check TDs Results.

  @param  PtrTD               A pointer to TD_STRUCT data.
  @param  Result              The result to return.
  @param  ErrTDPos            The Error TD position.
  @param  ActualTransferSize  Actual transfer size.

  @retval The TD is executed successfully or not.

**/
BOOLEAN
CheckTDsResults (
  IN  TD_STRUCT  *PtrTD,
  OUT UINT32     *Result,
  OUT UINTN      *ErrTDPos,
  OUT UINTN      *ActualTransferSize
  )
{
  UINTN  Len;

  *Result   = EFI_USB_NOERROR;
  *ErrTDPos = 0;

  //
  // Init to zero.
  //
  *ActualTransferSize = 0;

  while (PtrTD != NULL) {
    if (IsTDStatusActive (PtrTD)) {
      *Result |= EFI_USB_ERR_NOTEXECUTE;
    }

    if (IsTDStatusStalled (PtrTD)) {
      *Result |= EFI_USB_ERR_STALL;
    }

    if (IsTDStatusBufferError (PtrTD)) {
      *Result |= EFI_USB_ERR_BUFFER;
    }

    if (IsTDStatusBabbleError (PtrTD)) {
      *Result |= EFI_USB_ERR_BABBLE;
    }

    if (IsTDStatusNAKReceived (PtrTD)) {
      *Result |= EFI_USB_ERR_NAK;
    }

    if (IsTDStatusCRCTimeOutError (PtrTD)) {
      *Result |= EFI_USB_ERR_TIMEOUT;
    }

    if (IsTDStatusBitStuffError (PtrTD)) {
      *Result |= EFI_USB_ERR_BITSTUFF;
    }

    //
    // Accumulate actual transferred data length in each TD.
    //
    Len                  = GetTDStatusActualLength (PtrTD) & 0x7FF;
    *ActualTransferSize += Len;

    //
    // if any error encountered, stop processing the left TDs.
    //
    if ((*Result) != 0) {
      return FALSE;
    }

    PtrTD = (TD_STRUCT *)(PtrTD->PtrNextTD);
    //
    // Record the first Error TD's position in the queue,
    // this value is zero-based.
    //
    (*ErrTDPos)++;
  }

  return TRUE;
}

/**
  Create Memory Block.

  @param  UhcDev                   The UCHI device.
  @param  MemoryHeader             The Pointer to allocated memory block.
  @param  MemoryBlockSizeInPages   The page size of memory block to be allocated.

  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.
  @retval EFI_SUCCESS            Success.

**/
EFI_STATUS
CreateMemoryBlock (
  IN  USB_UHC_DEV           *UhcDev,
  OUT MEMORY_MANAGE_HEADER  **MemoryHeader,
  IN  UINTN                 MemoryBlockSizeInPages
  )
{
  EFI_STATUS            Status;
  UINT8                 *TempPtr;
  UINTN                 MemPages;
  UINT8                 *Ptr;
  VOID                  *Mapping;
  EFI_PHYSICAL_ADDRESS  MappedAddr;

  //
  // Memory Block uses MemoryBlockSizeInPages pages,
  // memory management header and bit array use 1 page
  //
  MemPages = MemoryBlockSizeInPages + 1;
  Status   = IoMmuAllocateBuffer (
               UhcDev->IoMmu,
               MemPages,
               (VOID **)&TempPtr,
               &MappedAddr,
               &Mapping
               );
  if (EFI_ERROR (Status) || (TempPtr == NULL)) {
    return EFI_OUT_OF_RESOURCES;
  }

  Ptr = TempPtr;

  ZeroMem (Ptr, MemPages * EFI_PAGE_SIZE);

  *MemoryHeader = (MEMORY_MANAGE_HEADER *)Ptr;
  //
  // adjust Ptr pointer to the next empty memory
  //
  Ptr += sizeof (MEMORY_MANAGE_HEADER);
  //
  // Set Bit Array initial address
  //
  (*MemoryHeader)->BitArrayPtr = Ptr;

  (*MemoryHeader)->Next = NULL;

  //
  // Memory block initial address
  //
  Ptr                             = TempPtr;
  Ptr                            += EFI_PAGE_SIZE;
  (*MemoryHeader)->MemoryBlockPtr = Ptr;
  //
  // set Memory block size
  //
  (*MemoryHeader)->MemoryBlockSizeInBytes = MemoryBlockSizeInPages * EFI_PAGE_SIZE;
  //
  // each bit in Bit Array will manage 32byte memory in memory block
  //
  (*MemoryHeader)->BitArraySizeInBytes = ((*MemoryHeader)->MemoryBlockSizeInBytes / 32) / 8;

  return EFI_SUCCESS;
}

/**
  Initialize UHCI memory management.

  @param  UhcDev                 The UCHI device.

  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.
  @retval EFI_SUCCESS            Success.

**/
EFI_STATUS
InitializeMemoryManagement (
  IN USB_UHC_DEV  *UhcDev
  )
{
  MEMORY_MANAGE_HEADER  *MemoryHeader;
  EFI_STATUS            Status;
  UINTN                 MemPages;

  MemPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;
  Status   = CreateMemoryBlock (UhcDev, &MemoryHeader, MemPages);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  UhcDev->Header1 = MemoryHeader;

  return EFI_SUCCESS;
}

/**
  Initialize UHCI memory management.

  @param  UhcDev           The UCHI device.
  @param  Pool             Buffer pointer to store the buffer pointer.
  @param  AllocSize        The size of the pool to be allocated.

  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.
  @retval EFI_SUCCESS            Success.

**/
EFI_STATUS
UhcAllocatePool (
  IN  USB_UHC_DEV  *UhcDev,
  OUT UINT8        **Pool,
  IN  UINTN        AllocSize
  )
{
  MEMORY_MANAGE_HEADER  *MemoryHeader;
  MEMORY_MANAGE_HEADER  *TempHeaderPtr;
  MEMORY_MANAGE_HEADER  *NewMemoryHeader;
  UINTN                 RealAllocSize;
  UINTN                 MemoryBlockSizeInPages;
  EFI_STATUS            Status;

  *Pool = NULL;

  MemoryHeader = UhcDev->Header1;

  //
  // allocate unit is 32 byte (align on 32 byte)
  //
  if ((AllocSize & 0x1F) != 0) {
    RealAllocSize = (AllocSize / 32 + 1) * 32;
  } else {
    RealAllocSize = AllocSize;
  }

  Status = EFI_NOT_FOUND;
  for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {
    Status = AllocMemInMemoryBlock (
               TempHeaderPtr,
               (VOID **)Pool,
               RealAllocSize / 32
               );
    if (!EFI_ERROR (Status)) {
      return EFI_SUCCESS;
    }
  }

  //
  // There is no enough memory,
  // Create a new Memory Block
  //
  //
  // if pool size is larger than NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES,
  // just allocate a large enough memory block.
  //
  if (RealAllocSize > (NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES * EFI_PAGE_SIZE)) {
    MemoryBlockSizeInPages = RealAllocSize / EFI_PAGE_SIZE + 1;
  } else {
    MemoryBlockSizeInPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;
  }

  Status = CreateMemoryBlock (UhcDev, &NewMemoryHeader, MemoryBlockSizeInPages);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Link the new Memory Block to the Memory Header list
  //
  InsertMemoryHeaderToList (MemoryHeader, NewMemoryHeader);

  Status = AllocMemInMemoryBlock (
             NewMemoryHeader,
             (VOID **)Pool,
             RealAllocSize / 32
             );
  return Status;
}

/**
  Alloc Memory In MemoryBlock.

  @param  MemoryHeader           The pointer to memory manage header.
  @param  Pool                   Buffer pointer to store the buffer pointer.
  @param  NumberOfMemoryUnit     The size of the pool to be allocated.

  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.
  @retval EFI_SUCCESS            Success.

**/
EFI_STATUS
AllocMemInMemoryBlock (
  IN  MEMORY_MANAGE_HEADER  *MemoryHeader,
  OUT VOID                  **Pool,
  IN  UINTN                 NumberOfMemoryUnit
  )
{
  UINTN  TempBytePos;
  UINTN  FoundBytePos;
  UINT8  Index;
  UINT8  FoundBitPos;
  UINT8  ByteValue;
  UINT8  BitValue;
  UINTN  NumberOfZeros;
  UINTN  Count;

  FoundBytePos = 0;
  FoundBitPos  = 0;

  ByteValue     = MemoryHeader->BitArrayPtr[0];
  NumberOfZeros = 0;
  Index         = 0;
  for (TempBytePos = 0; TempBytePos < MemoryHeader->BitArraySizeInBytes;) {
    //
    // Pop out BitValue from a byte in TempBytePos.
    //
    BitValue = (UINT8)(ByteValue & 0x1);

    if (BitValue == 0) {
      //
      // Found a free bit, the NumberOfZeros only record the number of those consecutive zeros
      //
      NumberOfZeros++;
      //
      // Found enough consecutive free space, break the loop
      //
      if (NumberOfZeros >= NumberOfMemoryUnit) {
        break;
      }
    } else {
      //
      // Encountering a '1', meant the bit is ocupied.
      //
      if (NumberOfZeros >= NumberOfMemoryUnit) {
        //
        // Found enough consecutive free space,break the loop
        //
        break;
      } else {
        //
        // the NumberOfZeros only record the number of those consecutive zeros,
        // so reset the NumberOfZeros to 0 when encountering '1' before finding
        // enough consecutive '0's
        //
        NumberOfZeros = 0;
        //
        // reset the (FoundBytePos,FoundBitPos) to the position of '1'
        //
        FoundBytePos = TempBytePos;
        FoundBitPos  = Index;
      }
    }

    //
    // right shift the byte
    //
    ByteValue /= 2;

    //
    // step forward a bit
    //
    Index++;
    if (Index == 8) {
      //
      // step forward a byte, getting the byte value,
      // and reset the bit pos.
      //
      TempBytePos += 1;
      ByteValue    = MemoryHeader->BitArrayPtr[TempBytePos];
      Index        = 0;
    }
  }

  if (NumberOfZeros < NumberOfMemoryUnit) {
    return EFI_NOT_FOUND;
  }

  //
  // Found enough free space.
  //
  //
  // The values recorded in (FoundBytePos,FoundBitPos) have two conditions:
  //  1)(FoundBytePos,FoundBitPos) record the position
  //    of the last '1' before the consecutive '0's, it must
  //    be adjusted to the start position of the consecutive '0's.
  //  2)the start address of the consecutive '0's is just the start of
  //    the bitarray. so no need to adjust the values of (FoundBytePos,FoundBitPos).
  //
  if ((MemoryHeader->BitArrayPtr[0] & BIT0) != 0) {
    FoundBitPos += 1;
  }

  //
  // Have the (FoundBytePos,FoundBitPos) make sense.
  //
  if (FoundBitPos > 7) {
    FoundBytePos += 1;
    FoundBitPos  -= 8;
  }

  //
  // Set the memory as allocated
  //
  for (TempBytePos = FoundBytePos, Index = FoundBitPos, Count = 0; Count < NumberOfMemoryUnit; Count++) {
    MemoryHeader->BitArrayPtr[TempBytePos] = (UINT8)(MemoryHeader->BitArrayPtr[TempBytePos] | (1 << Index));
    Index++;
    if (Index == 8) {
      TempBytePos += 1;
      Index        = 0;
    }
  }

  *Pool = MemoryHeader->MemoryBlockPtr + (FoundBytePos * 8 + FoundBitPos) * 32;

  return EFI_SUCCESS;
}

/**
  Uhci Free Pool.

  @param  UhcDev                 The UHCI device.
  @param  Pool                   A pointer to store the buffer address.
  @param  AllocSize              The size of the pool to be freed.

**/
VOID
UhcFreePool (
  IN USB_UHC_DEV  *UhcDev,
  IN UINT8        *Pool,
  IN UINTN        AllocSize
  )
{
  MEMORY_MANAGE_HEADER  *MemoryHeader;
  MEMORY_MANAGE_HEADER  *TempHeaderPtr;
  UINTN                 StartBytePos;
  UINTN                 Index;
  UINT8                 StartBitPos;
  UINT8                 Index2;
  UINTN                 Count;
  UINTN                 RealAllocSize;

  MemoryHeader = UhcDev->Header1;

  //
  // allocate unit is 32 byte (align on 32 byte)
  //
  if ((AllocSize & 0x1F) != 0) {
    RealAllocSize = (AllocSize / 32 + 1) * 32;
  } else {
    RealAllocSize = AllocSize;
  }

  for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL;
       TempHeaderPtr = TempHeaderPtr->Next)
  {
    if ((Pool >= TempHeaderPtr->MemoryBlockPtr) &&
        ((Pool + RealAllocSize) <= (TempHeaderPtr->MemoryBlockPtr +
                                    TempHeaderPtr->MemoryBlockSizeInBytes)))
    {
      //
      // Pool is in the Memory Block area,
      // find the start byte and bit in the bit array
      //
      StartBytePos = ((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) / 8;
      StartBitPos  = (UINT8)(((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) % 8);

      //
      // reset associated bits in bit array
      //
      for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / 32); Count++) {
        TempHeaderPtr->BitArrayPtr[Index] = (UINT8)(TempHeaderPtr->BitArrayPtr[Index] ^ (1 << Index2));
        Index2++;
        if (Index2 == 8) {
          Index += 1;
          Index2 = 0;
        }
      }

      //
      // break the loop
      //
      break;
    }
  }
}

/**
  Insert a new memory header into list.

  @param  MemoryHeader         A pointer to the memory header list.
  @param  NewMemoryHeader      A new memory header to be inserted into the list.

**/
VOID
InsertMemoryHeaderToList (
  IN MEMORY_MANAGE_HEADER  *MemoryHeader,
  IN MEMORY_MANAGE_HEADER  *NewMemoryHeader
  )
{
  MEMORY_MANAGE_HEADER  *TempHeaderPtr;

  for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {
    if (TempHeaderPtr->Next == NULL) {
      TempHeaderPtr->Next = NewMemoryHeader;
      break;
    }
  }
}

/**
  Map address of request structure buffer.

  @param  Uhc                The UHCI device.
  @param  Request            The user request buffer.
  @param  MappedAddr         Mapped address of request.
  @param  Map                Identificaion of this mapping to return.

  @return EFI_SUCCESS        Success.
  @return EFI_DEVICE_ERROR   Fail to map the user request.

**/
EFI_STATUS
UhciMapUserRequest (
  IN  USB_UHC_DEV  *Uhc,
  IN  OUT VOID     *Request,
  OUT UINT8        **MappedAddr,
  OUT VOID         **Map
  )
{
  EFI_STATUS            Status;
  UINTN                 Len;
  EFI_PHYSICAL_ADDRESS  PhyAddr;

  Len    = sizeof (EFI_USB_DEVICE_REQUEST);
  Status = IoMmuMap (
             Uhc->IoMmu,
             EdkiiIoMmuOperationBusMasterRead,
             Request,
             &Len,
             &PhyAddr,
             Map
             );

  if (!EFI_ERROR (Status)) {
    *MappedAddr = (UINT8 *)(UINTN)PhyAddr;
  }

  return Status;
}

/**
  Map address of user data buffer.

  @param  Uhc                The UHCI device.
  @param  Direction          Direction of the data transfer.
  @param  Data               The user data buffer.
  @param  Len                Length of the user data.
  @param  PktId              Packet identificaion.
  @param  MappedAddr         Mapped address to return.
  @param  Map                Identificaion of this mapping to return.

  @return EFI_SUCCESS        Success.
  @return EFI_DEVICE_ERROR   Fail to map the user data.

**/
EFI_STATUS
UhciMapUserData (
  IN  USB_UHC_DEV             *Uhc,
  IN  EFI_USB_DATA_DIRECTION  Direction,
  IN  VOID                    *Data,
  IN  OUT UINTN               *Len,
  OUT UINT8                   *PktId,
  OUT UINT8                   **MappedAddr,
  OUT VOID                    **Map
  )
{
  EFI_STATUS            Status;
  EFI_PHYSICAL_ADDRESS  PhyAddr;

  Status = EFI_SUCCESS;

  switch (Direction) {
    case EfiUsbDataIn:
      //
      // BusMasterWrite means cpu read
      //
      *PktId = INPUT_PACKET_ID;
      Status = IoMmuMap (
                 Uhc->IoMmu,
                 EdkiiIoMmuOperationBusMasterWrite,
                 Data,
                 Len,
                 &PhyAddr,
                 Map
                 );

      if (EFI_ERROR (Status)) {
        goto EXIT;
      }

      *MappedAddr = (UINT8 *)(UINTN)PhyAddr;
      break;

    case EfiUsbDataOut:
      *PktId = OUTPUT_PACKET_ID;
      Status = IoMmuMap (
                 Uhc->IoMmu,
                 EdkiiIoMmuOperationBusMasterRead,
                 Data,
                 Len,
                 &PhyAddr,
                 Map
                 );

      if (EFI_ERROR (Status)) {
        goto EXIT;
      }

      *MappedAddr = (UINT8 *)(UINTN)PhyAddr;
      break;

    case EfiUsbNoData:
      if ((Len != NULL) && (*Len != 0)) {
        Status = EFI_INVALID_PARAMETER;
        goto EXIT;
      }

      *PktId      = OUTPUT_PACKET_ID;
      *MappedAddr = NULL;
      *Map        = NULL;
      break;

    default:
      Status = EFI_INVALID_PARAMETER;
  }

EXIT:
  return Status;
}
