ezdma: Simple read()/write() userspace interface for dmaengine.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello all,

I've written a kernel module that allows data to be sent to or received from
any DMA device that supports the dmaengine API, using simple read()/write()
calls from userspace.

Motivation:

While doing some work for my master's thesis recently using the Xilinx Zynq
SoC, I needed a way to stream test data into and out of an FPGA soft-core I was
developing.  I was using the Xilinx AXI DMA soft-core (and its
dmaengine-compatible driver that I believe is related to Kedareswara rao
Appana's patch submitted recently).

Although dmaengine provides a versatile in-kernel API, to my knowledge there's
no direct userspace interface for the case where one wants to simply
send/receive data through a slave dma channel -- writing a separate
userspace-facing module would be required.  (Or some hack using /dev/kmem.)

Usage:

The ezdma ("easy DMA") module implements a read()/write() interface for
receiving/sending data through any slave DMA channel.

It is configured using the device tree:

1. Include a node like below into the device tree:

ezdma0 {
    compatible = "ezdma";
    dmas = <&loopback_dma 0 &loopback_dma 1>;
    dma-names = "loop_tx", "loop_rx";
    ezdma,dirs = <2 1>;     // direction of DMA channel:
                            //   1 = RX (dev->cpu), 2 = TX (cpu->dev)
};

2.  After inserting the ezdma module, two devices, as named in your dma-names
above, will become available:

    /dev/loop_tx
    /dev/loop_rx

3. Sending data is as easy as:

    int tx_fd = open("/dev/loop_tx", O_WRONLY);
    int rx_fd = open("/dev/loop_rx", O_RDONLY);

    write(tx_fd, tx_buf, xfer_size);    // send a DMA transaction
    read (rx_fd, rx_buf, xfer_size);

Currently, each read()/write() call causes a single transfer to occur in the
underlying slave DMA channel, but support could be added for readv()/writev()
as well.

Notes:

Although in my case I was using it with the AXI DMA to send and receive
AXI4-Stream packets, there is no dependency on any particular dmaengine driver
or hardware; it *should* work with any device that has a dmaengine driver.

I think it might be useful to others as an engineering/research tool.

I'm cleaning up the code and intend to submit it as a patch to this list in the
coming days.  Though I've been writing kernel code for a few years now, this
will be my first patch going upstream.  I appreciate any feedback.

Currently, I've posted my original code (before cleanup) here:
https://github.com/jeremytrimble/ezdma

Also, I'm open to changing the name if "ezdma" isn't seen as descriptive.


Cheers.

-Jeremy Trimble
--
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux PCI]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux