I do wirte dma by the framework, by using WdfDmaTransactionInitializeUsingRequest, and in EvtProgramDma() I fill DMA_SG_ELEMENT by the parameter SgList the call function pass into. But the strange thing happens, my pcie device receives zeros sometimes. Partial codes below:
In EvtIoCtrl()
pDeviceContext->ulWriteSize = InputBufferLength;
status = WdfDmaTransactionInitializeUsingRequest(
pDeviceContext->DmaWriteTransaction,
Request,
EvtProgramDma,
WdfDmaDirectionWriteToDevice);
status = WdfDmaTransactionExecute(pDeviceContext->DmaWriteTransaction, WDF_NO_CONTEXT);
In EvtProgramDma()
dteVA = (PDMA_TRANSFER_ELEMENT) pDeviceContext->WriteCommonBufferBase;
dteLA = (pDeviceContext->WriteCommonBufferBaseLA.LowPart +
sizeof(DMA_TRANSFER_ELEMENT));
// Translate the System’s SCATTER_GATHER_LIST elements
// into the device’s DMA_TRANSFER_ELEMENT elements.
for (i=0; i < SgList->NumberOfElements; i++) {
// Construct this DTE.
dteVA->PciAddressLow = SgList->Elements[i].Address.LowPart;
dteVA->PciAddressHigh = SgList->Elements[i].Address.HighPart;
dteVA->TransferSize = SgList->Elements[i].Length;
dteVA->NextPageLow_EndBit = dteLA;
dteVA->NextPageHigh = pDeviceContext->WriteCommonBufferBaseLA.HighPart;
// If at end of SgList, then set LastElement bit in final NTE.
if (i == SgList->NumberOfElements - 1) {
dteVA->NextPageLow_EndBit |= 0x00000001;
break;
}
// Adjust the next DMA_TRANSFER_ELEMEMT
dteVA++;
dteLA += sizeof(DMA_TRANSFER_ELEMENT);
}
WdfInterruptAcquireLock( pDeviceContext->Interrupt );
//set pcie device dma regs
…
…
WdfInterruptReleaseLock( pDeviceContext->Interrupt );
Thanks !