Avvio di una transazione DMA
[Si applica solo a KMDF]
Dopo aver creato e inizializzato una transazione DMA, il driver può chiamare il metodo WdfDmaTransactionExecute per avviare la transazione. Questo metodo compila un elenco di dispersione/raccolta per il primo trasferimento DMA associato alla transazione. Successivamente, il metodo chiama la funzione di callback EvtProgramDma registrata per la transazione. La funzione di callback programma l'hardware DMA per avviare il trasferimento.
Prima che il driver chiami WdfDmaTransactionExecute, il driver deve archiviare l'handle di transazione DMA in modo che possa essere recuperato in seguito quando il driver completa ogni trasferimento DMA associato alla transazione. Un buon posto per archiviare l'handle delle transazioni è nella memoria del contesto di un oggetto framework, in genere l'oggetto del dispositivo framework del dispositivo. Per altre informazioni sull'uso della memoria del contesto dell'oggetto, vedere Framework Object Context Space.
Nell'esempio di codice seguente dell'esempio PLX9x5x5x viene illustrato come inizializzare e quindi eseguire una transazione DMA. Questo codice viene visualizzato nel file Read.c .
VOID PLxEvtIoRead(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PDEVICE_EXTENSION devExt;
// Get the DevExt from the queue handle
devExt = PLxGetDeviceContext(WdfIoQueueGetDevice(Queue));
do {
// Validate the Length parameter.
if (Length > PCI9656_SRAM_SIZE) {
status = STATUS_INVALID_BUFFER_SIZE;
break;
}
// Initialize the DmaTransaction.
status =
WdfDmaTransactionInitializeUsingRequest(
devExt->ReadDmaTransaction,
Request,
PLxEvtProgramReadDma,
WdfDmaDirectionReadFromDevice
);
if(!NT_SUCCESS(status)) {
. . . //Error-handling code omitted
break;
}
// Execute this DmaTransaction.
status = WdfDmaTransactionExecute( devExt->ReadDmaTransaction,
WDF_NO_CONTEXT);
if(!NT_SUCCESS(status)) {
. . . //Error-handling code omitted
break;
}
// Indicate that the DMA transaction started successfully.
// The DPC routine will complete the request when the DMA
// transaction is complete.
status = STATUS_SUCCESS;
} while (0);
// If there are errors, clean up and complete the request.
if (!NT_SUCCESS(status )) {
WdfDmaTransactionRelease(devExt->ReadDmaTransaction);
WdfRequestComplete(Request, status);
}
return;
}