Starten einer DMA-Transaktion
[Gilt nur für KMDF]
Nachdem Ihr Treiber eine DMA-Transaktion erstellt und initialisiert hat, kann der Treiber die WdfDmaTransactionExecute-Methode aufrufen, um die Transaktion zu starten. Diese Methode erstellt eine Punkt-/Gather-Liste für die erste DMA-Übertragung , die der Transaktion zugeordnet ist. Als Nächstes ruft die Methode die Rückruffunktion EvtProgramDma auf, die der Treiber für die Transaktion registriert hat. Die Rückruffunktion programmiert die DMA-Hardware , um die Übertragung zu starten.
Bevor Ihr Treiber WdfDmaTransactionExecute aufruft, muss der Treiber das DMA-Transaktionshandle speichern, damit es später abgerufen werden kann, wenn der Treiber jede DMA-Übertragung abgeschlossen hat, die der Transaktion zugeordnet ist. Ein guter Ort zum Speichern des Transaktionshandles ist der Kontextspeicher eines Frameworkobjekts, in der Regel das Framework-Geräteobjekt des Geräts. Weitere Informationen zur Verwendung des Objektkontextspeichers finden Sie unter Framework Object Context Space.
Im folgenden Codebeispiel aus dem PLX9x5x-Beispiel wird gezeigt, wie eine DMA-Transaktion initialisiert und anschließend ausgeführt wird. Dieser Code wird in der Datei Read.c angezeigt.
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;
}