/* * Check for transfer completion. * * If the DMA engine has errors or any of the finished BDs has error bit set, * then the example should fail. * * @param InstancePtr is pointer to the XAxiCdma instance. * * @return Number of Bds that have been completed by hardware. * * @note None * ******************************************************************************/ static int CheckCompletion(XAxiCdma *InstancePtr) { int BdCount; XAxiCdma_Bd *BdPtr; XAxiCdma_Bd *BdCurPtr; int Status; int Index; /* Check whether the hardware has encountered any problems. * In some error cases, the DMA engine may not able to update the * BD that has caused the problem. */ if (XAxiCdma_GetError(InstancePtr) != 0x0) { xdbg_printf(XDBG_DEBUG_ERROR, "Transfer error %x\r\n", (unsigned int)XAxiCdma_GetError(InstancePtr)); Error = 1; return 0; } /* Get all processed BDs from hardware */ BdCount = XAxiCdma_BdRingFromHw(InstancePtr, XAXICDMA_ALL_BDS, &BdPtr); /* Check finished BDs then release them */ if(BdCount > 0) { BdCurPtr = BdPtr; for (Index = 0; Index < BdCount; Index++) { /* If the completed BD has error bit set, * then the example fails */ if (XAxiCdma_BdGetSts(BdCurPtr) & XAXICDMA_BD_STS_ALL_ERR_MASK) { Error = 1; return 0; } BdCurPtr = XAxiCdma_BdRingNext(InstancePtr, BdCurPtr); } /* Release the BDs so later submission can use them */ Status = XAxiCdma_BdRingFree(InstancePtr, BdCount, BdPtr); if(Status != XST_SUCCESS) { xdbg_printf(XDBG_DEBUG_ERROR, "Error free BD %x\r\n", Status); Error = 1; return 0; } Done += BdCount; } return Done; }
/* * Callback function for the scatter gather transfer. * It is called by the driver's interrupt handler. * * @param CallBackRef is the reference pointer registered through * transfer submission. In this case, it is the pointer to the * driver instance * @param IrqMask is the interrupt mask the driver interrupt handler * passes to the callback function. * @param NumBdPtr is the pointer to number of BDs this handler handles * * @return None * * @note None. * ******************************************************************************/ static void Example_SgCallBack(void *CallBackRef, u32 IrqMask, int *NumBdPtr) { XAxiCdma *InstancePtr; int BdCount; XAxiCdma_Bd *BdPtr; int Status; int Tmp; InstancePtr = (XAxiCdma *)CallBackRef; Tmp = *NumBdPtr; /* If error interrupt happened, the driver interrupt handler * has already reset the hardware */ if (IrqMask & XAXICDMA_XR_IRQ_ERROR_MASK) { Error = 1; } if (IrqMask & XAXICDMA_XR_IRQ_IOC_MASK) { /* Get all processed BDs from hardware */ BdCount = XAxiCdma_BdRingFromHw(InstancePtr, Tmp, &BdPtr); /* Release finished BDs * * It is ok if BdCount is zero as a previous callback may * have ripen all finished BDs */ if(BdCount > 0) { Status = XAxiCdma_BdRingFree(InstancePtr, BdCount, BdPtr); if(Status != XST_SUCCESS) { xdbg_printf(XDBG_DEBUG_ERROR, "Error free BD %x\r\n", Status); Error = 1; return; } Done += BdCount; *NumBdPtr = Tmp - BdCount; } } return; }