dma_set_mask_and_coherent(),具有适用于 arm64 上 PCIe 的 24 位 DMA 掩码

问题描述 投票:0回答:1

我正在编写 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

我觉得还不错。

我当前的问题轨迹是:

  1. dma_set_mask_and_coherent)_调用dma_set_mask()

  2. dma_set_mask()
    检查 dma_supported()(dev,mask) 是否返回零

  3. 对于 DMA_BIT_MASK(24),它返回 0 导致失败。对于 DMA_BIT_MASK(32),它返回 1 导致成功。

  4. dma_supported()
    检查
    get_dma_ops(dev)

    中是否有空指针
  5. get_dma_ops()实现取决于CONFIG_DMA_OPS

  6. gunzip -c /proc/config.gz | grep CONFIG_DMA_OPS
    返回
    CONFIG_DMA_OPS=y

  7. 由于启用了此功能:

    get_dma_ops()
    检查 dev->dma_ops

  8. pr_info("pdev->dev.dma_ops: %p\n", pdev->dev.dma_ops);
    返回0所以检查失败

  9. 这意味着

    dma_direct_supported()
    被调用。

您能帮我回答以下问题吗:

  • 为什么 dma_direct_supported 失败?
linux-kernel linux-device-driver arm64 dma pci-e
1个回答
0
投票

根据 Ian Abbots 提示,我查看了

dma_direct_supported()
并发现

min_mask = min_t(u64, min_mask, DMA_BIT_MASK(zone_dma_bits));

zone_dma_bits
对于arm64 解析为32,因此24 位掩码太小。

© www.soinside.com 2019 - 2024. All rights reserved.