/* Execute the transfer by polling the URB. This is a synchronous operation. */
EFI_STATUS EhcExecTransfer(IN PEI_USB2_HC_DEV *Ehc, IN PEI_URB *Urb, IN UINTN TimeOut)
/* Execute the transfer by polling the URB. This is a synchronous operation. */
EFI_STATUS EhcExecTransfer(IN PEI_USB2_HC_DEV *Ehc, IN PEI_URB *Urb, IN UINTN TimeOut)
{
  EFI_STATUS  Status;
  UINTN       Index;
  UINTN       Loop;
  BOOLEAN     Finished;
  BOOLEAN     InfiniteLoop;
  Status       = EFI_SUCCESS;
  Loop         = TimeOut * EHC_1_MILLISECOND;
  Finished     = FALSE;
  InfiniteLoop = FALSE;
  if (TimeOut == 0) {
    InfiniteLoop = TRUE;
  }
  for (Index = 0; InfiniteLoop || (Index < Loop); Index++) {
    Finished = EhcCheckUrbResult (Ehc, Urb);
    if (Finished) {
      break;
    }
    MicroSecondDelay (EHC_1_MICROSECOND);
  }
  if (!Finished) {
    Status = EFI_TIMEOUT;
  } else if (Urb->Result != EFI_USB_NOERROR) {
    Status = EFI_DEVICE_ERROR;
  }
  return Status;
}