XilinxProcessorIPLib/drivers/mcdma/src/xmcdma_bd.c
int XMcdma_BdChainFromHW(XMcdma_ChanCtrl *Chan, u32 BdLimit, XMcdma_Bd **BdSetPtr)
{
	XMcdma_Bd *CurBdPtr;
	u32 BdCount;
	int BdPartialCount;
	volatile u32 BdSts;
	volatile u32 BdCr;

	CurBdPtr = Chan->BdHead;
	BdCount = 0;
	BdPartialCount = 0;
	BdSts = 0;
	BdCr = 0;

	if (Chan->BdSubmitCnt == 0) {
		*BdSetPtr = NULL;

		return XST_SUCCESS;
	}

	if (BdLimit > Chan->BdSubmitCnt) {
		BdLimit = Chan->BdSubmitCnt;
	}

	while (BdCount < BdLimit) {
		XMCDMA_CACHE_INVALIDATE((UINTPTR)(CurBdPtr));

		if(!(Chan->IsRxChan)) {
			BdSts = XMcdma_BdRead(CurBdPtr, XMCDMA_BD_SIDEBAND_STS_OFFSET);
			BdCr = XMcdma_BdRead(CurBdPtr, XMCDMA_BD_CTRL_OFFSET);
		} else {
			BdSts = XMcdma_BdRead(CurBdPtr, XMCDMA_BD_STS_OFFSET);
		}

		if (!(BdSts & XMCDMA_BD_STS_COMPLETE_MASK))
			break;

		BdCount++;

		/* Need to handle Tx case as well */
		if ((!(Chan->IsRxChan) && (BdCr & XMCDMA_BD_CTRL_EOF_MASK)) ||
		    (Chan->IsRxChan && (BdSts & XMCDMA_BD_STS_RXEOF_MASK))) {
			BdPartialCount = 0;
		} else {
			BdPartialCount++;
		}

		if (CurBdPtr == Chan->BdTail) {
			break;
		}

		CurBdPtr = (XMcdma_Bd *)(XMcdma_BdChainNextBd(Chan, CurBdPtr));
	}

	BdCount -= BdPartialCount;

	if (BdCount) {
		*BdSetPtr = Chan->BdHead;
		Chan->BdSubmitCnt -= BdCount;
		Chan->BdCnt += BdCount;
		Chan->BdDoneCnt += BdCount;
		XMCDMA_CHAN_SEEKAHEAD(Chan, Chan->BdHead, BdCount);

		return BdCount;
	} else {
		*BdSetPtr = (XMcdma_Bd *)NULL;
		return 0;
	}
}
/*****************************************************************************/
/**
* Returns a set of BD(s) that have been processed by hardware. The returned
* BDs may be examined by the application to determine the outcome of the DMA
* transactions. Once the BDs have been examined, the application must call
* XMcdma_BdChainFree() in the same order which they were retrieved here.
*
* If hardware has partially completed a packet spanning multiple BDs, then
* none of the BDs for that packet will be included in the results.
*
* @param	Chan is the MCDMA Channel to be worked on..
* @param	BdLimit is the maximum number of BDs to return in the set.
* @param	BdSetPtr is an output parameter, it points to the first BD
*		available for examination.
*
* @return	The number of BDs processed by hardware. A value of 0 indicates
*		that no data is available. No more than BdLimit BDs will be
*		returned.
*
* @note	Treat BDs returned by this function as read-only.
*
*****************************************************************************/
Returns a set of BD(s) that have been processed by hardware. The returned
BDs may be examined by the application to determine the outcome of the DMA
transactions. Once the BDs have been examined, the application must call
XMcdma_BdChainFree() in the same order which they were retrieved here.

If hardware has partially completed a packet spanning multiple BDs, then
none of the BDs for that packet will be included in the results.
Returns a set of BD ( s ) that have been processed by hardware . The returned BDs may be examined by the application to determine the outcome of the DMA transactions . Once the BDs have been examined the application must call XMcdma_BdChainFree () in the same order which they were retrieved here . If hardware has partially completed a packet spanning multiple BDs then none of the BDs for that packet will be included in the results .
int XMcdma_BdChainFromHW(XMcdma_ChanCtrl *Chan, u32 BdLimit, XMcdma_Bd **BdSetPtr)
{
	XMcdma_Bd *CurBdPtr;
	u32 BdCount;
	int BdPartialCount;
	volatile u32 BdSts;
	volatile u32 BdCr;
	CurBdPtr = Chan->BdHead;
	BdCount = 0;
	BdPartialCount = 0;
	BdSts = 0;
	BdCr = 0;
	if (Chan->BdSubmitCnt == 0) {
		*BdSetPtr = NULL;
		return XST_SUCCESS;
	}
	if (BdLimit > Chan->BdSubmitCnt) {
		BdLimit = Chan->BdSubmitCnt;
	}
	while (BdCount < BdLimit) {
		XMCDMA_CACHE_INVALIDATE((UINTPTR)(CurBdPtr));
		if(!(Chan->IsRxChan)) {
			BdSts = XMcdma_BdRead(CurBdPtr, XMCDMA_BD_SIDEBAND_STS_OFFSET);
			BdCr = XMcdma_BdRead(CurBdPtr, XMCDMA_BD_CTRL_OFFSET);
		} else {
			BdSts = XMcdma_BdRead(CurBdPtr, XMCDMA_BD_STS_OFFSET);
		}
		if (!(BdSts & XMCDMA_BD_STS_COMPLETE_MASK))
			break;
		BdCount++;
		if ((!(Chan->IsRxChan) && (BdCr & XMCDMA_BD_CTRL_EOF_MASK)) ||
		    (Chan->IsRxChan && (BdSts & XMCDMA_BD_STS_RXEOF_MASK))) {
			BdPartialCount = 0;
		} else {
			BdPartialCount++;
		}
		if (CurBdPtr == Chan->BdTail) {
			break;
		}
		CurBdPtr = (XMcdma_Bd *)(XMcdma_BdChainNextBd(Chan, CurBdPtr));
	}
	BdCount -= BdPartialCount;
	if (BdCount) {
		*BdSetPtr = Chan->BdHead;
		Chan->BdSubmitCnt -= BdCount;
		Chan->BdCnt += BdCount;
		Chan->BdDoneCnt += BdCount;
		XMCDMA_CHAN_SEEKAHEAD(Chan, Chan->BdHead, BdCount);
		return BdCount;
	} else {
		*BdSetPtr = (XMcdma_Bd *)NULL;
		return 0;
	}
}
int XMcdma_BdChainFromHW ( XMcdma_ChanCtrl * Chan , u32 BdLimit , XMcdma_Bd * * BdSetPtr ) { XMcdma_Bd * CurBdPtr ; u32 BdCount ; int BdPartialCount ; volatile u32 BdSts ; volatile u32 BdCr ; CurBdPtr = Chan -> BdHead ; BdCount = 0 ; BdPartialCount = 0 ; BdSts = 0 ; BdCr = 0 ; if ( Chan -> BdSubmitCnt == 0 ) { * BdSetPtr = NULL ; return XST_SUCCESS ; } if ( BdLimit > Chan -> BdSubmitCnt ) { BdLimit = Chan -> BdSubmitCnt ; } while ( BdCount < BdLimit ) { XMCDMA_CACHE_INVALIDATE ( ( UINTPTR ) ( CurBdPtr ) ) ; if ( ! ( Chan -> IsRxChan ) ) { BdSts = XMcdma_BdRead ( CurBdPtr , XMCDMA_BD_SIDEBAND_STS_OFFSET ) ; BdCr = XMcdma_BdRead ( CurBdPtr , XMCDMA_BD_CTRL_OFFSET ) ; } else { BdSts = XMcdma_BdRead ( CurBdPtr , XMCDMA_BD_STS_OFFSET ) ; } if ( ! ( BdSts & XMCDMA_BD_STS_COMPLETE_MASK ) ) break ; BdCount ++ ; if ( ( ! ( Chan -> IsRxChan ) && ( BdCr & XMCDMA_BD_CTRL_EOF_MASK ) ) || ( Chan -> IsRxChan && ( BdSts & XMCDMA_BD_STS_RXEOF_MASK ) ) ) { BdPartialCount = 0 ; } else { BdPartialCount ++ ; } if ( CurBdPtr == Chan -> BdTail ) { break ; } CurBdPtr = ( XMcdma_Bd * ) ( XMcdma_BdChainNextBd ( Chan , CurBdPtr ) ) ; } BdCount -= BdPartialCount ; if ( BdCount ) { * BdSetPtr = Chan -> BdHead ; Chan -> BdSubmitCnt -= BdCount ; Chan -> BdCnt += BdCount ; Chan -> BdDoneCnt += BdCount ; XMCDMA_CHAN_SEEKAHEAD ( Chan , Chan -> BdHead , BdCount ) ; return BdCount ; } else { * BdSetPtr = ( XMcdma_Bd * ) NULL ; return 0 ; } }
Returns a set of BD(s) that have been processed by hardware.
Returns a set of BD ( s ) that have been processed by hardware .
/* Need to handle Tx case as well */