Linux 中的dmaengine显着简化了为使用 DMA 的设备编写驱动程序,特别是如果它们支持和使用分散-聚集 (SG) 传输。
然而,如果这种传输的长度事先未知,则存在问题。这种情况相当普遍。在 USB 传输或 AXI Stream 传输的情况下可能会发生这种情况。对于 AXI Stream 连接的设备,应通过将 tlast 信号设置为“1”来终止传输。驱动程序应该为尽可能长的传输准备缓冲区,但在传输完成后,它应该能够找到实际传输的字节数。不幸的是,似乎没有记录的方法来读取已完成传输的长度。
单一传导表示用SG-表,即后来转化为dma_async_tx_descriptor,使用dmaengine_prep_slave_sg功能,提交给DMA层(例如像在这里),最后经由调度执行dma_async_issue_pending。之后,只能通过 dmaengine_prep_slave_sg 函数返回的 dma_cookie 访问传输描述符。
为 USB 传输报告了确定传输实际长度的问题,并提出了将该字段添加到 dma_async_tx_descriptor的补丁transferred。然而,该提议被拒绝了,经过讨论后,基于使用dmaengine_tx_status并检查返回的dma_tx_state结构中的字段 的解决方案。residue
不幸的是,所提议的解决方案似乎既不适用于 4.4 内核(用于 Xilinx SoC 器件),也不适用于最新的 4.7 内核。无论实际传输的字节数是多少,在完成传输的情况下,该residue字段都设置为 0。
所以我的问题是:如何在 dmaengine 兼容驱动程序中可靠地确定已完成的 SG DMA 传输中实际传输的字节数?
附注。Xilinx 论坛上也提出了有关与 AXI DMA IP 核相关的更多 Xilinx 特定细节的问题。