Packet-Based Bus-Master DMA
Ordinarily, a display driver initiates a DMA operation by sending a transfer request to the miniport driver. When a miniport driver supporting packet-based DMA operations receives such a request, it first locks the buffer involved in the data transfer. The miniport driver then initiates the transfer by calling the video port driver's VideoPortStartDma function, which in turn calls the miniport driver's HwVidExecuteDma callback routine to carry out the data transfer. This DMA operation is handled asynchronously: VideoPortStartDma does not wait for the DMA operation to complete before returning control to the miniport driver.
Depending on the size of the transfer request and the number of system resources assigned to the adapter, the driver may not be able to transfer all of the data in a single DMA operation. The miniport driver should inspect the actual transfer size returned in order to find out whether there is more data to be transferred. As soon as the DMA hardware finishes the current transfer, the miniport driver should call the video port driver's VideoPortCompleteDma function to complete the current DMA operation. If there is still data remaining to be transferred, the miniport driver repeats the process of calling the video port driver's VideoPortStartDma and VideoPortCompleteDma functions iteratively until no more data remains to be transferred. When all of the data has been transferred, the miniport driver should unlock the buffer.
The miniport driver performs the following sequence of operations to use packet-based DMA:
Report hardware capabilities to the system and acquire an adapter object.
The miniport driver calls the video port driver's VideoPortGetDmaAdapter function, which returns a pointer to a VP_DMA_ADAPTER structure. This is usually done at initialization time, typically within the miniport driver's HwVidFindAdapter routine. The miniport driver uses this pointer for subsequent DMA operations.
Lock host memory.
The miniport driver calls the video port driver's VideoPortLockBuffer function, which probes the buffer, makes those memory pages resident, and locks them.
Start the DMA transfer.
The miniport driver calls the video port driver's VideoPortStartDma function, which flushes the host processor memory caches, builds the scatter/gather list, and calls the miniport driver's HwVidExecuteDma callback routine to carry out the DMA operation asynchronously. VideoPortStartDma returns control to the miniport driver without waiting for the DMA operation to complete.
Complete the DMA transfer.
The miniport driver should call the video port driver's VideoPortCompleteDma function as soon as the hardware finishes the DMA operation. Many video adapters generate an interrupt when a DMA operation is complete. For example, a system with this type of adapter could react to the interrupt in the following way. When the hardware generates the interrupt to notify the miniport driver that the DMA operation has completed, the miniport driver's interrupt service routine (ISR) calls the video port driver's VideoPortQueueDpc function to queue a DPC routine, which in turn calls the video port driver's VideoPortCompleteDma function. The ISR cannot directly call VideoPortCompleteDma since this video port driver function must be called at or below IRQL DISPATCH_LEVEL.
VideoPortCompleteDma flushes any data remaining in the bus-master adapter's internal cache, and frees any unused resources (including the scatter/gather list built by VideoPortStartDma).
If only part of the data has been transferred (due to limitations on the number of available map registers, for example), the miniport driver must make repeated calls to VideoPortStartDma and VideoPortCompleteDma until all of the data has been transferred.
Unlock host memory.
When all of the data has been transferred, the miniport driver should call the video port driver's VideoPortUnlockBuffer function to unlock the data buffer it acquired in the second step.
Discard the adapter object.
This step is optional. If, for some reason, the miniport driver decides that there will be no further DMA operations for the rest of its lifetime, it should discard the DMA adapter object by calling the video port driver's VideoPortPutDmaAdapter function.