Points to Consider When Using DMA
This section provides some important points to consider if you plan to use DMA operations in your miniport driver.
The display driver usually sends transfer requests to the miniport driver, which actually carries out those DMA transfers. The display driver cannot assume that just because its DMA engine is idle, all data in a transfer request has been transferred. This is because the miniport driver needs to call VideoPortStartDma and VideoPortCompleteDma multiple times for a large transfer request. The hardware's DMA engine is idle between two such DMA operations, even though there might be additional data to transfer. It is the miniport driver's responsibility to inform the display driver when the transfer request has been completely accomplished.
The Context parameter of VideoPortStartDma should point to nonpaged memory, such as memory in the hardware extension. This parameter is passed through to the miniport driver's HwVidExecuteDma callback routine, which runs at IRQL DISPATCH_LEVEL.
For many devices, an interrupt is generated when a hardware DMA operation is complete. The video miniport driver's interrupt service routine (ISR) should queue a DPC routine for further DMA-related tasks. Do not call the video port driver's DMA functions in an ISR since they can only be called at or below IRQL DISPATCH_LEVEL.
It is safe to check the size being transferred in the aforementioned DPC routine, even if the VideoPortStartDma function has not yet returned, since the variable pointed to by the pLength argument of VideoPortStartDma has already been updated at the time HwVidExecuteDma was called.
The video port driver's DMA implementation uses the concept of logical addresses, which are addresses used by the DMA hardware. Logical addresses can be different from physical addresses. The video port driver-provided DMA functions take into account any platform-specific memory restrictions. For this reason, it is important to use the video port driver DMA functions instead of such kernel-mode functions as MmGetPhysicalAddress. Please refer to Adapter Objects and DMA for more information about logical addresses.
For devices that support concurrent DMA transfers, either on a DMA controller that supports simultaneous reads and writes, or on two separate DMA controllers, miniport drivers should obtain a separate DMA adapter object for each concurrent path. For example, if a device has two DMA controllers that work in parallel, the miniport driver should make two calls to VideoPortGetDmaAdapter, thereby obtaining pointers to two VP_DMA_ADAPTER structures. After that, whenever the miniport driver makes a DMA transfer request of a particular DMA controller, it should use the appropriate pointer in that request.