Как найти подробную информацию о причине сбоя dma_request_chan()?

Во внешнем модуле ядра, используя DMA Engine, при вызове dma_request_chan()возвращает указатель ошибки со значением -19, то есть ENODEV или "Нет такого устройства". Теперь в активном дереве устройств я действительно нахожу запись dma-names с тем, для чего я пытаюсь получить канал, поэтому я подозреваю, что что-то еще глубже в лесу уже не найдено.

Как мне узнать, что случилось?

Задний план:

У меня есть плата Zynq MP Ultrascale+ с дизайном FPGA, который использует блок AXI VDMA для предоставления одного канала данных, которые должны быть получены в Linux Cortex A, где данные записываются в DDR4 с помощью FPGA и читаются из Linux.

Я обнаружил, что есть драйвер Xilinx DMA, включенный в ядро, в любом случае в репозитории исходного кода Xilinx, в настоящее время версия ядра 5.6.0. И что у этого драйвера нет интерфейса пользовательского пространства, поэтому требуется промежуточный драйвер ядра.

Это изображено, и у них есть пример здесь: Раздел "4 Проектирование прокси DMA". Я изменил код в dma-proxy.c связанного с ним zip-файла таким образом, что он использует только канал RX, то есть пытается только запросить его.

Код для этого здесь, чтобы не делать этот пост огромным:измененный dma-proxy.c на onlinegdb.com

  • Строка 407 имеет функцию create_channel(), который раньше использовал dma_request_slave_channel() который удаляет код ошибки функции, которую он обертывает, поэтому, чтобы увидеть ошибку, я использую вместо этого: dma_request_chan().
  • Функция create_channel() вызывается в функции dma_proxy_probe() @ строка 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 Engine "зондировал", что означает, что драйвер самого низкого уровня загружен и готов, верно?

Мне кажется, что там должно быть мое устройство, но ядро ​​не соглашается.

1 ответ

У меня такая же проблема с аналогичной конфигурацией. Покопавшись в большом количестве исходного кода ядра (особенно в драйверах / dma / xilinx / xilinx_dma.c), я решил эту проблему, изменив номер канала в dmas параметр от 0 до 1 в записи дерева устройств dma-proxy следующим образом:

      dma_proxy {
  compatible ="xlnx,dma_proxy";
  dmas = <&axi_dma_0 1>;
  dma-names = "dma_proxy_rx";
};

Похоже, что пример dma-proxy написан для блока AXI DMA с каналами mm2s (канал №0) и s2mm (канал №1). И если мы удалим канал mm2s из блока AXI DMA, канал s2mm останется №1.

Другие вопросы по тегам