知识杂货铺

不卖切糕

View on GitHub
7 August 2018 09:00

Linux驱动分析 - dmaengine

by 宋强

dmaengine注册

dmaengine的底层驱动回调函数在dma_device结构体中注册,实现时先alloc一段内存给这个结构体,并初始化以下几个属性:

dmaengine支持的传输模式设置

要增加支持的模式需要使用

void dma_cap_set(enum dma_transcation_type tx_type, dma_cap_mask_t *dstp);

第一个参数是要增加的模式,第二个是dma_device的cap_mask属性,模式通常还会影响源数据指针和目的数据指针的增减模式。

支持的模式有:

需要实现的底层回调方法

device_alloc_chan_resources, device_free_chan_resources

会在驱动第一次调用dma_request_channel和最后一次调用dma_release_channel的时候调用,负责申请和释放内存等资源,可以进入睡眠。

device_prep_dma_*

device_issue_pending

在传输描述符队列中取出第一个要传输的然后传输之后将指针指向下一个要传输的传输描述符,可以在中断过程中调用。

device_tx_status

返回指定传输描述符代表的传输剩余传输的字节数,如果是循环传输,那么只返回当前周期传输剩余的字节数。

device_config

使用新的配置配置指定的传输。

device_pause

立刻暂停正在进行的传输。

device_resume

立刻恢复传输。

device_terminal_all

放弃所有等待队列和正在进行得DMA传送,回调函数不会执行,可以在原子过程中调用并且不能进入睡眠。

device_synchronize

终止需要终止的传输过程,并且保证之前使用过的传送符占用的内存已被释放,还有之前的传送的回调函数全部都执行完了。 可能进入睡眠。

一些概念

dma_run_dependencies

在Async TX传送的结尾调用,slave传输不需要,用于在传送前执行必要的前提动作。

递增的DMA传送ID,用处不明。

DMA_CTRL_ACK

如果没设置这个值,驱动程序不可以在client响应前复用传输描述符,客户端使用async_tx_ack()响应,不过即使设置了也不一定可以重用。

DMA_CTRL_REUSE

如果设置了这个值,传输描述符可以被复用,也意味着使用过后不要释放传输符占用的内存。 使用dmaengine_desc_set_reuse()来设置这个值,但只有通道允许重用才会成功,使用dmaengine_desc_clear_reuse()来清除这个值。 方便如果要跳过某个传输后面的可以直接使用描述符。 只有这个值被设置之后才需要手动释放传输符内存,使用dmaengine_desc_free()来释放。

参考

  1. ELC 2015 - An Overview of the Kernel DMAEngine Subsystem - Maxime Ripard, Free Electrons
  2. Documentation/dmaengine/provider.txt
tags: Linux - dma