I am writing a PCI driver based on plx 9656, but the hw disabled interrupt. And the interface between the HW and software is a little different from 9656 described, as the hw implemented their own logic.
As is known, I need to set up a callback function EvtProgramDma for WdfDmaTransactionInitialize to start a DMA.
Based on the situation above, I have two questions regarding to write a customized driver.
No 1:
Because there is no interrupt, I have to polling the hw register to make sure the transfer is really done. After hw consumed all data in memory, I will need to invoke WdfDmaTransactionDmaCompleted, WdfDmaTransactionRelease and WdfRequestCompleteWithInformation to tell the driver framework data transfer is done. In the DDK sample code, the above calls are in DPC routine, Is it safe and appropriate to call the three above functions in the callback EvtProgramDma directly? During the polling process, the EvtProgramDma callback might sleep some time, is this way appropriate?
no2.
My driver works on 64 bit windows, whereas the hw DMA is 32 bit width. how I tell the hw where data is. I guess I just tell the hw with
SgList->Elements[i].Address.LowPart. Is my assumption correct? In sample code, driver indicate the hw with logical address, is the address in PSCATTER_GATHER_LIST physical address or logical address?
EvtProgramDma is called at DISPATCH_LEVEL. You cannot wait/sleep at that level. You'll need to setup a timer.
However, it is quite unusual to have a PCI device that is capable of DMA that does not have an interrupt. That's the whole point. I'm wondering if you're misreading the documentation somehow.
As long as you have declared that your device is only 32-bit capable, then the physical addresses you get in the scatter/gather list should be below the 4GB mark. However, this is a real performance problem. It means the system needs to allocate some space below 4GB and copy the user's buffer into it piece by piece. No one should be designing a piece of hardware in the 21st Century that is limited to 32-bit DMA. How large will your transfers be?
"However, it is quite unusual to have a PCI device that is capable of DMA that does not have an interrupt. That's the whole point. I'm wondering if you're misreading the documentation somehow."
yes, there is no interrupt, because the HW team is my workmates. I confirmed that with them.
"As long as you have declared that your device is only 32-bit capable, then the physical addresses you get in the scatter/gather list should be below the 4GB mark. However, this is a real performance problem. It means the system needs to allocate some space below 4GB and copy the user's buffer into it piece by piece. No one should be designing a piece of hardware in the 21st Century that is limited to 32-bit DMA. How large will your transfers be?"
yes, 32 bit. The bandwidth is approximate 100MBps.
Let's back to the driver implementation, is SgList->Elements[i].Address the correct value I should tell the hw where the data source is when the app wants to write data to the device.
“In your case, the high 32 bits will be 0. That's the only difference.”, unfortunately, I found the high is not zero from log. The high is 1 at most cases, ocationally 2. Does this matter? The physical memory size on my debug machine is 8G.
Show us how you set up your WDFDMAENABLER, please.
Would your design be amenable to using a common buffer? You can guarantee the common buffer is in low memory, and do the copy yourself. You then wouldn't use the DMA abstration at all.
Is that supposed to be 100 mega BYTEs per second. or 100 mega BITs per second?
Without an interrupt, you are going to poll the hardware. If this data rate is expected to be reasonably constant, and the device is for a special purpose system, then this can work. If it is supposed to be for general use, then this is an impossible design
Thanks you for your tips. After I changed WdfDmaProfileScatterGather64Duplex to WdfDmaProfileScatterGatherDuplex. The problem solved. The physical address are all below 4G.both in common buffer mode and scatter gather mode. Thank you for your help.