Freigeben über


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;
}