Greetings.
I am getting a STATUS_WDF_TOO_FRAGMENTED error returned when I call WdfDmaTransactionInitializeUsingRequest(). Here are the relevant code snippets from where the DMA enabler is setup:
#define SAMPCIE_DMA_MAX_SGE 0x00000400
#define SAMPCIE_DMA_MAX_SIZE 0x10000000
// set dma alignment
WdfDeviceSetAlignmentRequirement( wdfDevice, FILE_QUAD_ALIGNMENT );
// initialize dma enabler config
WDF_DMA_ENABLER_CONFIG_INIT( &dmaConfig,
WdfDmaProfileScatterGatherDuplex, SAMPCIE_DMA_MAX_SIZE );
// create dma enabler
status = WdfDmaEnablerCreate( wdfDevice, &dmaConfig,
WDF_NO_OBJECT_ATTRIBUTES, &pSampcieData->dmaEnabler );
// unsuccessful?
if( ! NT_SUCCESS( status ) )
{
// return status
TRACE_LOG_RET_0( status,
“WdfDmaEnablerCreate() failed.”,
wdfDevice, SAMPCIE_ERROR_DMA_ENABLER );
}
// set max sg elements
WdfDmaEnablerSetMaximumScatterGatherElements(
pSampcieData->dmaEnabler, SAMPCIE_DMA_MAX_SGE );
The S/G entiries for the DMA engine are stored in block RAM inside the FPGA, hence the 0x400 S/G element limit. The FPGA is connected to 256MB of DDR2 device memory, hence the 0x10000000 maximum transfer size.
So my question is, why is the call to WdfDmaTransactionInitializeUsingRequest() failing with STATUS_WDF_TOO_FRAGMENTED for a transfer length of 0xCF0000? ~13MB < 256MB … so what gives?
I am fairly certain there are more than 0x400 S/G elements for the request since the application’s heap is a fragmented mess and I rarely see consecutive physical pages showing up in the S/G list for DMA requests. However, I was under the impression the framework would break up the transfer and call the EvtProgramDmaFunction callback repeatedly. Is this not (at it appears to be from this example) the case?
From the WDK docs for WdfDmaTransactionDmaCompleted():
“The framework might divide a DMA transaction into several DMA transfer operations.”
The operative word being ‘might’. So I ‘might’ have misunderstood. Do I have to breakup the request into smaller (4MB - 4KB worst case for 0x400 S/G elements) ‘bite sized’ DMA morsels? Or is there a way to instruct the framework do it for me?
Many thanks!
110110101100