>In DMA chain you must have two physical addresses. Are they both correct?
Could you publish your code which does Read I/Os?
What are the 2 physicial addresses? I only know about the physicial address of the buffer that i have created. Also i memtioned that there is no Read IO in my driver, I am doing DMA in an IOCTL.
Here is the code anyway.
Initilization of DMA transaction:
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, “Alignment returned from WdfDeviceGetAlignmentRequirement = 0x%x, FILE_OCTA_ALIGNMENT = 0x%x”, WdfDeviceGetAlignmentRequirement(DeviceContext->WdfDevice), FILE_OCTA_ALIGNMENT);
WdfDeviceSetAlignmentRequirement( DeviceContext->WdfDevice,
// WdfDeviceGetAlignmentRequirement(DeviceContext->WdfDevice));
FILE_OCTA_ALIGNMENT);
//
// Create a new DMA Enabler instance.
// Use Scatter/Gather, 64-bit Addresses, Duplex-type profile.
//
{
WDF_DMA_ENABLER_CONFIG dmaConfig;
DeviceContext->MaximumTransferLength = DMA_MAX_TRANSFER_LENGTH;
WDF_DMA_ENABLER_CONFIG_INIT( &dmaConfig,
WdfDmaProfilePacket, //WdfDmaProfileScatterGatherDuplex,
DeviceContext->MaximumTransferLength );
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP," - The DMA Profile is WdfDmaProfilePacket");
status = WdfDmaEnablerCreate( DeviceContext->WdfDevice,
&dmaConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&DeviceContext->DmaEnabler );
if (!NT_SUCCESS (status)) {
KdPrint((“WdfDmaEnablerCreate failed: %!STATUS!”, status));
return status;
}
}
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, TRANSACTION_CONTEXT);
status = WdfDmaTransactionCreate( DeviceContext->DmaEnabler,
&attributes,
&DeviceContext->ReadDmaTransaction);
if(!NT_SUCCESS(status)) {
KdPrint((“WdfDmaTransactionCreate(read) failed: %!STATUS!”, status));
return status;
}
Transaction creation for data read:
pDevContext->pMemVA = MmAllocateContiguousMemorySpecifyCache( DataSize, PhyMin, PhyMax, PhyMin, MmNonCached);
if( pDevContext->pMemVA == NULL ) {
TraceEvents( TRACE_LEVEL_VERBOSE, DBG_INIT, “MmAllocateContiguousMemorySpecifyCache() FAILED to allocate buffer. Exiting\n”);
return ERROR;
}
memset(pDevContext->pMemVA, 0 , DataSize);
PhysicalAddr = MmGetPhysicalAddress(pDevContext->pMemVA) ;
//Initilize DMA transaction object for this
Mdl = IoAllocateMdl((PUCHAR)pDevContext->pMemVA, DataSize, FALSE, FALSE, NULL);
if( Mdl == NULL ) {
TraceEvents( TRACE_LEVEL_VERBOSE, DBG_INIT, “Mdl forCommon buffer could not be created. Exiting\n”);
return ERROR;
}
MmBuildMdlForNonPagedPool( Mdl );
TraceEvents( TRACE_LEVEL_VERBOSE, DBG_INIT, “Initializing DMA read transaction, Flushing cache for data buffer\n”);
KeFlushIoBuffers( Mdl, TRUE, TRUE);
status = WdfDmaTransactionInitialize( pDevContext->ReadDmaTransaction, NMMPEvtProgramReadDmaDummy, WdfDmaDirectionReadFromDevice, Mdl, MmGetMdlVirtualAddress(Mdl), MmGetMdlByteCount(Mdl) );
if( status != STATUS_SUCCESS ) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT, “WdfDmaTransactionInitialize() Failed. Exiting\n”);
return ERROR;
}
TraceEvents( TRACE_LEVEL_VERBOSE, DBG_INIT, “Initialized DMA read transaction\n”);
status = WdfDmaTransactionExecute ( pDevContext->ReadDmaTransaction, NULL);
if( status != STATUS_SUCCESS ) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT, “WdfDmaTransactionExecute() Failed. Exiting\n”);
return ERROR;
}
TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTLS,“Virt Address of non paged mem = 0X%X\n”, pDevContext->pMemVA);
}
/*
NMMPEvtProgramReadDmaDummy is a dummy function that does not do anything. But in this function I verify that the Physical address given in SgList is same as the one i get when i use MmGetPhysicalAddress(pDevContext->pMemVA) ;
After this callback is called, I send the Physical address of the buffer to the device as a part of a command that i write to the device bar register.
*/