示例#1
0
EFI_STATUS
OhciSetMemoryPointer(
  IN USB_OHCI_HC_DEV      *Ohc,
  IN UINTN                PointerType,
  IN VOID                 *Value
  )
{
  EFI_STATUS              Status;
  UINT32                  Verify;

  Status = OhciSetOperationalReg (Ohc, PointerType, (UINT32*)&Value);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Verify = OhciGetOperationalReg (Ohc, PointerType);

  while (Verify != (UINT32) Value) {
    MicroSecondDelay (HC_1_MILLISECOND);
    Verify = OhciGetOperationalReg (Ohc, PointerType);
  };


  return Status;
}
示例#2
0
UINT32
OhciGetRootHubDescriptor (
  IN USB_OHCI_HC_DEV     *Ohc,
  IN UINTN               Field
  )
{
  HcRH_DESC_A             DescriptorA;
  HcRH_DESC_B             DescriptorB;


  *(UINT32 *) &DescriptorA = OhciGetOperationalReg (Ohc, HC_RH_DESC_A);
  *(UINT32 *) &DescriptorB = OhciGetOperationalReg (Ohc, HC_RH_DESC_B);

  switch (Field){
    case RH_DEV_REMOVABLE:
      return DescriptorB.DeviceRemovable;
      break;

    case RH_PORT_PWR_CTRL_MASK:
      return DescriptorB.PortPowerControlMask;
      break;

    case RH_NUM_DS_PORTS:
      return DescriptorA.NumDownStrmPorts;
      break;

    case RH_NO_PSWITCH:
      return DescriptorA.NoPowerSwitch;
      break;

    case RH_PSWITCH_MODE:
      return DescriptorA.PowerSwitchMode;
      break;

    case RH_DEVICE_TYPE:
      return DescriptorA.DeviceType;
      break;

    case RH_OC_PROT_MODE:
      return DescriptorA.OverCurrentProtMode;
      break;

    case RH_NOC_PROT:
      return DescriptorA.NoOverCurrentProtMode;
      break;

    case RH_NO_POTPGT:
      return DescriptorA.PowerOnToPowerGoodTime;
      break;

    default:
      ASSERT (FALSE);
  }

  return 0;
}
示例#3
0
/**

  Set Root Hub Descriptor reg value

  @param  Ohc                   UHC private data
  @param  Field                 Field to set
  @param  Value                 Value to set

  @retval  EFI_SUCCESS          Value set

**/
EFI_STATUS
OhciSetRootHubDescriptor (
  IN USB_OHCI_HC_DEV      *Ohc,
  IN UINTN                Field,
  IN UINT32               Value
  )
{
  EFI_STATUS              Status;
  HcRH_DESC_A             DescriptorA;
  HcRH_DESC_B             DescriptorB;


  if (Field & (RH_DEV_REMOVABLE || RH_PORT_PWR_CTRL_MASK)) {
    *(UINT32 *) &DescriptorB = OhciGetOperationalReg (Ohc, HC_RH_DESC_B);

    if(Field & RH_DEV_REMOVABLE) {
      DescriptorB.DeviceRemovable = Value;
    }
    if(Field & RH_PORT_PWR_CTRL_MASK) {
      DescriptorB.PortPowerControlMask = Value;
    }

    Status = OhciSetOperationalReg (Ohc, HC_RH_DESC_B, (UINT32*)&DescriptorB);

    return Status;
  }

  *(UINT32 *)&DescriptorA = OhciGetOperationalReg (Ohc, HC_RH_DESC_A);

  if(Field & RH_NUM_DS_PORTS) {
    DescriptorA.NumDownStrmPorts = Value;
  }
  if(Field & RH_NO_PSWITCH) {
    DescriptorA.NoPowerSwitch = Value;
  }
  if(Field & RH_PSWITCH_MODE) {
    DescriptorA.PowerSwitchMode = Value;
  }
  if(Field & RH_DEVICE_TYPE) {
    DescriptorA.DeviceType = Value;
  }
  if(Field & RH_OC_PROT_MODE) {
    DescriptorA.OverCurrentProtMode = Value;
  }
  if(Field & RH_NOC_PROT) {
    DescriptorA.NoOverCurrentProtMode = Value;
  }
  if(Field & RH_NO_POTPGT) {
    DescriptorA.PowerOnToPowerGoodTime = Value;
  }

  Status = OhciSetOperationalReg (Ohc, HC_RH_DESC_A, (UINT32*)&DescriptorA);

  return Status;
}
示例#4
0
EFI_STATUS
OhciSetFrameInterval (
  IN USB_OHCI_HC_DEV      *Ohc,
  IN UINTN                Field,
  IN UINT32               Value
  )
{
  EFI_STATUS              Status;
  HcFRM_INTERVAL          FrameInterval;


  *(UINT32 *) &FrameInterval = OhciGetOperationalReg(Ohc, HC_FRM_INTERVAL);

  if (Field & FRAME_INTERVAL) {
    FrameInterval.FrmIntervalToggle = !FrameInterval.FrmIntervalToggle;
    FrameInterval.FrameInterval = Value;
  }

  if (Field & FS_LARGEST_DATA_PACKET) {
    FrameInterval.FSMaxDataPacket = Value;
  }

  if (Field & FRMINT_TOGGLE) {
    FrameInterval.FrmIntervalToggle = Value;
  }

  Status = OhciSetOperationalReg (
             Ohc,
             HC_FRM_INTERVAL,
             (UINT32*)&FrameInterval
             );

  return Status;
}
示例#5
0
/**

  Get value of frame remaining reg

  @param  Ohc                   UHC private data
  @param  Field                 Field to get

  @retval                       Value of frame remaining reg

**/
UINT32
OhciGetFrameRemaining (
  IN USB_OHCI_HC_DEV      *Ohc,
  IN UINTN                Field
  )

{
  HcFRAME_REMAINING       FrameRemaining;


  *(UINT32 *) &FrameRemaining = OhciGetOperationalReg (Ohc, HC_FRM_REMAINING);

  switch (Field){
    case FRAME_REMAINING:
      return FrameRemaining.FrameRemaining;
      break;

    case FRAME_REMAIN_TOGGLE:
      return FrameRemaining.FrameRemainingToggle;
      break;

    default:
      ASSERT (FALSE);
  }

  return 0;
}
示例#6
0
UINT32
OhciGetHcCommandStatus (
  IN USB_OHCI_HC_DEV      *Ohc,
  IN UINTN                Field
  )
{
  HcCOMMAND_STATUS        CommandStatus;

  *(UINT32 *) &CommandStatus = OhciGetOperationalReg (Ohc, HC_COMMAND_STATUS);

  switch (Field){
  case HC_RESET:
    return CommandStatus.HcReset;
    break;
  case CONTROL_LIST_FILLED:
    return CommandStatus.ControlListFilled;
    break;
  case BULK_LIST_FILLED:
    return CommandStatus.BulkListFilled;
    break;
  case CHANGE_OWNER_REQUEST:
    return CommandStatus.ChangeOwnerRequest;
    break;
  case SCHEDULE_OVERRUN_COUNT:
    return CommandStatus.ScheduleOverrunCount;
    break;
  default:
    ASSERT (FALSE);
  }

  return 0;
}
示例#7
0
UINT32
OhciGetHcRevision (
  USB_OHCI_HC_DEV         *Ohc
  )
{
  return OhciGetOperationalReg (Ohc, HC_REVISION);
}
示例#8
0
UINT32
OhciGetFrameNumber (
  IN USB_OHCI_HC_DEV      *Ohc
  )
{
  return OhciGetOperationalReg(Ohc, HC_FRM_NUMBER);
}
示例#9
0
UINT32
OhciGetPeriodicStart (
  IN USB_OHCI_HC_DEV      *Ohc
  )
{
  return OhciGetOperationalReg(Ohc, HC_PERIODIC_START);
}
示例#10
0
UINT32
OhciGetFrameInterval (
  IN USB_OHCI_HC_DEV      *Ohc,
  IN UINTN                Field
  )
{
  HcFRM_INTERVAL          FrameInterval;

  *(UINT32 *) &FrameInterval = OhciGetOperationalReg (Ohc, HC_FRM_INTERVAL);

  switch (Field){
    case FRAME_INTERVAL:
      return FrameInterval.FrameInterval;
      break;

    case FS_LARGEST_DATA_PACKET:
      return FrameInterval.FSMaxDataPacket;
      break;

    case FRMINT_TOGGLE:
      return FrameInterval.FrmIntervalToggle;
      break;

    default:
      ASSERT (FALSE);
  }

  return 0;
}
示例#11
0
UINT32
OhciGetLsThreshold (
  IN USB_OHCI_HC_DEV      *Ohc
  )
{
  return OhciGetOperationalReg(Ohc, HC_PERIODIC_START);
}
示例#12
0
VOID *
OhciGetMemoryPointer (
  IN USB_OHCI_HC_DEV      *Ohc,
  IN UINTN                PointerType
  )
{
  
  return (VOID *) OhciGetOperationalReg (Ohc, PointerType);
}
示例#13
0
UINT32
OhciGetHcReset (
  IN USB_OHCI_HC_DEV      *Ohc,
  IN UINT32               Field
  )
{
  HcRESET                 Reset;
  UINT32                  Value;


  *(UINT32 *) &Reset = OhciGetOperationalReg (Ohc, USBHOST_OFFSET_UHCHR);
  Value = 0;

  switch (Field) {
  case RESET_SYSTEM_BUS:
    Value = Reset.FSBIR;
    break;

  case RESET_HOST_CONTROLLER:
    Value = Reset.FHR;
    break;

  case RESET_CLOCK_GENERATION:
    Value = Reset.CGR;
    break;

  case RESET_SSE_GLOBAL:
    Value = Reset.SSE;
    break;

  case RESET_PSPL:
    Value = Reset.PSPL;
    break;

  case RESET_PCPL:
    Value = Reset.PCPL;
    break;

  case RESET_SSEP1:
    Value = Reset.SSEP1;
    break;

  case RESET_SSEP2:
    Value = Reset.SSEP2;
    break;

  case RESET_SSEP3:
    Value = Reset.SSEP3;
    break;

  default:
    ASSERT (FALSE);
  }


  return Value;
}
示例#14
0
UINT32
OhciReadRootHubPortStatus (
  IN USB_OHCI_HC_DEV      *Ohc,
  IN UINT32               Index,
  IN UINTN                Field
  )
{
  HcRHPORT_STATUS         PortStatus;

  *(UINT32 *) &PortStatus = OhciGetOperationalReg (
                              Ohc,
                              HC_RH_PORT_STATUS + (Index * 4)
                              );

  switch (Field){
  case RH_CURR_CONNECT_STAT:
    return PortStatus.CurrentConnectStat;
    break;
  case RH_PORT_ENABLE_STAT:
    return PortStatus.EnableStat;
    break;
  case RH_PORT_SUSPEND_STAT:
    return PortStatus.SuspendStat;
    break;
  case RH_PORT_OC_INDICATOR:
    return PortStatus.OCIndicator;
    break;
  case RH_PORT_RESET_STAT:
    return PortStatus.ResetStat;
    break;
  case RH_PORT_POWER_STAT:
    return PortStatus.PowerStat;
    break;
  case RH_LSDEVICE_ATTACHED:
    return PortStatus.LsDeviceAttached;
    break;
  case RH_CONNECT_STATUS_CHANGE:
    return PortStatus.ConnectStatChange;
    break;
  case RH_PORT_ENABLE_STAT_CHANGE:
    return PortStatus.EnableStatChange;
    break;
  case RH_PORT_SUSPEND_STAT_CHANGE:
    return PortStatus.SuspendStatChange;
    break;
  case RH_OC_INDICATOR_CHANGE:
    return PortStatus.OCIndicatorChange;
    break;
  case RH_PORT_RESET_STAT_CHANGE:
    return PortStatus.ResetStatChange;
    break;
  default:
    ASSERT (FALSE);
  }

  return 0;
}
示例#15
0
EFI_STATUS
OhciSetHcReset (
  IN USB_OHCI_HC_DEV            *Ohc,
  IN UINT32                     Field,
  IN UINT32                     Value
  )
{
  EFI_STATUS                    Status;
  HcRESET                       Reset;

  Status = EFI_SUCCESS;
  *(UINT32 *) &Reset = OhciGetOperationalReg (Ohc, USBHOST_OFFSET_UHCHR);

  if (Field & RESET_SYSTEM_BUS) {
    Reset.FSBIR = Value;
  }

  if (Field & RESET_HOST_CONTROLLER) {
    Reset.FHR = Value;
  }

  if (Field & RESET_CLOCK_GENERATION) {
    Reset.CGR = Value;
  }

  if (Field & RESET_SSE_GLOBAL) {
    Reset.SSE = Value;
  }

  if (Field & RESET_PSPL) {
    Reset.PSPL = Value;
  }

  if (Field & RESET_PCPL) {
    Reset.PCPL = Value;
  }

  if (Field & RESET_SSEP1) {
    Reset.SSEP1 = Value;
  }

  if (Field & RESET_SSEP2) {
    Reset.SSEP2 = Value;
  }

  if (Field & RESET_SSEP3) {
    Reset.SSEP3 = Value;
  }

  OhciSetOperationalReg (Ohc, USBHOST_OFFSET_UHCHR, (UINT32*)&Reset);

  return EFI_SUCCESS;
}
示例#16
0
UINT32
OhciGetHcInterruptControl (
  IN USB_OHCI_HC_DEV      *Ohc,
  IN UINTN                Field
  )
{
  HcINTERRUPT_CONTROL     InterruptState;

  *(UINT32 *) &InterruptState = OhciGetOperationalReg (Ohc, HC_INTERRUPT_ENABLE);

  switch (Field){
    case SCHEDULE_OVERRUN:
      return InterruptState.SchedulingOverrunInt;
      break;

    case WRITEBACK_DONE_HEAD:
      return InterruptState.WriteBackDoneInt;
      break;

    case START_OF_FRAME:
      return InterruptState.SofInt;
      break;

    case RESUME_DETECT:
      return InterruptState.ResumeDetectedInt;
      break;

    case UNRECOVERABLE_ERROR:
      return InterruptState.UnrecoverableErrorInt;
      break;

    case FRAME_NUMBER_OVERFLOW:
      return InterruptState.FrameNumOverflowInt;
      break;

    case ROOTHUB_STATUS_CHANGE:
      return InterruptState.RHStatusChangeInt;
      break;

    case OWNERSHIP_CHANGE:
      return InterruptState.OwnerChangedInt;
      break;

    case MASTER_INTERRUPT:
      return InterruptState.MasterInterruptEnable;
      break;

    default:
      ASSERT (FALSE);
  }

  return 0;
}
示例#17
0
UINT32
OhciGetHcInterruptStatus (
  IN USB_OHCI_HC_DEV      *Ohc,
  IN UINTN                Field
  )
{
  HcINTERRUPT_STATUS      InterruptStatus;

  *(UINT32 *) &InterruptStatus = OhciGetOperationalReg (Ohc, HC_INTERRUPT_STATUS);

  switch (Field){
  case SCHEDULE_OVERRUN:
    return InterruptStatus.SchedulingOverrun;
    break;

  case  WRITEBACK_DONE_HEAD:
    return InterruptStatus.WriteBackDone;
    break;

  case START_OF_FRAME:
    return InterruptStatus.Sof;
    break;

  case RESUME_DETECT:
    return InterruptStatus.ResumeDetected;
    break;

  case UNRECOVERABLE_ERROR:
    return InterruptStatus.UnrecoverableError;
    break;

  case FRAME_NUMBER_OVERFLOW:
    return InterruptStatus.FrameNumOverflow;
    break;

  case ROOTHUB_STATUS_CHANGE:
    return InterruptStatus.RHStatusChange;
    break;

  case OWNERSHIP_CHANGE:
    return InterruptStatus.OwnerChange;
    break;

  default:
    ASSERT (FALSE);
  }

  return 0;
}
示例#18
0
EFI_STATUS
OhciSetHcControl (
  IN USB_OHCI_HC_DEV      *Ohc,
  IN UINTN                Field,
  IN UINT32               Value
  )
{
  EFI_STATUS              Status;
  HcCONTROL               Control;



  *(UINT32 *) &Control = OhciGetOperationalReg (Ohc, HC_CONTROL);

  if (Field & CONTROL_BULK_RATIO) {
    Control.ControlBulkRatio = Value;
  }

  if (Field & HC_FUNCTIONAL_STATE) {
    Control.FunctionalState = Value;
  }

  if (Field & PERIODIC_ENABLE) {
    Control.PeriodicEnable = Value;
  }

  if (Field & CONTROL_ENABLE) {
    Control.ControlEnable = Value;
  }

  if (Field & ISOCHRONOUS_ENABLE) {
    Control.IsochronousEnable = Value;
  }

  if (Field & BULK_ENABLE) {
    Control.BulkEnable = Value;
  }

  if (Field & INTERRUPT_ROUTING) {
    Control.InterruptRouting = Value;
  }

  Status = OhciSetOperationalReg (Ohc, HC_CONTROL, (UINT32*)&Control);

  return Status;
}
示例#19
0
EFI_STATUS
OhciSetFrameRemaining (
  IN USB_OHCI_HC_DEV      *Ohc,
  IN UINT32               Value
  )
{
  EFI_STATUS              Status;
  HcFRAME_REMAINING       FrameRemaining;


  *(UINT32 *) &FrameRemaining = OhciGetOperationalReg (Ohc, HC_FRM_REMAINING);

  FrameRemaining.FrameRemaining = Value;
  FrameRemaining.FrameRemainingToggle = !FrameRemaining.FrameRemainingToggle;

  Status = OhciSetOperationalReg (Ohc, HC_FRM_REMAINING, (UINT32*)&FrameRemaining);

  return Status;
}
示例#20
0
UINT32
OhciGetHcControl (
  IN USB_OHCI_HC_DEV   *Ohc,
  IN UINTN             Field
  )
{
  HcCONTROL     Control;

  *(UINT32 *) &Control = OhciGetOperationalReg (Ohc, HC_CONTROL);

  switch (Field) {
  case CONTROL_BULK_RATIO:
    return Control.ControlBulkRatio;
    break;
  case PERIODIC_ENABLE:
    return Control.PeriodicEnable;
    break;
  case CONTROL_ENABLE:
    return Control.ControlEnable;
    break;
  case BULK_ENABLE:
    return Control.BulkEnable;
    break;
  case ISOCHRONOUS_ENABLE:
    return Control.IsochronousEnable;
    break;
  case HC_FUNCTIONAL_STATE:
    return Control.FunctionalState;
    break;
  case INTERRUPT_ROUTING:
    return Control.InterruptRouting;
    break;
  default:
    ASSERT (FALSE);
  }

  return 0;
}
示例#21
0
UINT32
OhciGetRootHubStatus (
  IN USB_OHCI_HC_DEV      *Ohc,
  IN UINTN                Field
  )
{
  HcRH_STATUS             RootHubStatus;


  *(UINT32 *) &RootHubStatus = OhciGetOperationalReg (Ohc, HC_RH_STATUS);

  switch (Field) {
    case RH_LOCAL_PSTAT:
      return RootHubStatus.LocalPowerStat;
      break;
    case RH_OC_ID:
      return RootHubStatus.OverCurrentIndicator;
      break;
    case RH_REMOTE_WK_ENABLE:
      return RootHubStatus.DevRemoteWakeupEnable;
      break;
    case RH_LOCAL_PSTAT_CHANGE:
      return RootHubStatus.LocalPowerStatChange;
      break;
    case RH_OC_ID_CHANGE:
      return RootHubStatus.OverCurrentIndicatorChange;
      break;
    case RH_CLR_RMT_WK_ENABLE:
      return RootHubStatus.ClearRemoteWakeupEnable;
      break;
    default:
      ASSERT (FALSE);
  }

  return 0;
}
示例#22
0
文件: OhcPeim.c 项目: shijunjing/edk2
/**
  Provides software reset for the USB host controller.

  @param  This                  This EFI_USB_HC_PROTOCOL instance.
  @param  Attributes            A bit mask of the reset operation to perform.

  @retval EFI_SUCCESS           The reset operation succeeded.
  @retval EFI_INVALID_PARAMETER Attributes is not valid.
  @retval EFI_UNSUPPOURTED      The type of reset specified by Attributes is
                                not currently supported by the host controller.
  @retval EFI_DEVICE_ERROR      Host controller isn't halted to reset.

**/
EFI_STATUS
InitializeUsbHC (
  IN EFI_PEI_SERVICES           **PeiServices,
  IN USB_OHCI_HC_DEV            *Ohc,
  IN UINT16                     Attributes
  )
{
  EFI_STATUS              Status;
  UINT8                   Index;
  UINT8                   NumOfPorts;
  UINT32                  PowerOnGoodTime;
  UINT32                  Data32;
  BOOLEAN                 Flag = FALSE;

  if ((Attributes & ~(EFI_USB_HC_RESET_GLOBAL | EFI_USB_HC_RESET_HOST_CONTROLLER)) != 0) {
    return EFI_INVALID_PARAMETER;
  }
  Status = EFI_SUCCESS;

  if ((Attributes & EFI_USB_HC_RESET_HOST_CONTROLLER) != 0) {
    MicroSecondDelay (50 * HC_1_MILLISECOND);
    Status = OhciSetHcCommandStatus (Ohc, HC_RESET, HC_RESET);
    if (EFI_ERROR (Status)) {
      return EFI_DEVICE_ERROR;
    }
    MicroSecondDelay (50 * HC_1_MILLISECOND);
    //
    // Wait for host controller reset.
    //
    PowerOnGoodTime = 50;
    do {
      MicroSecondDelay (HC_1_MILLISECOND);
      Data32 = OhciGetOperationalReg (Ohc, HC_COMMAND_STATUS );
      if ((Data32 & HC_RESET) == 0) {
        Flag = TRUE;
        break;
      }
    }while(PowerOnGoodTime--);
    if (!Flag){
      return EFI_DEVICE_ERROR;
    }
  }

  OhciSetFrameInterval (Ohc, FRAME_INTERVAL, 0x2edf);
  if ((Attributes &  EFI_USB_HC_RESET_GLOBAL) != 0) {
    Status = OhciSetHcControl (Ohc, HC_FUNCTIONAL_STATE, HC_STATE_RESET);
    if (EFI_ERROR (Status)) {
      return EFI_DEVICE_ERROR;
    }
    MicroSecondDelay (50 * HC_1_MILLISECOND);
  }
  //
  // Initialize host controller operational registers
  //
  OhciSetFrameInterval (Ohc, FS_LARGEST_DATA_PACKET, 0x2778);
  OhciSetFrameInterval (Ohc, FRAME_INTERVAL, 0x2edf);
  OhciSetPeriodicStart (Ohc, 0x2a2f);
  OhciSetHcControl (Ohc, CONTROL_BULK_RATIO, 0x0);
  OhciSetHcCommandStatus (Ohc, CONTROL_LIST_FILLED | BULK_LIST_FILLED, 0);
  OhciSetRootHubDescriptor (Ohc, RH_PSWITCH_MODE, 0);
  OhciSetRootHubDescriptor (Ohc, RH_NO_PSWITCH | RH_NOC_PROT, 1);
  //OhciSetRootHubDescriptor (Hc, RH_PSWITCH_MODE | RH_NO_PSWITCH, 0);
  //OhciSetRootHubDescriptor (Hc, RH_PSWITCH_MODE | RH_NOC_PROT, 1);

  OhciSetRootHubDescriptor (Ohc, RH_DEV_REMOVABLE, 0);
  OhciSetRootHubDescriptor (Ohc, RH_PORT_PWR_CTRL_MASK, 0xffff);
  OhciSetRootHubStatus (Ohc, RH_LOCAL_PSTAT_CHANGE);
  OhciSetRootHubPortStatus (Ohc, 0, RH_SET_PORT_POWER);
  OhciGetRootHubNumOfPorts (PeiServices, &Ohc->UsbHostControllerPpi, &NumOfPorts);
  for (Index = 0; Index < NumOfPorts; Index++) {
    if (!EFI_ERROR (OhciSetRootHubPortFeature (PeiServices, &Ohc->UsbHostControllerPpi, Index, EfiUsbPortReset))) {
      MicroSecondDelay (200 * HC_1_MILLISECOND);
      OhciClearRootHubPortFeature (PeiServices, &Ohc->UsbHostControllerPpi, Index, EfiUsbPortReset);
      MicroSecondDelay (HC_1_MILLISECOND);
      OhciSetRootHubPortFeature (PeiServices, &Ohc->UsbHostControllerPpi, Index, EfiUsbPortEnable);
      MicroSecondDelay (HC_1_MILLISECOND);
    }
  }

  Ohc->MemPool = UsbHcInitMemPool(TRUE, 0);
  if(Ohc->MemPool == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  OhciSetMemoryPointer (Ohc, HC_CONTROL_HEAD, NULL);
  OhciSetMemoryPointer (Ohc, HC_BULK_HEAD, NULL);
  OhciSetHcControl (Ohc, CONTROL_ENABLE | BULK_ENABLE, 1);
  OhciSetHcControl (Ohc, HC_FUNCTIONAL_STATE, HC_STATE_OPERATIONAL);
  MicroSecondDelay (50 * HC_1_MILLISECOND);
  //
  // Wait till first SOF occurs, and then clear it
  //
  while (OhciGetHcInterruptStatus (Ohc, START_OF_FRAME) == 0);
  OhciClearInterruptStatus (Ohc, START_OF_FRAME);
  MicroSecondDelay (HC_1_MILLISECOND);

  return EFI_SUCCESS;
}