When a device driver begins a DMA operation to a 32-bit only capable device, DmaOperations function HalGetScatterGatherList must determine whether any of the physical addresses describing the transfer reside above 4GB. The HAL will then substitute the transfer buffer physical addresses residing above 4GB with Map Register residing below 4GB, which the device is capable of addressing.
If substitutions were performed, the Scatter Gather List (SGL) generated will be comprised of physical addresses, some of which differ from the original Memory Descriptor List (MDL) describing the transfer. When the driver indicates that the DMA transfer is complete, the HAL determines whether it used map registers to support the transfer. If it did, and if the operation was a read from the device to system memory, the HAL will copy the contents of any Map Register used to the original data buffer. Data written directly to the transfer buffer virtual addresses by the driver prior to the requests completion will thus be overwritten by the contents of the HAL substituted Map Registers upon completion of the request.
If the data contained in the Map Registers does not match what the driver has written directly to the transfer buffer, then the data in the transfer buffer may be inconsistent.
If Map Register substitutions were done by the HAL, HalBuildMdlFromScatterGatherList will create a new MDL which is comprised of the non-substituted transfer buffer physical address and the physical addresses of the substituted HAL Map Registers. The virtual address mapping of the new MDL may be obtained by calling MmGetSystemAddressForMdlSafe. If HalBuildMdlFromScatterGatherList returns the original MDL then no Map Register substitutions were performed.
New MDLs created by HalBuildMdlFromScatterGatherList must be unmapped and freed by calls to MmUnmapLockedPages and IoFreeMdl.
Article ID: 2714876 - Last Review: 18 May 2012 - Revision: 1