Menyelesaikan Transfer DMA

[Hanya berlaku untuk KMDF]

Biasanya, fungsi panggilan balik EvtInterruptDpc driver Anda menyelesaikan pemrosesan setiap transfer DMA.

Pertama, karena beberapa transaksi DMA dapat berlangsung bersamaan, fungsi panggilan balik EvtInterruptDpc harus menentukan transaksi DMA mana yang terkait dengan transfer yang selesai. Fungsi panggilan balik dapat melakukan ini dengan mengambil handel transaksi yang disimpan driver saat memulai transaksi DMA. Untuk mengambil ekstensi perangkat, sampel PLX9x5x menentukan fungsi yang disebut PLxGetDeviceContext dalam file header Private.h-nya:

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_EXTENSION, PLxGetDeviceContext)

Kemudian, dalam panggilan balik EvtInterruptDpc driver, ia melakukan hal berikut:

WDFDMATRANSACTION   dmaTransaction;
PDEVICE_EXTENSION   devExt;
...
devExt  = PLxGetDeviceContext(WdfInterruptGetDevice(Interrupt));
...
dmaTransaction = devExt->WriteDmaTransaction;

Selanjutnya, fungsi panggilan balik EvtInterruptDpc harus menginformasikan kerangka kerja bahwa transfer selesai, dengan memanggil salah satu metode penyelesaian transfer berikut:

  • WdfDmaTransactionDmaCompleted, jika transfer berhasil diselesaikan dan perangkat keras tidak melaporkan jumlah byte yang ditransfer.

  • WdfDmaTransactionDmaCompletedWithLength, jika transfer berhasil diselesaikan dan perangkat keras melaporkan jumlah byte yang ditransfer (atau hitungan byte yang tidak ditransfer), atau jika driver mendeteksi kesalahan dan menentukan jumlah transfer nol untuk mencoba kembali transfer. Jika driver menentukan jumlah transfer nol, kerangka kerja mengurangi nol dari jumlah byte yang tersisa dan dengan demikian mengirim transfer yang sama ke fungsi panggilan balik EvtProgramDma .

  • WdfDmaTransactionDmaCompletedFinal, jika perangkat keras melaporkan kondisi underrun atau kegagalan.

Driver Anda dapat memanggil WdfDmaTransactionGetCurrentDmaTransferLength untuk mendapatkan panjang asli transfer yang telah selesai. Panggilan ini berguna jika perangkat Anda melaporkan hitungan byte yang tidak ditransfer, karena driver dapat mengurangi jumlah byte yang tidak ditransfer dari panjang transfer asli dan kemudian memanggil WdfDmaTransactionGetCurrentDmaTransferLength untuk melaporkan ukuran transfer aktual.

Setiap metode penyelesaian transfer sebelumnya menginformasikan kerangka kerja bahwa satu transfer DMA (bukan seluruh transaksi DMA) selesai. Setelah driver Anda memanggil salah satu metode ini, driver memeriksa nilai pengembalian metode untuk melihat apakah transaksi memerlukan lebih banyak transfer:

  • Jika nilai pengembalian metode penyelesaian adalah FALSE, kerangka kerja telah menentukan bahwa transfer DMA tambahan diperlukan untuk menyelesaikan pemrosesan transaksi DMA.

    Biasanya, fungsi panggilan balik EvtInterruptDpc driver hanya kembali. Kerangka kerja memanggil fungsi panggilan balik EvtProgramDma driver lagi, dan fungsi panggilan balik dapat memprogram perangkat keras untuk transfer berikutnya.

    Metode penyelesaian transfer memberikan nilai status, yang selalu STATUS_MORE_PROCESSING_REQUIRED dalam kasus ini.

  • Jika nilai yang dikembalikan TRUE, tidak ada lagi transfer yang akan terjadi untuk transaksi DMA.

    Metode penyelesaian transfer memberikan nilai status. Jika nilai status STATUS_SUCCESS, semua transfer untuk transaksi DMA selesai dan driver harus menyelesaikan transaksi DMA. Jika nilai status adalah hal lain, kesalahan terjadi dan transaksi DMA mungkin belum selesai.

Jika fungsi panggilan balik EvtInterruptDpc mendeteksi kesalahan, biasanya karena timer kedaluwarsa atau gangguan perangkat keras yang menandakan kesalahan transfer, driver dapat memulai ulang transfer transaksi saat ini.

Untuk memulai ulang transfer transaksi saat ini, fungsi panggilan balik EvtInterruptDpc driver dapat memanggil WdfDmaTransactionDmaCompletedWithLength dengan parameter TransferredLength diatur ke nol.