我正在为dma编写一个linux设备驱动程序,在浏览LXR中的dma驱动程序源时遇到了dma_cap_zero和dma_cap_set以及整个dma_cap_ *系列的函数。这些功能是什么? 还有一个名为dma_transaction_type
的结构enum dma_transaction_type {
DMA_MEMCPY,
DMA_XOR,
DMA_PQ,
DMA_XOR_VAL,
DMA_PQ_VAL,
DMA_MEMSET,
DMA_INTERRUPT,
DMA_SG,
DMA_PRIVATE,
DMA_ASYNC_TX,
DMA_SLAVE,
DMA_CYCLIC,
DMA_INTERLEAVE,
/* last transaction type for creation of the capabilities mask */
DMA_TX_TYPE_END,
};
枚举类型代表什么?
答案 0 :(得分:1)
这些函数实际上是预处理器宏函数,并由从属DMA设备用于配置和请求DMA通道。
以下是使用它们的示例:
dma_cap_mask_t mask;
dma_cap_zero(mask);
dma_cap_set(DMA_MEMCPY,mask);
dma_chan1 = dma_request_channel(mask,0,NULL);
此代码来自http://ecourse.wikidot.com/dmatest。
首先,dmaengine.h, ~line 233中定义了数据类型dma_cap_mask_t
。它是一种位域,其中位表示DMA通道能够进行何种传输。
在上面的代码片段中,该代码段发生在链接代码的__init
例程中,掩码被声明为特殊的dma_cap_mask_t
数据类型。然后调用dma_cap_zero()
函数并将掩码传递给它。
我相信dma_cap_zero
只是将功能掩码归零。它在dmaengine.h, ~line 733中定义。该函数返回void,我认为是将位域归零。但是,我并不完全确定,因为内核代码是一大堆宏观魔法,我有时很难解读。
掩码归零后,或dma_cap_zero
以某种方式初始化后,必须设置通道的功能。 dma_cap_set
函数实现了这一点。它采用请求通道类型并根据执行该类型事务所需的功能设置掩码。如果您对如何使用枚举感到困惑,请查看this page以简单查看枚举。在这种情况下,看起来枚举中的值用于描述不同类型的DMA事务,每个事务都需要一组不同的"功能"。 dma_set_cap
函数根据指定事务类型所需的功能设置功能掩码。
为您要执行的DMA事务类型正确设置掩码后,请求DMA通道。
其他dma_cap *宏用于在DMA掩码上执行其他类型的操作,而确实知道幕后发生了什么。这些类型的宏在内核代码中都存在,对于更多只是DMA的操作。它们允许设备驱动程序在内核中完成任务,而不必担心内核是如何完成的。