What is a DMA transfer?
DMA is the hardware mechanism that allows peripheral components to transfer their I/O data directly to and from main memory without the need to involve the system processor. Use of this mechanism can greatly increase throughput to and from a device, because a great deal of computational overhead is eliminated from the main CPU.
...the use of dma_alloc_coherent()
is done as if it actually responsible for the transaction.
On the contrary, dma_alloc_coherent()
simply creates a buffer that is acceptable to the dma controller i.e. reserves a region in main memory (usually contiguous) that can be shared between the CPU and the DMA controller.
For example to perform a DMA-write, the CPU can populate this buffer and instruct the DMA controller to write it to the device and once it is done, invoke the callback function (to notify the SW running on the CPU).
In the meantime, the CPU can continue performing other unrelated tasks that do not depend on the data being transferred at the same time when the data transfer to the external device is being handled by the DMA controller in parallel.
Similarly, to perform a DMA-read, the CPU simply passes a buffer obtained by calling dma_allocate_coherent()
to the DMA controller and instructs it to perform a read. Subsequently the DMA controller reads the external device and starts filling the provided buffer and invokes the callback function once the buffer is filled (or half-filled or after a certain time interval as configured.)
Further Reading:
Chapter 15 of LDD3 - "mmap and DMA".
Article on DMA APIs in the Linux kernel.
In general this depends on the DMA controller.
i.e. the APIs the DMA controller driver provides.
dma-engine
is a standard framework in the Linux kernel used by several DMA providers.
Related: What is DMA mapping and DMA engine in context of linux kernel?
In the case of dma-engine
:
Is there a callback when it is finished?
Populate the callback pointer in the descriptor obtained from dmaengine_prep_slave_sg()
How to trigger the dma transaction to start?
Use dma_async_issue_pending()
and pass the initialised descriptor.
For more details refer to the dma-engine
client documentation.