I am trying to implement scatter/gather in WDF. Code below shows the calls I am using. When I use MmGetMdlVirtualAddress(Mdl) call to get the virtual address of the Buffer associated with the MDL, in some cases, it is returning NULL. And the problem is that WdfDmaTransactionInitialize() does not take NULL arguments, so the driver crashes.
I also tried using MmGetSystemAddressForMdlSafe() instead and that gave me some bogus virtual addresses.
I am wondering if this is an issue/bug with KMDF where WdfDmaTransactionInitialize() does not accept NULL virtual address or if there is some other way of handling this problem.
Any thoughts?
//
// Create a new DmaTransaction.
//
ntStatus = WdfDmaTransactionCreate( pContext->WdfDmaEnabler,
WDF_NO_OBJECT_ATTRIBUTES,
&pTransferRequest->dmaTransaction );
if(!NT_SUCCESS(ntStatus)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_DMA,
“WdfDmaTransactionCreate failed %X\n”,
ntStatus);
}
ntStatus = WdfDmaTransactionInitialize(
pTransferRequest->dmaTransaction,
XHCI_EvtProgramDma_Bulk,
pTransferRequest->fWriteToDevice ? WdfDmaDirectionWriteToDevice : WdfDmaDirectionReadFromDevice,
pTransferRequest->pTransferMdl,
MmGetMdlVirtualAddress(pTransferRequest->pTransferMdl),
pTransferRequest->TransferLength);
if(!NT_SUCCESS(ntStatus)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_DMA,
“WdfDmaTransactionInitalize failed %X\n”,
ntStatus);
}
//
// Execute this DmaTransaction.
//
ntStatus = WdfDmaTransactionExecute( pTransferRequest->dmaTransaction,
pSGContext );
if(!NT_SUCCESS(ntStatus)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_DMA,
“WdfDmaTransactionExecute failed %X\n”, ntStatus);
}
Thanks,
Vidya
PS: Above code is assuming that I already created a DMA object like this
//
// Create a new DMA Object for Scatter/Gather DMA mode.
//
//
maximumLength = 64 * 1024;
WDF_DMA_ENABLER_CONFIG_INIT( &dmaConfig,
WdfDmaProfileScatterGather,
maximumLength );
ntStatus = WdfDmaEnablerCreate( pContext->WdfDevice,
&dmaConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&pContext->WdfDmaEnabler );
if (!NT_SUCCESS (ntStatus))
{
TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT,
“WdfDmaEnblerCreate failed: %08X\n”, ntStatus);
break;
}