2

My friend and I are attempting to write a device driver for a virtual device (read: not PCI or USB) for an advanced operating systems class. We are using Ubuntu 16.04. Our task is to invoke the IOCTL in our driver and give it a source buffer full of RGB values (an array of integers), an empty destination buffer, and a length. We are to invoke the DMA controller to transfer the contents of the source buffer into the destination buffer, then apply a linear transformation to the values in place in the destination buffer.

We have successfully done the transformations without DMA and we have successfully allocated a DMA channel to our device. The issue we're having is that we can't seem to find a function anywhere that describes initiating a transfer using the DMA. We want to have it raise an interrupt upon completion (the driver shouldn't spin waiting for the transfer to finish).

To be clear with what we're asking, we would just like to know where we can find definitions for functions describing this process. We're not asking for code or an exact method for completing this task; we would simply like to know what functions can be used and/or what header file to find them in. We have looked through linux/dma-mapping.h seemingly ad nauseam. We have also looked at LDD3 for a while, but it seems to go thoroughly through the process of setting up the DMA without giving much information on what functions should be used to actually begin the DMA transfer.

Cœur
  • 37,241
  • 25
  • 195
  • 267
ngc6027
  • 101
  • 11

1 Answers1

1

There are "DMA engine" APIs in recent Linux kernels to support local DMA engines capable of memory-to-memory copying in drivers/dma directory, check how they are implemented:

http://elixir.free-electrons.com/linux/latest/source/drivers/dma/Kconfig

menuconfig DMADEVICES
bool "DMA Engine support"
depends on HAS_DMA
help
  DMA engines can do asynchronous data transfers without
  involving the host CPU.  Currently, this framework can be
  used to offload memory copies in the network stack and
  RAID operations in the MD driver.  This menu only presents
  DMA Device drivers supported by the configured arch, it may
  be empty in some cases.

DMA Engines are implemented in several hardware platforms but not in every PC or server or SoC. Check options in the Kconfig like INTEL_IDMA64 "Intel integrated DMA .. Intel Skylake PCH", INTEL_IOATDMA "Intel(R) I/OAT DMA engine present in recent Intel Xeon chipsets."

Other option is to use some virtualization platform like qemu and implement your own device emulation for it (https://stackoverflow.com/a/44612957 edu device and simple driver, http://wiki.qemu.org/Features/QOM).

If you asking how to register interrupt handler, tell us what is your (virtual) bus, how your (virtual) device is connected (and how you did implement the virtual device). And qemu's "edu" pci.c driver has some examples for PCI-compatible interrupts: request_irq(pci_irq, irq_handler, IRQF_SHARED, "pci_irq_handler0", &major).

osgx
  • 90,338
  • 53
  • 357
  • 513