KMDF DMA using Windows DMA Abstraction

Hi All,
I am writing a very simple driver where the application will send me a read and/or write buffer (DMA from and to the device). The device needs a circular buffer for issuing request and completing request (NVME style queues). There can be more than one request issues to the device (4K requests). These requests transfer data to / from the user mode application buffers.

So this is a packet based DMA driver.

From what I have read so far, the following is the flow, when I am using the Windows (KMDF) DMA Abstraction.

  • Add Device : Create the queues using the common buffer DMA APIs. To use Windows DMA abstraction, create a single DMA enabler object.
  • EvtIoxxx : Create and Initialize the DMA transaction object.
  • EvtProgramDma : You will get your SGL, format it to the h/w specific format and then program the hardware for the DMA transfer.
  • Interrupt calls the DPC
  • DPC completes the request [one transaction is one transfer]

My problem is that the documentation states that “ If the driver has specified a packet based DMA profile, it must serialize all of the DMA transactions because the framework allows only one packet based DMA transaction to execute at any given time”.

Basically what it means is that I can only have a single DMA (single DMA enabler object) going on at any given time. For my device, I need to be able to fire 4K IOS at any given time and the hardware will complete (out of order) them whenever it has the data ready.

For a device of my type, I would not be able to use the Windows DMA abstraction as such.

Is my understanding correct about this?

Please let me know.
Thanks
AJ-

The abstraction does not fit every hardware design It’s always possible to use the enabler to do the virtual->logical mapping on your own, and then manage the buffering and completions yourself. DMA transactions are handy, but they aren’t required.

1 Like

I think I know the answer to this. The fact that we are creating a DMA Transaction object in EvtIOxxx should tell me that each IO can have it’s owned transaction object and I should be able to use that object for that. I believe I should be able to use that transaction object for that IO, effective having multiple DMA transaction objects active at the same time.

I think that this abstraction should make life very easy for me, as I do not have to process the MDL myself in the driver code.
This takes care of the map register and the processor cache coherencies as well.

May be wrong or missing something and hence open for comments.

  • AJ