Hello Tim:
Thank you for the response.
Presumably you meant dmaAdapter->DmaOperations->CalculateScatterGatherListSize instead of CalculateScatterGatherList.
Actually, the call CalculateScatterGatherList maps to PCALCULATE_SCATTER_GATHER_LIST_SIZE in wdm.h’s _DMA_OPERATIONS struct.
Technically, you should be using MmGetSystemAddressForMdlSafe(bufferMdlP).
Thank you for that, I ended up using MmMapLockedPagesSpecifyCache since I don’t want the memory to be cached
Unfortunately I still get the same “STATUS_INVALID_PARAMETER” return code from “…->CalculateScatterGatherList”
On the SW side, it is allocating a string buffer and passing it in via the outbuffer of the IO Control call (overlapped, generic_read).
The IOCTL is OUT_DIRECT.
The DMA Enabler: flag: WDF_DMA_ENABLER_CONFIG_REQUIRE_SINGLE_TRANSFER, Profile: WdfDmaProfilePacket64, Len: 128
I will dump the KVA and see what I find.
(Note: Abridged; Some declarations and checks omitted. EvtIoInCallerContext does check the IOControlCode and calls a helper to perform the SGList building shown below.)
void EvtIoInCallerContext( IN WDFDEVICE device, IN WDFREQUEST request )
// Get the outbuffer from the IOCTL request
WDFMEMORY outputBufferObj{ nullptr };
WdfRequestRetrieveOutputMemory( request, &outputBufferObj );
// Get the outbuffer size. Note: outBuffP not actually needed, we just want the size.
PVOID outBuffP = WdfMemoryGetBuffer( outputBufferObj, &outBuffByteSize );
// Get the MDL from the outbuffer
WdfRequestRetrieveOutputWdmMdl( request, &deviceContextP->hostMemoryMdlP );
// Get the DMA adapter.
PDMA_ADAPTER dmaAdapter = WdfDmaEnablerWdmGetDmaAdapter(
myDmaEnabler,
WdfDmaDirectionReadFromDevice );
// Get the Kernel Virtual Address for the MDL
PVOID hostMemoryKvaP = MmMapLockedPagesSpecifyCache(
hostMemoryMdlP, KernelMode,
MmNonCached, NULL,
FALSE, HighPagePriority );
// Get the SG List size
dmaAdapter->DmaOperations->CalculateScatterGatherList( dmaAdapter,
hostMemoryMdlP, hostMemoryKvaP,
hostMemoryMdlP->ByteCount,
&sgByteSize, &numMapRegisters );
// Allocate memory for the SG List
PVOID scatterGatherListBuffP{ nullptr };
WdfMemoryCreate( &buffAttributes, PagedPool, 0,
static_cast<size_t>( sgByteSize ),
&scatterGatherMemoryObj, &scatterGatherListBuffP );
// Get the Device Object
PDEVICE_OBJECT deviceObjectP = WdfDeviceWdmGetDeviceObject( device );
// Get the SG List
dmaAdapter->DmaOperations->BuildScatterGatherList( dmaAdapter, deviceObjectP,
hostMemoryMdlP, hostMemoryKvaP,
static_cast<ULONG>( outBuffByteSize ),
&(MyAdapterListControl), deviceContextP, FALSE,
scatterGatherListBuffP, sgByteSize );
Thank you, again!
Juan