I’ve been struggling to fully understand several aspects of AVStream and how to effectively utilize DMA given my device’s capabilities and constraints. I have several questions in this regard.
1.) Is is possible to use packet-based DMA without using scatter/gather? Since the buffers provided by AVStream are physically contiguous, I would think it should be possible to transfer a whole frame in a single DMA operation as long as the hardware supports such large transfers (mine does). However, I can’t figure out how to obtain a bus logical address for the buffers (and using the physical address directly seems to be a no-no).
Of course I could get bus logical addresses for scatter/gather mappings by specifying KSPIN_FLAGS_GENERATE_MAPPINGS. However, despite specifying a large value (larger than the frame size) for MaxMappingsByteCount in IKsDeviceFunctions::RegisterAdapterObjectEx() and for MaximumLength in DEVICE_DESCRIPTION, I still get a list of numerous small mappings, whereas I would like a single mapping large enough to transfer the whole frame in one operation (my hardware does not support scatter/gather).
2.) Could someone point out some documentation that describes how allocators are selected? The “AVStream Allocators” points out that the vendor-supplied allocator (I assume that the AVStream default allocator still counts as the “vendor-supplied” allocator if custom allocator dispatch routines are not used?) is not guaranteed to be used.
Does this mean that if I have alignment constraints (my DMA hardware requires a strict alignment) specified in my AllocatorFraming, it could be violated due to the use of some other downstream allocator? Is there any way to safeguard against this short of using a common buffer with known alignment and CPU copying the data into the AVStream buffer?
3.) Though IoGetDmaAdapter() works when my driver sits directly on top of pci.sys, the call fails and returns NULL if I introduce an intermediate bus driver between the two. How, if at all, can I obtain a DMA adapter in the AVStream driver if the driver is higher up in the stack?