--- /dev/null
+/** @file\r
+Private Header file for Usb Host Controller PEIM\r
+\r
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+ \r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions\r
+of the BSD License which accompanies this distribution. The\r
+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
+**/\r
+\r
+#ifndef _RECOVERY_UHC_H_\r
+#define _RECOVERY_UHC_H_\r
+\r
+\r
+#include <PiPei.h>\r
+\r
+#include <Ppi/UsbController.h>\r
+#include <Ppi/UsbHostController.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/PeimEntryPoint.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+\r
+#define USB_SLOW_SPEED_DEVICE 0x01\r
+#define USB_FULL_SPEED_DEVICE 0x02\r
+\r
+//\r
+// One memory block uses 16 page\r
+//\r
+#define NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES 16\r
+\r
+#define USBCMD 0 /* Command Register Offset 00-01h */\r
+#define USBCMD_RS BIT0 /* Run/Stop */\r
+#define USBCMD_HCRESET BIT1 /* Host reset */\r
+#define USBCMD_GRESET BIT2 /* Global reset */\r
+#define USBCMD_EGSM BIT3 /* Global Suspend Mode */\r
+#define USBCMD_FGR BIT4 /* Force Global Resume */\r
+#define USBCMD_SWDBG BIT5 /* SW Debug mode */\r
+#define USBCMD_CF BIT6 /* Config Flag (sw only) */\r
+#define USBCMD_MAXP BIT7 /* Max Packet (0 = 32, 1 = 64) */\r
+\r
+/* Status register */\r
+#define USBSTS 2 /* Status Register Offset 02-03h */\r
+#define USBSTS_USBINT BIT0 /* Interrupt due to IOC */\r
+#define USBSTS_ERROR BIT1 /* Interrupt due to error */\r
+#define USBSTS_RD BIT2 /* Resume Detect */\r
+#define USBSTS_HSE BIT3 /* Host System Error - basically PCI problems */\r
+#define USBSTS_HCPE BIT4 /* Host Controller Process Error - the scripts were buggy */\r
+#define USBSTS_HCH BIT5 /* HC Halted */\r
+\r
+/* Interrupt enable register */\r
+#define USBINTR 4 /* Interrupt Enable Register 04-05h */\r
+#define USBINTR_TIMEOUT BIT0 /* Timeout/CRC error enable */\r
+#define USBINTR_RESUME BIT1 /* Resume interrupt enable */\r
+#define USBINTR_IOC BIT2 /* Interrupt On Complete enable */\r
+#define USBINTR_SP BIT3 /* Short packet interrupt enable */\r
+\r
+/* Frame Number Register Offset 06-08h */\r
+#define USBFRNUM 6\r
+\r
+/* Frame List Base Address Register Offset 08-0Bh */\r
+#define USBFLBASEADD 8\r
+\r
+/* Start of Frame Modify Register Offset 0Ch */\r
+#define USBSOF 0x0c\r
+\r
+/* USB port status and control registers */\r
+#define USBPORTSC1 0x10 /*Port 1 offset 10-11h */\r
+#define USBPORTSC2 0x12 /*Port 2 offset 12-13h */\r
+\r
+#define USBPORTSC_CCS BIT0 /* Current Connect Status ("device present") */\r
+#define USBPORTSC_CSC BIT1 /* Connect Status Change */\r
+#define USBPORTSC_PED BIT2 /* Port Enable / Disable */\r
+#define USBPORTSC_PEDC BIT3 /* Port Enable / Disable Change */\r
+#define USBPORTSC_LSL BIT4 /* Line Status Low bit*/\r
+#define USBPORTSC_LSH BIT5 /* Line Status High bit*/\r
+#define USBPORTSC_RD BIT6 /* Resume Detect */\r
+#define USBPORTSC_LSDA BIT8 /* Low Speed Device Attached */\r
+#define USBPORTSC_PR BIT9 /* Port Reset */\r
+#define USBPORTSC_SUSP BIT12 /* Suspend */\r
+\r
+#define SETUP_PACKET_ID 0x2D\r
+#define INPUT_PACKET_ID 0x69\r
+#define OUTPUT_PACKET_ID 0xE1\r
+#define ERROR_PACKET_ID 0x55\r
+\r
+#define STALL_1_MILLI_SECOND 1000\r
+\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+ UINT32 FrameListPtrTerminate : 1;\r
+ UINT32 FrameListPtrQSelect : 1;\r
+ UINT32 FrameListRsvd : 2;\r
+ UINT32 FrameListPtr : 28;\r
+} FRAMELIST_ENTRY;\r
+\r
+typedef struct {\r
+ UINT32 QHHorizontalTerminate : 1;\r
+ UINT32 QHHorizontalQSelect : 1;\r
+ UINT32 QHHorizontalRsvd : 2;\r
+ UINT32 QHHorizontalPtr : 28;\r
+ UINT32 QHVerticalTerminate : 1;\r
+ UINT32 QHVerticalQSelect : 1;\r
+ UINT32 QHVerticalRsvd : 2;\r
+ UINT32 QHVerticalPtr : 28;\r
+} QUEUE_HEAD;\r
+\r
+typedef struct {\r
+ QUEUE_HEAD QueueHead;\r
+ UINT32 Reserved1;\r
+ UINT32 Reserved2;\r
+ VOID *PtrNext;\r
+ VOID *PtrDown;\r
+ VOID *Reserved3;\r
+ UINT32 Reserved4;\r
+} QH_STRUCT;\r
+\r
+typedef struct {\r
+ UINT32 TDLinkPtrTerminate : 1;\r
+ UINT32 TDLinkPtrQSelect : 1;\r
+ UINT32 TDLinkPtrDepthSelect : 1;\r
+ UINT32 TDLinkPtrRsvd : 1;\r
+ UINT32 TDLinkPtr : 28;\r
+ UINT32 TDStatusActualLength : 11;\r
+ UINT32 TDStatusRsvd : 5;\r
+ UINT32 TDStatus : 8;\r
+ UINT32 TDStatusIOC : 1;\r
+ UINT32 TDStatusIOS : 1;\r
+ UINT32 TDStatusLS : 1;\r
+ UINT32 TDStatusErr : 2;\r
+ UINT32 TDStatusSPD : 1;\r
+ UINT32 TDStatusRsvd2 : 2;\r
+ UINT32 TDTokenPID : 8;\r
+ UINT32 TDTokenDevAddr : 7;\r
+ UINT32 TDTokenEndPt : 4;\r
+ UINT32 TDTokenDataToggle : 1;\r
+ UINT32 TDTokenRsvd : 1;\r
+ UINT32 TDTokenMaxLen : 11;\r
+ UINT32 TDBufferPtr;\r
+} TD;\r
+\r
+typedef struct {\r
+ TD TDData;\r
+ UINT8 *PtrTDBuffer;\r
+ VOID *PtrNextTD;\r
+ VOID *PtrNextQH;\r
+ UINT16 TDBufferLength;\r
+ UINT16 Reserved;\r
+} TD_STRUCT;\r
+\r
+#pragma pack()\r
+\r
+typedef struct _MEMORY_MANAGE_HEADER MEMORY_MANAGE_HEADER;\r
+\r
+struct _MEMORY_MANAGE_HEADER {\r
+ UINT8 *BitArrayPtr;\r
+ UINTN BitArraySizeInBytes;\r
+ UINT8 *MemoryBlockPtr;\r
+ UINTN MemoryBlockSizeInBytes;\r
+ MEMORY_MANAGE_HEADER *Next;\r
+};\r
+\r
+#define USB_UHC_DEV_SIGNATURE SIGNATURE_32 ('p', 'u', 'h', 'c')\r
+typedef struct {\r
+ UINTN Signature;\r
+ PEI_USB_HOST_CONTROLLER_PPI UsbHostControllerPpi;\r
+ EFI_PEI_PPI_DESCRIPTOR PpiDescriptor;\r
+\r
+ UINT32 UsbHostControllerBaseAddress;\r
+ FRAMELIST_ENTRY *FrameListEntry;\r
+ QH_STRUCT *ConfigQH;\r
+ QH_STRUCT *BulkQH;\r
+ //\r
+ // Header1 used for QH,TD memory blocks management\r
+ //\r
+ MEMORY_MANAGE_HEADER *Header1;\r
+\r
+} USB_UHC_DEV;\r
+\r
+#define PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS(a) CR (a, USB_UHC_DEV, UsbHostControllerPpi, USB_UHC_DEV_SIGNATURE)\r
+\r
+/**\r
+ Submits control transfer to a target USB device.\r
+ \r
+ @param PeiServices The pointer of EFI_PEI_SERVICES.\r
+ @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI.\r
+ @param DeviceAddress The target device address.\r
+ @param DeviceSpeed Target device speed.\r
+ @param MaximumPacketLength Maximum packet size the default control transfer \r
+ endpoint is capable of sending or receiving.\r
+ @param Request USB device request to send.\r
+ @param TransferDirection Specifies the data direction for the data stage.\r
+ @param Data Data buffer to be transmitted or received from USB device.\r
+ @param DataLength The size (in bytes) of the data buffer.\r
+ @param TimeOut Indicates the maximum timeout, in millisecond.\r
+ @param TransferResult Return the result of this control transfer.\r
+\r
+ @retval EFI_SUCCESS Transfer was completed successfully.\r
+ @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources.\r
+ @retval EFI_INVALID_PARAMETER Some parameters are invalid.\r
+ @retval EFI_TIMEOUT Transfer failed due to timeout.\r
+ @retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UhcControlTransfer (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN PEI_USB_HOST_CONTROLLER_PPI * This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINT8 MaximumPacketLength,\r
+ IN EFI_USB_DEVICE_REQUEST * Request,\r
+ IN EFI_USB_DATA_DIRECTION TransferDirection,\r
+ IN OUT VOID *Data OPTIONAL,\r
+ IN OUT UINTN *DataLength OPTIONAL,\r
+ IN UINTN TimeOut,\r
+ OUT UINT32 *TransferResult\r
+ );\r
+\r
+/**\r
+ Submits bulk transfer to a bulk endpoint of a USB device.\r
+ \r
+ @param PeiServices The pointer of EFI_PEI_SERVICES.\r
+ @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI.\r
+ @param DeviceAddress Target device address.\r
+ @param EndPointAddress Endpoint number and its direction in bit 7.\r
+ @param MaximumPacketLength Maximum packet size the endpoint is capable of \r
+ sending or receiving.\r
+ @param Data Array of pointers to the buffers of data to transmit \r
+ from or receive into.\r
+ @param DataLength The lenght of the data buffer.\r
+ @param DataToggle On input, the initial data toggle for the transfer;\r
+ On output, it is updated to to next data toggle to use of \r
+ the subsequent bulk transfer.\r
+ @param TimeOut Indicates the maximum time, in millisecond, which the\r
+ transfer is allowed to complete.\r
+ @param TransferResult A pointer to the detailed result information of the\r
+ bulk transfer.\r
+\r
+ @retval EFI_SUCCESS The transfer was completed successfully.\r
+ @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource.\r
+ @retval EFI_INVALID_PARAMETER Parameters are invalid.\r
+ @retval EFI_TIMEOUT The transfer failed due to timeout.\r
+ @retval EFI_DEVICE_ERROR The transfer failed due to host controller error.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UhcBulkTransfer (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 MaximumPacketLength,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ OUT UINT32 *TransferResult\r
+ );\r
+\r
+/**\r
+ Retrieves the number of root hub ports.\r
+\r
+ @param[in] PeiServices The pointer to the PEI Services Table.\r
+ @param[in] This The pointer to this instance of the \r
+ PEI_USB_HOST_CONTROLLER_PPI.\r
+ @param[out] PortNumber The pointer to the number of the root hub ports. \r
+ \r
+ @retval EFI_SUCCESS The port number was retrieved successfully.\r
+ @retval EFI_INVALID_PARAMETER PortNumber is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UhcGetRootHubPortNumber (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,\r
+ OUT UINT8 *PortNumber\r
+ );\r
+\r
+/**\r
+ Retrieves the current status of a USB root hub port.\r
+ \r
+ @param PeiServices The pointer of EFI_PEI_SERVICES.\r
+ @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI.\r
+ @param PortNumber The root hub port to retrieve the state from. \r
+ @param PortStatus Variable to receive the port state.\r
+\r
+ @retval EFI_SUCCESS The status of the USB root hub port specified.\r
+ by PortNumber was returned in PortStatus.\r
+ @retval EFI_INVALID_PARAMETER PortNumber is invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UhcGetRootHubPortStatus (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,\r
+ IN UINT8 PortNumber,\r
+ OUT EFI_USB_PORT_STATUS *PortStatus\r
+ );\r
+\r
+/**\r
+ Sets a feature for the specified root hub port.\r
+ \r
+ @param PeiServices The pointer of EFI_PEI_SERVICES\r
+ @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI\r
+ @param PortNumber Root hub port to set.\r
+ @param PortFeature Feature to set.\r
+\r
+ @retval EFI_SUCCESS The feature specified by PortFeature was set.\r
+ @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.\r
+ @retval EFI_TIMEOUT The time out occurred.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UhcSetRootHubPortFeature (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,\r
+ IN UINT8 PortNumber,\r
+ IN EFI_USB_PORT_FEATURE PortFeature\r
+ );\r
+\r
+/**\r
+ Clears a feature for the specified root hub port.\r
+ \r
+ @param PeiServices The pointer of EFI_PEI_SERVICES.\r
+ @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI.\r
+ @param PortNumber Specifies the root hub port whose feature\r
+ is requested to be cleared.\r
+ @param PortFeature Indicates the feature selector associated with the\r
+ feature clear request.\r
+\r
+ @retval EFI_SUCCESS The feature specified by PortFeature was cleared \r
+ for the USB root hub port specified by PortNumber.\r
+ @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UhcClearRootHubPortFeature (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,\r
+ IN UINT8 PortNumber,\r
+ IN EFI_USB_PORT_FEATURE PortFeature\r
+ );\r
+\r
+/**\r
+ Initialize UHCI.\r
+\r
+ @param UhcDev UHCI Device.\r
+\r
+ @retval EFI_SUCCESS UHCI successfully initialized.\r
+ @retval EFI_OUT_OF_RESOURCES Resource can not be allocated.\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeUsbHC (\r
+ IN USB_UHC_DEV *UhcDev\r
+ );\r
+\r
+/**\r
+ Create Frame List Structure.\r
+\r
+ @param UhcDev UHCI device.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
+ @retval EFI_SUCCESS Success.\r
+\r
+**/\r
+EFI_STATUS\r
+CreateFrameList (\r
+ USB_UHC_DEV *UhcDev\r
+ );\r
+\r
+/**\r
+ Read a 16bit width data from Uhc HC IO space register.\r
+ \r
+ @param UhcDev The UHCI device.\r
+ @param Port The IO space address of the register.\r
+\r
+ @retval the register content read.\r
+\r
+**/\r
+UINT16\r
+USBReadPortW (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ IN UINT32 Port\r
+ );\r
+\r
+/**\r
+ Write a 16bit width data into Uhc HC IO space register.\r
+ \r
+ @param UhcDev The UHCI device.\r
+ @param Port The IO space address of the register.\r
+ @param Data The data written into the register.\r
+\r
+**/\r
+VOID\r
+USBWritePortW (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ IN UINT32 Port,\r
+ IN UINT16 Data\r
+ );\r
+\r
+/**\r
+ Write a 32bit width data into Uhc HC IO space register.\r
+ \r
+ @param UhcDev The UHCI device.\r
+ @param Port The IO space address of the register.\r
+ @param Data The data written into the register.\r
+\r
+**/\r
+VOID\r
+USBWritePortDW (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ IN UINT32 Port,\r
+ IN UINT32 Data\r
+ );\r
+\r
+/**\r
+ Clear the content of UHCI's Status Register.\r
+ \r
+ @param UhcDev The UHCI device.\r
+ @param StatusAddr The IO space address of the register.\r
+\r
+**/\r
+VOID\r
+ClearStatusReg (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ IN UINT32 StatusAddr\r
+ );\r
+\r
+/**\r
+ Check whether the host controller operates well.\r
+\r
+ @param UhcDev The UHCI device.\r
+ @param StatusRegAddr The io address of status register.\r
+\r
+ @retval TRUE Host controller is working.\r
+ @retval FALSE Host controller is halted or system error.\r
+\r
+**/\r
+BOOLEAN\r
+IsStatusOK (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ IN UINT32 StatusRegAddr\r
+ );\r
+\r
+/**\r
+ Get Current Frame Number.\r
+\r
+ @param UhcDev The UHCI device.\r
+ @param FrameNumberAddr The address of frame list register.\r
+\r
+ @retval The content of the frame list register.\r
+\r
+**/\r
+UINT16\r
+GetCurrentFrameNumber (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ IN UINT32 FrameNumberAddr\r
+ );\r
+\r
+/**\r
+ Set Frame List Base Address.\r
+\r
+ @param UhcDev The UHCI device.\r
+ @param FrameListRegAddr The address of frame list register.\r
+ @param Addr The address of frame list table.\r
+\r
+**/\r
+VOID\r
+SetFrameListBaseAddress (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ IN UINT32 FrameListRegAddr,\r
+ IN UINT32 Addr\r
+ );\r
+\r
+/**\r
+ Create QH and initialize.\r
+\r
+ @param UhcDev The UHCI device.\r
+ @param PtrQH Place to store QH_STRUCT pointer.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
+ @retval EFI_SUCCESS Success.\r
+\r
+**/\r
+EFI_STATUS\r
+CreateQH (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ OUT QH_STRUCT **PtrQH\r
+ );\r
+\r
+/**\r
+ Set the horizontal link pointer in QH.\r
+\r
+ @param PtrQH Place to store QH_STRUCT pointer.\r
+ @param PtrNext Place to the next QH_STRUCT.\r
+\r
+**/\r
+VOID\r
+SetQHHorizontalLinkPtr (\r
+ IN QH_STRUCT *PtrQH,\r
+ IN VOID *PtrNext\r
+ );\r
+\r
+/**\r
+ Get the horizontal link pointer in QH.\r
+\r
+ @param PtrQH Place to store QH_STRUCT pointer.\r
+\r
+ @retval The horizontal link pointer in QH.\r
+\r
+**/\r
+VOID *\r
+GetQHHorizontalLinkPtr (\r
+ IN QH_STRUCT *PtrQH\r
+ );\r
+\r
+/**\r
+ Set a QH or TD horizontally to be connected with a specific QH.\r
+\r
+ @param PtrQH Place to store QH_STRUCT pointer.\r
+ @param IsQH Specify QH or TD is connected.\r
+\r
+**/\r
+VOID\r
+SetQHHorizontalQHorTDSelect (\r
+ IN QH_STRUCT *PtrQH,\r
+ IN BOOLEAN IsQH\r
+ );\r
+\r
+/**\r
+ Set the horizontal validor bit in QH.\r
+\r
+ @param PtrQH Place to store QH_STRUCT pointer.\r
+ @param IsValid Specify the horizontal linker is valid or not.\r
+\r
+**/\r
+VOID\r
+SetQHHorizontalValidorInvalid (\r
+ IN QH_STRUCT *PtrQH,\r
+ IN BOOLEAN IsValid\r
+ );\r
+\r
+/**\r
+ Set the vertical link pointer in QH.\r
+\r
+ @param PtrQH Place to store QH_STRUCT pointer.\r
+ @param PtrNext Place to the next QH_STRUCT.\r
+\r
+**/\r
+VOID\r
+SetQHVerticalLinkPtr (\r
+ IN QH_STRUCT *PtrQH,\r
+ IN VOID *PtrNext\r
+ );\r
+\r
+/**\r
+ Set a QH or TD vertically to be connected with a specific QH.\r
+\r
+ @param PtrQH Place to store QH_STRUCT pointer.\r
+ @param IsQH Specify QH or TD is connected.\r
+\r
+**/\r
+VOID\r
+SetQHVerticalQHorTDSelect (\r
+ IN QH_STRUCT *PtrQH,\r
+ IN BOOLEAN IsQH\r
+ );\r
+\r
+/**\r
+ Set the vertical validor bit in QH.\r
+\r
+ @param PtrQH Place to store QH_STRUCT pointer.\r
+ @param IsValid Specify the vertical linker is valid or not.\r
+\r
+**/\r
+VOID\r
+SetQHVerticalValidorInvalid (\r
+ IN QH_STRUCT *PtrQH,\r
+ IN BOOLEAN IsValid\r
+ );\r
+\r
+/**\r
+ Get the vertical validor bit in QH.\r
+\r
+ @param PtrQH Place to store QH_STRUCT pointer.\r
+\r
+ @retval The vertical linker is valid or not.\r
+\r
+**/\r
+BOOLEAN\r
+GetQHHorizontalValidorInvalid (\r
+ IN QH_STRUCT *PtrQH\r
+ );\r
+\r
+/**\r
+ Allocate TD or QH Struct.\r
+\r
+ @param UhcDev The UHCI device.\r
+ @param Size The size of allocation.\r
+ @param PtrStruct Place to store TD_STRUCT pointer.\r
+\r
+ @return EFI_SUCCESS Allocate successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource.\r
+\r
+**/\r
+EFI_STATUS\r
+AllocateTDorQHStruct (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ IN UINT32 Size,\r
+ OUT VOID **PtrStruct\r
+ );\r
+\r
+/**\r
+ Create a TD Struct.\r
+\r
+ @param UhcDev The UHCI device.\r
+ @param PtrTD Place to store TD_STRUCT pointer.\r
+\r
+ @return EFI_SUCCESS Allocate successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource.\r
+\r
+**/\r
+EFI_STATUS\r
+CreateTD (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ OUT TD_STRUCT **PtrTD\r
+ );\r
+\r
+/**\r
+ Generate Setup Stage TD.\r
+\r
+ @param UhcDev The UHCI device.\r
+ @param DevAddr Device address.\r
+ @param Endpoint Endpoint number.\r
+ @param DeviceSpeed Device Speed.\r
+ @param DevRequest Device reuquest.\r
+ @param RequestLen Request length.\r
+ @param PtrTD TD_STRUCT generated.\r
+\r
+ @return EFI_SUCCESS Generate setup stage TD successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource.\r
+\r
+**/\r
+EFI_STATUS\r
+GenSetupStageTD (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ IN UINT8 DevAddr,\r
+ IN UINT8 Endpoint,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINT8 *DevRequest,\r
+ IN UINT8 RequestLen,\r
+ OUT TD_STRUCT **PtrTD\r
+ );\r
+\r
+/**\r
+ Generate Data Stage TD.\r
+\r
+ @param UhcDev The UHCI device.\r
+ @param DevAddr Device address.\r
+ @param Endpoint Endpoint number.\r
+ @param PtrData Data buffer.\r
+ @param Len Data length.\r
+ @param PktID PacketID.\r
+ @param Toggle Data toggle value.\r
+ @param DeviceSpeed Device Speed.\r
+ @param PtrTD TD_STRUCT generated.\r
+\r
+ @return EFI_SUCCESS Generate data stage TD successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource.\r
+\r
+**/\r
+EFI_STATUS\r
+GenDataTD (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ IN UINT8 DevAddr,\r
+ IN UINT8 Endpoint,\r
+ IN UINT8 *PtrData,\r
+ IN UINT8 Len,\r
+ IN UINT8 PktID,\r
+ IN UINT8 Toggle,\r
+ IN UINT8 DeviceSpeed,\r
+ OUT TD_STRUCT **PtrTD\r
+ );\r
+\r
+/**\r
+ Generate Status Stage TD.\r
+\r
+ @param UhcDev The UHCI device.\r
+ @param DevAddr Device address.\r
+ @param Endpoint Endpoint number.\r
+ @param PktID PacketID.\r
+ @param DeviceSpeed Device Speed.\r
+ @param PtrTD TD_STRUCT generated.\r
+\r
+ @return EFI_SUCCESS Generate status stage TD successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource.\r
+\r
+**/\r
+EFI_STATUS\r
+CreateStatusTD (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ IN UINT8 DevAddr,\r
+ IN UINT8 Endpoint,\r
+ IN UINT8 PktID,\r
+ IN UINT8 DeviceSpeed,\r
+ OUT TD_STRUCT **PtrTD\r
+ );\r
+\r
+/**\r
+ Set the link pointer validor bit in TD.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+ @param IsValid Specify the linker pointer is valid or not.\r
+\r
+**/\r
+VOID\r
+SetTDLinkPtrValidorInvalid (\r
+ IN TD_STRUCT *PtrTDStruct,\r
+ IN BOOLEAN IsValid\r
+ );\r
+\r
+/**\r
+ Set the Link Pointer pointing to a QH or TD.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+ @param IsQH Specify QH or TD is connected.\r
+\r
+**/\r
+VOID\r
+SetTDLinkPtrQHorTDSelect (\r
+ IN TD_STRUCT *PtrTDStruct,\r
+ IN BOOLEAN IsQH\r
+ );\r
+\r
+/**\r
+ Set the traverse is depth-first or breadth-first.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+ @param IsDepth Specify the traverse is depth-first or breadth-first.\r
+\r
+**/\r
+VOID\r
+SetTDLinkPtrDepthorBreadth (\r
+ IN TD_STRUCT *PtrTDStruct,\r
+ IN BOOLEAN IsDepth\r
+ );\r
+\r
+/**\r
+ Set TD Link Pointer in TD.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+ @param PtrNext Place to the next TD_STRUCT.\r
+\r
+**/\r
+VOID\r
+SetTDLinkPtr (\r
+ IN TD_STRUCT *PtrTDStruct,\r
+ IN VOID *PtrNext\r
+ );\r
+\r
+/**\r
+ Get TD Link Pointer.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+\r
+ @retval Get TD Link Pointer in TD.\r
+\r
+**/\r
+VOID*\r
+GetTDLinkPtr (\r
+ IN TD_STRUCT *PtrTDStruct\r
+ );\r
+\r
+/**\r
+ Get the information about whether the Link Pointer field pointing to\r
+ a QH or a TD.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+\r
+ @retval whether the Link Pointer field pointing to a QH or a TD.\r
+\r
+**/\r
+BOOLEAN\r
+IsTDLinkPtrQHOrTD (\r
+ IN TD_STRUCT *PtrTDStruct\r
+ );\r
+\r
+/**\r
+ Enable/Disable short packet detection mechanism.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+ @param IsEnable Enable or disable short packet detection mechanism.\r
+\r
+**/\r
+VOID\r
+EnableorDisableTDShortPacket (\r
+ IN TD_STRUCT *PtrTDStruct,\r
+ IN BOOLEAN IsEnable\r
+ );\r
+\r
+/**\r
+ Set the max error counter in TD.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+ @param MaxErrors The number of allowable error.\r
+\r
+**/\r
+VOID\r
+SetTDControlErrorCounter (\r
+ IN TD_STRUCT *PtrTDStruct,\r
+ IN UINT8 MaxErrors\r
+ );\r
+\r
+/**\r
+ Set the TD is targeting a low-speed device or not.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+ @param IsLowSpeedDevice Whether The device is low-speed.\r
+\r
+**/\r
+VOID\r
+SetTDLoworFullSpeedDevice (\r
+ IN TD_STRUCT *PtrTDStruct,\r
+ IN BOOLEAN IsLowSpeedDevice\r
+ );\r
+\r
+/**\r
+ Set the TD is isochronous transfer type or not.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+ @param IsIsochronous Whether the transaction isochronous transfer type.\r
+\r
+**/\r
+VOID\r
+SetTDControlIsochronousorNot (\r
+ IN TD_STRUCT *PtrTDStruct,\r
+ IN BOOLEAN IsIsochronous\r
+ );\r
+\r
+/**\r
+ Set if UCHI should issue an interrupt on completion of the frame\r
+ in which this TD is executed\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+ @param IsSet Whether HC should issue an interrupt on completion.\r
+\r
+**/\r
+VOID\r
+SetorClearTDControlIOC (\r
+ IN TD_STRUCT *PtrTDStruct,\r
+ IN BOOLEAN IsSet\r
+ );\r
+\r
+/**\r
+ Set if the TD is active and can be executed.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+ @param IsActive Whether the TD is active and can be executed.\r
+\r
+**/\r
+VOID\r
+SetTDStatusActiveorInactive (\r
+ IN TD_STRUCT *PtrTDStruct,\r
+ IN BOOLEAN IsActive\r
+ );\r
+\r
+/**\r
+ Specifies the maximum number of data bytes allowed for the transfer.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+ @param MaxLen The maximum number of data bytes allowed.\r
+\r
+ @retval The allowed maximum number of data.\r
+**/\r
+UINT16\r
+SetTDTokenMaxLength (\r
+ IN TD_STRUCT *PtrTDStruct,\r
+ IN UINT16 MaxLen\r
+ );\r
+\r
+/**\r
+ Set the data toggle bit to DATA1.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+\r
+**/\r
+VOID\r
+SetTDTokenDataToggle1 (\r
+ IN TD_STRUCT *PtrTDStruct\r
+ );\r
+\r
+/**\r
+ Set the data toggle bit to DATA0.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+\r
+**/\r
+VOID\r
+SetTDTokenDataToggle0 (\r
+ IN TD_STRUCT *PtrTDStruct\r
+ );\r
+\r
+/**\r
+ Set EndPoint Number the TD is targeting at.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+ @param EndPoint The Endport number of the target.\r
+\r
+**/\r
+VOID\r
+SetTDTokenEndPoint (\r
+ IN TD_STRUCT *PtrTDStruct,\r
+ IN UINTN EndPoint\r
+ );\r
+\r
+/**\r
+ Set Device Address the TD is targeting at.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+ @param DevAddr The Device Address of the target.\r
+\r
+**/\r
+VOID\r
+SetTDTokenDeviceAddress (\r
+ IN TD_STRUCT *PtrTDStruct,\r
+ IN UINTN DevAddr\r
+ );\r
+\r
+/**\r
+ Set Packet Identification the TD is targeting at.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+ @param PacketID The Packet Identification of the target.\r
+\r
+**/\r
+VOID\r
+SetTDTokenPacketID (\r
+ IN TD_STRUCT *PtrTDStruct,\r
+ IN UINT8 PacketID\r
+ );\r
+\r
+/**\r
+ Set the beginning address of the data buffer that will be used\r
+ during the transaction.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+\r
+**/\r
+VOID\r
+SetTDDataBuffer (\r
+ IN TD_STRUCT *PtrTDStruct\r
+ );\r
+\r
+/**\r
+ Detect whether the TD is active.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+\r
+ @retval The TD is active or not.\r
+\r
+**/\r
+BOOLEAN\r
+IsTDStatusActive (\r
+ IN TD_STRUCT *PtrTDStruct\r
+ );\r
+\r
+/**\r
+ Detect whether the TD is stalled.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+\r
+ @retval The TD is stalled or not.\r
+\r
+**/\r
+BOOLEAN\r
+IsTDStatusStalled (\r
+ IN TD_STRUCT *PtrTDStruct\r
+ );\r
+\r
+/**\r
+ Detect whether Data Buffer Error is happened.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+\r
+ @retval The Data Buffer Error is happened or not.\r
+\r
+**/\r
+BOOLEAN\r
+IsTDStatusBufferError (\r
+ IN TD_STRUCT *PtrTDStruct\r
+ );\r
+\r
+/**\r
+ Detect whether Babble Error is happened.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+\r
+ @retval The Babble Error is happened or not.\r
+\r
+**/\r
+BOOLEAN\r
+IsTDStatusBabbleError (\r
+ IN TD_STRUCT *PtrTDStruct\r
+ );\r
+\r
+/**\r
+ Detect whether NAK is received.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+\r
+ @retval The NAK is received or not.\r
+\r
+**/\r
+BOOLEAN\r
+IsTDStatusNAKReceived (\r
+ IN TD_STRUCT *PtrTDStruct\r
+ );\r
+\r
+/**\r
+ Detect whether CRC/Time Out Error is encountered.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+\r
+ @retval The CRC/Time Out Error is encountered or not.\r
+\r
+**/\r
+BOOLEAN\r
+IsTDStatusCRCTimeOutError (\r
+ IN TD_STRUCT *PtrTDStruct\r
+ );\r
+\r
+/**\r
+ Detect whether Bitstuff Error is received.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+\r
+ @retval The Bitstuff Error is received or not.\r
+\r
+**/\r
+BOOLEAN\r
+IsTDStatusBitStuffError (\r
+ IN TD_STRUCT *PtrTDStruct\r
+ );\r
+\r
+/**\r
+ Retrieve the actual number of bytes that were tansferred.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+\r
+ @retval The actual number of bytes that were tansferred.\r
+\r
+**/\r
+UINT16\r
+GetTDStatusActualLength (\r
+ IN TD_STRUCT *PtrTDStruct\r
+ );\r
+\r
+/**\r
+ Retrieve the information of whether the Link Pointer field is valid or not.\r
+\r
+ @param PtrTDStruct Place to store TD_STRUCT pointer.\r
+\r
+ @retval The linker pointer field is valid or not.\r
+\r
+**/\r
+BOOLEAN\r
+GetTDLinkPtrValidorInvalid (\r
+ IN TD_STRUCT *PtrTDStruct\r
+ );\r
+\r
+/**\r
+ Count TD Number from PtrFirstTD.\r
+\r
+ @param PtrFirstTD Place to store TD_STRUCT pointer.\r
+\r
+ @retval The queued TDs number.\r
+\r
+**/\r
+UINTN\r
+CountTDsNumber (\r
+ IN TD_STRUCT *PtrFirstTD\r
+ );\r
+\r
+/**\r
+ Link TD To QH.\r
+\r
+ @param PtrQH Place to store QH_STRUCT pointer.\r
+ @param PtrTD Place to store TD_STRUCT pointer.\r
+\r
+**/\r
+VOID\r
+LinkTDToQH (\r
+ IN QH_STRUCT *PtrQH,\r
+ IN TD_STRUCT *PtrTD\r
+ );\r
+\r
+/**\r
+ Link TD To TD.\r
+\r
+ @param PtrPreTD Place to store TD_STRUCT pointer.\r
+ @param PtrTD Place to store TD_STRUCT pointer.\r
+\r
+**/\r
+VOID\r
+LinkTDToTD (\r
+ IN TD_STRUCT *PtrPreTD,\r
+ IN TD_STRUCT *PtrTD\r
+ );\r
+\r
+/**\r
+ Execute Control Transfer.\r
+\r
+ @param UhcDev The UCHI device.\r
+ @param PtrTD A pointer to TD_STRUCT data.\r
+ @param ActualLen Actual transfer Length.\r
+ @param TimeOut TimeOut value.\r
+ @param TransferResult Transfer Result.\r
+\r
+ @return EFI_DEVICE_ERROR The transfer failed due to transfer error.\r
+ @return EFI_TIMEOUT The transfer failed due to time out.\r
+ @return EFI_SUCCESS The transfer finished OK.\r
+\r
+**/\r
+EFI_STATUS\r
+ExecuteControlTransfer (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ IN TD_STRUCT *PtrTD,\r
+ OUT UINTN *ActualLen,\r
+ IN UINTN TimeOut,\r
+ OUT UINT32 *TransferResult\r
+ );\r
+\r
+/**\r
+ Execute Bulk Transfer.\r
+\r
+ @param UhcDev The UCHI device.\r
+ @param PtrTD A pointer to TD_STRUCT data.\r
+ @param ActualLen Actual transfer Length.\r
+ @param DataToggle DataToggle value.\r
+ @param TimeOut TimeOut value.\r
+ @param TransferResult Transfer Result.\r
+\r
+ @return EFI_DEVICE_ERROR The transfer failed due to transfer error.\r
+ @return EFI_TIMEOUT The transfer failed due to time out.\r
+ @return EFI_SUCCESS The transfer finished OK.\r
+\r
+**/\r
+EFI_STATUS\r
+ExecBulkTransfer (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ IN TD_STRUCT *PtrTD,\r
+ IN OUT UINTN *ActualLen,\r
+ IN UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ OUT UINT32 *TransferResult\r
+ );\r
+\r
+/**\r
+ Delete Queued TDs.\r
+\r
+ @param UhcDev The UCHI device.\r
+ @param PtrFirstTD Place to store TD_STRUCT pointer.\r
+\r
+**/\r
+VOID\r
+DeleteQueuedTDs (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ IN TD_STRUCT *PtrFirstTD\r
+ );\r
+\r
+/**\r
+ Check TDs Results.\r
+\r
+ @param PtrTD A pointer to TD_STRUCT data.\r
+ @param Result The result to return.\r
+ @param ErrTDPos The Error TD position.\r
+ @param ActualTransferSize Actual transfer size.\r
+\r
+ @retval The TD is executed successfully or not.\r
+\r
+**/\r
+BOOLEAN\r
+CheckTDsResults (\r
+ IN TD_STRUCT *PtrTD,\r
+ OUT UINT32 *Result,\r
+ OUT UINTN *ErrTDPos,\r
+ OUT UINTN *ActualTransferSize\r
+ );\r
+\r
+/**\r
+ Create Memory Block.\r
+\r
+ @param UhcDev The UCHI device.\r
+ @param MemoryHeader The Pointer to allocated memory block.\r
+ @param MemoryBlockSizeInPages The page size of memory block to be allocated.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
+ @retval EFI_SUCCESS Success.\r
+\r
+**/\r
+EFI_STATUS\r
+CreateMemoryBlock (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ OUT MEMORY_MANAGE_HEADER **MemoryHeader,\r
+ IN UINTN MemoryBlockSizeInPages\r
+ );\r
+\r
+/**\r
+ Initialize UHCI memory management.\r
+\r
+ @param UhcDev The UCHI device.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
+ @retval EFI_SUCCESS Success.\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeMemoryManagement (\r
+ IN USB_UHC_DEV *UhcDev\r
+ );\r
+\r
+/**\r
+ Initialize UHCI memory management.\r
+\r
+ @param UhcDev The UCHI device.\r
+ @param Pool Buffer pointer to store the buffer pointer.\r
+ @param AllocSize The size of the pool to be allocated.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
+ @retval EFI_SUCCESS Success.\r
+\r
+**/\r
+EFI_STATUS\r
+UhcAllocatePool (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ OUT UINT8 **Pool,\r
+ IN UINTN AllocSize\r
+ );\r
+\r
+/**\r
+ Alloc Memory In MemoryBlock.\r
+\r
+ @param MemoryHeader The pointer to memory manage header.\r
+ @param Pool Buffer pointer to store the buffer pointer.\r
+ @param NumberOfMemoryUnit The size of the pool to be allocated.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
+ @retval EFI_SUCCESS Success.\r
+\r
+**/\r
+EFI_STATUS\r
+AllocMemInMemoryBlock (\r
+ IN MEMORY_MANAGE_HEADER *MemoryHeader,\r
+ OUT VOID **Pool,\r
+ IN UINTN NumberOfMemoryUnit\r
+ );\r
+\r
+/**\r
+ Uhci Free Pool.\r
+\r
+ @param UhcDev The UHCI device.\r
+ @param Pool A pointer to store the buffer address.\r
+ @param AllocSize The size of the pool to be freed.\r
+\r
+**/\r
+VOID\r
+UhcFreePool (\r
+ IN USB_UHC_DEV *UhcDev,\r
+ IN UINT8 *Pool,\r
+ IN UINTN AllocSize\r
+ );\r
+\r
+/**\r
+ Insert a new memory header into list.\r
+\r
+ @param MemoryHeader A pointer to the memory header list.\r
+ @param NewMemoryHeader A new memory header to be inserted into the list.\r
+\r
+**/\r
+VOID\r
+InsertMemoryHeaderToList (\r
+ IN MEMORY_MANAGE_HEADER *MemoryHeader,\r
+ IN MEMORY_MANAGE_HEADER *NewMemoryHeader\r
+ );\r
+\r
+/**\r
+ Judge the memory block in the memory header is empty or not.\r
+\r
+ @param MemoryHeaderPtr A pointer to the memory header list.\r
+\r
+ @retval Whether the memory block in the memory header is empty or not.\r
+\r
+**/\r
+BOOLEAN\r
+IsMemoryBlockEmptied (\r
+ IN MEMORY_MANAGE_HEADER *MemoryHeaderPtr\r
+ );\r
+\r
+/**\r
+ remove a memory header from list.\r
+\r
+ @param FirstMemoryHeader A pointer to the memory header list.\r
+ @param FreeMemoryHeader A memory header to be removed into the list.\r
+\r
+**/\r
+VOID\r
+DelinkMemoryBlock (\r
+ IN MEMORY_MANAGE_HEADER *FirstMemoryHeader,\r
+ IN MEMORY_MANAGE_HEADER *FreeMemoryHeader\r
+ );\r
+\r
+#endif\r