Re: [PATCH] WIP: at_xdmac: fix residue computation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Feb 18, 2016 at 02:10:56PM +0100, David Engraf wrote:
> Hi Ludovic,
> 
> Am 18.02.2016 um 11:48 schrieb Ludovic Desroches:
> >---
> >  drivers/dma/at_xdmac.c | 25 ++++++++++++++++++++++---
> >  1 file changed, 22 insertions(+), 3 deletions(-)
> >
> >Hi David,
> >
> >I tried to adpat the fix Cyrille did for at_hdmac. I think it was exactly the
> >same issue. We have to read two registers, one to know the descriptor currently
> >used and one to know the residue for this descriptor. Unfortunately, between
> >the two reads, the descriptor currently used can change.
> >
> >Could you try this draft patch?
> 
> It works as well with your patch. I did several runs without loosing any
> bytes or a wrong residue. I've also checked how often the loop needs to
> retry when check_nda and cur_nda is different and in all cases one more read
> was enough. So trying up to 5 times is a good value.

Good news, thanks for testing it. I will send a new version with
comments, commit message, etc.

> 
> Tested-by: David Engraf <david.engraf@xxxxxxxxx>
> 
> Best regards
> - David
> 
> 
> >Regards
> >
> >Ludovic
> >
> >diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
> >index 6b512a2..a38356e 100644
> >--- a/drivers/dma/at_xdmac.c
> >+++ b/drivers/dma/at_xdmac.c
> >@@ -1395,8 +1395,8 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
> >  	struct at_xdmac_desc	*desc, *_desc;
> >  	struct list_head	*descs_list;
> >  	enum dma_status		ret;
> >-	int			residue;
> >-	u32			cur_nda, mask, value;
> >+	int			residue, i;
> >+	u32			cur_nda, check_nda, cur_ubc, mask, value;
> >  	u8			dwidth = 0;
> >  	unsigned long		flags;
> >
> >@@ -1434,6 +1434,25 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
> >  	}
> >
> >  	cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
> >+	rmb();
> >+	cur_ubc = at_xdmac_chan_read(atchan, AT_XDMAC_CUBC);
> >+	for (i = 0; i < 5; i++) {
> >+		rmb();
> >+		check_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
> >+
> >+		if (likely (cur_nda == check_nda))
> >+			break;
> >+
> >+		cur_nda = check_nda;
> >+		rmb();
> >+		cur_ubc = at_xdmac_chan_read(atchan, AT_XDMAC_CUBC);
> >+	}
> >+
> >+	if (unlikely(i >= 5)) {
> >+		ret = DMA_ERROR;
> >+		goto spin_unlock;
> >+	}
> >+
> >  	/*
> >  	 * Remove size of all microblocks already transferred and the current
> >  	 * one. Then add the remaining size to transfer of the current
> >@@ -1446,7 +1465,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
> >  		if ((desc->lld.mbr_nda & 0xfffffffc) == cur_nda)
> >  			break;
> >  	}
> >-	residue += at_xdmac_chan_read(atchan, AT_XDMAC_CUBC) << dwidth;
> >+	residue += cur_ubc << dwidth;
> >
> >  	dma_set_residue(txstate, residue);
> >
> >
> 
> --
> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux PCI]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux