Message ID | 20220324014836.19149-8-Sergey.Semin@baikalelectronics.ru (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | dmaengine: dw-edma: Add RP/EP local DMA controllers support | expand |
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 > >
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); - } } }
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. 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(-)