Three features can be helpful in testing drivers that support DMA: Driver Verifier, the !dma debugger extension, and the KMDF-specific debugger extensions for DMA.
Chapter 21, "Tools for Testing Drivers," provides information about Driver Verifier. Chapter 22, "How to Debug WDF Drivers," describes debugger extensions.
In Windows XP and later Windows versions, Driver Verifier includes specific verification tests to detect improper use of various DMA operations. Driver Verifier includes checks for the following DMA-specific errors, which involve the underlying WDM structures rather than the WDF objects:
Overrunning or underrunning the DMA memory buffer.
These errors can be made by the hardware or by the driver.
Freeing the same common buffer, adapter channel, map register, or scatter/gather list more than once.
Leaking memory by failing to free common buffers, adapter channels, map registers, scatter/gather lists, or adapters.
Attempting to use an adapter that has already been freed and no longer exists.
Failing to flush an adapter buffer.
Performing DMA on a pageable buffer.
Allocating too many map registers at one time or allocating more map registers than the maximum allowed number.
Attempting to free map registers while some are still mapped.
Attempting to flush a map register that has not been mapped.
Calling DMA routines at an improper IRQL.
In addition to the above, Driver Verifier includes several minor consistency checks that are described in "DMA verification" in the WDK-online at http://go.microsoft.com/fwlink/?LinkId=80070.
Many of these errors pertain to actions that the framework, rather than the KMDF driver, performs. However, some such errors can indicate problems in driver code as well.
Driver Verifier implements one additional feature to facilitate testing of drivers for DMA devices. When Driver Verifier runs, it double-buffers all DMA transfers for verified drivers. Double-buffering helps to ensure that the driver uses the correct addresses for DMA operations. Depending on the kind of error it discovers, Driver Verifier reports DMA-specific errors either by generating an ASSERT or by issuing Bug Check 0x6E (that is, DRIVER_VERIFIER_DMA_VIOLATION).
When you test your driver, remember that Driver Verifier is not an automated test utility. Rather, enabling verification for your driver causes Driver Verifier to watch the operations that your driver performs and warn you if it detects any operations that your driver performs incorrectly. Therefore, you must ensure that your driver is thoroughly exercised with a wide variety of I/O requests while Driver Verifier is enabled, including read and write requests of various lengths.
Another debugging aid for drivers that support DMA devices is the !dma debugger extension. This extension displays information about the DMA subsystem and DMA device drivers that are being verified by Driver Verifier.
If DMA verification is not enabled for a driver, the !dma debugger extension can list all of the DMA adapters in the system. The DMA adapter object is the WDM representation of the DMA capabilities of the device. A WDF DMA enabler object represents one or more underlying DMA adapters for a device. When DMA verification is enabled, the !dma debugger extension can also list the following information:
Device object, map registers, scatter/gather lists, and common buffers that are associated with each DMA adapter.
Map register usage for a particular DMA adapter, including whether transfers to and from the device are being double-buffered.
Length, virtual and physical addresses of any common-buffer segments.
The information pertains to the underlying framework data structures, not to the objects that the KMDF driver itself creates. Nevertheless, it can be useful in debugging to help you determine whether DMA is being performed as you expect.
The !dma debugger extension is described in detail in the documentation that accompanies the Debugging Tools for Windows package.
The KMDF debugger extensions that are provided with the WDK include several commands that are specifically designed to help you debug drivers for DMA drivers. Table 17-3 lists these extensions.
Lists all of the DMA enablers and their transactions and common buffer objects.
Dumps information about a specific DMA enabler object and its transactions and common buffer objects.
Dumps information about a given transaction object.
Dumps information about a given common buffer object.
Chapter 22, "How to Debug WDF Drivers," provides more information about debugger extensions for KMDF.
Listing 17-5 shows the output of the DMA debugger extensions.
Listing 17-5: Output of KMDF debugger extensions for DMA
0: kd> !wdfdmaenablers 0x7e6128a8 Dumping WDFDMAENABLERS 0x7e6128a8 =============================== 1) !WDFDMAENABLER 0x7e7ac630: --------------------------- List of Transaction objects: 1)!WDFDMATRANSACTION 0x016f5fb0 List of CommonBuffer objects: 1)!WDFCOMMONBUFFER 0x7e887c00 2)!WDFCOMMONBUFFER 0x7e780cd0 3)!WDFCOMMONBUFFER 0x7ec6b338 0: kd> !WDFDMAENABLER 0x7e7ac630 Dumping WDFDMAENABLER 0x7e7ac630 =============================== Profile : WdfDmaProfileScatterGather64Duplex Read DMA Description: WDM AdapterObject (!dma): 0x81b37938 Maximum fragment length : 32768 Number of map registers : 9 Write AdapterObject Description: WDM AdapterObject (!dma): 0xff0b92d0 Maximum fragment length : 32768 Number of map registers : 9 Default common buffer alignment: 1 Max SG-elements per transaction: 0xffffffff List of Transaction objects: 1)!WDFDMATRANSACTION 0x016f5fb0 State: FxDmaTransactionStateTransfer Direction: Read Associated WDFREQUEST: 0x0108b2d0 Input Mdl: 0x81b042b8 Starting Addr: 0x81893000 Mdl of current fragment being transferred: 0x81b042b8 VA of current fragment being transferred: 0x81893000 Length of fragment being transferred: 0x8c Max length of fragment: 0x8000 Bytes transfered : 0x0 Bytes remaining to be transferred: 0x0 ProgramDmaFunction: (0xf7cc62e0) testdma!EvtProgramDma List of CommonBuffer objects: 1)!WDFCOMMONBUFFER 0x7e887c00 Virtual address allocated: 0xff8ca560 Aligned: 0xff8ca560 Logical address allocated: 0x18b79560 Aligned: 0x18b79560 Length allocated: 0x1a Length requested: 0xa Alignment Mask: 0x10