Menggunakan Sebar/Kumpulkan DMA

Driver yang melakukan DMA berbasis paket sistem atau bus dapat menggunakan rutinitas dukungan yang dirancang khusus untuk menyebarkan/mengumpulkan DMA. Alih-alih memanggil urutan rutinitas yang diuraikan dalam Menggunakan DMA Sistem Packet-Based dan DMA berbasis paket Bus-Master, driver dapat menggunakan GetScatterGatherList dan PutScatterGatherList.

Perangkat tidak perlu memiliki dukungan tersebar/kumpulkan bawaan agar drivernya menggunakan rutinitas ini.

Driver yang menggunakan DMA berbasis paket memanggil urutan umum rutinitas dukungan berikut untuk operasi sebar/kumpulkan:

  1. MmGetMdlVirtualAddress untuk mendapatkan indeks ke MDL, diperlukan sebagai parameter dalam panggilan ke GetScatterGatherList

  2. GetScatterGatherList ketika driver siap untuk memprogram perangkatnya untuk DMA dan membutuhkan pengontrol DMA sistem atau adaptor bus-master

    GetScatterGatherList mengalokasikan pengontrol DMA sistem atau adaptor bus-master, menentukan berapa banyak register peta yang diperlukan dan mengalokasikannya, mengisi daftar sebar/kumpulkan, dan memanggil rutinitas AdapterListControl driver ketika pengontrol DMA atau adaptor dan register peta tersedia.

  3. PutScatterGatherList segera setelah semua data yang diminta telah ditransfer atau driver gagal IRP karena kesalahan I/O perangkat

    PutScatterGatherList membersihkan buffer adaptor, membebaskan daftar peta, dan membebaskan daftar sebar/kumpulkan. Driver harus memanggil PutScatterGatherList sebelum dapat mengakses data di buffer.

Penunjuk objek adaptor yang dikembalikan oleh IoGetDmaAdapter adalah parameter yang diperlukan untuk masing-masing rutinitas ini kecuali MmGetMdlVirtualAddress, yang memerlukan penunjuk ke MDL di Irp-MdlAddress>.

Rutinitas GetScatterGatherList mencakup panggilan ke AllocateAdapterChannel dan MapTransfer, sehingga driver tidak perlu melakukan panggilan ini. Rutinitas mengambil yang berikut sebagai parameter:

  • Penunjuk ke struktur DMA_ADAPTER yang dikembalikan oleh IoGetDmaAdapter

  • Penunjuk ke objek perangkat target untuk operasi DMA

  • Penunjuk ke MDL yang menjelaskan buffer di Irp-MdlAddress>

  • Penunjuk ke alamat virtual saat ini di buffer yang dijelaskan oleh Mdl

  • Jumlah byte yang akan dipetakan

  • Penunjuk ke rutinitas AdapterListControl yang melakukan transfer

  • Penunjuk ke area konteks yang ditentukan driver untuk diteruskan ke rutinitas AdapterListControl

  • Nilai Boolean: TRUE untuk transfer ke perangkat; FALSE jika tidak

Setelah menentukan jumlah register peta yang diperlukan, mengalokasikan saluran adaptor dan register peta, mengisi daftar sebar/kumpulkan dan mempersiapkan transfer, GetScatterGatherList memanggil rutinitas AdapterListControl yang disediakan driver. Rutinitas AdapterListControl dijalankan dalam konteks utas arbitrer di IRQL = DISPATCH_LEVEL.

AdapterListControl rutin memasok driver dalam panggilan ke GetScatterGatherList berbeda dari rutinitas AdapterControl yang diteruskan ke AllocateAdapterChannel dalam hal-hal penting berikut:

  • Rutinitas AdapterListControl tidak memiliki nilai pengembalian, sedangkan rutinitas AdapterControl mengembalikan IO_ALLOCATION_ACTION.

  • Daripada penunjuk ke MapRegisterBase untuk register peta yang dialokasikan sistem, parameter ketiga ke rutinitas AdapterListControl alih-alih menunjuk ke struktur SCATTER_GATHER_LIST di mana driver dapat melakukan DMA.

  • Rutinitas AdapterListControl melakukan subset tugas yang diperlukan dalam rutinitas AdapterControl .

    Rutinitas AdapterListControl tidak memanggil AllocateAdapterChannel atau MapTransfer. Satu-satunya tanggung jawabnya adalah menyimpan penunjuk daftar sebar/kumpulkan input, menyiapkan perangkatnya, dan menggunakan daftar sebar/kumpulkan untuk melakukan DMA.

Struktur daftar sebar/kumpulkan mencakup array SCATTER_GATHER_ELEMENT dan jumlah elemen dalam array. Setiap elemen array menyediakan panjang dan memulai alamat fisik dari wilayah sebar/kumpulkan yang berdekatan secara fisik. Driver menggunakan panjang dan alamat dalam transfer data.

Driver dapat menggunakan GetScatterGatherList terlepas dari apakah perangkatnya mendukung DMA sebar/kumpulkan. Untuk perangkat yang tidak mendukung DMA sebar/kumpulkan, daftar sebar/kumpulkan hanya akan berisi satu elemen.

Menggunakan rutinitas sebar/kumpulkan dapat meningkatkan performa melalui panggilan AllocateAdapterChannel (seperti yang dijelaskan sebelumnya dalam Menggunakan DMA Sistem Packet-Based dan Menggunakan DMA Packet-Based Bus-Master). Tidak seperti panggilan ke AllocateAdapterChannel, lebih dari satu panggilan ke GetScatterGatherList dapat diantrekan untuk objek perangkat kapan saja. Driver dapat memanggil GetScatterGatherList lagi untuk operasi DMA lain pada objek driver yang sama sebelum rutinitas AdapterListControl selesai.

Saat kembali dari rutinitas AdapterListControl yang disediakan driver, GetScatterGatherList menyimpan register peta tetapi membebaskan struktur adaptor DMA.

Ketika driver telah memenuhi permintaan transfer IRP saat ini atau harus gagal IRP karena kesalahan I/O perangkat atau bus, driver harus memanggil PutScatterGatherList sebelum dapat mengakses data yang ditransfer di buffer. PutScatterGatherList membersihkan buffer adaptor dan membebaskan daftar peta dan menyebarkan/mengumpulkan daftar.