Как передать данные из пространства пользователя в вызов использования клиента dmaengine? - PullRequest
0 голосов
/ 06 апреля 2020

[отредактировано]

У меня есть доска на arm64 с fpga (Итак C).

Задача проста:

  • позволяет передавать данные из / в область "User Space" (приложение) в / из "Kernel Space" phys mem (device mem = fpga regs), с использованием поддержки dma и без нее (тип потоковой передачи). Этот dma находится на плате (ZynqMP / GDMA).

У меня будет несколько устройств - на fpga и снаружи, которые должны использовать эту связь, но сейчас я работаю только с fpga-ddr4 mem area.

Теперь я вижу следующий логический поток c:

  • некоторая инициализация (параметры dma и т. д.);
  • ioremap () устройства fpga area;
  • сделать буфер (по kzallo c () или другому) - этот буфер я должен дать США с помощью mmap fops;
  • сделать список рассеяния из буфера (псевдо- код ниже);
  • используйте список рассеяния с dmaengine для передачи данных;
// scatterlist init pseudo-code

struct scatterlist sgl[2];
struct scatterlist *sge;
int i, buf_n, err_code;
__u8 *buffer; // allocated earlier

sg_init_table(sgl, ARRAY_SIZE(sgl));

for_each_sg(sgl, sge, ARRAY_SIZE(sgl), i) {
  struct page *pg = virt_to_page(buffer + i * PAGE_SIZE);
  dma_addr_t dma_handle = dma_map_page(&pdev->dev, pg, 0, PAGE_SIZE, direction /* DMA_TO_DEVICE */);
  if ((err_code = dma_mapping_error(&pdev->dev, dma_handle))) {
    dev_err(&pdev->dev, "dma page mapping failed! (code: %i)\n", err_code);
    break;
  }
  sg_set_page(sge, pg, PAGE_SIZE, 0);
}

dma_map_sg(&pdev->dev, sgl, ARRAY_SIZE(sgl), direction) // with appropriate check

Теперь я неправильно понял следующее - как или где управлял пункт назначения? Я имею в виду, что я выделил буфер в ОЗУ, сделал из него scatterlist и передал этот список аргументом функций dmaengine для передачи. Но я не устанавливаю / не использую область памяти устройства ioremapped для сохранения этих данных буфера! Это dma работает только с соответствующей областью памяти RAM, и я должен скопировать буфер в область устройства? Или я должен использовать область ioremapped в качестве буфера? Это правильный поток? Объясните мне мои ошибки, признает?

...