--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ Ehchlp.c\r
+ \r
+Abstract: \r
+ \r
+\r
+Revision History\r
+--*/\r
+\r
+#include "Ehci.h"\r
+\r
+\r
+EFI_STATUS\r
+ReadEhcCapabiltiyReg (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT32 CapabiltiyRegAddr,\r
+ IN OUT UINT32 *Data\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Read Ehc Capabitlity register\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ CapabiltiyRegAddr - Ehc Capability register address\r
+ Data - A pointer to data read from register\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ return HcDev->PciIo->Mem.Read (\r
+ HcDev->PciIo,\r
+ EfiPciIoWidthUint32,\r
+ USB_BAR_INDEX,\r
+ (UINT64) CapabiltiyRegAddr,\r
+ 1,\r
+ Data\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+ReadEhcOperationalReg (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT32 OperationalRegAddr,\r
+ IN OUT UINT32 *Data\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Read Ehc Operation register\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ OperationalRegAddr - Ehc Operation register address\r
+ Data - A pointer to data read from register\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ ASSERT (mUsbCapabilityLen);\r
+ return HcDev->PciIo->Mem.Read (\r
+ HcDev->PciIo,\r
+ EfiPciIoWidthUint32,\r
+ USB_BAR_INDEX,\r
+ (UINT64) (OperationalRegAddr + mUsbCapabilityLen),\r
+ 1,\r
+ Data\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+WriteEhcOperationalReg (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT32 OperationalRegAddr,\r
+ IN UINT32 Data\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Write Ehc Operation register\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ OperationalRegAddr - Ehc Operation register address\r
+ Data - 32bit write to register\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ ASSERT (mUsbCapabilityLen);\r
+ return HcDev->PciIo->Mem.Write (\r
+ HcDev->PciIo,\r
+ EfiPciIoWidthUint32,\r
+ USB_BAR_INDEX,\r
+ (UINT64) (OperationalRegAddr + mUsbCapabilityLen),\r
+ 1,\r
+ &Data\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+GetCapabilityLen (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get the length of capability register\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 CapabilityLenAddr;\r
+\r
+ CapabilityLenAddr = CAPLENGTH;\r
+\r
+ Status = ReadEhcCapabiltiyReg (\r
+ HcDev,\r
+ CapabilityLenAddr,\r
+ &mUsbCapabilityLen\r
+ );\r
+ mUsbCapabilityLen = (UINT8) mUsbCapabilityLen;\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetFrameListLen (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Length\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set the length of Frame List\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Length - the required length of frame list\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_INVALID_PARAMETER Invalid parameter\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ if (256 != Length && 512 != Length) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ if (256 == Length) {\r
+ UsbCommandReg |= USBCMD_FLS_256;\r
+ } else {\r
+ UsbCommandReg |= USBCMD_FLS_512;\r
+ }\r
+\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetFrameListBaseAddr (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT32 FrameBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set base address of frame list first entry\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ FrameBuffer - base address of first entry of frame list\r
+ \r
+Returns:\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 PeriodicListBaseAddr;\r
+ UINT32 PeriodicListBaseReg;\r
+\r
+ Status = EFI_SUCCESS;\r
+ PeriodicListBaseAddr = PERIODICLISTBASE;\r
+ PeriodicListBaseReg = FrameBuffer & 0xfffff000;\r
+\r
+ if (IsEhcHalted (HcDev)) {\r
+\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ PeriodicListBaseAddr,\r
+ PeriodicListBaseReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetAsyncListAddr (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_QH_ENTITY *QhPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set address of first Async schedule Qh\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ QhPtr - A pointer to first Qh in the Async schedule\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 AsyncListAddr;\r
+ UINT32 AsyncListReg;\r
+\r
+ AsyncListAddr = ASYNCLISTADDR;\r
+ AsyncListReg = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh));\r
+\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ AsyncListAddr,\r
+ AsyncListReg\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetCtrlDataStructSeg (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set register of control and data structure segment\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 CtrlDsSegmentAddr;\r
+ UINT32 CtrlDsSegmentReg;\r
+\r
+ CtrlDsSegmentAddr = CTRLDSSGMENT;\r
+ CtrlDsSegmentReg = HcDev->High32BitAddr;\r
+\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ CtrlDsSegmentAddr,\r
+ CtrlDsSegmentReg\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetPortRoutingEhc (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set Ehc port routing bit\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 ConfigFlagAddr;\r
+ UINT32 ConfigFlagReg;\r
+\r
+ ConfigFlagAddr = CONFIGFLAG;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ ConfigFlagAddr,\r
+ &ConfigFlagReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ ConfigFlagReg |= CONFIGFLAG_CF;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ ConfigFlagAddr,\r
+ ConfigFlagReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetEhcDoorbell (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set Ehc door bell bit\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ UsbCommandReg |= USBCMD_IAAD;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+ClearEhcAllStatus (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Clear Ehc all status bits\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ UINT32 UsbStatusAddr;\r
+\r
+ UsbStatusAddr = USBSTS;\r
+\r
+ return WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbStatusAddr,\r
+ 0x003F\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+EnablePeriodicSchedule (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Enable periodic schedule\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ UsbCommandReg |= USBCMD_PSE;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+DisablePeriodicSchedule (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Disable periodic schedule\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ UsbCommandReg &= ~USBCMD_PSE;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EnableAsynchronousSchedule (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Enable asynchrounous schedule\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ UsbCommandReg |= USBCMD_ASE;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+DisableAsynchronousSchedule (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Disable asynchrounous schedule\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ UsbCommandReg &= ~USBCMD_ASE;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+ResetEhc (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Reset Ehc\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ UsbCommandReg |= USBCMD_HCRESET;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+StartScheduleExecution (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Start Ehc schedule execution\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ UsbCommandReg |= USBCMD_RS;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+BOOLEAN\r
+IsFrameListProgrammable (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether frame list is programmable\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Programmable\r
+ FALSE Unprogrammable\r
+ \r
+--*/\r
+{\r
+ BOOLEAN Value;\r
+ UINT32 HcCapParamsAddr;\r
+ UINT32 HcCapParamsReg;\r
+\r
+ HcCapParamsAddr = HCCPARAMS;\r
+\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ HcCapParamsAddr,\r
+ &HcCapParamsReg\r
+ );\r
+\r
+ if (HcCapParamsReg & HCCP_PFLF) {\r
+ Value = TRUE;\r
+ } else {\r
+ Value = FALSE;\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsPeriodicScheduleEnabled (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether periodic schedule is enabled\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Enabled\r
+ FALSE Disabled\r
+ \r
+--*/\r
+{\r
+ BOOLEAN Value;\r
+ UINT32 UsbStatusAddr;\r
+ UINT32 UsbStatusReg;\r
+\r
+ UsbStatusAddr = USBSTS;\r
+\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbStatusAddr,\r
+ &UsbStatusReg\r
+ );\r
+\r
+ if (UsbStatusReg & USBSTS_PSS) {\r
+ Value = TRUE;\r
+ } else {\r
+ Value = FALSE;\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsAsyncScheduleEnabled (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether asynchronous schedule is enabled\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Enabled\r
+ FALSE Disabled\r
+ \r
+--*/\r
+{\r
+ BOOLEAN Value;\r
+ UINT32 UsbStatusAddr;\r
+ UINT32 UsbStatusReg;\r
+\r
+ UsbStatusAddr = USBSTS;\r
+\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbStatusAddr,\r
+ &UsbStatusReg\r
+ );\r
+\r
+ if (UsbStatusReg & USBSTS_ASS) {\r
+ Value = TRUE;\r
+ } else {\r
+ Value = FALSE;\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsEhcPortEnabled (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 PortNum\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether port is enabled\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Enabled\r
+ FALSE Disabled\r
+ \r
+--*/\r
+{\r
+ UINT32 PortStatusControlAddr;\r
+ UINT32 PortStatusControlReg;\r
+\r
+ PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNum));\r
+\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ PortStatusControlAddr,\r
+ &PortStatusControlReg\r
+ );\r
+\r
+ return ((PortStatusControlReg & PORTSC_PED) ? TRUE : FALSE);\r
+}\r
+\r
+BOOLEAN\r
+IsEhcReseted (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Ehc is reseted\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Reseted\r
+ FALSE Unreseted\r
+ \r
+--*/\r
+{\r
+ BOOLEAN Value;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+\r
+ if (UsbCommandReg & USBCMD_HCRESET) {\r
+ Value = FALSE;\r
+ } else {\r
+ Value = TRUE;\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsEhcHalted (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Ehc is halted\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Halted\r
+ FALSE Not halted\r
+ \r
+--*/\r
+{\r
+ BOOLEAN Value;\r
+ UINT32 UsbStatusAddr;\r
+ UINT32 UsbStatusReg;\r
+\r
+ UsbStatusAddr = USBSTS;\r
+\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbStatusAddr,\r
+ &UsbStatusReg\r
+ );\r
+\r
+ if (UsbStatusReg & USBSTS_HCH) {\r
+ Value = TRUE;\r
+ } else {\r
+ Value = FALSE;\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsEhcSysError (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Ehc is system error\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE System error\r
+ FALSE No system error\r
+ \r
+--*/\r
+{\r
+ BOOLEAN Value;\r
+ UINT32 UsbStatusAddr;\r
+ UINT32 UsbStatusReg;\r
+\r
+ UsbStatusAddr = USBSTS;\r
+\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbStatusAddr,\r
+ &UsbStatusReg\r
+ );\r
+\r
+ if (UsbStatusReg & USBSTS_HSE) {\r
+ Value = TRUE;\r
+ } else {\r
+ Value = FALSE;\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsHighSpeedDevice (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 PortNum \r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether high speed device attached\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE High speed\r
+ FALSE Full speed\r
+ \r
+--*/\r
+{\r
+ USB2_HC_DEV *HcDev;\r
+ UINT32 PortStatusControlAddr;\r
+ UINT32 PortStatusControlReg;\r
+ \r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+ PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNum));\r
+\r
+ //\r
+ // Set port reset bit\r
+ //\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ PortStatusControlAddr,\r
+ &PortStatusControlReg\r
+ );\r
+ //\r
+ // Make sure Host Controller not halt before reset it\r
+ //\r
+ if (IsEhcHalted (HcDev)) {\r
+ StartScheduleExecution (HcDev);\r
+ WaitForEhcNotHalt (HcDev, EHCI_GENERIC_TIMEOUT);\r
+ }\r
+ PortStatusControlReg &= 0xffffffd5;\r
+ PortStatusControlReg |= PORTSC_PR;\r
+ //\r
+ // Set one to PortReset bit must also set zero to PortEnable bit\r
+ //\r
+ PortStatusControlReg &= ~PORTSC_PED;\r
+ WriteEhcOperationalReg (\r
+ HcDev,\r
+ PortStatusControlAddr,\r
+ PortStatusControlReg\r
+ );\r
+\r
+ //\r
+ // Set Port reset recovery time\r
+ //\r
+ gBS->Stall (EHCI_SET_PORT_RESET_RECOVERY_TIME);\r
+\r
+ //\r
+ // Clear port reset bit\r
+ //\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ PortStatusControlAddr,\r
+ &PortStatusControlReg\r
+ );\r
+ PortStatusControlReg &= 0xffffffd5;\r
+ PortStatusControlReg &= ~PORTSC_PR;\r
+ WriteEhcOperationalReg (\r
+ HcDev,\r
+ PortStatusControlAddr,\r
+ PortStatusControlReg\r
+ );\r
+\r
+ //\r
+ // Clear port reset recovery time\r
+ //\r
+ gBS->Stall (EHCI_CLEAR_PORT_RESET_RECOVERY_TIME);\r
+\r
+ return (IsEhcPortEnabled (HcDev, PortNum) ? TRUE : FALSE);\r
+}\r
+\r
+EFI_STATUS\r
+WaitForEhcReset (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ wait for Ehc reset or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Delay;\r
+\r
+ //\r
+ // Timeout is in US unit\r
+ //\r
+ Delay = (Timeout / 50) + 1;\r
+ do {\r
+\r
+ if (IsEhcReseted (HcDev)) {\r
+ Status = EFI_SUCCESS;\r
+ goto exit;\r
+ }\r
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+ } while (Delay--);\r
+\r
+ Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForEhcHalt (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ wait for Ehc halt or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Delay;\r
+\r
+ //\r
+ // Timeout is in US unit\r
+ //\r
+ Delay = (Timeout / 50) + 1;\r
+ do {\r
+\r
+ if (IsEhcHalted (HcDev)) {\r
+ Status = EFI_SUCCESS;\r
+ goto exit;\r
+ }\r
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+ } while (Delay--);\r
+\r
+ Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForEhcNotHalt (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ wait for Ehc not halt or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Delay;\r
+\r
+ //\r
+ // Timeout is in US unit\r
+ //\r
+ Delay = (Timeout / 50) + 1;\r
+ do {\r
+\r
+ if (!IsEhcHalted (HcDev)) {\r
+ Status = EFI_SUCCESS;\r
+ goto exit;\r
+ }\r
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+ } while (Delay--);\r
+\r
+ Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForAsyncScheduleEnable (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Wait for Ehc asynchronous schedule enable or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Delay;\r
+\r
+ //\r
+ // Timeout is in US unit\r
+ //\r
+ Delay = (Timeout / 50) + 1;\r
+ do {\r
+\r
+ if (IsAsyncScheduleEnabled (HcDev)) {\r
+ Status = EFI_SUCCESS;\r
+ goto exit;\r
+ }\r
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+ } while (Delay--);\r
+\r
+ Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForAsyncScheduleDisable (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Wait for Ehc asynchronous schedule disable or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Delay;\r
+\r
+ //\r
+ // Timeout is in US unit\r
+ //\r
+ Delay = (Timeout / 50) + 1;\r
+ do {\r
+\r
+ if (!IsAsyncScheduleEnabled (HcDev)) {\r
+ Status = EFI_SUCCESS;\r
+ goto exit;\r
+ }\r
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+ } while (Delay--);\r
+\r
+ Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForPeriodicScheduleEnable (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Wait for Ehc periodic schedule enable or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Delay;\r
+\r
+ //\r
+ // Timeout is in US unit\r
+ //\r
+ Delay = (Timeout / 50) + 1;\r
+ do {\r
+\r
+ if (IsPeriodicScheduleEnabled (HcDev)) {\r
+ Status = EFI_SUCCESS;\r
+ goto exit;\r
+ }\r
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+ } while (Delay--);\r
+\r
+ Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForPeriodicScheduleDisable (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Wait for periodic schedule disable or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Delay;\r
+\r
+ //\r
+ // Timeout is in US unit\r
+ //\r
+ Delay = (Timeout / 50) + 1;\r
+ do {\r
+\r
+ if (!IsPeriodicScheduleEnabled (HcDev)) {\r
+ Status = EFI_SUCCESS;\r
+ goto exit;\r
+ }\r
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+ } while (Delay--);\r
+\r
+ Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForEhcDoorbell (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Wait for periodic schedule disable or timeout\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+ UINTN Delay;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+ Delay = (Timeout / 50) + 1;\r
+ \r
+ do {\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ if (!(UsbCommandReg & USBCMD_IAAD)) {\r
+ break;\r
+ }\r
+ \r
+ } while (--Delay);\r
+\r
+ if (0 == Delay) {\r
+ Status = EFI_TIMEOUT;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r