/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc.  All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/******************************************************************************/
/**
 * @file xusbps_endpoint.c
* @addtogroup usbps_v2_2
* @{
 *
 * Endpoint specific function implementations.
 *
 * @note     None.
 *
 * <pre>
 * MODIFICATION HISTORY:
 *
 * Ver   Who  Date     Changes
 * ----- ---- -------- --------------------------------------------------------
 * 1.00a jz  10/10/10 First release
 * 1.03a nm  09/21/12 Fixed CR#678977. Added proper sequence for setup packet
 *                    handling.
 * 1.04a nm  11/02/12 Fixed CR#683931. Mult bits are set properly in dQH.
 * 2.00a kpc 04/03/14 Fixed CR#777763. Updated the macro names 
 * 2.1   kpc 04/28/14 Added XUsbPs_EpBufferSendWithZLT api and merged common
 *		      code to XUsbPs_EpQueueRequest.
 * 2.3   bss 01/19/16 Modified XUsbPs_EpQueueRequest function to fix CR#873972
 *            (moving of dTD Head/Tail Pointers)and CR#873974(invalidate
 *            Caches After Buffer Receive in Endpoint Buffer Handler...)
 * </pre>
 ******************************************************************************/

/***************************** Include Files **********************************/

#include <string.h> /* for bzero() */
#include <stdio.h>

#include "xusbps.h"
#include "xusbps_endpoint.h"

/************************** Constant Definitions ******************************/

/**************************** Type Definitions ********************************/

/************************** Variable Definitions ******************************/

/************************** Function Prototypes ******************************/

static void XUsbPs_EpListInit(XUsbPs_DeviceConfig *DevCfgPtr);
static void XUsbPs_dQHInit(XUsbPs_DeviceConfig *DevCfgPtr);
static int  XUsbPs_dTDInit(XUsbPs_DeviceConfig *DevCfgPtr);
static int  XUsbPs_dTDAttachBuffer(XUsbPs_dTD *dTDPtr,
					const u8 *BufferPtr, u32 BufferLen);

static void XUsbPs_dQHSetMaxPacketLenISO(XUsbPs_dQH *dQHPtr, u32 Len);

/* Functions to reconfigure endpoint upon host's set alternate interface
 * request.
 */
static void XUsbPs_dQHReinitEp(XUsbPs_DeviceConfig *DevCfgPtr,
					int EpNum, unsigned short NewDirection);
static int XUsbPs_dTDReinitEp(XUsbPs_DeviceConfig *DevCfgPtr,
					int EpNum, unsigned short NewDirection);
static int XUsbPs_EpQueueRequest(XUsbPs *InstancePtr, u8 EpNum,
				const u8 *BufferPtr, u32 BufferLen, u8 ReqZero);

/******************************* Functions ************************************/

/*****************************************************************************/
/**
 *
 * This function configures the DEVICE side of the controller. The caller needs
 * to pass in the desired configuration (e.g. number of endpoints) and a
 * DMAable buffer that will hold the Queue Head List and the Transfer
 * Descriptors. The required size for this buffer can be obtained by the caller
 * using the: XUsbPs_DeviceMemRequired() macro.
 *
 * @param	InstancePtr is a pointer to the XUsbPs instance of the
 *		controller.
 * @param	CfgPtr is a pointer to the configuration structure that contains
 *		the desired DEVICE side configuration.
 *
 * @return
 *		- XST_SUCCESS: The operation completed successfully.
 *		- XST_FAILURE: An error occured.
 *
 * @note
 * 		The caller may configure the controller for both, DEVICE and
 * 		HOST side.
 *
 ******************************************************************************/
int XUsbPs_ConfigureDevice(XUsbPs *InstancePtr,
			    const XUsbPs_DeviceConfig *CfgPtr)
{
	int	Status;
	u32 ModeValue = 0x0;

	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(CfgPtr      != NULL);

	/* Copy the configuration data over into the local instance structure */
	InstancePtr->DeviceConfig = *CfgPtr;


	/* Align the buffer to a 2048 byte (XUSBPS_dQH_BASE_ALIGN) boundary.*/
	InstancePtr->DeviceConfig.PhysAligned =
		(InstancePtr->DeviceConfig.DMAMemPhys +
					 XUSBPS_dQH_BASE_ALIGN) &
						~(XUSBPS_dQH_BASE_ALIGN -1);

	/* Initialize the endpoint pointer list data structure. */
	XUsbPs_EpListInit(&InstancePtr->DeviceConfig);


	/* Initialize the Queue Head structures in DMA memory. */
	XUsbPs_dQHInit(&InstancePtr->DeviceConfig);


	/* Initialize the Transfer Descriptors in DMA memory.*/
	Status = XUsbPs_dTDInit(&InstancePtr->DeviceConfig);
	if (XST_SUCCESS != Status) {
		return XST_FAILURE;
	}

	/* Changing the DEVICE mode requires a controller RESET. */
	if (XST_SUCCESS != XUsbPs_Reset(InstancePtr)) {
		return XST_FAILURE;
	}

	/* Set the Queue Head List address. */
	XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
				XUSBPS_EPLISTADDR_OFFSET,
				InstancePtr->DeviceConfig.PhysAligned);

	/* Set the USB mode register to configure DEVICE mode.
	 *
	 * XUSBPS_MODE_SLOM_MASK note:
	 *   Disable Setup Lockout. Setup Lockout is not required as we
	 *   will be using the tripwire mechanism when handling setup
	 *   packets.
	 */
	ModeValue = XUSBPS_MODE_CM_DEVICE_MASK | XUSBPS_MODE_SLOM_MASK;

	XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
				XUSBPS_MODE_OFFSET, ModeValue);

	XUsbPs_SetBits(InstancePtr, XUSBPS_OTGCSR_OFFSET,
				XUSBPS_OTGSC_OT_MASK);

	return XST_SUCCESS;
}

/*****************************************************************************/
/**
* This function sends a given data buffer.
*
* @param	InstancePtr is a pointer to XUsbPs instance of the controller.
* @param	EpNum is the number of the endpoint to receive data from.
* @param	BufferPtr is a pointer to the buffer to send.
* @param	BufferLen is the Buffer length.
*
* @return
*		- XST_SUCCESS: The operation completed successfully.
*		- XST_FAILURE: An error occured.
*		- XST_USB_BUF_TOO_BIG: Provided buffer is too big (>16kB).
*		- XST_USB_NO_DESC_AVAILABLE: No TX descriptor is available.
*
******************************************************************************/
int XUsbPs_EpBufferSend(XUsbPs *InstancePtr, u8 EpNum,
				const u8 *BufferPtr, u32 BufferLen)
{
	Xil_AssertNonvoid(InstancePtr  != NULL);
	Xil_AssertNonvoid(EpNum < InstancePtr->DeviceConfig.NumEndpoints);

	return XUsbPs_EpQueueRequest(InstancePtr, EpNum, BufferPtr,
					BufferLen, FALSE);
}

/*****************************************************************************/
/**
* This function sends a given data buffer and also zero length packet if the
* Bufferlen is in multiples of endpoint max packet size.
*
* @param	InstancePtr is a pointer to XUsbPs instance of the controller.
* @param	EpNum is the number of the endpoint to receive data from.
* @param	BufferPtr is a pointer to the buffer to send.
* @param	BufferLen is the Buffer length.
*
* @return
*		- XST_SUCCESS: The operation completed successfully.
*		- XST_FAILURE: An error occured.
*		- XST_USB_BUF_TOO_BIG: Provided buffer is too big (>16kB).
*		- XST_USB_NO_DESC_AVAILABLE: No TX descriptor is available.
*
******************************************************************************/
int XUsbPs_EpBufferSendWithZLT(XUsbPs *InstancePtr, u8 EpNum,
				const u8 *BufferPtr, u32 BufferLen)
{
	u8 ReqZero = FALSE;
	XUsbPs_EpSetup *Ep;

	Xil_AssertNonvoid(InstancePtr  != NULL);
	Xil_AssertNonvoid(EpNum < InstancePtr->DeviceConfig.NumEndpoints);

	Ep = &InstancePtr->DeviceConfig.EpCfg[EpNum].In;

	if ((BufferLen >= Ep->MaxPacketSize) &&
		(BufferLen % Ep->MaxPacketSize == 0)) {
		ReqZero = TRUE;
	}

	return XUsbPs_EpQueueRequest(InstancePtr, EpNum, BufferPtr,
						BufferLen, ReqZero);
}

/*****************************************************************************/
/**
* This function sends a given data buffer and also sends ZLT packet if it is
* requested.
*
* @param	InstancePtr is a pointer to XUsbPs instance of the controller.
* @param	EpNum is the number of the endpoint to receive data from.
* @param	BufferPtr is a pointer to the buffer to send.
* @param	BufferLen is the Buffer length.
* @param	ReqZero is the
*
* @return
*		- XST_SUCCESS: The operation completed successfully.
*		- XST_FAILURE: An error occured.
*		- XST_USB_BUF_TOO_BIG: Provided buffer is too big (>16kB).
*		- XST_USB_NO_DESC_AVAILABLE: No TX descriptor is available.
*
******************************************************************************/
static int XUsbPs_EpQueueRequest(XUsbPs *InstancePtr, u8 EpNum,
				const u8 *BufferPtr, u32 BufferLen, u8 ReqZero)
{
	int		Status;
	u32		Token;
	XUsbPs_EpIn	*Ep;
	XUsbPs_dTD	*DescPtr;
	u32 		Length;
	u32		PipeEmpty = 1;
	u32		Mask = 0x00010000;
	u32		BitMask = Mask << EpNum;
	u32		RegValue;
	u32		Temp;
	u32 exit = 1;


	/* Locate the next available buffer in the ring. A buffer is available
	 * if its descriptor is not active.
	 */
	Ep = &InstancePtr->DeviceConfig.Ep[EpNum].In;

	Xil_DCacheFlushRange((unsigned int)BufferPtr, BufferLen);

	if(Ep->dTDTail != Ep->dTDHead) {
		PipeEmpty = 0;
	}
	XUsbPs_dTDInvalidateCache(Ep->dTDHead);

	/* Tell the caller if we do not have any descriptors available. */
	if (XUsbPs_dTDIsActive(Ep->dTDHead)) {
		return XST_USB_NO_DESC_AVAILABLE;
	}

	/* Remember the current head. */
	DescPtr = Ep->dTDHead;

	do {

		/* Tell the caller if we do not have any descriptors available. */
		if (XUsbPs_dTDIsActive(Ep->dTDHead)) {
			return XST_USB_NO_DESC_AVAILABLE;
		}

		Length = (BufferLen > XUSBPS_dTD_BUF_MAX_SIZE) ? XUSBPS_dTD_BUF_MAX_SIZE : BufferLen;
		/* Attach the provided buffer to the current descriptor.*/
		Status = XUsbPs_dTDAttachBuffer(Ep->dTDHead, BufferPtr, Length);
		if (XST_SUCCESS != Status) {
			return XST_FAILURE;
		}
		BufferLen -= Length;
		BufferPtr += Length;

		XUsbPs_dTDSetActive(Ep->dTDHead);
		if (BufferLen == 0 && (ReqZero == FALSE)) {
			XUsbPs_dTDSetIOC(Ep->dTDHead);
			exit = 0;
		}
		XUsbPs_dTDClrTerminate(Ep->dTDHead);
		XUsbPs_dTDFlushCache(Ep->dTDHead);

		/* Advance the head descriptor pointer to the next descriptor. */
		Ep->dTDHead = XUsbPs_dTDGetNLP(Ep->dTDHead);
		/* Terminate the next descriptor and flush the cache.*/
		XUsbPs_dTDInvalidateCache(Ep->dTDHead);

		if (ReqZero && BufferLen == 0) {
			ReqZero = FALSE;
		}

	} while(BufferLen || exit);

	XUsbPs_dTDSetTerminate(Ep->dTDHead);
	XUsbPs_dTDFlushCache(Ep->dTDHead);

	if(!PipeEmpty) {
		/* Read the endpoint prime register. */
		RegValue = XUsbPs_ReadReg(InstancePtr->Config.BaseAddress, XUSBPS_EPPRIME_OFFSET);
		if(RegValue & BitMask) {
			return XST_SUCCESS;
		}

		do {
			RegValue = XUsbPs_ReadReg(InstancePtr->Config.BaseAddress, XUSBPS_CMD_OFFSET);
			XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, XUSBPS_CMD_OFFSET,
						RegValue | XUSBPS_CMD_ATDTW_MASK);
			Temp = XUsbPs_ReadReg(InstancePtr->Config.BaseAddress, XUSBPS_EPRDY_OFFSET)
						& BitMask;
		} while(!(XUsbPs_ReadReg(InstancePtr->Config.BaseAddress, XUSBPS_CMD_OFFSET) &
				XUSBPS_CMD_ATDTW_MASK));

		RegValue = XUsbPs_ReadReg(InstancePtr->Config.BaseAddress, XUSBPS_CMD_OFFSET);
		XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, XUSBPS_CMD_OFFSET,
					RegValue & ~XUSBPS_CMD_ATDTW_MASK);

		if(Temp) {
			return XST_SUCCESS;
		}
	}

	/* Check, if the DMA engine is still running. If it is running, we do
	 * not clear Queue Head fields.
	 *
	 * Same cache rule as for the Transfer Descriptor applies for the Queue
	 * Head.
	 */
	XUsbPs_dQHInvalidateCache(Ep->dQH);
	/* Add the dTD to the dQH */
	XUsbPs_WritedQH(Ep->dQH, XUSBPS_dQHdTDNLP, DescPtr);
	Token = XUsbPs_ReaddQH(Ep->dQH, XUSBPS_dQHdTDTOKEN);
	Token &= ~(XUSBPS_dTDTOKEN_ACTIVE_MASK | XUSBPS_dTDTOKEN_HALT_MASK);
	XUsbPs_WritedQH(Ep->dQH, XUSBPS_dQHdTDTOKEN, Token);

	XUsbPs_dQHFlushCache(Ep->dQH);

	Status = XUsbPs_EpPrime(InstancePtr, EpNum, XUSBPS_EP_DIRECTION_IN);

	return Status;
}

/*****************************************************************************/
/**
 * This function receives a data buffer from the endpoint of the given endpoint
 * number.
 *
 * @param	InstancePtr is a pointer to the XUsbPs instance of the
 *		controller.
 * @param	EpNum is the number of the endpoint to receive data from.
 * @param	BufferPtr (OUT param) is a pointer to the buffer pointer to hold
 *		the reference of the data buffer.
 * @param	BufferLenPtr (OUT param) is a pointer to the integer that will
 *		hold the buffer length.
 * @param	Handle is the opaque handle to be used when the buffer is
 *		released.
 *
 * @return
 *		- XST_SUCCESS: The operation completed successfully.
 *		- XST_FAILURE: An error occured.
 *		- XST_USB_NO_BUF: No buffer available.
 *
 * @note
 * 		After handling the data in the buffer, the user MUST release
 * 		the buffer using the Handle by calling the
 * 		XUsbPs_EpBufferRelease() function.
 *
 ******************************************************************************/
int XUsbPs_EpBufferReceive(XUsbPs *InstancePtr, u8 EpNum,
				u8 **BufferPtr, u32 *BufferLenPtr, u32 *Handle)
{
	XUsbPs_EpOut	*Ep;
	XUsbPs_EpSetup	*EpSetup;
	u32 length = 0;

	Xil_AssertNonvoid(InstancePtr  != NULL);
	Xil_AssertNonvoid(BufferPtr    != NULL);
	Xil_AssertNonvoid(BufferLenPtr != NULL);
	Xil_AssertNonvoid(Handle       != NULL);
	Xil_AssertNonvoid(EpNum < InstancePtr->DeviceConfig.NumEndpoints);

	/* Locate the next available buffer in the ring. A buffer is available
	 * if its descriptor is not active.
	 */
	Ep = &InstancePtr->DeviceConfig.Ep[EpNum].Out;

	XUsbPs_dTDInvalidateCache(Ep->dTDCurr);

	if (XUsbPs_dTDIsActive(Ep->dTDCurr)) {
		return XST_USB_NO_BUF;
	}

	/* The buffer is not active which means that it has been processed by
	 * the DMA engine and contains valid data.
	 */
	EpSetup = &InstancePtr->DeviceConfig.EpCfg[EpNum].Out;


	/* Use the buffer pointer stored in the "user data" field of the
	 * Transfer Descriptor.
	 */
	*BufferPtr = (u8 *) XUsbPs_ReaddTD(Ep->dTDCurr,
						XUSBPS_dTDUSERDATA);

	length = EpSetup->BufSize -
			XUsbPs_dTDGetTransferLen(Ep->dTDCurr);

	if(length > 0) {
		*BufferLenPtr = length;
	}else {
		*BufferLenPtr = 0;
	}

	*Handle	= (u32) Ep->dTDCurr;


	/* Reset the descriptor's BufferPointer0 and Transfer Length fields to
	 * their original value. Note that we can not yet re-activate the
	 * descriptor as the caller will be using the attached buffer. Once the
	 * caller releases the buffer by calling XUsbPs_EpBufferRelease(), we
	 * can re-activate the descriptor.
	 */
	XUsbPs_WritedTD(Ep->dTDCurr, XUSBPS_dTDBPTR0, *BufferPtr);
	XUsbPs_dTDSetTransferLen(Ep->dTDCurr, EpSetup->BufSize);

	XUsbPs_dTDFlushCache(Ep->dTDCurr);

	return XST_SUCCESS;
}


/*****************************************************************************/
/**
* This function returns a previously received data buffer to the driver.
*
* @param	Handle is a pointer to the buffer that is returned.
*
* @return	None.
*
******************************************************************************/
void XUsbPs_EpBufferRelease(u32 Handle)
{
	XUsbPs_dTD		*dTDPtr;

	/* Perform sanity check on Handle.*/
	Xil_AssertVoid((0 != Handle) && (0 == (Handle % XUSBPS_dTD_ALIGN)));

	/* Activate the descriptor and clear the Terminate bit. Make sure to do
	 * the proper cache handling.
	 */
	dTDPtr = (XUsbPs_dTD *) Handle;

	XUsbPs_dTDInvalidateCache(dTDPtr);

	XUsbPs_dTDClrTerminate(dTDPtr);
	XUsbPs_dTDSetActive(dTDPtr);
	XUsbPs_dTDSetIOC(dTDPtr);

	XUsbPs_dTDFlushCache(dTDPtr);

}


/*****************************************************************************/
/**
 * This function sets the handler for endpoint events.
 *
 * @param	InstancePtr is a pointer to the XUsbPs instance of the
 *		controller.
 * @param	EpNum is the number of the endpoint to receive data from.
 * @param	Direction is the direction of the endpoint (bitfield):
 * 			- XUSBPS_EP_DIRECTION_OUT
 * 			- XUSBPS_EP_DIRECTION_IN
 * @param	CallBackFunc is the Handler callback function.
 *		Can be NULL if the user wants to disable the handler entry.
 * @param	CallBackRef is the user definable data pointer that will be
 *		passed back if the handler is called. May be NULL.
 *
 * @return
 *		- XST_SUCCESS: The operation completed successfully.
 *		- XST_FAILURE: An error occured.
 *		- XST_INVALID_PARAM: Invalid parameter passed.
 *
 * @note
 * 		The user can disable a handler by setting the callback function
 * 		pointer to NULL.
 *
 ******************************************************************************/
int XUsbPs_EpSetHandler(XUsbPs *InstancePtr, u8 EpNum, u8 Direction,
			 XUsbPs_EpHandlerFunc CallBackFunc,
			 void *CallBackRef)
{
	XUsbPs_Endpoint	*Ep;

	Xil_AssertNonvoid(InstancePtr  != NULL);
	Xil_AssertNonvoid(CallBackFunc != NULL);
	Xil_AssertNonvoid(EpNum < InstancePtr->DeviceConfig.NumEndpoints);

	Ep = &InstancePtr->DeviceConfig.Ep[EpNum];

	if(Direction & XUSBPS_EP_DIRECTION_OUT) {
		Ep->Out.HandlerFunc	= CallBackFunc;
		Ep->Out.HandlerRef	= CallBackRef;
	}

	if(Direction & XUSBPS_EP_DIRECTION_IN) {
		Ep->In.HandlerFunc	= CallBackFunc;
		Ep->In.HandlerRef	= CallBackRef;
	}

	return XST_SUCCESS;
}


/*****************************************************************************/
/**
* This function primes an endpoint.
*
* @param	InstancePtr is pointer to the XUsbPs instance.
* @param	EpNum is the number of the endpoint to receive data from.
* @param	Direction is the direction of the endpoint (bitfield):
* 			- XUSBPS_EP_DIRECTION_OUT
* 			- XUSBPS_EP_DIRECTION_IN
*
* @return
*		- XST_SUCCESS: The operation completed successfully.
*		- XST_FAILURE: An error occured.
*		- XST_INVALID_PARAM: Invalid parameter passed.
*
* @note		None.
*
******************************************************************************/
int XUsbPs_EpPrime(XUsbPs *InstancePtr, u8 EpNum, u8 Direction)
{
	u32	Mask;

	Xil_AssertNonvoid(InstancePtr  != NULL);
	Xil_AssertNonvoid(EpNum < InstancePtr->DeviceConfig.NumEndpoints);

	/* Get the right bit mask for the endpoint direction. */
	switch (Direction) {

	case XUSBPS_EP_DIRECTION_OUT:
		Mask = 0x00000001;
		break;

	case XUSBPS_EP_DIRECTION_IN:
		Mask = 0x00010000;
		break;

	default:
		return XST_INVALID_PARAM;
	}

	/* Write the endpoint prime register. */
	XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
				XUSBPS_EPPRIME_OFFSET, Mask << EpNum);

	return XST_SUCCESS;
}


/*****************************************************************************/
/**
* This function extracts the Setup Data from a given endpoint.
*
* @param	InstancePtr is a pointer to the XUsbPs instance of the
*		controller.
* @param	EpNum is the number of the endpoint to receive data from.
* @param	SetupDataPtr is a pointer to the setup data structure to be
*		filled.
*
* @return
*		- XST_SUCCESS: The operation completed successfully.
*		- XST_FAILURE: An error occured.
*
* @note		None.
******************************************************************************/
int XUsbPs_EpGetSetupData(XUsbPs *InstancePtr, int EpNum,
				XUsbPs_SetupData *SetupDataPtr)
{
	XUsbPs_EpOut	*Ep;

	u32	Data[2];
	u8	*p;

	int Timeout;

	Xil_AssertNonvoid(InstancePtr  != NULL);
	Xil_AssertNonvoid(SetupDataPtr != NULL);
	Xil_AssertNonvoid(EpNum < InstancePtr->DeviceConfig.NumEndpoints);

	Ep = &InstancePtr->DeviceConfig.Ep[EpNum].Out;


	/* Get the data from the Queue Heads Setup buffer into local variables
	 * so we can extract the setup data values.
	 */
	do {
		/* Arm the tripwire. The tripwire will tell us if a new setup
		 * packet arrived (in which case the tripwire bit will be
		 * cleared) while we were reading the buffer. If a new setup
		 * packet arrived the buffer is corrupted and we continue
		 * reading.
		 */
		XUsbPs_SetSetupTripwire(InstancePtr);

		XUsbPs_dQHInvalidateCache(Ep->dQH);

		Data[0] = XUsbPs_ReaddQH(Ep->dQH, XUSBPS_dQHSUB0);
		Data[1] = XUsbPs_ReaddQH(Ep->dQH, XUSBPS_dQHSUB1);
	} while (FALSE == XUsbPs_SetupTripwireIsSet(InstancePtr));

	/* Clear the pending endpoint setup stat bit.
	 */
	XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
				XUSBPS_EPSTAT_OFFSET, 1 << EpNum);

	/* Clear the Tripwire bit and continue.
	 */
	XUsbPs_ClrSetupTripwire(InstancePtr);


	/* Data in the setup buffer is being converted by the core to big
	 * endian format. We have to take care of proper byte swapping when
	 * reading the setup data values.
	 *
	 * Need to check if there is a smarter way to do this and take the
	 * processor/memory-controller endianess into account?
	 */
	p = (u8 *) Data;

	SetupDataPtr->bmRequestType	= p[0];
	SetupDataPtr->bRequest		= p[1];
	SetupDataPtr->wValue		= (p[3] << 8) | p[2];
	SetupDataPtr->wIndex		= (p[5] << 8) | p[4];
	SetupDataPtr->wLength		= (p[7] << 8) | p[6];

	/* Before we leave we need to make sure that the endpoint setup bit has
	 * cleared. It needs to be 0 before the endpoint can be re-primed.
	 *
	 * Note: According to the documentation this endpoint setup bit should
	 * clear within 1-2us after it has been written above. This means that
	 * we should never catch it being 1 here. However, we still need to
	 * poll it to make sure. Just in case, we use a counter 'Timeout' so we
	 * won't hang here if the bit is stuck for some reason.
	 */
	Timeout = XUSBPS_TIMEOUT_COUNTER;
	while ((XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
				XUSBPS_EPSTAT_OFFSET) &
				(1 << EpNum)) && --Timeout) {
		/* NOP */
	}
	if (0 == Timeout) {
		return XST_FAILURE;
	}

	return XST_SUCCESS;
}


/*****************************************************************************/
/**
*
* This function initializes the endpoint pointer data structure.
*
* The function sets up the local data structure with the aligned addresses for
* the Queue Head and Transfer Descriptors.
*
* @param	DevCfgPtr is pointer to the XUsbPs DEVICE configuration
*		structure.
*
* @return	none
*
* @note
* 		Endpoints of type XUSBPS_EP_TYPE_NONE are not used in the
* 		system. Therefore no memory is reserved for them.
*
******************************************************************************/
static void XUsbPs_EpListInit(XUsbPs_DeviceConfig *DevCfgPtr)
{
	int	EpNum;
	u8	*p;

	XUsbPs_Endpoint	*Ep;
	XUsbPs_EpConfig	*EpCfg;

	/* Set up the XUsbPs_Endpoint array. This array is used to define the
	 * location of the Queue Head list and the Transfer Descriptors in the
	 * block of DMA memory that has been passed into the driver.
	 *
	 * 'p' is used to set the pointers in the local data structure.
	 * Initially 'p' is pointed to the beginning of the DMAable memory
	 * block. As pointers are assigned, 'p' is incremented by the size of
	 * the respective object.
	 */
	Ep	= DevCfgPtr->Ep;
	EpCfg	= DevCfgPtr->EpCfg;

	/* Start off with 'p' pointing to the (aligned) beginning of the DMA
	 * buffer.
	 */
	p = (u8 *) DevCfgPtr->PhysAligned;


	/* Initialize the Queue Head pointer list.
	 *
	 * Each endpoint has two Queue Heads. One for the OUT direction and one
	 * for the IN direction. An OUT Queue Head is always followed by an IN
	 * Queue Head.
	 *
	 * Queue Head alignment is XUSBPS_dQH_ALIGN.
	 *
	 * Note that we have to reserve space here for unused endpoints.
	 */
	for (EpNum = 0; EpNum < DevCfgPtr->NumEndpoints; ++EpNum) {
		/* OUT Queue Head */
		Ep[EpNum].Out.dQH = (XUsbPs_dQH *) p;
		p += XUSBPS_dQH_ALIGN;

		/* IN Queue Head */
		Ep[EpNum].In.dQH = (XUsbPs_dQH *) p;
		p += XUSBPS_dQH_ALIGN;
	}


	/* 'p' now points to the first address after the Queue Head list. The
	 * Transfer Descriptors start here.
	 *
	 * Each endpoint has a variable number of Transfer Descriptors
	 * depending on user configuration.
	 *
	 * Transfer Descriptor alignment is XUSBPS_dTD_ALIGN.
	 */
	for (EpNum = 0; EpNum < DevCfgPtr->NumEndpoints; ++EpNum) {
		/* OUT Descriptors.
		 */
		if (XUSBPS_EP_TYPE_NONE != EpCfg[EpNum].Out.Type) {
			Ep[EpNum].Out.dTDs		= (XUsbPs_dTD *) p;
			Ep[EpNum].Out.dTDCurr	= (XUsbPs_dTD *) p;
			p += XUSBPS_dTD_ALIGN * EpCfg[EpNum].Out.NumBufs;
		}

		/* IN Descriptors.
		 */
		if (XUSBPS_EP_TYPE_NONE != EpCfg[EpNum].In.Type) {
			Ep[EpNum].In.dTDs		= (XUsbPs_dTD *) p;
			Ep[EpNum].In.dTDHead	= (XUsbPs_dTD *) p;
			Ep[EpNum].In.dTDTail	= (XUsbPs_dTD *) p;
			p += XUSBPS_dTD_ALIGN * EpCfg[EpNum].In.NumBufs;
		}
	}


	/* 'p' now points to the first address after the Transfer Descriptors.
	 * The data buffers for the OUT Transfer Desciptors start here.
	 *
	 * Note that IN (TX) Transfer Descriptors are not assigned buffers at
	 * this point. Buffers will be assigned when the user calls the send()
	 * function.
	 */
	for (EpNum = 0; EpNum < DevCfgPtr->NumEndpoints; ++EpNum) {

		if (XUSBPS_EP_TYPE_NONE != EpCfg[EpNum].Out.Type) {
			/* If BufSize for this endpoint is set to 0 it means
			 * that we do not need to attach a buffer to this
			 * descriptor. We also initialize it's buffer pointer
			 * to NULL.
			 */
			if (0 == EpCfg[EpNum].Out.BufSize) {
				Ep[EpNum].Out.dTDBufs = NULL;
				continue;
			}

			Ep[EpNum].Out.dTDBufs = p;
			p += EpCfg[EpNum].Out.BufSize * EpCfg[EpNum].Out.NumBufs;
		}
	}


	/* Initialize the endpoint event handlers to NULL.
	 */
	for (EpNum = 0; EpNum < DevCfgPtr->NumEndpoints; ++EpNum) {
		Ep[EpNum].Out.HandlerFunc = NULL;
		Ep[EpNum].In.HandlerFunc  = NULL;
	}
}


/*****************************************************************************/
/**
*
* This function initializes the Queue Head List in memory.
*
* @param	DevCfgPtr is a pointer to the XUsbPs DEVICE configuration
*		structure.
*
* @return	None
*
* @note		None.
*
******************************************************************************/
static void XUsbPs_dQHInit(XUsbPs_DeviceConfig *DevCfgPtr)
{
	int	EpNum;

	XUsbPs_Endpoint	*Ep;
	XUsbPs_EpConfig	*EpCfg;

	/* Setup pointers for simpler access. */
	Ep	= DevCfgPtr->Ep;
	EpCfg	= DevCfgPtr->EpCfg;


	/* Go through the list of Queue Head entries and:
	 *
	 * - Set Transfer Descriptor addresses
	 * - Set Maximum Packet Size
	 * - Disable Zero Length Termination (ZLT) for non-isochronous transfers
	 * - Enable Interrupt On Setup (IOS)
	 *
	 */
	for (EpNum = 0; EpNum < DevCfgPtr->NumEndpoints; ++EpNum) {

		/* OUT Queue Heads.*/
		if (XUSBPS_EP_TYPE_NONE != EpCfg[EpNum].Out.Type) {
			XUsbPs_WritedQH(Ep[EpNum].Out.dQH,
					XUSBPS_dQHCPTR, Ep[EpNum].Out.dTDs);

			/* For isochronous, ep max packet size translates to different
			 * values in queue head than other types.
			 * Also	enable ZLT for isochronous.
			 */
			if(XUSBPS_EP_TYPE_ISOCHRONOUS == EpCfg[EpNum].Out.Type) {
				XUsbPs_dQHSetMaxPacketLenISO(Ep[EpNum].Out.dQH,
                        EpCfg[EpNum].Out.MaxPacketSize);
				XUsbPs_dQHEnableZLT(Ep[EpNum].Out.dQH);
			}else {
				XUsbPs_dQHSetMaxPacketLen(Ep[EpNum].Out.dQH,
					    EpCfg[EpNum].Out.MaxPacketSize);
				XUsbPs_dQHDisableZLT(Ep[EpNum].Out.dQH);
			}

			/* Only control OUT needs this */
			if(XUSBPS_EP_TYPE_CONTROL == EpCfg[EpNum].Out.Type) {
				XUsbPs_dQHSetIOS(Ep[EpNum].Out.dQH);
			}

			/* Set up the overlay next dTD pointer. */
			XUsbPs_WritedQH(Ep[EpNum].Out.dQH,
					XUSBPS_dQHdTDNLP, Ep[EpNum].Out.dTDs);

			XUsbPs_dQHFlushCache(Ep[EpNum].Out.dQH);
		}


		/* IN Queue Heads. */
		if (XUSBPS_EP_TYPE_NONE != EpCfg[EpNum].In.Type) {
			XUsbPs_WritedQH(Ep[EpNum].In.dQH,
				  XUSBPS_dQHCPTR, Ep[EpNum].In.dTDs);


			/* Isochronous ep packet size can be larger than 1024.*/
			if(XUSBPS_EP_TYPE_ISOCHRONOUS == EpCfg[EpNum].In.Type) {
				XUsbPs_dQHSetMaxPacketLenISO(Ep[EpNum].In.dQH,
						EpCfg[EpNum].In.MaxPacketSize);
				XUsbPs_dQHEnableZLT(Ep[EpNum].In.dQH);
			}else {
				XUsbPs_dQHSetMaxPacketLen(Ep[EpNum].In.dQH,
					    EpCfg[EpNum].In.MaxPacketSize);
				XUsbPs_dQHDisableZLT(Ep[EpNum].In.dQH);
			}

			XUsbPs_dQHFlushCache(Ep[EpNum].In.dQH);
		}
	}
}


/*****************************************************************************/
/**
 *
 * This function initializes the Transfer Descriptors lists in memory.
 *
 * @param	DevCfgPtr is a pointer to the XUsbPs DEVICE configuration
 *		structure.
 *
 * @return
 *		- XST_SUCCESS: The operation completed successfully.
 *		- XST_FAILURE: An error occured.
 *
 ******************************************************************************/
static int XUsbPs_dTDInit(XUsbPs_DeviceConfig *DevCfgPtr)
{
	int	EpNum;

	XUsbPs_Endpoint	*Ep;
	XUsbPs_EpConfig	*EpCfg;

	/* Setup pointers for simpler access. */
	Ep	= DevCfgPtr->Ep;
	EpCfg	= DevCfgPtr->EpCfg;


	/* Walk through the list of endpoints and initialize their Transfer
	 * Descriptors.
	 */
	for (EpNum = 0; EpNum < DevCfgPtr->NumEndpoints; ++EpNum) {
		int	Td;
		int	NumdTD;

		XUsbPs_EpOut	*Out = &Ep[EpNum].Out;
		XUsbPs_EpIn	*In  = &Ep[EpNum].In;


		/* OUT Descriptors
		 * ===============
		 *
		 * + Set the next link pointer
		 * + Set the interrupt complete and the active bit
		 * + Attach the buffer to the dTD
		 */
		if (XUSBPS_EP_TYPE_NONE != EpCfg[EpNum].Out.Type) {
			NumdTD = EpCfg[EpNum].Out.NumBufs;
		}
		else {
			NumdTD = 0;
		}

		for (Td = 0; Td < NumdTD; ++Td) {
			int	Status;

			int NextTd = (Td + 1) % NumdTD;

			XUsbPs_dTDInvalidateCache(&Out->dTDs[Td]);

			/* Set NEXT link pointer. */
			XUsbPs_WritedTD(&Out->dTDs[Td], XUSBPS_dTDNLP,
					  &Out->dTDs[NextTd]);

			/* Set the OUT descriptor ACTIVE and enable the
			 * interrupt on complete.
			 */
			XUsbPs_dTDSetActive(&Out->dTDs[Td]);
			XUsbPs_dTDSetIOC(&Out->dTDs[Td]);


			/* Set up the data buffer with the descriptor. If the
			 * buffer pointer is NULL it means that we do not need
			 * to attach a buffer to this descriptor.
			 */
			if (NULL == Out->dTDBufs) {
				XUsbPs_dTDFlushCache(&Out->dTDs[Td]);
				continue;
			}

			Status = XUsbPs_dTDAttachBuffer(
					&Out->dTDs[Td],
					Out->dTDBufs +
						(Td * EpCfg[EpNum].Out.BufSize),
					EpCfg[EpNum].Out.BufSize);
			if (XST_SUCCESS != Status) {
				return XST_FAILURE;
			}

			XUsbPs_dTDFlushCache(&Out->dTDs[Td]);
		}


		/* IN Descriptors
		 * ==============
		 *
		 * + Set the next link pointer
		 * + Set the Terminate bit to mark it available
		 */
		if (XUSBPS_EP_TYPE_NONE != EpCfg[EpNum].In.Type) {
			NumdTD = EpCfg[EpNum].In.NumBufs;
		}
		else {
			NumdTD = 0;
		}

		for (Td = 0; Td < NumdTD; ++Td) {
			int NextTd = (Td + 1) % NumdTD;

			XUsbPs_dTDInvalidateCache(&In->dTDs[Td]);

			/* Set NEXT link pointer. */
			XUsbPs_WritedTD(In->dTDs[Td], XUSBPS_dTDNLP,
					  In->dTDs[NextTd]);

			/* Set the IN descriptor's TERMINATE bits. */
			XUsbPs_dTDSetTerminate(In->dTDs[Td]);

			XUsbPs_dTDFlushCache(&In->dTDs[Td]);
		}
	}

	return XST_SUCCESS;
}


/*****************************************************************************/
/**
 *
 * This function associates a buffer with a Transfer Descriptor. The function
 * will take care of splitting the buffer into multiple 4kB aligned segments if
 * the buffer happens to span one or more 4kB pages.
 *
 * @param	dTDIndex is a pointer to the Transfer Descriptor
 * @param	BufferPtr is pointer to the buffer to link to the descriptor.
 * @param	BufferLen is the length of the buffer.
 *
 * @return
 *		- XST_SUCCESS: The operation completed successfully.
 *		- XST_FAILURE: An error occured.
 *		- XST_USB_BUF_TOO_BIG: The provided buffer is bigger than tha
 *		maximum allowed buffer size (16k).
 *
 * @note
 * 		Cache invalidation and flushing needs to be handler by the
 * 		caller of this function.
 *
 ******************************************************************************/
static int XUsbPs_dTDAttachBuffer(XUsbPs_dTD *dTDPtr,
					const u8 *BufferPtr, u32 BufferLen)
{
	u32	BufAddr;
	u32	BufEnd;
	u32	PtrNum;

	Xil_AssertNonvoid(dTDPtr    != NULL);

	/* Check if the buffer is smaller than 16kB. */
	if (BufferLen > XUSBPS_dTD_BUF_MAX_SIZE) {
		return XST_USB_BUF_TOO_BIG;
	}

	/* Get a u32 of the buffer pointer to avoid casting in the following
	 * logic operations.
	 */
	BufAddr = (u32) BufferPtr;


	/* Set the buffer pointer 0. Buffer pointer 0 can point to any location
	 * in memory. It does not need to be 4kB aligned. However, if the
	 * provided buffer spans one or more 4kB boundaries, we need to set up
	 * the subsequent buffer pointers which must be 4kB aligned.
	 */
	XUsbPs_WritedTD(dTDPtr, XUSBPS_dTDBPTR(0), BufAddr);

	/* Check if the buffer spans a 4kB boundary.
	 *
	 * Only do this check, if we are not sending a 0-length buffer.
	 */
	if (BufferLen > 0) {
		BufEnd = BufAddr + BufferLen -1;
		PtrNum = 1;

		while ((BufAddr & 0xFFFFF000) != (BufEnd & 0xFFFFF000)) {
			/* The buffer spans at least one boundary, let's set
			 * the next buffer pointer and repeat the procedure
			 * until the end of the buffer and the pointer written
			 * are in the same 4kB page.
			 */
			BufAddr = (BufAddr + 0x1000) & 0xFFFFF000;
			XUsbPs_WritedTD(dTDPtr, XUSBPS_dTDBPTR(PtrNum),
								BufAddr);
			PtrNum++;
		}
	}

	/* Set the length of the buffer. */
	XUsbPs_dTDSetTransferLen(dTDPtr, BufferLen);


	/* We remember the buffer pointer in the user data field (reserved
	 * field in the dTD). This makes it easier to reset the buffer pointer
	 * after a buffer has been received on the endpoint. The buffer pointer
	 * needs to be reset because the DMA engine modifies the buffer pointer
	 * while receiving.
	 */
	XUsbPs_WritedTD(dTDPtr, XUSBPS_dTDUSERDATA, BufferPtr);

	return XST_SUCCESS;
}


/*****************************************************************************/
/**
 * This function set the Max PacketLen for the queue head for isochronous EP.
 *
 * If the max packet length is greater than XUSBPS_MAX_PACKET_SIZE, then
 * Mult bits are set to reflect that.
 *
 * @param	dQHPtr is a pointer to the dQH element.
 * @param	Len is the Length to be set.
 *
 ******************************************************************************/
static void XUsbPs_dQHSetMaxPacketLenISO(XUsbPs_dQH *dQHPtr, u32 Len)
{
	u32 Mult = (Len & ENDPOINT_MAXP_MULT_MASK) >> ENDPOINT_MAXP_MULT_SHIFT;
	u32 MaxPktSize = (Mult > 1) ? ENDPOINT_MAXP_LENGTH : Len;

	if (MaxPktSize > XUSBPS_MAX_PACKET_SIZE) {
		return;
	}

	if (Mult > 3) {
		return;
	}

	/* Set Max packet size */
	XUsbPs_WritedQH(dQHPtr, XUSBPS_dQHCFG,
		(XUsbPs_ReaddQH(dQHPtr, XUSBPS_dQHCFG) &
			~XUSBPS_dQHCFG_MPL_MASK) |
			(MaxPktSize << XUSBPS_dQHCFG_MPL_SHIFT));

	/* Set Mult to tell hardware how many transactions in each microframe */
	XUsbPs_WritedQH(dQHPtr, XUSBPS_dQHCFG,
		(XUsbPs_ReaddQH(dQHPtr, XUSBPS_dQHCFG) &
			~XUSBPS_dQHCFG_MULT_MASK) |
			(Mult << XUSBPS_dQHCFG_MULT_SHIFT));

}

/*****************************************************************************/
/**
* This function reconfigures one Ep corresponding to host's request of setting
* alternate interface. The endpoint has been disabled before this call.
*
* Both QH and dTDs are updated for the new configuration.
*
* @param	InstancePtr is a pointer to the XUsbPs instance of the
*		controller.
* @param	CfgPtr
* 		Pointer to the updated XUsbPs DEVICE configuration structure.
*
* @param	EpNum
*		The endpoint to be reconfigured.
*
* @param NewDirection
*		The new transfer direction the endpoint.
*
* @param DirectionChanged
*		A boolean value indicate whether the transfer direction has changed.
*
* @return
*	XST_SUCCESS upon success, XST_FAILURE otherwise.
*
******************************************************************************/
int XUsbPs_ReconfigureEp(XUsbPs *InstancePtr, XUsbPs_DeviceConfig *CfgPtr,
				int EpNum, unsigned short NewDirection,
				int DirectionChanged) {

	int Status = XST_SUCCESS;
	XUsbPs_Endpoint *Ep;
	XUsbPs_EpConfig *EpCfg;

	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(CfgPtr      != NULL);

	Ep = CfgPtr->Ep;
	EpCfg = CfgPtr->EpCfg;

	/* If transfer direction changes, dTDs has to be reset
	 * Number of buffers are preset and should not to be changed.
	 */
	if(DirectionChanged) {
		if(NewDirection == XUSBPS_EP_DIRECTION_OUT) {
			u8 *p;

			/* Swap the pointer to the dTDs.
			 */
			Ep[EpNum].Out.dTDs = Ep[EpNum].In.dTDs;
			p = (u8 *)(Ep[EpNum].Out.dTDs + XUSBPS_dTD_ALIGN * EpCfg[EpNum].Out.NumBufs);

			/* Set the OUT buffer if buffer size is not zero
			 */
			if(EpCfg[EpNum].Out.BufSize > 0) {
				Ep[EpNum].Out.dTDBufs = p;
			}
		} else if(NewDirection == XUSBPS_EP_DIRECTION_IN) {
			Ep[EpNum].In.dTDs = Ep[EpNum].Out.dTDs;
		}
	}

	/* Reset dTD progress tracking pointers
	 */
	if(NewDirection == XUSBPS_EP_DIRECTION_IN) {
		Ep[EpNum].In.dTDHead = Ep[EpNum].In.dTDTail = Ep[EpNum].In.dTDs;
	} else if(NewDirection == XUSBPS_EP_DIRECTION_OUT) {
		Ep[EpNum].Out.dTDCurr = Ep[EpNum].Out.dTDs;
	}

	/* Reinitialize information in QH
	 */
	XUsbPs_dQHReinitEp(CfgPtr, EpNum, NewDirection);

	/* Reinitialize the dTD linked list, and flush the cache
	 */
	Status = XUsbPs_dTDReinitEp(CfgPtr, EpNum, NewDirection);
	if(Status != XST_SUCCESS) {
		return Status;
	}

	return XST_SUCCESS;
}


/*****************************************************************************/
/**
 * This function re-initializes the Queue Head List in memory.
 * The endpoint 1 has been disabled before this call.
 *
 * @param	DevCfgPtr
 * 		Pointer to the updated XUsbPs DEVICE configuration structure.
 *
 * @param	EpNum
 *		The endpoint to be reconfigured.
 *
 * @param	NewDirection
 *		The new transfer direction of endpoint 1
 *
 * @return	none
 *
 ******************************************************************************/
static void XUsbPs_dQHReinitEp(XUsbPs_DeviceConfig *DevCfgPtr,
int EpNum, unsigned short NewDirection)
{
	XUsbPs_Endpoint	*Ep;
	XUsbPs_EpConfig	*EpCfg;

	/* Setup pointers for simpler access.
	 */
	Ep	= DevCfgPtr->Ep;
	EpCfg	= DevCfgPtr->EpCfg;


	/* Go through the list of Queue Head entries and:
	 *
	 * - Set Transfer Descriptor addresses
	 * - Set Maximum Packet Size
	 * - Disable Zero Length Termination (ZLT) for non-isochronous transfers
	 * - Enable Interrupt On Setup (IOS)
	 *
	 */
	if(NewDirection == XUSBPS_EP_DIRECTION_OUT) {
		/* OUT Queue Heads.
		 */
		XUsbPs_WritedQH(Ep[EpNum].Out.dQH,
			XUSBPS_dQHCPTR, Ep[EpNum].Out.dTDs);

		/* For isochronous, ep max packet size translates to different
		 * values in queue head than other types.
		 * Also	enable ZLT for isochronous.
		 */
		if(XUSBPS_EP_TYPE_ISOCHRONOUS == EpCfg[EpNum].Out.Type) {
			XUsbPs_dQHSetMaxPacketLenISO(Ep[EpNum].Out.dQH,
   					EpCfg[EpNum].Out.MaxPacketSize);
			XUsbPs_dQHEnableZLT(Ep[EpNum].Out.dQH);
		}else {
			XUsbPs_dQHSetMaxPacketLen(Ep[EpNum].Out.dQH,
				    EpCfg[EpNum].Out.MaxPacketSize);
			XUsbPs_dQHDisableZLT(Ep[EpNum].Out.dQH);
		}

		XUsbPs_dQHSetIOS(Ep[EpNum].Out.dQH);

		/* Set up the overlay next dTD pointer.
		 */
		XUsbPs_WritedQH(Ep[EpNum].Out.dQH,
				XUSBPS_dQHdTDNLP, Ep[EpNum].Out.dTDs);

		XUsbPs_dQHFlushCache(Ep[EpNum].Out.dQH);

	} else if(NewDirection == XUSBPS_EP_DIRECTION_IN) {

		/* IN Queue Heads.
		 */
		XUsbPs_WritedQH(Ep[EpNum].In.dQH,
			  XUSBPS_dQHCPTR, Ep[EpNum].In.dTDs);

		/* Isochronous ep packet size can be larger than 1024. */
		if(XUSBPS_EP_TYPE_ISOCHRONOUS == EpCfg[EpNum].In.Type) {
			XUsbPs_dQHSetMaxPacketLenISO(Ep[EpNum].In.dQH,
   				EpCfg[EpNum].In.MaxPacketSize);
			XUsbPs_dQHEnableZLT(Ep[EpNum].In.dQH);
		}else {
			XUsbPs_dQHSetMaxPacketLen(Ep[EpNum].In.dQH,
			    EpCfg[EpNum].In.MaxPacketSize);
			XUsbPs_dQHDisableZLT(Ep[EpNum].In.dQH);
		}

		XUsbPs_dQHSetIOS(Ep[EpNum].In.dQH);

		XUsbPs_dQHFlushCache(Ep[EpNum].In.dQH);
	}

}

/*****************************************************************************/
/**
 *
 * This function re-initializes the Transfer Descriptors lists in memory.
 * The endpoint has been disabled before the call. The transfer descriptors
 * list pointer has been initialized too.
 *
 * @param	DevCfgPtr
 * 		Pointer to the XUsbPs DEVICE configuration structure.
 *
 * @param	EpNum
 *		The endpoint to be reconfigured.
 *
 * @param	NewDirection
 *		The new transfer direction of endpoint 1
 *
 * @return
 *		- XST_SUCCESS: The operation completed successfully.
 *		- XST_FAILURE: An error occured.
 *
 ******************************************************************************/
static int XUsbPs_dTDReinitEp(XUsbPs_DeviceConfig *DevCfgPtr,
int EpNum, unsigned short NewDirection)
{
	XUsbPs_Endpoint	*Ep;
	XUsbPs_EpConfig	*EpCfg;
	int	Td;
	int	NumdTD;


	/* Setup pointers for simpler access.
	 */
	Ep	= DevCfgPtr->Ep;
	EpCfg	= DevCfgPtr->EpCfg;


	if(NewDirection == XUSBPS_EP_DIRECTION_OUT) {
		XUsbPs_EpOut	*Out = &Ep[EpNum].Out;

		/* OUT Descriptors
		 * ===============
		 *
		 * + Set the next link pointer
		 * + Set the interrupt complete and the active bit
		 * + Attach the buffer to the dTD
		 */
		NumdTD = EpCfg[EpNum].Out.NumBufs;

		for (Td = 0; Td < NumdTD; ++Td) {
			int	Status;

			int NextTd = (Td + 1) % NumdTD;

			XUsbPs_dTDInvalidateCache(&Out->dTDs[Td]);

			/* Set NEXT link pointer.
			 */
			XUsbPs_WritedTD(&Out->dTDs[Td], XUSBPS_dTDNLP,
					  &Out->dTDs[NextTd]);

			/* Set the OUT descriptor ACTIVE and enable the
			 * interrupt on complete.
			 */
			XUsbPs_dTDSetActive(&Out->dTDs[Td]);
			XUsbPs_dTDSetIOC(&Out->dTDs[Td]);

			/* Set up the data buffer with the descriptor. If the
			 * buffer pointer is NULL it means that we do not need
			 * to attach a buffer to this descriptor.
			 */
			if (Out->dTDBufs != NULL) {

				Status = XUsbPs_dTDAttachBuffer(
						&Out->dTDs[Td],
						Out->dTDBufs +
							(Td * EpCfg[EpNum].Out.BufSize),
						EpCfg[EpNum].Out.BufSize);
				if (Status != XST_SUCCESS) {
					return XST_FAILURE;
				}
			}
			XUsbPs_dTDFlushCache(&Out->dTDs[Td]);
		}
	} else if(NewDirection == XUSBPS_EP_DIRECTION_IN) {
		XUsbPs_EpIn	*In  = &Ep[EpNum].In;

		/* IN Descriptors
		 * ==============
		 *
		 * + Set the next link pointer
		 * + Set the Terminate bit to mark it available
		 */
		NumdTD = EpCfg[EpNum].In.NumBufs;

		for (Td = 0; Td < NumdTD; ++Td) {
			int NextTd = (Td + 1) % NumdTD;

			XUsbPs_dTDInvalidateCache(&In->dTDs[Td]);

			/* Set NEXT link pointer.
			 */
			XUsbPs_WritedTD(&In->dTDs[Td], XUSBPS_dTDNLP,
					  &In->dTDs[NextTd]);

			/* Set the IN descriptor's TERMINATE bits.
			 */
			XUsbPs_dTDSetTerminate(&In->dTDs[Td]);

			XUsbPs_dTDFlushCache(&In->dTDs[Td]);
		}
	}

	return XST_SUCCESS;
}

/** @} */
