ehcireg.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,733 行 · 第 1/2 页

C
1,733
字号

  UsbCommandReg &= ~USBCMD_ASE;
  Status = WriteEhcOperationalReg (
             HcDev,
             UsbCommandAddr,
             UsbCommandReg
             );
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  return Status;
}

EFI_STATUS
ResetEhc (
  IN  USB2_HC_DEV     *HcDev
  )
/*++

Routine Description:

  Reset Ehc

Arguments:

  HcDev - USB2_HC_DEV

Returns:

  EFI_SUCCESS       Success
  EFI_DEVICE_ERROR  Fail

--*/
{
  EFI_STATUS  Status;
  UINT32      UsbCommandAddr;
  UINT32      UsbCommandReg;

  UsbCommandAddr = USBCMD;

  Status = ReadEhcOperationalReg (
             HcDev,
             UsbCommandAddr,
             &UsbCommandReg
             );
  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
    goto exit;
  }

  UsbCommandReg |= USBCMD_HCRESET;
  Status = WriteEhcOperationalReg (
             HcDev,
             UsbCommandAddr,
             UsbCommandReg
             );
  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
  }

exit:
  return Status;
}

EFI_STATUS
StartScheduleExecution (
  IN  USB2_HC_DEV     *HcDev
  )
/*++

Routine Description:

  Start Ehc schedule execution

Arguments:

  HcDev - USB2_HC_DEV

Returns:

  EFI_SUCCESS       Success
  EFI_DEVICE_ERROR  Fail

--*/
{
  EFI_STATUS  Status;
  UINT32      UsbCommandAddr;
  UINT32      UsbCommandReg;

  UsbCommandAddr = USBCMD;

  Status = ReadEhcOperationalReg (
             HcDev,
             UsbCommandAddr,
             &UsbCommandReg
             );
  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
    goto exit;
  }

  UsbCommandReg |= USBCMD_RS;
  Status = WriteEhcOperationalReg (
             HcDev,
             UsbCommandAddr,
             UsbCommandReg
             );
  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
  }

exit:
  return Status;
}

BOOLEAN
IsFrameListProgrammable (
  IN  USB2_HC_DEV     *HcDev
  )
/*++

Routine Description:

  Whether frame list is programmable

Arguments:

  HcDev - USB2_HC_DEV

Returns:

  TRUE   Programmable
  FALSE  Unprogrammable

--*/
{
  BOOLEAN Value;
  UINT32  HcCapParamsAddr;
  UINT32  HcCapParamsReg;

  HcCapParamsAddr = HCCPARAMS;

  ReadEhcCapabiltiyReg(
    HcDev,
    HcCapParamsAddr,
    &HcCapParamsReg
    );

  if (HcCapParamsReg & HCCP_PFLF) {
    Value = TRUE;
  } else {
    Value = FALSE;
  }

  return Value;
}

BOOLEAN
IsPeriodicScheduleEnabled (
  IN  USB2_HC_DEV     *HcDev
  )
/*++

Routine Description:

  Whether periodic schedule is enabled

Arguments:

  HcDev - USB2_HC_DEV

Returns:

  TRUE    Enabled
  FALSE   Disabled

--*/
{
  BOOLEAN Value;
  UINT32  UsbStatusAddr;
  UINT32  UsbStatusReg;

  UsbStatusAddr = USBSTS;

  ReadEhcOperationalReg (
    HcDev,
    UsbStatusAddr,
    &UsbStatusReg
    );

  if (UsbStatusReg & USBSTS_PSS) {
    Value = TRUE;
  } else {
    Value = FALSE;
  }

  return Value;
}

BOOLEAN
IsAsyncScheduleEnabled (
  IN  USB2_HC_DEV     *HcDev
  )
/*++

Routine Description:

  Whether asynchronous schedule is enabled

Arguments:

  HcDev - USB2_HC_DEV

Returns:

  TRUE   Enabled
  FALSE  Disabled

--*/
{
  BOOLEAN Value;
  UINT32  UsbStatusAddr;
  UINT32  UsbStatusReg;

  UsbStatusAddr = USBSTS;

  ReadEhcOperationalReg (
    HcDev,
    UsbStatusAddr,
    &UsbStatusReg
    );

  if (UsbStatusReg & USBSTS_ASS) {
    Value = TRUE;
  } else {
    Value = FALSE;
  }

  return Value;
}

BOOLEAN
IsEhcPortEnabled (
  IN  USB2_HC_DEV     *HcDev,
  IN  UINT8           PortNum
  )
/*++

Routine Description:

  Whether port is enabled

Arguments:

  HcDev - USB2_HC_DEV

Returns:

  TRUE   Enabled
  FALSE  Disabled

--*/
{
  UINT32  PortStatusControlAddr;
  UINT32  PortStatusControlReg;

  PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNum));

  ReadEhcOperationalReg (
    HcDev,
    PortStatusControlAddr,
    &PortStatusControlReg
    );

  return ((PortStatusControlReg & PORTSC_PED) ? TRUE : FALSE);
}

BOOLEAN
IsEhcReseted (
  IN  USB2_HC_DEV     *HcDev
  )
/*++

Routine Description:

  Whether Ehc is reseted

Arguments:

  HcDev - USB2_HC_DEV

Returns:

  TRUE   Reseted
  FALSE  Unreseted

--*/
{
  BOOLEAN Value;
  UINT32  UsbCommandAddr;
  UINT32  UsbCommandReg;

  UsbCommandAddr = USBCMD;

  ReadEhcOperationalReg (
    HcDev,
    UsbCommandAddr,
    &UsbCommandReg
    );

  if (UsbCommandReg & USBCMD_HCRESET) {
    Value = FALSE;
  } else {
    Value = TRUE;
  }

  return Value;
}

BOOLEAN
IsEhcHalted (
  IN  USB2_HC_DEV     *HcDev
  )
/*++

Routine Description:

  Whether Ehc is halted

Arguments:

  HcDev - USB2_HC_DEV

Returns:

  TRUE   Halted
  FALSE  Not halted

--*/
{
  BOOLEAN Value;
  UINT32  UsbStatusAddr;
  UINT32  UsbStatusReg;

  UsbStatusAddr = USBSTS;

  ReadEhcOperationalReg (
    HcDev,
    UsbStatusAddr,
    &UsbStatusReg
    );

  if (UsbStatusReg & USBSTS_HCH) {
    Value = TRUE;
  } else {
    Value = FALSE;
  }

  return Value;
}

BOOLEAN
IsEhcSysError (
  IN  USB2_HC_DEV     *HcDev
  )
/*++

Routine Description:

  Whether Ehc is system error

Arguments:

  HcDev - USB2_HC_DEV

Returns:

  TRUE   System error
  FALSE  No system error

--*/
{
  BOOLEAN Value;
  UINT32  UsbStatusAddr;
  UINT32  UsbStatusReg;

  UsbStatusAddr = USBSTS;

  ReadEhcOperationalReg (
    HcDev,
    UsbStatusAddr,
    &UsbStatusReg
    );

  if (UsbStatusReg & USBSTS_HSE) {
    Value = TRUE;
  } else {
    Value = FALSE;
  }

  return Value;
}

BOOLEAN
IsHighSpeedDevice (
  IN EFI_USB2_HC_PROTOCOL *This,
  IN UINT8                PortNum
  )
/*++

Routine Description:

  Whether high speed device attached

Arguments:

  HcDev - USB2_HC_DEV

Returns:

  TRUE   High speed
  FALSE  Full speed

--*/
{
  USB2_HC_DEV          *HcDev;
  UINT32               PortStatusControlAddr;
  UINT32               PortStatusControlReg;

  HcDev = USB2_HC_DEV_FROM_THIS (This);
  PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNum));

  //
  // Set port reset bit
  //
  ReadEhcOperationalReg (
    HcDev,
    PortStatusControlAddr,
    &PortStatusControlReg
    );
  //
  // Make sure Host Controller not halt before reset it
  //
  if (IsEhcHalted (HcDev)) {
    StartScheduleExecution (HcDev);
    WaitForEhcNotHalt (HcDev, EHCI_GENERIC_TIMEOUT);
  }
  PortStatusControlReg &= 0xffffffd5;
  PortStatusControlReg |= PORTSC_PR;
  //
  // Set one to PortReset bit must also set zero to PortEnable bit
  //
  PortStatusControlReg &= ~PORTSC_PED;
  WriteEhcOperationalReg (
    HcDev,
    PortStatusControlAddr,
    PortStatusControlReg
    );

  //
  // Set Port reset recovery time
  //
  gBS->Stall (EHCI_SET_PORT_RESET_RECOVERY_TIME);

  //
  // Clear port reset bit
  //
  ReadEhcOperationalReg (
    HcDev,
    PortStatusControlAddr,
    &PortStatusControlReg
    );
  PortStatusControlReg &= 0xffffffd5;
  PortStatusControlReg &= ~PORTSC_PR;
  WriteEhcOperationalReg (
    HcDev,
    PortStatusControlAddr,
    PortStatusControlReg
    );

  //
  // Clear port reset recovery time
  //
  gBS->Stall (EHCI_CLEAR_PORT_RESET_RECOVERY_TIME);

  return (IsEhcPortEnabled (HcDev, PortNum) ? TRUE : FALSE);
}

EFI_STATUS
WaitForEhcReset (
  IN USB2_HC_DEV             *HcDev,
  IN UINTN                   Timeout
  )
/*++

Routine Description:

  wait for Ehc reset or timeout

Arguments:

  HcDev   - USB2_HC_DEV
  Timeout - timeout threshold

Returns:

  EFI_SUCCESS    Success
  EFI_TIMEOUT    Timeout

--*/
{
  EFI_STATUS  Status;
  UINTN       Delay;

  //
  // Timeout is in US unit
  //
  Delay = (Timeout / 50) + 1;
  do {

    if (IsEhcReseted (HcDev)) {
      Status = EFI_SUCCESS;
      goto exit;
    }
    gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);

  } while (Delay--);

  Status = EFI_TIMEOUT;

exit:
  return Status;
}

EFI_STATUS
WaitForEhcHalt (
  IN USB2_HC_DEV             *HcDev,
  IN UINTN                   Timeout
  )
/*++

Routine Description:

  wait for Ehc halt or timeout

Arguments:

  HcDev   - USB2_HC_DEV
  Timeout - timeout threshold

Returns:

  EFI_SUCCESS    Success
  EFI_TIMEOUT    Timeout

--*/
{
  EFI_STATUS  Status;
  UINTN       Delay;

  //
  // Timeout is in US unit
  //
  Delay = (Timeout / 50) + 1;
  do {

    if (IsEhcHalted (HcDev)) {
      Status = EFI_SUCCESS;
      goto exit;
    }
    gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);

  } while (Delay--);

  Status = EFI_TIMEOUT;

exit:
  return Status;
}

EFI_STATUS
WaitForEhcNotHalt (
  IN USB2_HC_DEV             *HcDev,
  IN UINTN                   Timeout
  )
/*++

Routine Description:

  wait for Ehc not halt or timeout

Arguments:

  HcDev   - USB2_HC_DEV
  Timeout - timeout threshold

Returns:

  EFI_SUCCESS    Success
  EFI_TIMEOUT    Timeout

--*/
{
  EFI_STATUS  Status;
  UINTN       Delay;

  //
  // Timeout is in US unit
  //
  Delay = (Timeout / 50) + 1;
  do {

    if (!IsEhcHalted (HcDev)) {
      Status = EFI_SUCCESS;
      goto exit;
    }
    gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);

  } while (Delay--);

  Status = EFI_TIMEOUT;

exit:
  return Status;
}

EFI_STATUS
WaitForAsyncScheduleEnable (
  IN  USB2_HC_DEV            *HcDev,
  IN UINTN                   Timeout
  )
/*++

Routine Description:

  Wait for Ehc asynchronous schedule enable or timeout

Arguments:

  HcDev   - USB2_HC_DEV
  Timeout - timeout threshold

Returns:

  EFI_SUCCESS    Success
  EFI_TIMEOUT    Timeout

--*/
{
  EFI_STATUS  Status;
  UINTN       Delay;

  //
  // Timeout is in US unit
  //
  Delay = (Timeout / 50) + 1;
  do {

    if (IsAsyncScheduleEnabled (HcDev)) {
      Status = EFI_SUCCESS;
      goto exit;
    }
    gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);

  } while (Delay--);

  Status = EFI_TIMEOUT;

exit:
  return Status;
}

EFI_STATUS
WaitForAsyncScheduleDisable (
  IN USB2_HC_DEV             *HcDev,
  IN UINTN                   Timeout
  )
/*++

Routine Description:

  Wait for Ehc asynchronous schedule disable or timeout

Arguments:

  HcDev   - USB2_HC_DEV
  Timeout - timeout threshold

Returns:

  EFI_SUCCESS    Success
  EFI_TIMEOUT    Timeout

--*/
{
  EFI_STATUS  Status;
  UINTN       Delay;

  //
  // Timeout is in US unit
  //
  Delay = (Timeout / 50) + 1;
  do {

    if (!IsAsyncScheduleEnabled (HcDev)) {
      Status = EFI_SUCCESS;
      goto exit;
    }
    gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);

  } while (Delay--);

  Status = EFI_TIMEOUT;

exit:
  return Status;
}

EFI_STATUS
WaitForPeriodicScheduleEnable (
  IN USB2_HC_DEV             *HcDev,
  IN UINTN                   Timeout
  )
/*++

Routine Description:

  Wait for Ehc periodic schedule enable or timeout

Arguments:

  HcDev   - USB2_HC_DEV
  Timeout - timeout threshold

Returns:

  EFI_SUCCESS    Success
  EFI_TIMEOUT    Timeout

--*/
{
  EFI_STATUS  Status;
  UINTN       Delay;

  //
  // Timeout is in US unit
  //
  Delay = (Timeout / 50) + 1;
  do {

    if (IsPeriodicScheduleEnabled (HcDev)) {
      Status = EFI_SUCCESS;
      goto exit;
    }
    gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);

  } while (Delay--);

  Status = EFI_TIMEOUT;

exit:
  return Status;
}

EFI_STATUS
WaitForPeriodicScheduleDisable (
  IN USB2_HC_DEV             *HcDev,
  IN UINTN                   Timeout
  )
/*++

Routine Description:

  Wait for periodic schedule disable or timeout

Arguments:

  HcDev   - USB2_HC_DEV
  Timeout - timeout threshold

Returns:

  EFI_SUCCESS    Success
  EFI_TIMEOUT    Timeout

--*/
{
  EFI_STATUS  Status;
  UINTN       Delay;

  //
  // Timeout is in US unit
  //
  Delay = (Timeout / 50) + 1;
  do {

    if (!IsPeriodicScheduleEnabled (HcDev)) {
      Status = EFI_SUCCESS;
      goto exit;
    }
    gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);

  } while (Delay--);

  Status = EFI_TIMEOUT;

exit:
  return Status;
}

EFI_STATUS
WaitForEhcDoorbell (
  IN USB2_HC_DEV             *HcDev,
  IN UINTN                   Timeout
  )
/*++

Routine Description:

  Wait for periodic schedule disable or timeout

Arguments:

  HcDev   - USB2_HC_DEV
  Timeout - timeout threshold

Returns:

  EFI_SUCCESS    Success
  EFI_TIMEOUT    Timeout

--*/
{
  EFI_STATUS  Status;
  UINT32      UsbCommandAddr;
  UINT32      UsbCommandReg;
  UINTN       Delay;

  UsbCommandAddr  = USBCMD;
  Delay           = (Timeout / 50) + 1;

  do {
    Status = ReadEhcOperationalReg (
               HcDev,
               UsbCommandAddr,
               &UsbCommandReg
               );
    if (EFI_ERROR (Status)) {
      Status = EFI_DEVICE_ERROR;
      goto exit;
    }
    if (!(UsbCommandReg & USBCMD_IAAD)) {
      break;
    }

  } while (--Delay);

  if (0 == Delay) {
    Status = EFI_TIMEOUT;
  }

exit:
  return Status;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?