Поделиться через


Завершение транзакции DMA

[Применяется только к KMDF]

Каждый раз, когда устройство драйвера завершает передачу DMA, драйвер должен вызывать WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompletedWithLength или WdfDmaTransactionDmaCompletedFinal, а затем проверка возвращаемое значение.

Если возвращаемое значение равно TRUE, передача транзакций DMA не требуется, и драйвер должен завершить транзакцию DMA. Как правило, драйвер еще не возвращается из функции обратного вызова EvtInterruptDpc . Таким образом, эта функция обратного вызова завершает транзакцию DMA следующим образом:

  1. Вызов WdfObjectDelete для удаления объекта транзакции или вызов WdfDmaTransactionRelease , если драйвер повторно использует объекты транзакций DMA.

  2. Вызов WdfRequestComplete или WdfRequestCompleteWithInformation, если транзакция связана с объектом запроса платформы.

Если драйвер вызывает WdfRequestCompleteWithInformation, он обычно сначала вызывает WdfDmaTransactionGetBytesTransferred , чтобы получить общую длину (количество байтов) всех передач транзакций.

Эти шаги показаны в следующем примере кода, взятом из функции обратного вызова EvtInterruptDpc примера PLX9x5x в файле Isrdpc.c:

if (readComplete) {
    BOOLEAN              transactionComplete;
    WDFDMATRANSACTION    dmaTransaction;
    size_t               bytesTransferred;

    // Get the current Read DmaTransaction.
    dmaTransaction = devExt->CurrentReadDmaTransaction;

    // Indicate that this DMA operation has completed:
    // This may start the transfer on the next packet if 
    // there is still data to be transferred.
    transactionComplete = 
          WdfDmaTransactionDmaCompleted( dmaTransaction, &status ); 
    if (transactionComplete) {
        // Complete the DmaTransaction and the request.
        devExt->CurrentReadDmaTransaction = NULL;
        bytesTransferred =  
               ((NT_SUCCESS(status)) ? 
               WdfDmaTransactionGetBytesTransferred(dmaTransaction): 0 );
        WdfDmaTransactionRelease(dmaTransaction);
        WdfRequestCompleteWithInformation(request, status, bytesTransferred);
    }
}