Re: [PATCH 07/25] dmaengine: dw-edma: Don't permit non-inc interleaved xfers

Serge Semin
2022-04-17T23:00:25Z

On Thu, Mar 24, 2022 at 10:45:12PM +0530, Manivannan Sadhasivam wrote:
> On Thu, Mar 24, 2022 at 04:48:18AM +0300, Serge Semin wrote:
> > DW eDMA controller always increments both source and destination
> > addresses. Permitting DMA interleaved transfers with no src_inc/dst_inc
> > flags set may lead to unexpected behaviour for the device users. Let's fix
> > that by terminating the interleaved transfers if at least one of the
> > dma_interleaved_template.{src_inc,dst_inc} flag is initialized with false
> > value. Note in addition to that we need we need to increase the source and
> > destination addresses accordingly after each iteration.
> >
>

> Can you please point me where this gets documented in databook?

10.3.1 Source and Destination Address Registers (SAR, DAR)
"... You program the start of the local and remote data buffers using
these registers, and the DMA increments the SAR and DAR as the DMA
transfer progresses. ..."

[1] DesignWare Cores PCI Express Controller databook, v4.70a, March 2016,
p. 882.
[2] DesignWare Cores PCI Express Controller databook, v5.40a, March 2019,
p. 1110.

-Sergey

>
> Thanks,
> Mani
>
> > Fixes: 85e7518f42c8 ("dmaengine: dw-edma: Add device_prep_interleave_dma() support")
> > Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> > ---
> > drivers/dma/dw-edma/dw-edma-core.c | 12 ++++++------
> > 1 file changed, 6 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
> > index 2010d7f8191f..f41bde27795c 100644
> > --- a/drivers/dma/dw-edma/dw-edma-core.c
> > +++ b/drivers/dma/dw-edma/dw-edma-core.c
> > @@ -386,6 +386,8 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer)
> > return NULL;
> > if (xfer->xfer.il->numf > 0 && xfer->xfer.il->frame_size > 0)
> > return NULL;
> > + if (!xfer->xfer.il->src_inc || !xfer->xfer.il->dst_inc)
> > + return NULL;
> > } else {
> > return NULL;
> > }
> > @@ -485,15 +487,13 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer)
> > struct dma_interleaved_template *il = xfer->xfer.il;
> > struct data_chunk *dc = &il->sgl[i];
> >
> > - if (il->src_sgl) {
> > - src_addr += burst->sz;
> > + src_addr += burst->sz;
> > + if (il->src_sgl)
> > src_addr += dmaengine_get_src_icg(il, dc);
> > - }
> >
> > - if (il->dst_sgl) {
> > - dst_addr += burst->sz;
> > + dst_addr += burst->sz;
> > + if (il->dst_sgl)
> > dst_addr += dmaengine_get_dst_icg(il, dc);
> > - }
> > }
> > }
> >
> > --
> > 2.35.1
> >