我正在编写 PCIe 驱动程序,但在设置 DMA 掩码时遇到问题。
主机是带有四核ARM-Cortex A53的zcu102。 PCIe 设备是自定义设备。
内核是 v5.15.0-1023-xilinx-zynqmp,带有 Xilinx Ubuntu 22.04.3 LTS。
根据 DMA API HOWTO 我需要使用
dma_set_mask_and_coherent()
设置 DMA 掩码
我的设备支持 24 位 DMA 掩码。
因此我尝试以下方法:
status=dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(24));
这将返回 -5 => -EIO => I/O 错误。
我尝试过以下方法:
当我用
DMA_BIT_MASK(32)
尝试相同的代码时,它有效。所以看来是24位的问题。
我查看了内核配置
gunzip -c /proc/config.gz | grep CONFIG_ZONE_DMA
:
CONFIG_ZONE_DMA=y
CONFIG_ZONE_DMA32=y
我觉得还不错。
我当前的问题轨迹是:
dma_set_mask()
检查 dma_supported()(dev,mask) 是否返回零
对于 DMA_BIT_MASK(24),它返回 0 导致失败。对于 DMA_BIT_MASK(32),它返回 1 导致成功。
dma_supported()
检查 get_dma_ops(dev)
中是否有空指针
get_dma_ops()实现取决于CONFIG_DMA_OPS
gunzip -c /proc/config.gz | grep CONFIG_DMA_OPS
返回CONFIG_DMA_OPS=y
由于启用了此功能:
get_dma_ops()
检查 dev->dma_ops
pr_info("pdev->dev.dma_ops: %p\n", pdev->dev.dma_ops);
返回0所以检查失败
这意味着
dma_direct_supported()
被调用。
您能帮我回答以下问题吗:
根据 Ian Abbots 提示,我查看了
dma_direct_supported()
并发现
min_mask = min_t(u64, min_mask, DMA_BIT_MASK(zone_dma_bits));
zone_dma_bits
对于arm64 解析为32,因此24 位掩码太小。