Supporting System-Mode DMA

[Applies to KMDF only]

System-mode DMA, in contrast to bus-master DMA, describes a configuration in which multiple devices share a single, typically multichannel DMA controller.

Starting in Kernel-Mode Driver Framework (KMDF) version 1.11, the framework supports system-mode DMA on System on a Chip (SoC)–based systems running on Windows 8 or later versions of the Windows operating system.

This topic describes the code that a KMDF driver must provide in its event callback functions, as well as optional event callback functions it can register, to handle I/O requests for a system-mode DMA device.

For information about KMDF and bus-master DMA, see Handling I/O Requests in a KMDF Driver for a Bus-Master DMA Device.

The following figure shows the event callback functions that your driver uses to support system-mode DMA:

system-mode dma implementation in kmdf drivers

Creating a System-Mode DMA Enabler

Creating a system-mode DMA profile is a two-step process. The following steps represent a typical scenario:

  1. Typically in its EvtDriverDeviceAdd callback function, the driver calls WDF_DMA_ENABLER_CONFIG_INIT, setting the Profile parameter to SystemMode or SystemModeDuplex. The driver then calls WdfDmaEnablerCreate, passing the WDF_DMA_ENABLER_CONFIG structure that it just received.

    The driver might alternatively create the enabler during EvtDevicePrepareHardware.

  2. Your driver's EvtDevicePrepareHardware callback function associates the DMA enabler with its DMA resources by calling the WdfDmaEnablerConfigureSystemProfile method. For a duplex enabler, the driver calls WdfDmaEnablerConfigureSystemProfile twice, once to configure each transfer direction.

    The driver can call WdfDmaEnablerConfigureSystemProfile after EvtDevicePrepareHardware has completed, but the driver must call this method before it initializes DMA transactions.

Providing Optional Callback Functions

Configuring a DMA Channel

Typically, KMDF drivers do not configure DMA channels. However, in certain circumstances, drivers may need to perform channel-specific configuration. For example, a driver might call a custom function that is implemented by the DMA controller by using the following steps:

  1. In one of the driver's request handlers, the driver calls WdfDmaTransactionSetChannelConfigurationCallback to register a EvtDmaTransactionConfigureDmaChannel callback function.
  2. Your driver's EvtDmaTransactionConfigureDmaChannel callback function calls WdfDmaEnablerWdmGetDmaAdapter to retrieve a pointer to the WDM DMA_ADAPTER. This structure is the adapter object that represents the driver's system-mode DMA channel.
  3. The driver can then call ConfigureAdapterChannel to enable custom functions implemented by the DMA controller. This routine is callable only by pointer from the address returned in a DMA_OPERATIONS structure.
  4. Your driver's EvtDmaTransactionConfigureDmaChannel callback function returns TRUE if it successfully configures the DMA channel.
  5. The framework calls the driver's EvtProgramDma callback function.

Receiving Notification of Transfer Completion

Unlike devices that use bus-mastering controllers, the hardware for a system-mode DMA device might not signal DMA transfer completion by issuing an interrupt.

If your device does not raise an interrupt to signal DMA transfer completion, your driver can provide an EvtDmaTransactionDmaTransferComplete event callback function that the framework calls when a system-mode DMA transfer has completed.

To register this callback function, a driver calls WdfDmaTransactionSetTransferCompleteCallback from one of its request handlers.