Bagikan melalui


Memulai Transaksi DMA

[Berlaku untuk KMDF saja]

Setelah driver Anda membuat dan menginisialisasi transaksi DMA, driver dapat memanggil metode WdfDmaTransactionExecute untuk memulai transaksi. Metode ini membangun daftar sebar/kumpulkan untuk transfer DMA pertama yang terkait dengan transaksi. Selanjutnya, metode memanggil fungsi panggilan balik EvtProgramDma yang didaftarkan driver untuk transaksi. Fungsi panggilan balik memprogram perangkat keras DMA untuk memulai transfer.

Sebelum driver Anda memanggil WdfDmaTransactionExecute, driver harus menyimpan handel transaksi DMA sehingga dapat diambil nanti ketika driver menyelesaikan setiap transfer DMA yang terkait dengan transaksi. Tempat yang baik untuk menyimpan handel transaksi berada dalam memori konteks objek kerangka kerja, biasanya objek perangkat kerangka kerja perangkat. Untuk informasi selengkapnya tentang menggunakan memori konteks objek, lihat Ruang Konteks Objek Kerangka Kerja.

Contoh kode berikut dari sampel PLX9x5x menunjukkan cara menginisialisasi lalu menjalankan transaksi DMA. Kode ini muncul dalam 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;
}