包含linked list的DMA驱动代码
时间: 2023-11-13 08:02:03 浏览: 156
JS中的算法与数据结构之链表(Linked-list)实例详解
以下是一个简单的DMA驱动代码,用于从一个链接列表中传输数据。该代码假定链接列表中的每个元素都包含一个指向数据缓冲区的指针和一个指向下一个元素的指针。该代码使用DMA控制器来传输数据,并在传输完成后调用一个回调函数。
```
#include <linux/dmaengine.h>
#include <linux/list.h>
struct dma_data {
void *buf;
struct list_head list;
};
static struct dma_chan *dma_chan;
static void dma_callback(void *data)
{
// DMA transfer is complete, do any necessary cleanup
}
int dma_transfer(struct list_head *list)
{
struct dma_data *data;
dma_cookie_t cookie;
int ret;
// Allocate a DMA descriptor
struct dma_async_tx_descriptor *desc = dma_chan->device->device_prep_dma_memcpy(
dma_chan, NULL, NULL, 0, DMA_PREP_INTERRUPT);
// Iterate over the list and add each buffer to the DMA descriptor
list_for_each_entry(data, list, list) {
dmaengine_prep_slave_sg(desc, &data->buf, sizeof(void *), DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT);
desc = dmaengine_desc_chain(desc, desc);
}
// Submit the DMA transfer and wait for it to complete
cookie = dmaengine_submit(desc);
ret = dma_submit_error(cookie);
if (ret)
return ret;
ret = dma_async_is_tx_complete(cookie, dma_chan, DMA_TIMEOUT);
if (!ret)
return -ETIMEDOUT;
// Call the callback function
dma_callback(NULL);
return 0;
}
```
在该代码中,我们首先定义了一个`dma_data`结构体来表示我们链接列表中的数据。然后我们定义了一个指向DMA通道的指针`dma_chan`,以及一个回调函数`dma_callback`,在DMA传输完成后将调用该函数。
`dma_transfer`函数是主要的DMA传输函数。它接受一个指向链接列表的指针,并使用DMA控制器将数据从每个链接列表元素的缓冲区传输到设备。我们首先使用`dma_chan->device->device_prep_dma_memcpy`函数分配一个DMA描述符,然后使用`dmaengine_prep_slave_sg`函数将每个缓冲区添加到描述符中。
一旦我们完成了描述符的构建,我们使用`dmaengine_submit`函数将传输提交到DMA控制器,并使用`dma_async_is_tx_complete`函数等待传输完成。一旦传输完成,我们调用回调函数`dma_callback`。
阅读全文