如何找到 dma_request_chan() 失败原因的详细信息?
How to find dma_request_chan() failure reason details?
在外部内核模块中,使用 DMA 引擎,当调用 dma_request_chan()
returns 一个值为 -19 的错误指针时,即 ENODEV 或 "No such device"。
现在,在活动设备树中,我确实找到了一个 dma-names 条目,其中包含我要为其获取通道的内容,所以我怀疑森林中更深的东西是尚未找到。
我如何找出问题所在?
背景:
我这里有一块 Zynq MP Ultrascale+ 开发板,其 FPGA 设计使用 AXI VDMA 块提供一个数据通道,以便在 Cortex A 的 Linux 上接收数据,其中数据通过以下方式写入 DDR4 FPGA 并从 Linux.
中读取
我发现内核中包含一个 Xilinx DMA 驱动程序,无论如何在 Xilinx 源代码库中,当前内核版本为 5.6.0。
而且该驱动程序没有用户 space 接口,因此需要一个中间内核驱动程序。
这是描绘的,他们在这里有一个例子:Section "4 DMA Proxy Design"。我修改了那里链接的 zip 文件的 dma-proxy.c 中的代码,使其仅使用 RX 通道,即也仅尝试请求它。
相关代码在这里,不要让 post 变大:
Modified dma-proxy.c at onlinegdb.com
- 第 407 行有函数
create_channel()
,它曾经使用 dma_request_slave_channel()
来排除它包装的函数的错误代码,所以为了查看错误,我正在使用那个:dma_request_chan()
.
- 函数
create_channel()
在函数 dma_proxy_probe()
@ line 470 中被调用(之前出现的事件被编译开关停用)。
所以通过这个调用,dma_request_chan()
将使用参数调用:
create_channel(pdev, &channels[RX_CHANNEL], "dma_proxy_rx", DMA_DEV_TO_MEM);
我的板子的 设备树 为 dma-proxy 驱动程序添加了一个节点,如 dma-proxy.c 顶部所示
dma_proxy {
compatible ="xlnx,dma_proxy";
dmas = <&axi_dma_0 0>;
dma-names = "dma_proxy_rx";
};
名称"axi_dma_0"与axi DMA设备树节点中的名称匹配:
axi_dma_0: dma@a0000000 {
#dma-cells = <0x1>;
clock-names = "s_axi_lite_aclk", "m_axi_s2mm_aclk";
clocks = <0x3 0x47 0x3 0x47>;
compatible = "xlnx,axi-dma-7.1", "xlnx,axi-dma-1.00.a";
interrupt-names = "s2mm_introut";
interrupt-parent = <0x1d>;
interrupts = <0x0 0x2>;
reg = <0x0 0xa0000000 0x0 0x1000>;
xlnx,addrwidth = <0x28>;
xlnx,sg-length-width = <0x1a>;
phandle = <0x1e>;
dma-channel@a0000030 {
compatible = "xlnx,axi-dma-s2mm-channel";
dma-channels = <0x1>;
interrupts = <0x0 0x2>;
xlnx,datawidth = <0x40>;
xlnx,device-id = <0x0>;
};
如果我现在看这里:
% cat /proc/device-tree/dma_proxy/dma-names
dma_proxy_rx
看起来我正在尝试为其请求频道的 dma_proxy_rx 就在那里。
编辑:
在启动日志中,我看到了这个:
xilinx-vdma a0000000.dma: Please ensure that IP supports buffer length > 23 bits
irq: no irq domain found for interrupt-controller@a0010000 !
xilinx-vdma a0000000.dma: unable to request IRQ 0
xilinx-vdma a0000000.dma: WARN: Device release is not defined so it is not safe to unbind this driver while in use
xilinx-vdma a0000000.dma: Xilinx AXI DMA Engine Driver Probed!!
有警告 - 但最后,Xilinx AXI DMA 引擎得到了 "probed",这意味着最低级别的驱动程序已加载并准备就绪,对吧?
所以在我看来应该有我的设备,但内核不同意。
我在类似的配置下遇到了同样的问题。在挖掘了大量内核源代码(尤其是 drivers/dma/xilinx/xilinx_dma.c)之后,我通过在 dma-proxy 设备树条目中将 dmas
参数中的通道号从 0 更改为 1 来解决了这个问题,如下所示:
dma_proxy {
compatible ="xlnx,dma_proxy";
dmas = <&axi_dma_0 1>;
dma-names = "dma_proxy_rx";
};
dma-proxy 示例似乎是为具有 mm2s(通道 #0)和 s2mm(通道 #1)通道的 AXI DMA 块编写的。如果我们从 AXI DMA 块中删除 mm2s 通道,s2mm 通道将保持 #1。
在外部内核模块中,使用 DMA 引擎,当调用 dma_request_chan()
returns 一个值为 -19 的错误指针时,即 ENODEV 或 "No such device"。
现在,在活动设备树中,我确实找到了一个 dma-names 条目,其中包含我要为其获取通道的内容,所以我怀疑森林中更深的东西是尚未找到。
我如何找出问题所在?
背景:
我这里有一块 Zynq MP Ultrascale+ 开发板,其 FPGA 设计使用 AXI VDMA 块提供一个数据通道,以便在 Cortex A 的 Linux 上接收数据,其中数据通过以下方式写入 DDR4 FPGA 并从 Linux.
中读取我发现内核中包含一个 Xilinx DMA 驱动程序,无论如何在 Xilinx 源代码库中,当前内核版本为 5.6.0。 而且该驱动程序没有用户 space 接口,因此需要一个中间内核驱动程序。
这是描绘的,他们在这里有一个例子:Section "4 DMA Proxy Design"。我修改了那里链接的 zip 文件的 dma-proxy.c 中的代码,使其仅使用 RX 通道,即也仅尝试请求它。
相关代码在这里,不要让 post 变大: Modified dma-proxy.c at onlinegdb.com
- 第 407 行有函数
create_channel()
,它曾经使用dma_request_slave_channel()
来排除它包装的函数的错误代码,所以为了查看错误,我正在使用那个:dma_request_chan()
. - 函数
create_channel()
在函数dma_proxy_probe()
@ line 470 中被调用(之前出现的事件被编译开关停用)。 所以通过这个调用,
dma_request_chan()
将使用参数调用:create_channel(pdev, &channels[RX_CHANNEL], "dma_proxy_rx", DMA_DEV_TO_MEM);
我的板子的 设备树 为 dma-proxy 驱动程序添加了一个节点,如 dma-proxy.c 顶部所示
dma_proxy {
compatible ="xlnx,dma_proxy";
dmas = <&axi_dma_0 0>;
dma-names = "dma_proxy_rx";
};
名称"axi_dma_0"与axi DMA设备树节点中的名称匹配:
axi_dma_0: dma@a0000000 {
#dma-cells = <0x1>;
clock-names = "s_axi_lite_aclk", "m_axi_s2mm_aclk";
clocks = <0x3 0x47 0x3 0x47>;
compatible = "xlnx,axi-dma-7.1", "xlnx,axi-dma-1.00.a";
interrupt-names = "s2mm_introut";
interrupt-parent = <0x1d>;
interrupts = <0x0 0x2>;
reg = <0x0 0xa0000000 0x0 0x1000>;
xlnx,addrwidth = <0x28>;
xlnx,sg-length-width = <0x1a>;
phandle = <0x1e>;
dma-channel@a0000030 {
compatible = "xlnx,axi-dma-s2mm-channel";
dma-channels = <0x1>;
interrupts = <0x0 0x2>;
xlnx,datawidth = <0x40>;
xlnx,device-id = <0x0>;
};
如果我现在看这里:
% cat /proc/device-tree/dma_proxy/dma-names
dma_proxy_rx
看起来我正在尝试为其请求频道的 dma_proxy_rx 就在那里。
编辑: 在启动日志中,我看到了这个:
xilinx-vdma a0000000.dma: Please ensure that IP supports buffer length > 23 bits
irq: no irq domain found for interrupt-controller@a0010000 !
xilinx-vdma a0000000.dma: unable to request IRQ 0
xilinx-vdma a0000000.dma: WARN: Device release is not defined so it is not safe to unbind this driver while in use
xilinx-vdma a0000000.dma: Xilinx AXI DMA Engine Driver Probed!!
有警告 - 但最后,Xilinx AXI DMA 引擎得到了 "probed",这意味着最低级别的驱动程序已加载并准备就绪,对吧?
所以在我看来应该有我的设备,但内核不同意。
我在类似的配置下遇到了同样的问题。在挖掘了大量内核源代码(尤其是 drivers/dma/xilinx/xilinx_dma.c)之后,我通过在 dma-proxy 设备树条目中将 dmas
参数中的通道号从 0 更改为 1 来解决了这个问题,如下所示:
dma_proxy {
compatible ="xlnx,dma_proxy";
dmas = <&axi_dma_0 1>;
dma-names = "dma_proxy_rx";
};
dma-proxy 示例似乎是为具有 mm2s(通道 #0)和 s2mm(通道 #1)通道的 AXI DMA 块编写的。如果我们从 AXI DMA 块中删除 mm2s 通道,s2mm 通道将保持 #1。