dmaengine: Add API documentation for slave dma usage
diff mbox

Message ID 1306238657-30089-1-git-send-email-vinod.koul@intel.com
State New, archived
Headers show

Commit Message

Vinod Koul May 24, 2011, 12:04 p.m. UTC
From: Vinod Koul <vinod.koul@intel.com>

Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 Documentation/dma-slave-api.txt |   74 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 74 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/dma-slave-api.txt

Comments

Per Forlin May 24, 2011, 3:40 p.m. UTC | #1
Hi Vinod,

On Tue, May 24, 2011 at 2:04 PM, Koul, Vinod <vinod.koul@intel.com> wrote:
> From: Vinod Koul <vinod.koul@intel.com>
>
> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> ---
>  Documentation/dma-slave-api.txt |   74 +++++++++++++++++++++++++++++++++++++++
>  1 files changed, 74 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/dma-slave-api.txt
I suggest putting this in subsection of dmaengine.txt instead.
dmaengine.txt would be the natural place to look at.

>
> diff --git a/Documentation/dma-slave-api.txt b/Documentation/dma-slave-api.txt
> new file mode 100644
> index 0000000..7498807
> --- /dev/null
> +++ b/Documentation/dma-slave-api.txt
> @@ -0,0 +1,74 @@
> +                    Slave DMA API Guide
> +                    ===================
> +
> +                Vinod Koul <vinod dot koul at intel.com>
> +
> +This is a guide to device driver writers on how to use the Slave-DMA API of the
> +DMA Engine. This is applicable only for slave DMA usage and not async tx. For
> +the async tx usage of DMA Engine please see
> +Documentation/crypto/async-tx-api.txt
> +
> +The slave DMA usage consists of following steps
> +1. Allocate a DMA slave channel
> +2. Set slave and controller specific parameters
> +3. Get a descriptor for transaction
> +4. Submit the transaction and wait for callback notification
> +
> +1. Allocate a DMA slave channel
> +Channel allocation is slightly different in the slave DMA context, client
> +drivers typically need a channel from a particular DMA controller only and even
> +in some cases a specific channel is desired. To request a channel
> +__dma_request_channel() API is used.
> +
> +Interface:
> +struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
> +               dma_filter_fn filter_fn,
> +               void *filter_param);
> +where dma_filter_fn is defined as:
> +typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param);
> +
> +When the optional 'filter_fn' parameter is set to NULL dma_request_channel
> +simply returns the first channel that satisfies the capability mask.  Otherwise,
> +when the mask parameter is insufficient for specifying the necessary channel,
> +the filter_fn routine can be used to disposition the available channels in the
> +system. The filter_fn routine is called once for each free channel in the
> +system.  Upon seeing a suitable channel filter_fn returns DMA_ACK which flags
> +that channel to be the return value from dma_request_channel.  A channel
> +allocated via this interface is exclusive to the caller, until
> +dma_release_channel() is called.
> +
> +2. Set slave and controller specific parameters
> +Next step is always to pass some specific information to the DMA driver. Most of
> +the generic information which a slave DMA can use is in struct dma_slave_config.
> +It allows the clients to specify DMA direction, DMA addresses, bus widths, DMA
> +burst lengths etc. If some DMA controllers have more parameters to be sent then
> +they should try to embed struct dma_slave_config in their controller specific
> +structure. That gives flexibility to client to pass more parameters, if
> +required.
> +
> +Interface:
> +struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_sg)(
> +               struct dma_chan *chan,
> +               struct scatterlist *dst_sg, unsigned int dst_nents,
> +               struct scatterlist *src_sg, unsigned int src_nents,
> +               unsigned long flags);
> +struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_cyclic)(
> +               struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
> +               size_t period_len, enum dma_data_direction direction);
> +
> +4. Submit the transaction(s) and wait for callback notification when slave API
> +is 3 above returns, the non NULL value would imply a "descriptor" for the
> +transaction. These transaction(s) would need to be submitted which pushes them
> +into queue in DMA driver. If DMA is idle then the first descriptor submit will
> +be pushed to DMA and subsequent ones will be queued. On completion of the DMA
> +operation the next in queue is submitted and a tasklet triggered. The tasklet
> +would then call the client driver completion callback routine for notification,
> +if set.
> +
Does submit really start the transfer as well? My interpretation of
submit is that is only adds desc to a pending queue. When calling
issue_pending all these descs will be schedule for DMA transfer. Calls
to submit after this point will added to the pending queue again and
not be issued until calling issue_pending once more.

Thanks for your initiative to document the slave parts of dmaegine.
Per
Vinod Koul May 24, 2011, 4:06 p.m. UTC | #2
On Tue, 2011-05-24 at 17:40 +0200, Per Forlin wrote:
> Hi Vinod,
> 
> On Tue, May 24, 2011 at 2:04 PM, Koul, Vinod <vinod.koul@intel.com> wrote:
> > From: Vinod Koul <vinod.koul@intel.com>
> >
> > Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> > ---
> >  Documentation/dma-slave-api.txt |   74 +++++++++++++++++++++++++++++++++++++++
> >  1 files changed, 74 insertions(+), 0 deletions(-)
> >  create mode 100644 Documentation/dma-slave-api.txt
> I suggest putting this in subsection of dmaengine.txt instead.
> dmaengine.txt would be the natural place to look at.
Agreed, that would make it easier for people to find

> > +4. Submit the transaction(s) and wait for callback notification when slave API
> > +is 3 above returns, the non NULL value would imply a "descriptor" for the
> > +transaction. These transaction(s) would need to be submitted which pushes them
> > +into queue in DMA driver. If DMA is idle then the first descriptor submit will
> > +be pushed to DMA and subsequent ones will be queued. On completion of the DMA
> > +operation the next in queue is submitted and a tasklet triggered. The tasklet
> > +would then call the client driver completion callback routine for notification,
> > +if set.
> > +
> Does submit really start the transfer as well? My interpretation of
> submit is that is only adds desc to a pending queue. When calling
> issue_pending all these descs will be schedule for DMA transfer. Calls
> to submit after this point will added to the pending queue again and
> not be issued until calling issue_pending once more.
For slave dma devices, submit() is used to start the transaction if the
channel is idle. If its already doing a transaction then it will queue
it up and submit once cureent excuting one is completed. It is not
required to call issue_pending once more.
I am not sure if this is true for non slave usage, Dan would that be
correct for you as well?
Russell King - ARM Linux May 24, 2011, 5:48 p.m. UTC | #3
On Tue, May 24, 2011 at 05:34:17PM +0530, Koul, Vinod wrote:
> +1. Allocate a DMA slave channel
> +Channel allocation is slightly different in the slave DMA context, client
> +drivers typically need a channel from a particular DMA controller only and even
> +in some cases a specific channel is desired. To request a channel
> +__dma_request_channel() API is used.

Shouldn't this be "dma_request_channel" ?

> +
> +Interface:
> +struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
> +		dma_filter_fn filter_fn,
> +		void *filter_param);
> +where dma_filter_fn is defined as:
> +typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param);

This should have some description as to what contexts it can be called.

> +
> +When the optional 'filter_fn' parameter is set to NULL dma_request_channel
> +simply returns the first channel that satisfies the capability mask.  Otherwise,
> +when the mask parameter is insufficient for specifying the necessary channel,
> +the filter_fn routine can be used to disposition the available channels in the
> +system. The filter_fn routine is called once for each free channel in the
> +system.  Upon seeing a suitable channel filter_fn returns DMA_ACK which flags
> +that channel to be the return value from dma_request_channel.  A channel
> +allocated via this interface is exclusive to the caller, until
> +dma_release_channel() is called.
> +
> +2. Set slave and controller specific parameters
> +Next step is always to pass some specific information to the DMA driver. Most of
> +the generic information which a slave DMA can use is in struct dma_slave_config.
> +It allows the clients to specify DMA direction, DMA addresses, bus widths, DMA
> +burst lengths etc. If some DMA controllers have more parameters to be sent then
> +they should try to embed struct dma_slave_config in their controller specific
> +structure. That gives flexibility to client to pass more parameters, if
> +required.
> +

This doesn't give the interface for this.

Presumably there's section 3 missing here too for this interface:

> +Interface:
> +struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_sg)(
> +		struct dma_chan *chan,
> +		struct scatterlist *dst_sg, unsigned int dst_nents,
> +		struct scatterlist *src_sg, unsigned int src_nents,
> +		unsigned long flags);
> +struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_cyclic)(
> +		struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
> +		size_t period_len, enum dma_data_direction direction);

This should have some description as to what contexts it can be called.

> +
> +4. Submit the transaction(s) and wait for callback notification when slave API
> +is 3 above returns, the non NULL value would imply a "descriptor" for the

"when the slave API is 3 above returns" doesn't make sense - could you
re-phrase?

> +transaction. These transaction(s) would need to be submitted which pushes them
> +into queue in DMA driver. If DMA is idle then the first descriptor submit will
> +be pushed to DMA and subsequent ones will be queued. On completion of the DMA
> +operation the next in queue is submitted and a tasklet triggered. The tasklet
> +would then call the client driver completion callback routine for notification,
> +if set.
> +
> +Additional usage notes
> +1/ Although DMA engine specifies that completion callback routines cannot submit
> +any new operations, but typically for slave DMA subsequent transaction may not
> +be available for submit prior to callback routine being called. This requirement
> +|is not a requirement for DMA-slave devices. But they should take care to drop

spurious | character.

> +the spin-lock they might be holding before calling the callback routine

Is this document aimed at driver writers using the DMA engine slave API,
or DMA engine writers implemting the DMA engine slave API?  Most of the
document appears to be aimed at the users of the API except for this
last paragraph, and so could be confusing to users reading this document.
Dan Williams May 24, 2011, 9:03 p.m. UTC | #4
On Tue, May 24, 2011 at 9:06 AM, Koul, Vinod <vinod.koul@intel.com> wrote:
> On Tue, 2011-05-24 at 17:40 +0200, Per Forlin wrote:
>> Hi Vinod,
>>
>> On Tue, May 24, 2011 at 2:04 PM, Koul, Vinod <vinod.koul@intel.com> wrote:
>> > From: Vinod Koul <vinod.koul@intel.com>
>> >
>> > Signed-off-by: Vinod Koul <vinod.koul@intel.com>
>> > ---
>> >  Documentation/dma-slave-api.txt |   74 +++++++++++++++++++++++++++++++++++++++
>> >  1 files changed, 74 insertions(+), 0 deletions(-)
>> >  create mode 100644 Documentation/dma-slave-api.txt
>> I suggest putting this in subsection of dmaengine.txt instead.
>> dmaengine.txt would be the natural place to look at.
> Agreed, that would make it easier for people to find
>
>> > +4. Submit the transaction(s) and wait for callback notification when slave API
>> > +is 3 above returns, the non NULL value would imply a "descriptor" for the
>> > +transaction. These transaction(s) would need to be submitted which pushes them
>> > +into queue in DMA driver. If DMA is idle then the first descriptor submit will
>> > +be pushed to DMA and subsequent ones will be queued. On completion of the DMA
>> > +operation the next in queue is submitted and a tasklet triggered. The tasklet
>> > +would then call the client driver completion callback routine for notification,
>> > +if set.
>> > +
>> Does submit really start the transfer as well? My interpretation of
>> submit is that is only adds desc to a pending queue. When calling
>> issue_pending all these descs will be schedule for DMA transfer. Calls
>> to submit after this point will added to the pending queue again and
>> not be issued until calling issue_pending once more.
> For slave dma devices, submit() is used to start the transaction if the
> channel is idle. If its already doing a transaction then it will queue
> it up and submit once cureent excuting one is completed. It is not
> required to call issue_pending once more.
> I am not sure if this is true for non slave usage, Dan would that be
> correct for you as well?

No, ->submit() is just an "add this descriptor to the chain"
operation, and ->issue_pending() is always required to make sure the
everything submitted previously is actively executing.  This was a
holdover from the very first dmaengine implementation where, for
efficiency reasons, it could save mmio writes by batching the issuing
of requests.

--
Dan
Per Forlin May 25, 2011, 7:47 a.m. UTC | #5
On 24 May 2011 23:03, Dan Williams <dan.j.williams@intel.com> wrote:
> On Tue, May 24, 2011 at 9:06 AM, Koul, Vinod <vinod.koul@intel.com> wrote:
>> On Tue, 2011-05-24 at 17:40 +0200, Per Forlin wrote:
>>> Hi Vinod,
>>>
>>> On Tue, May 24, 2011 at 2:04 PM, Koul, Vinod <vinod.koul@intel.com> wrote:
>>> > From: Vinod Koul <vinod.koul@intel.com>
>>> >
>>> > Signed-off-by: Vinod Koul <vinod.koul@intel.com>
>>> > ---
>>> >  Documentation/dma-slave-api.txt |   74 +++++++++++++++++++++++++++++++++++++++
>>> >  1 files changed, 74 insertions(+), 0 deletions(-)
>>> >  create mode 100644 Documentation/dma-slave-api.txt
>>> I suggest putting this in subsection of dmaengine.txt instead.
>>> dmaengine.txt would be the natural place to look at.
>> Agreed, that would make it easier for people to find
>>
>>> > +4. Submit the transaction(s) and wait for callback notification when slave API
>>> > +is 3 above returns, the non NULL value would imply a "descriptor" for the
>>> > +transaction. These transaction(s) would need to be submitted which pushes them
>>> > +into queue in DMA driver. If DMA is idle then the first descriptor submit will
>>> > +be pushed to DMA and subsequent ones will be queued. On completion of the DMA
>>> > +operation the next in queue is submitted and a tasklet triggered. The tasklet
>>> > +would then call the client driver completion callback routine for notification,
>>> > +if set.
>>> > +
>>> Does submit really start the transfer as well? My interpretation of
>>> submit is that is only adds desc to a pending queue. When calling
>>> issue_pending all these descs will be schedule for DMA transfer. Calls
>>> to submit after this point will added to the pending queue again and
>>> not be issued until calling issue_pending once more.
>> For slave dma devices, submit() is used to start the transaction if the
>> channel is idle. If its already doing a transaction then it will queue
>> it up and submit once cureent excuting one is completed. It is not
>> required to call issue_pending once more.
>> I am not sure if this is true for non slave usage, Dan would that be
>> correct for you as well?
>
> No, ->submit() is just an "add this descriptor to the chain"
> operation, and ->issue_pending() is always required to make sure the
> everything submitted previously is actively executing.  This was a
> holdover from the very first dmaengine implementation where, for
> efficiency reasons, it could save mmio writes by batching the issuing
> of requests.
Thanks Dan for clarifying.
Vinod, I propose that the submit and issue_pending works the same for
SLAVE and none SLAVE channels. The API should have the same definition
independent of DMA_CAP. Please enlighten me if there are things I have
foreseen on this matter.

Thanks,
Per
Vinod Koul May 25, 2011, 8:26 a.m. UTC | #6
On Wed, 2011-05-25 at 09:47 +0200, Per Forlin wrote:
> On 24 May 2011 23:03, Dan Williams <dan.j.williams@intel.com> wrote:

> >>> Does submit really start the transfer as well? My interpretation of
> >>> submit is that is only adds desc to a pending queue. When calling
> >>> issue_pending all these descs will be schedule for DMA transfer. Calls
> >>> to submit after this point will added to the pending queue again and
> >>> not be issued until calling issue_pending once more.
> >> For slave dma devices, submit() is used to start the transaction if the
> >> channel is idle. If its already doing a transaction then it will queue
> >> it up and submit once cureent excuting one is completed. It is not
> >> required to call issue_pending once more.
> >> I am not sure if this is true for non slave usage, Dan would that be
> >> correct for you as well?
> >
> > No, ->submit() is just an "add this descriptor to the chain"
> > operation, and ->issue_pending() is always required to make sure the
> > everything submitted previously is actively executing.  This was a
> > holdover from the very first dmaengine implementation where, for
> > efficiency reasons, it could save mmio writes by batching the issuing
> > of requests.
> Thanks Dan for clarifying.
> Vinod, I propose that the submit and issue_pending works the same for
> SLAVE and none SLAVE channels. The API should have the same definition
> independent of DMA_CAP. Please enlighten me if there are things I have
> foreseen on this matter.
I am okay with making this same for the slave devices as well.

That would also require to change few drivers which start the txn in
submit()
Vinod Koul May 25, 2011, 8:34 a.m. UTC | #7
On Tue, 2011-05-24 at 18:48 +0100, Russell King - ARM Linux wrote:
> On Tue, May 24, 2011 at 05:34:17PM +0530, Koul, Vinod wrote:
> 
> Is this document aimed at driver writers using the DMA engine slave API,
> or DMA engine writers implemting the DMA engine slave API?  Most of the
> document appears to be aimed at the users of the API except for this
> last paragraph, and so could be confusing to users reading this document.
Thanks for the comments :)

Its aimed at users, but then thought to add the last one as its often
asked and causes confusion, will explicitly state this...
Vinod Koul May 25, 2011, 9:34 a.m. UTC | #8
On Wed, 2011-05-25 at 11:47 +0200, Per Forlin wrote:
> On 25 May 2011 10:26, Koul, Vinod <vinod.koul@intel.com> wrote:
> > I am okay with making this same for the slave devices as well.
> >
> > That would also require to change few drivers which start the txn in
> > submit()
> Yes,
> The trivial part is to move enable from submit to issue_pending. I had
> a quick look and it looks like the following drivers need to be
> changed.
> mpc512x_dma.c
> imx-dma.c
> imx-sdma.c
> mxs-dma.c
> 
> The other part is more complex. To make submit only add descs to a
> queue that will be pushed down to the DMA only after issue_pending. It
> is not as trivial to identify which of the drivers support this or
> not.
> I still think it make sense to fix the documentation first and then
> fix the drivers. Keep a list inside the dmaengine.txt of drivers that
> need to be fixed in order to comply with the API. Over time drivers
> will be fixed and removed from the list. When we have agreed upon the
> API (we may not be there yet) I am willingly to make a draft of such a
> list.
Yes this sounds right, I will send updated version and now drivers would
need to call issue_pending.

I know dw_dmac, intel_mid_dma and ste_dma40 would need changes as well.

Was thinking to add TODO in drivers/dma with these and any other changes
we feel are required moving forward.
We need dw_dmac to be moved to new slave interface and remove old slave
pointer mechanism when all are moved.
Per Forlin May 25, 2011, 9:47 a.m. UTC | #9
On 25 May 2011 10:26, Koul, Vinod <vinod.koul@intel.com> wrote:
> On Wed, 2011-05-25 at 09:47 +0200, Per Forlin wrote:
>> On 24 May 2011 23:03, Dan Williams <dan.j.williams@intel.com> wrote:
>
>> >>> Does submit really start the transfer as well? My interpretation of
>> >>> submit is that is only adds desc to a pending queue. When calling
>> >>> issue_pending all these descs will be schedule for DMA transfer. Calls
>> >>> to submit after this point will added to the pending queue again and
>> >>> not be issued until calling issue_pending once more.
>> >> For slave dma devices, submit() is used to start the transaction if the
>> >> channel is idle. If its already doing a transaction then it will queue
>> >> it up and submit once cureent excuting one is completed. It is not
>> >> required to call issue_pending once more.
>> >> I am not sure if this is true for non slave usage, Dan would that be
>> >> correct for you as well?
>> >
>> > No, ->submit() is just an "add this descriptor to the chain"
>> > operation, and ->issue_pending() is always required to make sure the
>> > everything submitted previously is actively executing.  This was a
>> > holdover from the very first dmaengine implementation where, for
>> > efficiency reasons, it could save mmio writes by batching the issuing
>> > of requests.
>> Thanks Dan for clarifying.
>> Vinod, I propose that the submit and issue_pending works the same for
>> SLAVE and none SLAVE channels. The API should have the same definition
>> independent of DMA_CAP. Please enlighten me if there are things I have
>> foreseen on this matter.
> I am okay with making this same for the slave devices as well.
>
> That would also require to change few drivers which start the txn in
> submit()
Yes,
The trivial part is to move enable from submit to issue_pending. I had
a quick look and it looks like the following drivers need to be
changed.
mpc512x_dma.c
imx-dma.c
imx-sdma.c
mxs-dma.c

The other part is more complex. To make submit only add descs to a
queue that will be pushed down to the DMA only after issue_pending. It
is not as trivial to identify which of the drivers support this or
not.
I still think it make sense to fix the documentation first and then
fix the drivers. Keep a list inside the dmaengine.txt of drivers that
need to be fixed in order to comply with the API. Over time drivers
will be fixed and removed from the list. When we have agreed upon the
API (we may not be there yet) I am willingly to make a draft of such a
list.

/Per
Per Forlin May 25, 2011, 10:51 a.m. UTC | #10
On 25 May 2011 11:34, Koul, Vinod <vinod.koul@intel.com> wrote:
> On Wed, 2011-05-25 at 11:47 +0200, Per Forlin wrote:
>> On 25 May 2011 10:26, Koul, Vinod <vinod.koul@intel.com> wrote:
>> > I am okay with making this same for the slave devices as well.
>> >
>> > That would also require to change few drivers which start the txn in
>> > submit()
>> Yes,
>> The trivial part is to move enable from submit to issue_pending. I had
>> a quick look and it looks like the following drivers need to be
>> changed.
>> mpc512x_dma.c
>> imx-dma.c
>> imx-sdma.c
>> mxs-dma.c
>>
>> The other part is more complex. To make submit only add descs to a
>> queue that will be pushed down to the DMA only after issue_pending. It
>> is not as trivial to identify which of the drivers support this or
>> not.
>> I still think it make sense to fix the documentation first and then
>> fix the drivers. Keep a list inside the dmaengine.txt of drivers that
>> need to be fixed in order to comply with the API. Over time drivers
>> will be fixed and removed from the list. When we have agreed upon the
>> API (we may not be there yet) I am willingly to make a draft of such a
>> list.
> Yes this sounds right, I will send updated version and now drivers would
> need to call issue_pending.
>
> I know dw_dmac, intel_mid_dma and ste_dma40 would need changes as well.
>
I think ste_dma40 treats issue_pending and submit correctly but it may
be other things not aligned. I need to double check this since it was
a long time since I did any work in this driver. I can update
ste_dma40 where it need changes.

> Was thinking to add TODO in drivers/dma with these and any other changes
> we feel are required moving forward.
> We need dw_dmac to be moved to new slave interface and remove old slave
> pointer mechanism when all are moved.
>
I agree, TODO is a better place for it.

I would like to ask a question on usage of DMA_CTRL_ACK while we're at it.
In ste_dma40 I added support to reuse descriptors if DMA_CTRL_ACK is
clear. The purpose of DMA_CTRL_ACK is to set up dependency but is it
also a valid to reuse it?
I mean submit the same descriptor again and again without having to
call prepare_slave_sg.
Example:
desc = prepare_slave_sg()
submit(desc)
issue_pending(desc)

wait_for_callback()

submit(desc)
issue_pending(desc)

/Per
Vinod Koul May 25, 2011, 10:55 a.m. UTC | #11
On Wed, 2011-05-25 at 16:21 +0530, Per Forlin wrote:
> On 25 May 2011 11:34, Koul, Vinod <vinod.koul@intel.com> wrote:

> I would like to ask a question on usage of DMA_CTRL_ACK while we're at it.
> In ste_dma40 I added support to reuse descriptors if DMA_CTRL_ACK is
> clear. The purpose of DMA_CTRL_ACK is to set up dependency but is it
> also a valid to reuse it?
> I mean submit the same descriptor again and again without having to
> call prepare_slave_sg.
> Example:
> desc = prepare_slave_sg()
> submit(desc)
> issue_pending(desc)
> 
> wait_for_callback()
> 
> submit(desc)
> issue_pending(desc)
> 
I think your question is answered in dmaengine.h. Quoting here:
* @DMA_CTRL_ACK - if clear, the descriptor cannot be reused until the 
* client acknowledges receipt, i.e. has has a chance to establish any
* dependency chains

The DMA driver recycles the descriptors which it returns for the
transfer APIs. The DMA_CTRL_ACK flag would tell driver explicitly not to
reuse this descriptor until the client clears this flag.
Since the descriptor is still valid after callback notification it can
be reused by client in the way you described.

Again, Dan can you please confirm if my interpretation is correct.

Patch
diff mbox

diff --git a/Documentation/dma-slave-api.txt b/Documentation/dma-slave-api.txt
new file mode 100644
index 0000000..7498807
--- /dev/null
+++ b/Documentation/dma-slave-api.txt
@@ -0,0 +1,74 @@ 
+		     Slave DMA API Guide
+		     ===================
+
+		 Vinod Koul <vinod dot koul at intel.com>
+
+This is a guide to device driver writers on how to use the Slave-DMA API of the
+DMA Engine. This is applicable only for slave DMA usage and not async tx. For
+the async tx usage of DMA Engine please see
+Documentation/crypto/async-tx-api.txt
+
+The slave DMA usage consists of following steps
+1. Allocate a DMA slave channel
+2. Set slave and controller specific parameters
+3. Get a descriptor for transaction
+4. Submit the transaction and wait for callback notification
+
+1. Allocate a DMA slave channel
+Channel allocation is slightly different in the slave DMA context, client
+drivers typically need a channel from a particular DMA controller only and even
+in some cases a specific channel is desired. To request a channel
+__dma_request_channel() API is used.
+
+Interface:
+struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
+		dma_filter_fn filter_fn,
+		void *filter_param);
+where dma_filter_fn is defined as:
+typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param);
+
+When the optional 'filter_fn' parameter is set to NULL dma_request_channel
+simply returns the first channel that satisfies the capability mask.  Otherwise,
+when the mask parameter is insufficient for specifying the necessary channel,
+the filter_fn routine can be used to disposition the available channels in the
+system. The filter_fn routine is called once for each free channel in the
+system.  Upon seeing a suitable channel filter_fn returns DMA_ACK which flags
+that channel to be the return value from dma_request_channel.  A channel
+allocated via this interface is exclusive to the caller, until
+dma_release_channel() is called.
+
+2. Set slave and controller specific parameters
+Next step is always to pass some specific information to the DMA driver. Most of
+the generic information which a slave DMA can use is in struct dma_slave_config.
+It allows the clients to specify DMA direction, DMA addresses, bus widths, DMA
+burst lengths etc. If some DMA controllers have more parameters to be sent then
+they should try to embed struct dma_slave_config in their controller specific
+structure. That gives flexibility to client to pass more parameters, if
+required.
+
+Interface:
+struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_sg)(
+		struct dma_chan *chan,
+		struct scatterlist *dst_sg, unsigned int dst_nents,
+		struct scatterlist *src_sg, unsigned int src_nents,
+		unsigned long flags);
+struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_cyclic)(
+		struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
+		size_t period_len, enum dma_data_direction direction);
+
+4. Submit the transaction(s) and wait for callback notification when slave API
+is 3 above returns, the non NULL value would imply a "descriptor" for the
+transaction. These transaction(s) would need to be submitted which pushes them
+into queue in DMA driver. If DMA is idle then the first descriptor submit will
+be pushed to DMA and subsequent ones will be queued. On completion of the DMA
+operation the next in queue is submitted and a tasklet triggered. The tasklet
+would then call the client driver completion callback routine for notification,
+if set.
+
+Additional usage notes
+1/ Although DMA engine specifies that completion callback routines cannot submit
+any new operations, but typically for slave DMA subsequent transaction may not
+be available for submit prior to callback routine being called. This requirement
+|is not a requirement for DMA-slave devices. But they should take care to drop
+the spin-lock they might be holding before calling the callback routine
+