dma_set_mask_and_coherent 具有 24 位 DMA 掩码,适用于 ARM64 上的 PCIe

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

我正在编写 PCIe 驱动程序,但在设置 DMA 掩码时遇到问题。

主机是带有四核ARM-Cortex A53的zcu102。 PCIe 设备是自定义设备。

内核为 5.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.