Re: [PATCH v3 01/11] dmaengine: Add API function dmaengine_prep_slave_dma_array()

From: Christian König
Date: Tue Apr 04 2023 - 04:54:37 EST


Am 04.04.23 um 09:42 schrieb Paul Cercueil:
Hi Hillf,

Le mardi 04 avril 2023 à 09:59 +0800, Hillf Danton a écrit :
On 3 Apr 2023 17:47:50 +0200 Paul Cercueil <paul@xxxxxxxxxxxxxxx>
This function can be used to initiate a scatter-gather DMA transfer
where the DMA addresses and lengths are located inside arrays.

The major difference with dmaengine_prep_slave_sg() is that it
supports
specifying the lengths of each DMA transfer; as trying to override
the
length of the transfer with dmaengine_prep_slave_sg() is a very
tedious
process. The introduction of a new API function is also justified
by the
fact that scatterlists are on their way out.
Given sg's wayout and conceptually iovec and kvec (in
include/linux/uio.h),
what you add should have been dma_vec to ease people making use of
it.

        struct dma_vec {
                dma_addr_t      addr;
                size_t          len;
        };
Well it's not too late ;)

Yeah adding that is pretty much the job I have on my TODO list for quite some time.

I wouldn't mind if you start adding that and provide helper functions in DMA-buf to convert from/to an sg_table.

This way we can migrate the interface over to a new design over time.

Regards,
Christian.


Thanks for the feedback.

Cheers,
-Paul

Signed-off-by: Paul Cercueil <paul@xxxxxxxxxxxxxxx>

---
v3: New patch
---
 include/linux/dmaengine.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index c3656e590213..62efa28c009a 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -912,6 +912,11 @@ struct dma_device {
        struct dma_async_tx_descriptor
*(*device_prep_dma_interrupt)(
                struct dma_chan *chan, unsigned long flags);
+       struct dma_async_tx_descriptor
*(*device_prep_slave_dma_array)(
+               struct dma_chan *chan, dma_addr_t *addrs,
+               size_t *lengths, size_t nb,
+               enum dma_transfer_direction direction,
+               unsigned long flags);
Then the callback looks like

        struct dma_async_tx_descriptor *(*device_prep_slave_vec)(
                struct dma_chan *chan,
                struct dma_vec *vec,
                int nvec,
                enum dma_transfer_direction direction,
                unsigned long flags);