Issue
I want to write a kernel module that can transfer data via DMA from RAM to RAM. There are some posts that discuss this, but I don't really get it. Some say it is possible others say it isn’t.
If I understood ldd3 right, RAM to RAM copying isn‘t possible with the DMA API of linux, but the driver/dma/dmaengine.c provides a flag DMA_MEMCPY for a "DMA Transfer Type", so there should be a way.
Is this correct, can I use a dma engine to transfer data from one ram address to another?
If it is hardware dependent, how can I determine if my system supports dma memcpy?
Solution
As you correctly pointed out, DMA_MEMCPY
should be used to perform RAM-to-RAM copy. It is described in Documentation/dmaengine/provider.txt. Here is just a related excerpt, please see the whole file for more details:
Supported transaction types
The next thing you need is to set which transaction types your device (and driver) supports.
Our
dma_device
structure has a field calledcap_mask
that holds the various types of transaction supported, and you need to modify this mask using thedma_cap_set
function, with various flags depending on transaction types you support as an argument.
All those capabilities are defined in the
dma_transaction_type
enum, ininclude/linux/dmaengine.h
Currently, the types available are:
DMA_MEMCPY
- The device is able to do memory to memory copies
Just to summarize:
It depends on your DMA controller. Some are able to do RAM-to-RAM transaction, some aren't.
For example, for OMAP-based SoCs, DMA controller does this (
drivers/dma/omap-dma.c
file, inomap_dma_probe()
function):dma_cap_set(DMA_MEMCPY, od->ddev.cap_mask);
This way you can later check it (if your DMA controller is capable of RAM-to-RAM transactions) in your driver. See how it's done in
drivers/dma/dmatest.c
, indmatest_add_channel()
function:if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) {
If you need an example on how to use DMA API to perform RAM-to-RAM transaction, please see drivers/dma/dmatest.c.
Answered By - Sam Protsenko Answer Checked By - Dawn Plyler (WPSolving Volunteer)