DMA Timeout and Change of Length


I have a driver that is very similar to the PLX9x5x sample driver insofar as it initializes a DMA transaction using the request (WdfDmaTransactionInitializeUsingRequest) and then sends the list to the driver by sharing a common buffer where we build a list of descriptors, and giving the driver the pointer to the beginning of the list.


Assuming the device is opened synchronously (i.e. not using the FILE_FLAG_OVERLAPPED) the read blocks until it gets an interrupt when DMA processing is done. However, in some cases when the data requested is greater than the data available, the read hangs. For this device, we can never really know how much data will come because the packet descriptor arrives after the data and technically packets can be larger than the FIFOs.

When we do this in Linux, we create a timeout by having a semaphore that the ISR increments and in the read() routine we wait for this semaphore for some timeout period, if it does get triggered because the ISR isn’t run then we fail the read().

Question 1: Is there a good example of how a timeout on a synchronous DMA read should be done in Windows? Or would a design similar to our Linux one work in Windows?

Question 2: Alternatively, is there some way to change the length of the request from inside the driver so that the scatter gather list matches the amount of data actually available in the FIFOs. My initial thought was to use WdfDmaTransactionInitialize() because it takes a length parameter that maybe I could change, but it also takes a pointer to an mdl and from what understand from the documentation the request (because we are using DirectIO) already created an mdl based on the user’s requested amount of data before sending the WDFREQUEST object to the XxxEvtIoRead().

Let me know if you have any thoughts, I appreciate any feedback.