Linux中的dmaengine显着简化了使用DMA的设备驱动程序的编写,尤其是当它们支持和使用分散 - 聚集(SG)传输时。
然而,如果这种转移的长度不是先验已知的话,则存在问题。这种情况很常见。在USB传输的情况下,或在AXI流传输的情况下,可能会发生这种情况。在AXI Stream连接设备的情况下,应通过将tlast信号设置为'来终止传输。驱动程序应为最长的传输准备缓冲区,但在传输完成后,它应该能够找到实际传输的字节数。不幸的是,似乎没有记录的方法来读取已完成转移的长度。
单次传输用SG-table表示,后来使用提交到DMA层的dma_async_tx_descriptor函数转换为dmaengine_prep_slave_sg(例如here ),最后通过dma_async_issue_pending安排执行。之后,只能通过dmaengine_prep_slave_sg函数返回的dma_cookie访问传输描述符。
针对USB传输报告了确定传输的实际长度的问题,并且提出了将transferred
字段添加到dma_async_tx_descriptor的patch。但是,该提案遭到拒绝,经过讨论后solution基于使用dmaengine_tx_status,并检查了返回的dma_tx_state结构中的residue
字段。
不幸的是,似乎所提出的解决方案在4.4内核(用于Xilinx SoC器件)和最新的4.7内核中都不起作用。
无论实际传输的字节数是多少,residue
字段都是set to 0,无论实际传输的字节数是多少。
所以我的问题是:如何在dmaengine兼容驱动程序中可靠地确定完成的SG DMA传输中的实际传输字节数?
PS。这个问题涉及Xilinx论坛上与AXI DMA IP核has been also asked相关的更多Xilinx特定细节。