Niels Jensen wrote:
I have a bus master dma device which cannot work across a 32MB physical
address boundary.
Weeeelllll… it gets ugly. The only function that I’m aware of
that’ll let you allocate memory with the alignment requirement that you
need is MmAllocateContiguousMemorySpecifyCache.
If you MmAllocateContiguousMemory, and then call MmGetPhysicalAddress,
it’ll work but you’ll be violating the Windows DMA abstraction with no
guarantee that your code will work in future.
OTOH, if you try to be good and follow the DMA abstraction, and build an
MDL that describes the allocated region and pass that into
AllocateAdapterChannel (returning “DeallocateObjectKeepRegisters” from
your execution rutine), that’ll only work if your device has been
declared as supporting scatter/gather via the DEVICE_DESCRIPTION data
structure.
In either case, you wind up with code that’s difficult to document and
which relies on the intracacies of the current implementation of the
Windows standard DMA components.
So, you’re damned if you do and damned if you don’t.
Have you tried allocating a few 700K blocks in a loop, and checking the
alignment of each, to see if you can get one that coincidentally will
meet your alignment requirement?? i.e.
while (maxTries–) {
goodBuffer = AllocateCommonBuffer(“the size you need”);
if ( “buffer meets alignment requirement”) {
break;
} else {
unalignedBuffer[i++]=buffer;
}
}
for(j=0;j _ReturnCommonBuffer(unalignedBuffer[j]);
}
if(goodBuffer == NULL) {
goodBuffer = AllocateCommonBuffer(“twice the size”);
bigBufferUsed = TRUE;
}
If you prototype that and find it doesn’t ever do any good, I’d do what
you’re doing now. That’s life in the driver business,
Peter
OSR_