diff options
Diffstat (limited to 'EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciReg.c')
-rw-r--r-- | EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciReg.c | 1539 |
1 files changed, 1539 insertions, 0 deletions
diff --git a/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciReg.c b/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciReg.c new file mode 100644 index 0000000000..9ce816ecc9 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciReg.c @@ -0,0 +1,1539 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Ehchlp.c
+
+Abstract:
+
+
+Revision History
+--*/
+
+#include "Ehci.h"
+
+
+EFI_STATUS
+ReadEhcCapabiltiyReg (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT32 CapabiltiyRegAddr,
+ IN OUT UINT32 *Data
+ )
+/*++
+
+Routine Description:
+
+ Read Ehc Capabitlity register
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ CapabiltiyRegAddr - Ehc Capability register address
+ Data - A pointer to data read from register
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ return HcDev->PciIo->Mem.Read (
+ HcDev->PciIo,
+ EfiPciIoWidthUint32,
+ USB_BAR_INDEX,
+ (UINT64) CapabiltiyRegAddr,
+ 1,
+ Data
+ );
+}
+
+EFI_STATUS
+ReadEhcOperationalReg (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT32 OperationalRegAddr,
+ IN OUT UINT32 *Data
+ )
+/*++
+
+Routine Description:
+
+ Read Ehc Operation register
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ OperationalRegAddr - Ehc Operation register address
+ Data - A pointer to data read from register
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ ASSERT (mUsbCapabilityLen);
+ return HcDev->PciIo->Mem.Read (
+ HcDev->PciIo,
+ EfiPciIoWidthUint32,
+ USB_BAR_INDEX,
+ (UINT64) (OperationalRegAddr + mUsbCapabilityLen),
+ 1,
+ Data
+ );
+}
+
+EFI_STATUS
+WriteEhcOperationalReg (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT32 OperationalRegAddr,
+ IN UINT32 Data
+ )
+/*++
+
+Routine Description:
+
+ Write Ehc Operation register
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ OperationalRegAddr - Ehc Operation register address
+ Data - 32bit write to register
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ ASSERT (mUsbCapabilityLen);
+ return HcDev->PciIo->Mem.Write (
+ HcDev->PciIo,
+ EfiPciIoWidthUint32,
+ USB_BAR_INDEX,
+ (UINT64) (OperationalRegAddr + mUsbCapabilityLen),
+ 1,
+ &Data
+ );
+}
+
+EFI_STATUS
+GetCapabilityLen (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Get the length of capability register
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 CapabilityLenAddr;
+
+ CapabilityLenAddr = CAPLENGTH;
+
+ Status = ReadEhcCapabiltiyReg (
+ HcDev,
+ CapabilityLenAddr,
+ &mUsbCapabilityLen
+ );
+ mUsbCapabilityLen = (UINT8) mUsbCapabilityLen;
+
+ return Status;
+}
+
+EFI_STATUS
+SetFrameListLen (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Set the length of Frame List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Length - the required length of frame list
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_INVALID_PARAMETER Invalid parameter
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 UsbCommandAddr;
+ UINT32 UsbCommandReg;
+
+ UsbCommandAddr = USBCMD;
+
+ if (256 != Length && 512 != Length) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ Status = ReadEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ &UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ if (256 == Length) {
+ UsbCommandReg |= USBCMD_FLS_256;
+ } else {
+ UsbCommandReg |= USBCMD_FLS_512;
+ }
+
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+SetFrameListBaseAddr (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT32 FrameBuffer
+ )
+/*++
+
+Routine Description:
+
+ Set base address of frame list first entry
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ FrameBuffer - base address of first entry of frame list
+
+Returns:
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 PeriodicListBaseAddr;
+ UINT32 PeriodicListBaseReg;
+
+ Status = EFI_SUCCESS;
+ PeriodicListBaseAddr = PERIODICLISTBASE;
+ PeriodicListBaseReg = FrameBuffer & 0xfffff000;
+
+ if (IsEhcHalted (HcDev)) {
+
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ PeriodicListBaseAddr,
+ PeriodicListBaseReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+SetAsyncListAddr (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_QH_ENTITY *QhPtr
+ )
+/*++
+
+Routine Description:
+
+ Set address of first Async schedule Qh
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ QhPtr - A pointer to first Qh in the Async schedule
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 AsyncListAddr;
+ UINT32 AsyncListReg;
+
+ AsyncListAddr = ASYNCLISTADDR;
+ AsyncListReg = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh));
+
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ AsyncListAddr,
+ AsyncListReg
+ );
+
+ return Status;
+}
+
+EFI_STATUS
+SetCtrlDataStructSeg (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Set register of control and data structure segment
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 CtrlDsSegmentAddr;
+ UINT32 CtrlDsSegmentReg;
+
+ CtrlDsSegmentAddr = CTRLDSSGMENT;
+ CtrlDsSegmentReg = HcDev->High32BitAddr;
+
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ CtrlDsSegmentAddr,
+ CtrlDsSegmentReg
+ );
+
+ return Status;
+}
+
+EFI_STATUS
+SetPortRoutingEhc (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Set Ehc port routing bit
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 ConfigFlagAddr;
+ UINT32 ConfigFlagReg;
+
+ ConfigFlagAddr = CONFIGFLAG;
+
+ Status = ReadEhcOperationalReg (
+ HcDev,
+ ConfigFlagAddr,
+ &ConfigFlagReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ ConfigFlagReg |= CONFIGFLAG_CF;
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ ConfigFlagAddr,
+ ConfigFlagReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+SetEhcDoorbell (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Set Ehc door bell bit
+
+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_IAAD;
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+ClearEhcAllStatus (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Clear Ehc all status bits
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ UINT32 UsbStatusAddr;
+
+ UsbStatusAddr = USBSTS;
+
+ return WriteEhcOperationalReg (
+ HcDev,
+ UsbStatusAddr,
+ 0x003F
+ );
+}
+
+EFI_STATUS
+EnablePeriodicSchedule (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Enable periodic schedule
+
+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_PSE;
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+DisablePeriodicSchedule (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Disable periodic schedule
+
+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)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ UsbCommandReg &= ~USBCMD_PSE;
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EnableAsynchronousSchedule (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Enable asynchrounous schedule
+
+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_ASE;
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+DisableAsynchronousSchedule (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Disable asynchrounous schedule
+
+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)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ 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;
+
+ ReadEhcOperationalReg (
+ 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;
+}
|