driverdevicedmapci-ewdf

limitation for NumberOfElements in scatter/gather list


My device driver for a PCIe FPGA is based on 7600.16385.1\src\general\PLX9x5x

Upon ReadFile in the application, PLxEvtIoRead is called:

//
// Initialize this new DmaTransaction.
//
status = WdfDmaTransactionInitializeUsingRequest(
                                              devExt->ReadDmaTransaction,
                                              Request,
                                              PLxEvtProgramReadDma,
                                              WdfDmaDirectionReadFromDevice );

//
// Execute this DmaTransaction.
//

status = WdfDmaTransactionExecute( devExt->ReadDmaTransaction, 
                                           WDF_NO_CONTEXT);

....

Upon calling to WdfDmaTransactionExecute, PLxEvtProgramReadDma is called. 

BOOLEAN
PLxEvtProgramReadDma(
    IN  WDFDMATRANSACTION       Transaction,
    IN  WDFDEVICE               Device,
    IN  WDFCONTEXT              Context,
    IN  WDF_DMA_DIRECTION       Direction,
    IN  PSCATTER_GATHER_LIST    SgList
    )
{
    KdPrint ((???SgList->NumberOfElements = %d\n???,SgList->NumberOfElements));

}

The problem: i want to transfer a large amount of data via this Scatter/Gather list(around 1 GB), but it seems NumberOfElements is limited by something, somehow that the larges transmition is 1MB(255 element in list, each 4k). i changed MaximumTransfecrLength in function below to 500MB:

WDF_DMA_ENABLER_CONFIG_INIT(&dmaConfig,
                         WdfDmaProfileScatterGatherDuplex,
                         deviceContext->MaximumTransferLength);

but still i can not transfer more than 1MB. what is the thing that limits NumberOfElements and how i can solve it?


Solution

  • I needed to change the second parameter in WDF_DMA_ENABLER_CONFIG_INIT function to WdfDmaProfileScatterGather64, and of course we have to make sure that hardware(FPGA or anything in other side of PCIE endpoint) can support 64-bit addressing mode.

    I just change my code as below:

    WDF_DMA_ENABLER_CONFIG_INIT(&dmaConfig,
                WdfDmaProfileScatterGather64,
                deviceContext->MaximumTransferLength);