limitations on DMA transfer size?

Well, you’ve got ME stumped.

Peter
OSR

xxxxx@neurologica.com wrote:


if (NT_SUCCESS(status))
{
size_t maxLen = WdfDmaEnablerGetMaximumLength(pDmaDevExt->DmaEnabler);
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,
“dmaConfig.MaximumLength is %lld (0x%x%08x)”, dmaConfig.MaximumLength,
dmaConfig.MaximumLength >> 32,
dmaConfig.MaximumLength);
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,
“WdfDmaEnablerGetMaximumLength returns %lld (0x%x%08x)”,
maxLen, maxLen >> 32, maxLen);
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,
“pDmaDevExt->MaximumTransferLength is %lld (0x%x%08x) (sizeof(size_t) is %d)”,
pDmaDevExt->MaximumTransferLength,
pDmaDevExt->MaximumTransferLength >> 32,
pDmaDevExt->MaximumTransferLength, sizeof(size_t));

For what it’s worth, you can write 0x%16llx instead of passing the two
halves separately.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

(Those TraceEvents statements are more complex than most drivers I’ve seen :wink:

FWIW, you can write 0x%p and make it even easier.

Peter
OSR

I just tried calling IoGetDmaAdapter() and it is telling me that I have 524288 (0x80000) map registers (corresponding to max transfer length of 2GB). So, this appears to be giving me the same result as KMDF. I gave it a maxLength of 0xfffff000 (4GB - PAGE_SIZE).

>For what it’s worth, you can write 0x%16llx instead of passing the two

halves separately.

(Those TraceEvents statements are more complex than most drivers I’ve seen :wink:

FWIW, you can write 0x%p and make it even easier.

Thanks :stuck_out_tongue:

Your problem is intriguing…

I’d appreciate conformation from some of our friends at Microsoft – like the folks who own the HAL for amd64 these days – but from my brief research it sure looks to ME like the maximum length for a DMA transfer is limited to 2GB by the HAL.

Peter
OSR

“When I tried to put
PutScatterGatherList/GetScatterGatherList in my DPC, I kept getting BugCheck on
GetScatterGatherList. I figured that it was because I was in the wrong context
from the buffer alloc context. (buffer virt addresses were wrong)”

The virtual address in the MDL is used as a reference address if you want a partial SGL. It’s not referenced in any current-process-related way. Because of that, GetSGL should be safe to call in arbitrary DISPATCH_LEVEL context.

The CurrentVa argument of GetSGL is obtained from MmGetMdlVirtualAddress and desired offset. You can call it multiple times for smaller sizes (say, 1GB) and passing varying CurrentVa arguments (say, advancing it by 1GB every time).

Also, keep in mind that GetSGL theoretically (in unusual conditions) may not be synchronous. You should only continue in the callback function.

I wanted to put the question out again, before this thread falls much further into obscurity:

Has anyone done a DMA >2GB on Windows?

Or, more specifically, has anyone been able to specify a MaxTransferSize of >2GB? (to IoGetDmaAdapter() or WdfDmaEnablerCreate())

OK, I guess there’s than one question here… :wink: #3:
Can anyone confirm whether or not there is a 2GB hard limit imposed by OS/HAL??

Thanks
~Jeff