Завершение транзакции DMA
[Применяется только к KMDF]
Каждый раз, когда устройство драйвера завершает передачу DMA, драйвер должен вызывать WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompletedWithLength или WdfDmaTransactionDmaCompletedFinal, а затем проверка возвращаемое значение.
Если возвращаемое значение равно TRUE, передача транзакций DMA не требуется, и драйвер должен завершить транзакцию DMA. Как правило, драйвер еще не возвращается из функции обратного вызова EvtInterruptDpc . Таким образом, эта функция обратного вызова завершает транзакцию DMA следующим образом:
Вызов WdfObjectDelete для удаления объекта транзакции или вызов WdfDmaTransactionRelease , если драйвер повторно использует объекты транзакций DMA.
Вызов 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);
}
}