1 /******************************************************************************
3 * Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
31 ******************************************************************************/
32 /******************************************************************************/
34 * @file xusbps_endpoint.c
35 * @addtogroup usbps_v2_1
38 * Endpoint specific function implementations.
43 * MODIFICATION HISTORY:
45 * Ver Who Date Changes
46 * ----- ---- -------- --------------------------------------------------------
47 * 1.00a jz 10/10/10 First release
48 * 1.03a nm 09/21/12 Fixed CR#678977. Added proper sequence for setup packet
50 * 1.04a nm 11/02/12 Fixed CR#683931. Mult bits are set properly in dQH.
51 * 2.00a kpc 04/03/14 Fixed CR#777763. Updated the macro names
52 * 2.1 kpc 04/28/14 Added XUsbPs_EpBufferSendWithZLT api and merged common
53 * code to XUsbPs_EpQueueRequest.
55 ******************************************************************************/
57 /***************************** Include Files **********************************/
59 #include <string.h> /* for bzero() */
63 #include "xusbps_endpoint.h"
65 /************************** Constant Definitions ******************************/
67 /**************************** Type Definitions ********************************/
69 /************************** Variable Definitions ******************************/
71 /************************** Function Prototypes ******************************/
73 static void XUsbPs_EpListInit(XUsbPs_DeviceConfig *DevCfgPtr);
74 static void XUsbPs_dQHInit(XUsbPs_DeviceConfig *DevCfgPtr);
75 static int XUsbPs_dTDInit(XUsbPs_DeviceConfig *DevCfgPtr);
76 static int XUsbPs_dTDAttachBuffer(XUsbPs_dTD *dTDPtr,
77 const u8 *BufferPtr, u32 BufferLen);
79 static void XUsbPs_dQHSetMaxPacketLenISO(XUsbPs_dQH *dQHPtr, u32 Len);
81 /* Functions to reconfigure endpoint upon host's set alternate interface
84 static void XUsbPs_dQHReinitEp(XUsbPs_DeviceConfig *DevCfgPtr,
85 int EpNum, unsigned short NewDirection);
86 static int XUsbPs_dTDReinitEp(XUsbPs_DeviceConfig *DevCfgPtr,
87 int EpNum, unsigned short NewDirection);
88 static int XUsbPs_EpQueueRequest(XUsbPs *InstancePtr, u8 EpNum,
89 const u8 *BufferPtr, u32 BufferLen, u8 ReqZero);
91 /******************************* Functions ************************************/
93 /*****************************************************************************/
96 * This function configures the DEVICE side of the controller. The caller needs
97 * to pass in the desired configuration (e.g. number of endpoints) and a
98 * DMAable buffer that will hold the Queue Head List and the Transfer
99 * Descriptors. The required size for this buffer can be obtained by the caller
100 * using the: XUsbPs_DeviceMemRequired() macro.
102 * @param InstancePtr is a pointer to the XUsbPs instance of the
104 * @param CfgPtr is a pointer to the configuration structure that contains
105 * the desired DEVICE side configuration.
108 * - XST_SUCCESS: The operation completed successfully.
109 * - XST_FAILURE: An error occured.
112 * The caller may configure the controller for both, DEVICE and
115 ******************************************************************************/
116 int XUsbPs_ConfigureDevice(XUsbPs *InstancePtr,
117 const XUsbPs_DeviceConfig *CfgPtr)
122 Xil_AssertNonvoid(InstancePtr != NULL);
123 Xil_AssertNonvoid(CfgPtr != NULL);
125 /* Copy the configuration data over into the local instance structure */
126 InstancePtr->DeviceConfig = *CfgPtr;
129 /* Align the buffer to a 2048 byte (XUSBPS_dQH_BASE_ALIGN) boundary.*/
130 InstancePtr->DeviceConfig.PhysAligned =
131 (InstancePtr->DeviceConfig.DMAMemPhys +
132 XUSBPS_dQH_BASE_ALIGN) &
133 ~(XUSBPS_dQH_BASE_ALIGN -1);
135 /* Initialize the endpoint pointer list data structure. */
136 XUsbPs_EpListInit(&InstancePtr->DeviceConfig);
139 /* Initialize the Queue Head structures in DMA memory. */
140 XUsbPs_dQHInit(&InstancePtr->DeviceConfig);
143 /* Initialize the Transfer Descriptors in DMA memory.*/
144 Status = XUsbPs_dTDInit(&InstancePtr->DeviceConfig);
145 if (XST_SUCCESS != Status) {
149 /* Changing the DEVICE mode requires a controller RESET. */
150 if (XST_SUCCESS != XUsbPs_Reset(InstancePtr)) {
154 /* Set the Queue Head List address. */
155 XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
156 XUSBPS_EPLISTADDR_OFFSET,
157 InstancePtr->DeviceConfig.PhysAligned);
159 /* Set the USB mode register to configure DEVICE mode.
161 * XUSBPS_MODE_SLOM_MASK note:
162 * Disable Setup Lockout. Setup Lockout is not required as we
163 * will be using the tripwire mechanism when handling setup
166 ModeValue = XUSBPS_MODE_CM_DEVICE_MASK | XUSBPS_MODE_SLOM_MASK;
168 XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
169 XUSBPS_MODE_OFFSET, ModeValue);
171 XUsbPs_SetBits(InstancePtr, XUSBPS_OTGCSR_OFFSET,
172 XUSBPS_OTGSC_OT_MASK);
177 /*****************************************************************************/
179 * This function sends a given data buffer.
181 * @param InstancePtr is a pointer to XUsbPs instance of the controller.
182 * @param EpNum is the number of the endpoint to receive data from.
183 * @param BufferPtr is a pointer to the buffer to send.
184 * @param BufferLen is the Buffer length.
187 * - XST_SUCCESS: The operation completed successfully.
188 * - XST_FAILURE: An error occured.
189 * - XST_USB_BUF_TOO_BIG: Provided buffer is too big (>16kB).
190 * - XST_USB_NO_DESC_AVAILABLE: No TX descriptor is available.
192 ******************************************************************************/
193 int XUsbPs_EpBufferSend(XUsbPs *InstancePtr, u8 EpNum,
194 const u8 *BufferPtr, u32 BufferLen)
196 Xil_AssertNonvoid(InstancePtr != NULL);
197 Xil_AssertNonvoid(EpNum < InstancePtr->DeviceConfig.NumEndpoints);
199 return XUsbPs_EpQueueRequest(InstancePtr, EpNum, BufferPtr,
203 /*****************************************************************************/
205 * This function sends a given data buffer and also zero length packet if the
206 * Bufferlen is in multiples of endpoint max packet size.
208 * @param InstancePtr is a pointer to XUsbPs instance of the controller.
209 * @param EpNum is the number of the endpoint to receive data from.
210 * @param BufferPtr is a pointer to the buffer to send.
211 * @param BufferLen is the Buffer length.
214 * - XST_SUCCESS: The operation completed successfully.
215 * - XST_FAILURE: An error occured.
216 * - XST_USB_BUF_TOO_BIG: Provided buffer is too big (>16kB).
217 * - XST_USB_NO_DESC_AVAILABLE: No TX descriptor is available.
219 ******************************************************************************/
220 int XUsbPs_EpBufferSendWithZLT(XUsbPs *InstancePtr, u8 EpNum,
221 const u8 *BufferPtr, u32 BufferLen)
226 Xil_AssertNonvoid(InstancePtr != NULL);
227 Xil_AssertNonvoid(EpNum < InstancePtr->DeviceConfig.NumEndpoints);
229 Ep = &InstancePtr->DeviceConfig.EpCfg[EpNum].In;
231 if ((BufferLen >= Ep->MaxPacketSize) &&
232 (BufferLen % Ep->MaxPacketSize == 0)) {
236 return XUsbPs_EpQueueRequest(InstancePtr, EpNum, BufferPtr,
240 /*****************************************************************************/
242 * This function sends a given data buffer and also sends ZLT packet if it is
245 * @param InstancePtr is a pointer to XUsbPs instance of the controller.
246 * @param EpNum is the number of the endpoint to receive data from.
247 * @param BufferPtr is a pointer to the buffer to send.
248 * @param BufferLen is the Buffer length.
249 * @param ReqZero is the
252 * - XST_SUCCESS: The operation completed successfully.
253 * - XST_FAILURE: An error occured.
254 * - XST_USB_BUF_TOO_BIG: Provided buffer is too big (>16kB).
255 * - XST_USB_NO_DESC_AVAILABLE: No TX descriptor is available.
257 ******************************************************************************/
258 static int XUsbPs_EpQueueRequest(XUsbPs *InstancePtr, u8 EpNum,
259 const u8 *BufferPtr, u32 BufferLen, u8 ReqZero)
267 u32 Mask = 0x00010000;
268 u32 BitMask = Mask << EpNum;
274 /* Locate the next available buffer in the ring. A buffer is available
275 * if its descriptor is not active.
277 Ep = &InstancePtr->DeviceConfig.Ep[EpNum].In;
279 Xil_DCacheFlushRange((unsigned int)BufferPtr, BufferLen);
281 if(Ep->dTDTail != Ep->dTDHead) {
284 XUsbPs_dTDInvalidateCache(Ep->dTDHead);
286 /* Tell the caller if we do not have any descriptors available. */
287 if (XUsbPs_dTDIsActive(Ep->dTDHead)) {
288 return XST_USB_NO_DESC_AVAILABLE;
291 /* Remember the current head. */
292 DescPtr = Ep->dTDHead;
295 Length = (BufferLen > XUSBPS_dTD_BUF_MAX_SIZE) ? XUSBPS_dTD_BUF_MAX_SIZE : BufferLen;
296 /* Attach the provided buffer to the current descriptor.*/
297 Status = XUsbPs_dTDAttachBuffer(Ep->dTDHead, BufferPtr, Length);
298 if (XST_SUCCESS != Status) {
304 XUsbPs_dTDSetActive(Ep->dTDHead);
305 if (BufferLen == 0 && (ReqZero == FALSE)) {
306 XUsbPs_dTDSetIOC(Ep->dTDHead);
309 XUsbPs_dTDClrTerminate(Ep->dTDHead);
310 XUsbPs_dTDFlushCache(Ep->dTDHead);
312 /* Advance the head descriptor pointer to the next descriptor. */
313 Ep->dTDHead = XUsbPs_dTDGetNLP(Ep->dTDHead);
314 /* Terminate the next descriptor and flush the cache.*/
315 XUsbPs_dTDInvalidateCache(Ep->dTDHead);
316 /* Tell the caller if we do not have any descriptors available. */
317 if (XUsbPs_dTDIsActive(Ep->dTDHead)) {
318 return XST_USB_NO_DESC_AVAILABLE;
321 if (ReqZero && BufferLen == 0) {
325 } while(BufferLen || exit);
327 XUsbPs_dTDSetTerminate(Ep->dTDHead);
328 XUsbPs_dTDFlushCache(Ep->dTDHead);
331 /* Read the endpoint prime register. */
332 RegValue = XUsbPs_ReadReg(InstancePtr->Config.BaseAddress, XUSBPS_EPPRIME_OFFSET);
333 if(RegValue & BitMask) {
338 RegValue = XUsbPs_ReadReg(InstancePtr->Config.BaseAddress, XUSBPS_CMD_OFFSET);
339 XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, XUSBPS_CMD_OFFSET,
340 RegValue | XUSBPS_CMD_ATDTW_MASK);
341 Temp = XUsbPs_ReadReg(InstancePtr->Config.BaseAddress, XUSBPS_EPRDY_OFFSET)
343 } while(!(XUsbPs_ReadReg(InstancePtr->Config.BaseAddress, XUSBPS_CMD_OFFSET) &
344 XUSBPS_CMD_ATDTW_MASK));
346 RegValue = XUsbPs_ReadReg(InstancePtr->Config.BaseAddress, XUSBPS_CMD_OFFSET);
347 XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, XUSBPS_CMD_OFFSET,
348 RegValue & ~XUSBPS_CMD_ATDTW_MASK);
355 /* Check, if the DMA engine is still running. If it is running, we do
356 * not clear Queue Head fields.
358 * Same cache rule as for the Transfer Descriptor applies for the Queue
361 XUsbPs_dQHInvalidateCache(Ep->dQH);
362 /* Add the dTD to the dQH */
363 XUsbPs_WritedQH(Ep->dQH, XUSBPS_dQHdTDNLP, DescPtr);
364 Token = XUsbPs_ReaddQH(Ep->dQH, XUSBPS_dQHdTDTOKEN);
365 Token &= ~(XUSBPS_dTDTOKEN_ACTIVE_MASK | XUSBPS_dTDTOKEN_HALT_MASK);
366 XUsbPs_WritedQH(Ep->dQH, XUSBPS_dQHdTDTOKEN, Token);
368 XUsbPs_dQHFlushCache(Ep->dQH);
370 Status = XUsbPs_EpPrime(InstancePtr, EpNum, XUSBPS_EP_DIRECTION_IN);
375 /*****************************************************************************/
377 * This function receives a data buffer from the endpoint of the given endpoint
380 * @param InstancePtr is a pointer to the XUsbPs instance of the
382 * @param EpNum is the number of the endpoint to receive data from.
383 * @param BufferPtr (OUT param) is a pointer to the buffer pointer to hold
384 * the reference of the data buffer.
385 * @param BufferLenPtr (OUT param) is a pointer to the integer that will
386 * hold the buffer length.
387 * @param Handle is the opaque handle to be used when the buffer is
391 * - XST_SUCCESS: The operation completed successfully.
392 * - XST_FAILURE: An error occured.
393 * - XST_USB_NO_BUF: No buffer available.
396 * After handling the data in the buffer, the user MUST release
397 * the buffer using the Handle by calling the
398 * XUsbPs_EpBufferRelease() function.
400 ******************************************************************************/
401 int XUsbPs_EpBufferReceive(XUsbPs *InstancePtr, u8 EpNum,
402 u8 **BufferPtr, u32 *BufferLenPtr, u32 *Handle)
405 XUsbPs_EpSetup *EpSetup;
408 Xil_AssertNonvoid(InstancePtr != NULL);
409 Xil_AssertNonvoid(BufferPtr != NULL);
410 Xil_AssertNonvoid(BufferLenPtr != NULL);
411 Xil_AssertNonvoid(Handle != NULL);
412 Xil_AssertNonvoid(EpNum < InstancePtr->DeviceConfig.NumEndpoints);
414 /* Locate the next available buffer in the ring. A buffer is available
415 * if its descriptor is not active.
417 Ep = &InstancePtr->DeviceConfig.Ep[EpNum].Out;
419 XUsbPs_dTDInvalidateCache(Ep->dTDCurr);
421 if (XUsbPs_dTDIsActive(Ep->dTDCurr)) {
422 return XST_USB_NO_BUF;
425 /* The buffer is not active which means that it has been processed by
426 * the DMA engine and contains valid data.
428 EpSetup = &InstancePtr->DeviceConfig.EpCfg[EpNum].Out;
431 /* Use the buffer pointer stored in the "user data" field of the
432 * Transfer Descriptor.
434 *BufferPtr = (u8 *) XUsbPs_ReaddTD(Ep->dTDCurr,
437 length = EpSetup->BufSize -
438 XUsbPs_dTDGetTransferLen(Ep->dTDCurr);
441 *BufferLenPtr = length;
446 *Handle = (u32) Ep->dTDCurr;
449 /* Reset the descriptor's BufferPointer0 and Transfer Length fields to
450 * their original value. Note that we can not yet re-activate the
451 * descriptor as the caller will be using the attached buffer. Once the
452 * caller releases the buffer by calling XUsbPs_EpBufferRelease(), we
453 * can re-activate the descriptor.
455 XUsbPs_WritedTD(Ep->dTDCurr, XUSBPS_dTDBPTR0, *BufferPtr);
456 XUsbPs_dTDSetTransferLen(Ep->dTDCurr, EpSetup->BufSize);
458 XUsbPs_dTDFlushCache(Ep->dTDCurr);
464 /*****************************************************************************/
466 * This function returns a previously received data buffer to the driver.
468 * @param Handle is a pointer to the buffer that is returned.
472 ******************************************************************************/
473 void XUsbPs_EpBufferRelease(u32 Handle)
477 /* Perform sanity check on Handle.*/
478 Xil_AssertVoid((0 != Handle) && (0 == (Handle % XUSBPS_dTD_ALIGN)));
480 /* Activate the descriptor and clear the Terminate bit. Make sure to do
481 * the proper cache handling.
483 dTDPtr = (XUsbPs_dTD *) Handle;
485 XUsbPs_dTDInvalidateCache(dTDPtr);
487 XUsbPs_dTDClrTerminate(dTDPtr);
488 XUsbPs_dTDSetActive(dTDPtr);
489 XUsbPs_dTDSetIOC(dTDPtr);
491 XUsbPs_dTDFlushCache(dTDPtr);
496 /*****************************************************************************/
498 * This function sets the handler for endpoint events.
500 * @param InstancePtr is a pointer to the XUsbPs instance of the
502 * @param EpNum is the number of the endpoint to receive data from.
503 * @param Direction is the direction of the endpoint (bitfield):
504 * - XUSBPS_EP_DIRECTION_OUT
505 * - XUSBPS_EP_DIRECTION_IN
506 * @param CallBackFunc is the Handler callback function.
507 * Can be NULL if the user wants to disable the handler entry.
508 * @param CallBackRef is the user definable data pointer that will be
509 * passed back if the handler is called. May be NULL.
512 * - XST_SUCCESS: The operation completed successfully.
513 * - XST_FAILURE: An error occured.
514 * - XST_INVALID_PARAM: Invalid parameter passed.
517 * The user can disable a handler by setting the callback function
520 ******************************************************************************/
521 int XUsbPs_EpSetHandler(XUsbPs *InstancePtr, u8 EpNum, u8 Direction,
522 XUsbPs_EpHandlerFunc CallBackFunc,
527 Xil_AssertNonvoid(InstancePtr != NULL);
528 Xil_AssertNonvoid(CallBackFunc != NULL);
529 Xil_AssertNonvoid(EpNum < InstancePtr->DeviceConfig.NumEndpoints);
531 Ep = &InstancePtr->DeviceConfig.Ep[EpNum];
533 if(Direction & XUSBPS_EP_DIRECTION_OUT) {
534 Ep->Out.HandlerFunc = CallBackFunc;
535 Ep->Out.HandlerRef = CallBackRef;
538 if(Direction & XUSBPS_EP_DIRECTION_IN) {
539 Ep->In.HandlerFunc = CallBackFunc;
540 Ep->In.HandlerRef = CallBackRef;
547 /*****************************************************************************/
549 * This function primes an endpoint.
551 * @param InstancePtr is pointer to the XUsbPs instance.
552 * @param EpNum is the number of the endpoint to receive data from.
553 * @param Direction is the direction of the endpoint (bitfield):
554 * - XUSBPS_EP_DIRECTION_OUT
555 * - XUSBPS_EP_DIRECTION_IN
558 * - XST_SUCCESS: The operation completed successfully.
559 * - XST_FAILURE: An error occured.
560 * - XST_INVALID_PARAM: Invalid parameter passed.
564 ******************************************************************************/
565 int XUsbPs_EpPrime(XUsbPs *InstancePtr, u8 EpNum, u8 Direction)
569 Xil_AssertNonvoid(InstancePtr != NULL);
570 Xil_AssertNonvoid(EpNum < InstancePtr->DeviceConfig.NumEndpoints);
572 /* Get the right bit mask for the endpoint direction. */
575 case XUSBPS_EP_DIRECTION_OUT:
579 case XUSBPS_EP_DIRECTION_IN:
584 return XST_INVALID_PARAM;
587 /* Write the endpoint prime register. */
588 XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
589 XUSBPS_EPPRIME_OFFSET, Mask << EpNum);
595 /*****************************************************************************/
597 * This function extracts the Setup Data from a given endpoint.
599 * @param InstancePtr is a pointer to the XUsbPs instance of the
601 * @param EpNum is the number of the endpoint to receive data from.
602 * @param SetupDataPtr is a pointer to the setup data structure to be
606 * - XST_SUCCESS: The operation completed successfully.
607 * - XST_FAILURE: An error occured.
610 ******************************************************************************/
611 int XUsbPs_EpGetSetupData(XUsbPs *InstancePtr, int EpNum,
612 XUsbPs_SetupData *SetupDataPtr)
621 Xil_AssertNonvoid(InstancePtr != NULL);
622 Xil_AssertNonvoid(SetupDataPtr != NULL);
623 Xil_AssertNonvoid(EpNum < InstancePtr->DeviceConfig.NumEndpoints);
625 Ep = &InstancePtr->DeviceConfig.Ep[EpNum].Out;
628 /* Get the data from the Queue Heads Setup buffer into local variables
629 * so we can extract the setup data values.
632 /* Arm the tripwire. The tripwire will tell us if a new setup
633 * packet arrived (in which case the tripwire bit will be
634 * cleared) while we were reading the buffer. If a new setup
635 * packet arrived the buffer is corrupted and we continue
638 XUsbPs_SetSetupTripwire(InstancePtr);
640 XUsbPs_dQHInvalidateCache(Ep->dQH);
642 Data[0] = XUsbPs_ReaddQH(Ep->dQH, XUSBPS_dQHSUB0);
643 Data[1] = XUsbPs_ReaddQH(Ep->dQH, XUSBPS_dQHSUB1);
644 } while (FALSE == XUsbPs_SetupTripwireIsSet(InstancePtr));
646 /* Clear the pending endpoint setup stat bit.
648 XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
649 XUSBPS_EPSTAT_OFFSET, 1 << EpNum);
651 /* Clear the Tripwire bit and continue.
653 XUsbPs_ClrSetupTripwire(InstancePtr);
656 /* Data in the setup buffer is being converted by the core to big
657 * endian format. We have to take care of proper byte swapping when
658 * reading the setup data values.
660 * Need to check if there is a smarter way to do this and take the
661 * processor/memory-controller endianess into account?
665 SetupDataPtr->bmRequestType = p[0];
666 SetupDataPtr->bRequest = p[1];
667 SetupDataPtr->wValue = (p[3] << 8) | p[2];
668 SetupDataPtr->wIndex = (p[5] << 8) | p[4];
669 SetupDataPtr->wLength = (p[7] << 8) | p[6];
671 /* Before we leave we need to make sure that the endpoint setup bit has
672 * cleared. It needs to be 0 before the endpoint can be re-primed.
674 * Note: According to the documentation this endpoint setup bit should
675 * clear within 1-2us after it has been written above. This means that
676 * we should never catch it being 1 here. However, we still need to
677 * poll it to make sure. Just in case, we use a counter 'Timeout' so we
678 * won't hang here if the bit is stuck for some reason.
680 Timeout = XUSBPS_TIMEOUT_COUNTER;
681 while ((XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
682 XUSBPS_EPSTAT_OFFSET) &
683 (1 << EpNum)) && --Timeout) {
694 /*****************************************************************************/
697 * This function initializes the endpoint pointer data structure.
699 * The function sets up the local data structure with the aligned addresses for
700 * the Queue Head and Transfer Descriptors.
702 * @param DevCfgPtr is pointer to the XUsbPs DEVICE configuration
708 * Endpoints of type XUSBPS_EP_TYPE_NONE are not used in the
709 * system. Therefore no memory is reserved for them.
711 ******************************************************************************/
712 static void XUsbPs_EpListInit(XUsbPs_DeviceConfig *DevCfgPtr)
718 XUsbPs_EpConfig *EpCfg;
720 /* Set up the XUsbPs_Endpoint array. This array is used to define the
721 * location of the Queue Head list and the Transfer Descriptors in the
722 * block of DMA memory that has been passed into the driver.
724 * 'p' is used to set the pointers in the local data structure.
725 * Initially 'p' is pointed to the beginning of the DMAable memory
726 * block. As pointers are assigned, 'p' is incremented by the size of
727 * the respective object.
730 EpCfg = DevCfgPtr->EpCfg;
732 /* Start off with 'p' pointing to the (aligned) beginning of the DMA
735 p = (u8 *) DevCfgPtr->PhysAligned;
738 /* Initialize the Queue Head pointer list.
740 * Each endpoint has two Queue Heads. One for the OUT direction and one
741 * for the IN direction. An OUT Queue Head is always followed by an IN
744 * Queue Head alignment is XUSBPS_dQH_ALIGN.
746 * Note that we have to reserve space here for unused endpoints.
748 for (EpNum = 0; EpNum < DevCfgPtr->NumEndpoints; ++EpNum) {
750 Ep[EpNum].Out.dQH = (XUsbPs_dQH *) p;
751 p += XUSBPS_dQH_ALIGN;
754 Ep[EpNum].In.dQH = (XUsbPs_dQH *) p;
755 p += XUSBPS_dQH_ALIGN;
759 /* 'p' now points to the first address after the Queue Head list. The
760 * Transfer Descriptors start here.
762 * Each endpoint has a variable number of Transfer Descriptors
763 * depending on user configuration.
765 * Transfer Descriptor alignment is XUSBPS_dTD_ALIGN.
767 for (EpNum = 0; EpNum < DevCfgPtr->NumEndpoints; ++EpNum) {
770 if (XUSBPS_EP_TYPE_NONE != EpCfg[EpNum].Out.Type) {
771 Ep[EpNum].Out.dTDs = (XUsbPs_dTD *) p;
772 Ep[EpNum].Out.dTDCurr = (XUsbPs_dTD *) p;
773 p += XUSBPS_dTD_ALIGN * EpCfg[EpNum].Out.NumBufs;
778 if (XUSBPS_EP_TYPE_NONE != EpCfg[EpNum].In.Type) {
779 Ep[EpNum].In.dTDs = (XUsbPs_dTD *) p;
780 Ep[EpNum].In.dTDHead = (XUsbPs_dTD *) p;
781 Ep[EpNum].In.dTDTail = (XUsbPs_dTD *) p;
782 p += XUSBPS_dTD_ALIGN * EpCfg[EpNum].In.NumBufs;
787 /* 'p' now points to the first address after the Transfer Descriptors.
788 * The data buffers for the OUT Transfer Desciptors start here.
790 * Note that IN (TX) Transfer Descriptors are not assigned buffers at
791 * this point. Buffers will be assigned when the user calls the send()
794 for (EpNum = 0; EpNum < DevCfgPtr->NumEndpoints; ++EpNum) {
796 if (XUSBPS_EP_TYPE_NONE != EpCfg[EpNum].Out.Type) {
797 /* If BufSize for this endpoint is set to 0 it means
798 * that we do not need to attach a buffer to this
799 * descriptor. We also initialize it's buffer pointer
802 if (0 == EpCfg[EpNum].Out.BufSize) {
803 Ep[EpNum].Out.dTDBufs = NULL;
807 Ep[EpNum].Out.dTDBufs = p;
808 p += EpCfg[EpNum].Out.BufSize * EpCfg[EpNum].Out.NumBufs;
813 /* Initialize the endpoint event handlers to NULL.
815 for (EpNum = 0; EpNum < DevCfgPtr->NumEndpoints; ++EpNum) {
816 Ep[EpNum].Out.HandlerFunc = NULL;
817 Ep[EpNum].In.HandlerFunc = NULL;
822 /*****************************************************************************/
825 * This function initializes the Queue Head List in memory.
827 * @param DevCfgPtr is a pointer to the XUsbPs DEVICE configuration
834 ******************************************************************************/
835 static void XUsbPs_dQHInit(XUsbPs_DeviceConfig *DevCfgPtr)
840 XUsbPs_EpConfig *EpCfg;
842 /* Setup pointers for simpler access. */
844 EpCfg = DevCfgPtr->EpCfg;
847 /* Go through the list of Queue Head entries and:
849 * - Set Transfer Descriptor addresses
850 * - Set Maximum Packet Size
851 * - Disable Zero Length Termination (ZLT) for non-isochronous transfers
852 * - Enable Interrupt On Setup (IOS)
855 for (EpNum = 0; EpNum < DevCfgPtr->NumEndpoints; ++EpNum) {
857 /* OUT Queue Heads.*/
858 if (XUSBPS_EP_TYPE_NONE != EpCfg[EpNum].Out.Type) {
859 XUsbPs_WritedQH(Ep[EpNum].Out.dQH,
860 XUSBPS_dQHCPTR, Ep[EpNum].Out.dTDs);
862 /* For isochronous, ep max packet size translates to different
863 * values in queue head than other types.
864 * Also enable ZLT for isochronous.
866 if(XUSBPS_EP_TYPE_ISOCHRONOUS == EpCfg[EpNum].Out.Type) {
867 XUsbPs_dQHSetMaxPacketLenISO(Ep[EpNum].Out.dQH,
868 EpCfg[EpNum].Out.MaxPacketSize);
869 XUsbPs_dQHEnableZLT(Ep[EpNum].Out.dQH);
871 XUsbPs_dQHSetMaxPacketLen(Ep[EpNum].Out.dQH,
872 EpCfg[EpNum].Out.MaxPacketSize);
873 XUsbPs_dQHDisableZLT(Ep[EpNum].Out.dQH);
876 /* Only control OUT needs this */
877 if(XUSBPS_EP_TYPE_CONTROL == EpCfg[EpNum].Out.Type) {
878 XUsbPs_dQHSetIOS(Ep[EpNum].Out.dQH);
881 /* Set up the overlay next dTD pointer. */
882 XUsbPs_WritedQH(Ep[EpNum].Out.dQH,
883 XUSBPS_dQHdTDNLP, Ep[EpNum].Out.dTDs);
885 XUsbPs_dQHFlushCache(Ep[EpNum].Out.dQH);
889 /* IN Queue Heads. */
890 if (XUSBPS_EP_TYPE_NONE != EpCfg[EpNum].In.Type) {
891 XUsbPs_WritedQH(Ep[EpNum].In.dQH,
892 XUSBPS_dQHCPTR, Ep[EpNum].In.dTDs);
895 /* Isochronous ep packet size can be larger than 1024.*/
896 if(XUSBPS_EP_TYPE_ISOCHRONOUS == EpCfg[EpNum].In.Type) {
897 XUsbPs_dQHSetMaxPacketLenISO(Ep[EpNum].In.dQH,
898 EpCfg[EpNum].In.MaxPacketSize);
899 XUsbPs_dQHEnableZLT(Ep[EpNum].In.dQH);
901 XUsbPs_dQHSetMaxPacketLen(Ep[EpNum].In.dQH,
902 EpCfg[EpNum].In.MaxPacketSize);
903 XUsbPs_dQHDisableZLT(Ep[EpNum].In.dQH);
906 XUsbPs_dQHFlushCache(Ep[EpNum].In.dQH);
912 /*****************************************************************************/
915 * This function initializes the Transfer Descriptors lists in memory.
917 * @param DevCfgPtr is a pointer to the XUsbPs DEVICE configuration
921 * - XST_SUCCESS: The operation completed successfully.
922 * - XST_FAILURE: An error occured.
924 ******************************************************************************/
925 static int XUsbPs_dTDInit(XUsbPs_DeviceConfig *DevCfgPtr)
930 XUsbPs_EpConfig *EpCfg;
932 /* Setup pointers for simpler access. */
934 EpCfg = DevCfgPtr->EpCfg;
937 /* Walk through the list of endpoints and initialize their Transfer
940 for (EpNum = 0; EpNum < DevCfgPtr->NumEndpoints; ++EpNum) {
944 XUsbPs_EpOut *Out = &Ep[EpNum].Out;
945 XUsbPs_EpIn *In = &Ep[EpNum].In;
951 * + Set the next link pointer
952 * + Set the interrupt complete and the active bit
953 * + Attach the buffer to the dTD
955 if (XUSBPS_EP_TYPE_NONE != EpCfg[EpNum].Out.Type) {
956 NumdTD = EpCfg[EpNum].Out.NumBufs;
962 for (Td = 0; Td < NumdTD; ++Td) {
965 int NextTd = (Td + 1) % NumdTD;
967 XUsbPs_dTDInvalidateCache(&Out->dTDs[Td]);
969 /* Set NEXT link pointer. */
970 XUsbPs_WritedTD(&Out->dTDs[Td], XUSBPS_dTDNLP,
973 /* Set the OUT descriptor ACTIVE and enable the
974 * interrupt on complete.
976 XUsbPs_dTDSetActive(&Out->dTDs[Td]);
977 XUsbPs_dTDSetIOC(&Out->dTDs[Td]);
980 /* Set up the data buffer with the descriptor. If the
981 * buffer pointer is NULL it means that we do not need
982 * to attach a buffer to this descriptor.
984 if (NULL == Out->dTDBufs) {
985 XUsbPs_dTDFlushCache(&Out->dTDs[Td]);
989 Status = XUsbPs_dTDAttachBuffer(
992 (Td * EpCfg[EpNum].Out.BufSize),
993 EpCfg[EpNum].Out.BufSize);
994 if (XST_SUCCESS != Status) {
998 XUsbPs_dTDFlushCache(&Out->dTDs[Td]);
1005 * + Set the next link pointer
1006 * + Set the Terminate bit to mark it available
1008 if (XUSBPS_EP_TYPE_NONE != EpCfg[EpNum].In.Type) {
1009 NumdTD = EpCfg[EpNum].In.NumBufs;
1015 for (Td = 0; Td < NumdTD; ++Td) {
1016 int NextTd = (Td + 1) % NumdTD;
1018 XUsbPs_dTDInvalidateCache(&In->dTDs[Td]);
1020 /* Set NEXT link pointer. */
1021 XUsbPs_WritedTD(In->dTDs[Td], XUSBPS_dTDNLP,
1024 /* Set the IN descriptor's TERMINATE bits. */
1025 XUsbPs_dTDSetTerminate(In->dTDs[Td]);
1027 XUsbPs_dTDFlushCache(&In->dTDs[Td]);
1035 /*****************************************************************************/
1038 * This function associates a buffer with a Transfer Descriptor. The function
1039 * will take care of splitting the buffer into multiple 4kB aligned segments if
1040 * the buffer happens to span one or more 4kB pages.
1042 * @param dTDIndex is a pointer to the Transfer Descriptor
1043 * @param BufferPtr is pointer to the buffer to link to the descriptor.
1044 * @param BufferLen is the length of the buffer.
1047 * - XST_SUCCESS: The operation completed successfully.
1048 * - XST_FAILURE: An error occured.
1049 * - XST_USB_BUF_TOO_BIG: The provided buffer is bigger than tha
1050 * maximum allowed buffer size (16k).
1053 * Cache invalidation and flushing needs to be handler by the
1054 * caller of this function.
1056 ******************************************************************************/
1057 static int XUsbPs_dTDAttachBuffer(XUsbPs_dTD *dTDPtr,
1058 const u8 *BufferPtr, u32 BufferLen)
1064 Xil_AssertNonvoid(dTDPtr != NULL);
1066 /* Check if the buffer is smaller than 16kB. */
1067 if (BufferLen > XUSBPS_dTD_BUF_MAX_SIZE) {
1068 return XST_USB_BUF_TOO_BIG;
1071 /* Get a u32 of the buffer pointer to avoid casting in the following
1074 BufAddr = (u32) BufferPtr;
1077 /* Set the buffer pointer 0. Buffer pointer 0 can point to any location
1078 * in memory. It does not need to be 4kB aligned. However, if the
1079 * provided buffer spans one or more 4kB boundaries, we need to set up
1080 * the subsequent buffer pointers which must be 4kB aligned.
1082 XUsbPs_WritedTD(dTDPtr, XUSBPS_dTDBPTR(0), BufAddr);
1084 /* Check if the buffer spans a 4kB boundary.
1086 * Only do this check, if we are not sending a 0-length buffer.
1088 if (BufferLen > 0) {
1089 BufEnd = BufAddr + BufferLen -1;
1092 while ((BufAddr & 0xFFFFF000) != (BufEnd & 0xFFFFF000)) {
1093 /* The buffer spans at least one boundary, let's set
1094 * the next buffer pointer and repeat the procedure
1095 * until the end of the buffer and the pointer written
1096 * are in the same 4kB page.
1098 BufAddr = (BufAddr + 0x1000) & 0xFFFFF000;
1099 XUsbPs_WritedTD(dTDPtr, XUSBPS_dTDBPTR(PtrNum),
1105 /* Set the length of the buffer. */
1106 XUsbPs_dTDSetTransferLen(dTDPtr, BufferLen);
1109 /* We remember the buffer pointer in the user data field (reserved
1110 * field in the dTD). This makes it easier to reset the buffer pointer
1111 * after a buffer has been received on the endpoint. The buffer pointer
1112 * needs to be reset because the DMA engine modifies the buffer pointer
1115 XUsbPs_WritedTD(dTDPtr, XUSBPS_dTDUSERDATA, BufferPtr);
1121 /*****************************************************************************/
1123 * This function set the Max PacketLen for the queue head for isochronous EP.
1125 * If the max packet length is greater than XUSBPS_MAX_PACKET_SIZE, then
1126 * Mult bits are set to reflect that.
1128 * @param dQHPtr is a pointer to the dQH element.
1129 * @param Len is the Length to be set.
1131 ******************************************************************************/
1132 static void XUsbPs_dQHSetMaxPacketLenISO(XUsbPs_dQH *dQHPtr, u32 Len)
1134 u32 Mult = (Len & ENDPOINT_MAXP_MULT_MASK) >> ENDPOINT_MAXP_MULT_SHIFT;
1135 u32 MaxPktSize = (Mult > 1) ? ENDPOINT_MAXP_LENGTH : Len;
1137 if (MaxPktSize > XUSBPS_MAX_PACKET_SIZE) {
1145 /* Set Max packet size */
1146 XUsbPs_WritedQH(dQHPtr, XUSBPS_dQHCFG,
1147 (XUsbPs_ReaddQH(dQHPtr, XUSBPS_dQHCFG) &
1148 ~XUSBPS_dQHCFG_MPL_MASK) |
1149 (MaxPktSize << XUSBPS_dQHCFG_MPL_SHIFT));
1151 /* Set Mult to tell hardware how many transactions in each microframe */
1152 XUsbPs_WritedQH(dQHPtr, XUSBPS_dQHCFG,
1153 (XUsbPs_ReaddQH(dQHPtr, XUSBPS_dQHCFG) &
1154 ~XUSBPS_dQHCFG_MULT_MASK) |
1155 (Mult << XUSBPS_dQHCFG_MULT_SHIFT));
1159 /*****************************************************************************/
1161 * This function reconfigures one Ep corresponding to host's request of setting
1162 * alternate interface. The endpoint has been disabled before this call.
1164 * Both QH and dTDs are updated for the new configuration.
1166 * @param InstancePtr is a pointer to the XUsbPs instance of the
1169 * Pointer to the updated XUsbPs DEVICE configuration structure.
1172 * The endpoint to be reconfigured.
1174 * @param NewDirection
1175 * The new transfer direction the endpoint.
1177 * @param DirectionChanged
1178 * A boolean value indicate whether the transfer direction has changed.
1181 * XST_SUCCESS upon success, XST_FAILURE otherwise.
1183 ******************************************************************************/
1184 int XUsbPs_ReconfigureEp(XUsbPs *InstancePtr, XUsbPs_DeviceConfig *CfgPtr,
1185 int EpNum, unsigned short NewDirection,
1186 int DirectionChanged) {
1188 int Status = XST_SUCCESS;
1189 XUsbPs_Endpoint *Ep;
1190 XUsbPs_EpConfig *EpCfg;
1192 Xil_AssertNonvoid(InstancePtr != NULL);
1193 Xil_AssertNonvoid(CfgPtr != NULL);
1196 EpCfg = CfgPtr->EpCfg;
1198 /* If transfer direction changes, dTDs has to be reset
1199 * Number of buffers are preset and should not to be changed.
1201 if(DirectionChanged) {
1202 if(NewDirection == XUSBPS_EP_DIRECTION_OUT) {
1205 /* Swap the pointer to the dTDs.
1207 Ep[EpNum].Out.dTDs = Ep[EpNum].In.dTDs;
1208 p = (u8 *)(Ep[EpNum].Out.dTDs + XUSBPS_dTD_ALIGN * EpCfg[EpNum].Out.NumBufs);
1210 /* Set the OUT buffer if buffer size is not zero
1212 if(EpCfg[EpNum].Out.BufSize > 0) {
1213 Ep[EpNum].Out.dTDBufs = p;
1215 } else if(NewDirection == XUSBPS_EP_DIRECTION_IN) {
1216 Ep[EpNum].In.dTDs = Ep[EpNum].Out.dTDs;
1220 /* Reset dTD progress tracking pointers
1222 if(NewDirection == XUSBPS_EP_DIRECTION_IN) {
1223 Ep[EpNum].In.dTDHead = Ep[EpNum].In.dTDTail = Ep[EpNum].In.dTDs;
1224 } else if(NewDirection == XUSBPS_EP_DIRECTION_OUT) {
1225 Ep[EpNum].Out.dTDCurr = Ep[EpNum].Out.dTDs;
1228 /* Reinitialize information in QH
1230 XUsbPs_dQHReinitEp(CfgPtr, EpNum, NewDirection);
1232 /* Reinitialize the dTD linked list, and flush the cache
1234 Status = XUsbPs_dTDReinitEp(CfgPtr, EpNum, NewDirection);
1235 if(Status != XST_SUCCESS) {
1243 /*****************************************************************************/
1245 * This function re-initializes the Queue Head List in memory.
1246 * The endpoint 1 has been disabled before this call.
1249 * Pointer to the updated XUsbPs DEVICE configuration structure.
1252 * The endpoint to be reconfigured.
1254 * @param NewDirection
1255 * The new transfer direction of endpoint 1
1259 ******************************************************************************/
1260 static void XUsbPs_dQHReinitEp(XUsbPs_DeviceConfig *DevCfgPtr,
1261 int EpNum, unsigned short NewDirection)
1263 XUsbPs_Endpoint *Ep;
1264 XUsbPs_EpConfig *EpCfg;
1266 /* Setup pointers for simpler access.
1269 EpCfg = DevCfgPtr->EpCfg;
1272 /* Go through the list of Queue Head entries and:
1274 * - Set Transfer Descriptor addresses
1275 * - Set Maximum Packet Size
1276 * - Disable Zero Length Termination (ZLT) for non-isochronous transfers
1277 * - Enable Interrupt On Setup (IOS)
1280 if(NewDirection == XUSBPS_EP_DIRECTION_OUT) {
1283 XUsbPs_WritedQH(Ep[EpNum].Out.dQH,
1284 XUSBPS_dQHCPTR, Ep[EpNum].Out.dTDs);
1286 /* For isochronous, ep max packet size translates to different
1287 * values in queue head than other types.
1288 * Also enable ZLT for isochronous.
1290 if(XUSBPS_EP_TYPE_ISOCHRONOUS == EpCfg[EpNum].Out.Type) {
1291 XUsbPs_dQHSetMaxPacketLenISO(Ep[EpNum].Out.dQH,
1292 EpCfg[EpNum].Out.MaxPacketSize);
1293 XUsbPs_dQHEnableZLT(Ep[EpNum].Out.dQH);
1295 XUsbPs_dQHSetMaxPacketLen(Ep[EpNum].Out.dQH,
1296 EpCfg[EpNum].Out.MaxPacketSize);
1297 XUsbPs_dQHDisableZLT(Ep[EpNum].Out.dQH);
1300 XUsbPs_dQHSetIOS(Ep[EpNum].Out.dQH);
1302 /* Set up the overlay next dTD pointer.
1304 XUsbPs_WritedQH(Ep[EpNum].Out.dQH,
1305 XUSBPS_dQHdTDNLP, Ep[EpNum].Out.dTDs);
1307 XUsbPs_dQHFlushCache(Ep[EpNum].Out.dQH);
1309 } else if(NewDirection == XUSBPS_EP_DIRECTION_IN) {
1313 XUsbPs_WritedQH(Ep[EpNum].In.dQH,
1314 XUSBPS_dQHCPTR, Ep[EpNum].In.dTDs);
1316 /* Isochronous ep packet size can be larger than 1024. */
1317 if(XUSBPS_EP_TYPE_ISOCHRONOUS == EpCfg[EpNum].In.Type) {
1318 XUsbPs_dQHSetMaxPacketLenISO(Ep[EpNum].In.dQH,
1319 EpCfg[EpNum].In.MaxPacketSize);
1320 XUsbPs_dQHEnableZLT(Ep[EpNum].In.dQH);
1322 XUsbPs_dQHSetMaxPacketLen(Ep[EpNum].In.dQH,
1323 EpCfg[EpNum].In.MaxPacketSize);
1324 XUsbPs_dQHDisableZLT(Ep[EpNum].In.dQH);
1327 XUsbPs_dQHSetIOS(Ep[EpNum].In.dQH);
1329 XUsbPs_dQHFlushCache(Ep[EpNum].In.dQH);
1334 /*****************************************************************************/
1337 * This function re-initializes the Transfer Descriptors lists in memory.
1338 * The endpoint has been disabled before the call. The transfer descriptors
1339 * list pointer has been initialized too.
1342 * Pointer to the XUsbPs DEVICE configuration structure.
1345 * The endpoint to be reconfigured.
1347 * @param NewDirection
1348 * The new transfer direction of endpoint 1
1351 * - XST_SUCCESS: The operation completed successfully.
1352 * - XST_FAILURE: An error occured.
1354 ******************************************************************************/
1355 static int XUsbPs_dTDReinitEp(XUsbPs_DeviceConfig *DevCfgPtr,
1356 int EpNum, unsigned short NewDirection)
1358 XUsbPs_Endpoint *Ep;
1359 XUsbPs_EpConfig *EpCfg;
1364 /* Setup pointers for simpler access.
1367 EpCfg = DevCfgPtr->EpCfg;
1370 if(NewDirection == XUSBPS_EP_DIRECTION_OUT) {
1371 XUsbPs_EpOut *Out = &Ep[EpNum].Out;
1376 * + Set the next link pointer
1377 * + Set the interrupt complete and the active bit
1378 * + Attach the buffer to the dTD
1380 NumdTD = EpCfg[EpNum].Out.NumBufs;
1382 for (Td = 0; Td < NumdTD; ++Td) {
1385 int NextTd = (Td + 1) % NumdTD;
1387 XUsbPs_dTDInvalidateCache(&Out->dTDs[Td]);
1389 /* Set NEXT link pointer.
1391 XUsbPs_WritedTD(&Out->dTDs[Td], XUSBPS_dTDNLP,
1392 &Out->dTDs[NextTd]);
1394 /* Set the OUT descriptor ACTIVE and enable the
1395 * interrupt on complete.
1397 XUsbPs_dTDSetActive(&Out->dTDs[Td]);
1398 XUsbPs_dTDSetIOC(&Out->dTDs[Td]);
1400 /* Set up the data buffer with the descriptor. If the
1401 * buffer pointer is NULL it means that we do not need
1402 * to attach a buffer to this descriptor.
1404 if (Out->dTDBufs != NULL) {
1406 Status = XUsbPs_dTDAttachBuffer(
1409 (Td * EpCfg[EpNum].Out.BufSize),
1410 EpCfg[EpNum].Out.BufSize);
1411 if (Status != XST_SUCCESS) {
1415 XUsbPs_dTDFlushCache(&Out->dTDs[Td]);
1417 } else if(NewDirection == XUSBPS_EP_DIRECTION_IN) {
1418 XUsbPs_EpIn *In = &Ep[EpNum].In;
1423 * + Set the next link pointer
1424 * + Set the Terminate bit to mark it available
1426 NumdTD = EpCfg[EpNum].In.NumBufs;
1428 for (Td = 0; Td < NumdTD; ++Td) {
1429 int NextTd = (Td + 1) % NumdTD;
1431 XUsbPs_dTDInvalidateCache(&In->dTDs[Td]);
1433 /* Set NEXT link pointer.
1435 XUsbPs_WritedTD(&In->dTDs[Td], XUSBPS_dTDNLP,
1438 /* Set the IN descriptor's TERMINATE bits.
1440 XUsbPs_dTDSetTerminate(&In->dTDs[Td]);
1442 XUsbPs_dTDFlushCache(&In->dTDs[Td]);