XilinxProcessorIPLib/drivers/axidma/src/xaxidma_bdring.c
int XAxiDma_BdRingCheck(XAxiDma_BdRing * RingPtr)
{
	u32 AddrV;
	u32 AddrP;
	int i;

	/* Is the list created */
	if (RingPtr->AllCnt == 0) {

		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: no BDs\r\n");

		return XST_DMA_SG_NO_LIST;
	}

	/* Can't check if channel is running */
	if (RingPtr->RunState == AXIDMA_CHANNEL_NOT_HALTED) {

		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: Bd ring is "
		"running, cannot check it\r\n");

		return XST_IS_STARTED;
	}

	/* RunState doesn't make sense */
	else if (RingPtr->RunState != AXIDMA_CHANNEL_HALTED) {

		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: unknown BD ring "
			"state %d ", RingPtr->RunState);

		return XST_DMA_SG_LIST_ERROR;
	}

	/* Verify internal pointers point to correct memory space */
	AddrV = (UINTPTR) RingPtr->FreeHead;
	if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {

		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: FreeHead wrong "
		"%x, should be in range of %x/%x\r\n",
		    (unsigned int)AddrV,
		    (unsigned int)RingPtr->FirstBdAddr,
			(unsigned int)RingPtr->LastBdAddr);

		return XST_DMA_SG_LIST_ERROR;
	}

	AddrV = (UINTPTR) RingPtr->PreHead;
	if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {

		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: PreHead wrong %x, "
			"should be in range of %x/%x\r\n",
		    (unsigned int)AddrV,
		    (unsigned int)RingPtr->FirstBdAddr,
			(unsigned int)RingPtr->LastBdAddr);

		return XST_DMA_SG_LIST_ERROR;
	}

	AddrV = (UINTPTR) RingPtr->HwHead;
	if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {

		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: HwHead wrong %x, "
			"should be in range of %x/%x\r\n",
		    (unsigned int)AddrV,
		    (unsigned int)RingPtr->FirstBdAddr,
			(unsigned int)RingPtr->LastBdAddr);

		return XST_DMA_SG_LIST_ERROR;
	}

	AddrV = (UINTPTR) RingPtr->HwTail;
	if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {

		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: HwTail wrong %x, "
			"should be in range of %x/%x\r\n",
		    (unsigned int)AddrV,
		    (unsigned int)RingPtr->FirstBdAddr,
			(unsigned int)RingPtr->LastBdAddr);

		return XST_DMA_SG_LIST_ERROR;
	}

	AddrV = (UINTPTR) RingPtr->PostHead;
	if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {

		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: PostHead wrong "
		"%x, should be in range of %x/%x\r\n",
		    (unsigned int)AddrV,
		    (unsigned int)RingPtr->FirstBdAddr,
			(unsigned int)RingPtr->LastBdAddr);

		return XST_DMA_SG_LIST_ERROR;
	}

	/* Verify internal counters add up */
	if ((RingPtr->HwCnt + RingPtr->PreCnt + RingPtr->FreeCnt +
	     RingPtr->PostCnt) != RingPtr->AllCnt) {

		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: internal counter "
			"error\r\n");

		return XST_DMA_SG_LIST_ERROR;
	}

	/* Verify BDs are linked correctly */
	AddrV = RingPtr->FirstBdAddr;
	AddrP = RingPtr->FirstBdPhysAddr + RingPtr->Separation;
	for (i = 1; i < RingPtr->AllCnt; i++) {
		XAXIDMA_CACHE_INVALIDATE(AddrV);
		/* Check next pointer for this BD. It should equal to the
		 * physical address of next BD
		 */
		if (XAxiDma_BdRead(AddrV, XAXIDMA_BD_NDESC_OFFSET) != AddrP) {

			xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: Next Bd "
			"ptr %x wrong, expect %x\r\n",
				(unsigned int)XAxiDma_BdRead(AddrV,
			        XAXIDMA_BD_NDESC_OFFSET),
				(unsigned int)AddrP);

			return XST_DMA_SG_LIST_ERROR;
		}

		/* Move on to next BD */
		AddrV += RingPtr->Separation;
		AddrP += RingPtr->Separation;
	}

	XAXIDMA_CACHE_INVALIDATE(AddrV);
	/* Last BD should point back to the beginning of ring */
	if (XAxiDma_BdRead(AddrV, XAXIDMA_BD_NDESC_OFFSET) !=
	    RingPtr->FirstBdPhysAddr) {

		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: last Bd Next BD "
		"ptr %x wrong, expect %x\r\n",
			(unsigned int)XAxiDma_BdRead(AddrV,
		          XAXIDMA_BD_NDESC_OFFSET),
			(unsigned int)RingPtr->FirstBdPhysAddr);

		return XST_DMA_SG_LIST_ERROR;
	}

	/* No problems found */
	return XST_SUCCESS;
}
/*****************************************************************************/
/**
 * Check the internal data structures of the BD ring for the provided channel.
 * The following checks are made:
 *
 *	- The BD ring is linked correctly in physical address space.
 *	- The internal pointers point to BDs in the ring.
 *	- The internal counters add up.
 *
 * The channel should be stopped (through XAxiDma_Pause() or XAxiDma_Reset())
 * prior to calling this function.
 *
 * @param	RingPtr is a pointer to the descriptor ring to be worked on.
 *
 * @return
 *		- XST_SUCCESS if no errors were found.
 *		- XST_DMA_SG_NO_LIST if the ring has not been created.
 *		- XST_IS_STARTED if the channel is not stopped.
 *		- XST_DMA_SG_LIST_ERROR if a problem is found with the internal
 *		data structures. If this value is returned, the channel should
 *		be reset,and the BD ring should be recreated through
 *		XAxiDma_BdRingCreate() to avoid data corruption or system
 *		instability.
 *
 * @note	This function can be used only when DMA is in SG mode
 *
 *****************************************************************************/
Check the internal data structures of the BD ring for the provided channel.
The following checks are made.

- The BD ring is linked correctly in physical address space.
- The internal pointers point to BDs in the ring.
- The internal counters add up.

The channel should be stopped (through XAxiDma_Pause() or XAxiDma_Reset())
prior to calling this function.

@param       RingPtr is a pointer to the descriptor ring to be worked on.

@return
- XST_SUCCESS if no errors were found.
- XST_DMA_SG_NO_LIST if the ring has not been created.
- XST_IS_STARTED if the channel is not stopped.
- XST_DMA_SG_LIST_ERROR if a problem is found with the internal
data structures. If this value is returned, the channel should
be reset,and the BD ring should be recreated through
XAxiDma_BdRingCreate() to avoid data corruption or system
instability.

@note        This function can be used only when DMA is in SG mode
Check the internal data structures of the BD ring for the provided channel . The following checks are made . - The BD ring is linked correctly in physical address space . - The internal pointers point to BDs in the ring . - The internal counters add up . The channel should be stopped ( through XAxiDma_Pause () or XAxiDma_Reset () ) prior to calling this function . @param RingPtr is a pointer to the descriptor ring to be worked on . @return - XST_SUCCESS if no errors were found . - XST_DMA_SG_NO_LIST if the ring has not been created . - XST_IS_STARTED if the channel is not stopped . - XST_DMA_SG_LIST_ERROR if a problem is found with the internal data structures . If this value is returned the channel should be reset and the BD ring should be recreated through XAxiDma_BdRingCreate () to avoid data corruption or system instability . @note This function can be used only when DMA is in SG mode
int XAxiDma_BdRingCheck(XAxiDma_BdRing * RingPtr)
{
	u32 AddrV;
	u32 AddrP;
	int i;
	if (RingPtr->AllCnt == 0) {
		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: no BDs\r\n");
		return XST_DMA_SG_NO_LIST;
	}
	if (RingPtr->RunState == AXIDMA_CHANNEL_NOT_HALTED) {
		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: Bd ring is "
		"running, cannot check it\r\n");
		return XST_IS_STARTED;
	}
	else if (RingPtr->RunState != AXIDMA_CHANNEL_HALTED) {
		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: unknown BD ring "
			"state %d ", RingPtr->RunState);
		return XST_DMA_SG_LIST_ERROR;
	}
	AddrV = (UINTPTR) RingPtr->FreeHead;
	if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {
		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: FreeHead wrong "
		"%x, should be in range of %x/%x\r\n",
		    (unsigned int)AddrV,
		    (unsigned int)RingPtr->FirstBdAddr,
			(unsigned int)RingPtr->LastBdAddr);
		return XST_DMA_SG_LIST_ERROR;
	}
	AddrV = (UINTPTR) RingPtr->PreHead;
	if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {
		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: PreHead wrong %x, "
			"should be in range of %x/%x\r\n",
		    (unsigned int)AddrV,
		    (unsigned int)RingPtr->FirstBdAddr,
			(unsigned int)RingPtr->LastBdAddr);
		return XST_DMA_SG_LIST_ERROR;
	}
	AddrV = (UINTPTR) RingPtr->HwHead;
	if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {
		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: HwHead wrong %x, "
			"should be in range of %x/%x\r\n",
		    (unsigned int)AddrV,
		    (unsigned int)RingPtr->FirstBdAddr,
			(unsigned int)RingPtr->LastBdAddr);
		return XST_DMA_SG_LIST_ERROR;
	}
	AddrV = (UINTPTR) RingPtr->HwTail;
	if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {
		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: HwTail wrong %x, "
			"should be in range of %x/%x\r\n",
		    (unsigned int)AddrV,
		    (unsigned int)RingPtr->FirstBdAddr,
			(unsigned int)RingPtr->LastBdAddr);
		return XST_DMA_SG_LIST_ERROR;
	}
	AddrV = (UINTPTR) RingPtr->PostHead;
	if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {
		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: PostHead wrong "
		"%x, should be in range of %x/%x\r\n",
		    (unsigned int)AddrV,
		    (unsigned int)RingPtr->FirstBdAddr,
			(unsigned int)RingPtr->LastBdAddr);
		return XST_DMA_SG_LIST_ERROR;
	}
	if ((RingPtr->HwCnt + RingPtr->PreCnt + RingPtr->FreeCnt +
	     RingPtr->PostCnt) != RingPtr->AllCnt) {
		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: internal counter "
			"error\r\n");
		return XST_DMA_SG_LIST_ERROR;
	}
	AddrV = RingPtr->FirstBdAddr;
	AddrP = RingPtr->FirstBdPhysAddr + RingPtr->Separation;
	for (i = 1; i < RingPtr->AllCnt; i++) {
		XAXIDMA_CACHE_INVALIDATE(AddrV);
		if (XAxiDma_BdRead(AddrV, XAXIDMA_BD_NDESC_OFFSET) != AddrP) {
			xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: Next Bd "
			"ptr %x wrong, expect %x\r\n",
				(unsigned int)XAxiDma_BdRead(AddrV,
			        XAXIDMA_BD_NDESC_OFFSET),
				(unsigned int)AddrP);
			return XST_DMA_SG_LIST_ERROR;
		}
		AddrV += RingPtr->Separation;
		AddrP += RingPtr->Separation;
	}
	XAXIDMA_CACHE_INVALIDATE(AddrV);
	if (XAxiDma_BdRead(AddrV, XAXIDMA_BD_NDESC_OFFSET) !=
	    RingPtr->FirstBdPhysAddr) {
		xdbg_printf(XDBG_DEBUG_ERROR, "BdRingCheck: last Bd Next BD "
		"ptr %x wrong, expect %x\r\n",
			(unsigned int)XAxiDma_BdRead(AddrV,
		          XAXIDMA_BD_NDESC_OFFSET),
			(unsigned int)RingPtr->FirstBdPhysAddr);
		return XST_DMA_SG_LIST_ERROR;
	}
	return XST_SUCCESS;
}
int XAxiDma_BdRingCheck ( XAxiDma_BdRing * RingPtr ) { u32 AddrV ; u32 AddrP ; int i ; if ( RingPtr -> AllCnt == 0 ) { xdbg_printf ( XDBG_DEBUG_ERROR , " \r \n " ) ; return XST_DMA_SG_NO_LIST ; } if ( RingPtr -> RunState == AXIDMA_CHANNEL_NOT_HALTED ) { xdbg_printf ( XDBG_DEBUG_ERROR , " " " \r \n " ) ; return XST_IS_STARTED ; } else if ( RingPtr -> RunState != AXIDMA_CHANNEL_HALTED ) { xdbg_printf ( XDBG_DEBUG_ERROR , " " " " , RingPtr -> RunState ) ; return XST_DMA_SG_LIST_ERROR ; } AddrV = ( UINTPTR ) RingPtr -> FreeHead ; if ( ( AddrV < RingPtr -> FirstBdAddr ) || ( AddrV > RingPtr -> LastBdAddr ) ) { xdbg_printf ( XDBG_DEBUG_ERROR , " " " \r \n " , ( unsigned int ) AddrV , ( unsigned int ) RingPtr -> FirstBdAddr , ( unsigned int ) RingPtr -> LastBdAddr ) ; return XST_DMA_SG_LIST_ERROR ; } AddrV = ( UINTPTR ) RingPtr -> PreHead ; if ( ( AddrV < RingPtr -> FirstBdAddr ) || ( AddrV > RingPtr -> LastBdAddr ) ) { xdbg_printf ( XDBG_DEBUG_ERROR , " " " \r \n " , ( unsigned int ) AddrV , ( unsigned int ) RingPtr -> FirstBdAddr , ( unsigned int ) RingPtr -> LastBdAddr ) ; return XST_DMA_SG_LIST_ERROR ; } AddrV = ( UINTPTR ) RingPtr -> HwHead ; if ( ( AddrV < RingPtr -> FirstBdAddr ) || ( AddrV > RingPtr -> LastBdAddr ) ) { xdbg_printf ( XDBG_DEBUG_ERROR , " " " \r \n " , ( unsigned int ) AddrV , ( unsigned int ) RingPtr -> FirstBdAddr , ( unsigned int ) RingPtr -> LastBdAddr ) ; return XST_DMA_SG_LIST_ERROR ; } AddrV = ( UINTPTR ) RingPtr -> HwTail ; if ( ( AddrV < RingPtr -> FirstBdAddr ) || ( AddrV > RingPtr -> LastBdAddr ) ) { xdbg_printf ( XDBG_DEBUG_ERROR , " " " \r \n " , ( unsigned int ) AddrV , ( unsigned int ) RingPtr -> FirstBdAddr , ( unsigned int ) RingPtr -> LastBdAddr ) ; return XST_DMA_SG_LIST_ERROR ; } AddrV = ( UINTPTR ) RingPtr -> PostHead ; if ( ( AddrV < RingPtr -> FirstBdAddr ) || ( AddrV > RingPtr -> LastBdAddr ) ) { xdbg_printf ( XDBG_DEBUG_ERROR , " " " \r \n " , ( unsigned int ) AddrV , ( unsigned int ) RingPtr -> FirstBdAddr , ( unsigned int ) RingPtr -> LastBdAddr ) ; return XST_DMA_SG_LIST_ERROR ; } if ( ( RingPtr -> HwCnt + RingPtr -> PreCnt + RingPtr -> FreeCnt + RingPtr -> PostCnt ) != RingPtr -> AllCnt ) { xdbg_printf ( XDBG_DEBUG_ERROR , " " " \r \n " ) ; return XST_DMA_SG_LIST_ERROR ; } AddrV = RingPtr -> FirstBdAddr ; AddrP = RingPtr -> FirstBdPhysAddr + RingPtr -> Separation ; for ( i = 1 ; i < RingPtr -> AllCnt ; i ++ ) { XAXIDMA_CACHE_INVALIDATE ( AddrV ) ; if ( XAxiDma_BdRead ( AddrV , XAXIDMA_BD_NDESC_OFFSET ) != AddrP ) { xdbg_printf ( XDBG_DEBUG_ERROR , " " " \r \n " , ( unsigned int ) XAxiDma_BdRead ( AddrV , XAXIDMA_BD_NDESC_OFFSET ) , ( unsigned int ) AddrP ) ; return XST_DMA_SG_LIST_ERROR ; } AddrV += RingPtr -> Separation ; AddrP += RingPtr -> Separation ; } XAXIDMA_CACHE_INVALIDATE ( AddrV ) ; if ( XAxiDma_BdRead ( AddrV , XAXIDMA_BD_NDESC_OFFSET ) != RingPtr -> FirstBdPhysAddr ) { xdbg_printf ( XDBG_DEBUG_ERROR , " " " \r \n " , ( unsigned int ) XAxiDma_BdRead ( AddrV , XAXIDMA_BD_NDESC_OFFSET ) , ( unsigned int ) RingPtr -> FirstBdPhysAddr ) ; return XST_DMA_SG_LIST_ERROR ; } return XST_SUCCESS ; }
Check the internal data structures of the BD ring for the provided channel.
Check the internal data structures of the BD ring for the provided channel .
/* Is the list created */ /* Can't check if channel is running */ /* RunState doesn't make sense */ /* Verify internal pointers point to correct memory space */ /* Verify internal counters add up */ /* Verify BDs are linked correctly */ /* Check next pointer for this BD. It should equal to the
		 * physical address of next BD
		 */ /* Move on to next BD */ /* Last BD should point back to the beginning of ring */ /* No problems found */