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