Cara mengirim struktur MDL berantai

Artikel ini menjelaskan kemampuan MDL berantai di tumpukan driver USB, dan bagaimana driver klien dapat mengirim buffer transfer sebagai rantai struktur MDL .

Sebagian besar pengontrol host USB mengharuskan buffer transfer menjadi hampir berdampingan. Hampir berdekatan berarti bahwa buffer dapat dimulai dan berakhir di mana saja di halaman tetapi sisa buffer harus dimulai dan diakhir pada batas halaman. Banyak driver klien USB yang dapat memenuhi persyaratan tersebut. Namun, untuk driver klien tertentu, terutama yang perlu menambahkan atau menghapus data tambahan ke atau dari buffer, mengalokasikan memori yang hampir berdekatan untuk buffer transfer tidak lebih disukai.

Misalnya, pertimbangkan tumpukan jaringan tiga driver, driver protokol jaringan, driver perantara, dan driver miniport. Driver protokol memulai transfer dan mengirim paket ke driver berikutnya di tumpukan: driver perantara. Driver perantara ingin menambahkan header kustom (terkandung dalam blok memori terpisah) ke paket. Driver perantara mengirim header tersebut dan paket yang diterima, ke driver berikutnya di tumpukan: driver miniport. Driver miniport berinteraksi dengan tumpukan driver USB dan oleh karena itu harus menyiapkan buffer transfer yang hampir berdampingan. Untuk membuat buffer seperti itu, driver miniport mengalokasikan buffer besar, menambahkan header kustom, lalu menyalin payload. Karena payload biasanya besar, menyalin seluruh payload dapat berdampak signifikan pada performa.

Driver klien dapat mengatasi dampak performa tersebut dengan mengirim buffer transfer sebagai rantai daftar deskriptor memori (MDL). Tumpukan driver USB baru di Windows 8, mampu menerima MDL berantai (lihat MDL) dari driver klien. Dengan menyediakan MDL berantai, driver klien dapat mereferensikan halaman yang tidak berdampingan dalam memori alih-alih melakukan operasi salin asing. Kemampuan ini menghapus pembatasan pada jumlah, ukuran, dan penyelarasan buffer, memungkinkan buffer transfer disegmentasi dalam memori fisik.

Untuk menggunakan MDL berantai, driver klien harus mendeteksi apakah tumpukan driver USB yang mendasar, yang dimuat oleh Windows, mendukung kemampuan dan kemudian membangun rantai MDL dalam urutan yang tepat.

Sebelum memulai

Kemampuan MDL berantai hanya didukung untuk transfer massal, isochronous, dan interupsi. Sebelum Anda meminta kemampuan MDL berantai, pastikan driver klien Anda memiliki handel USBD untuk pendaftaran driver dengan tumpukan driver USB. Untuk membuat handel USBD, panggil USBD_CreateHandle. Biasanya, driver klien membuat handel USBD dalam rutinitas AddDevice-nya .

Anda dapat mengkueri kemampuan MDL berantai di handler IRP_MN_START_DEVICE driver klien atau kapan saja nanti. Driver klien tidak boleh meminta kemampuan ini dalam rutinitas AddDevice-nya .

Petunjuk

  1. Panggil rutinitas USBD_QueryUsbCapability untuk menentukan apakah tumpukan driver USB mendukung kemampuan MDL berantai. Untuk mengkueri kemampuan tersebut, tentukan UsbCapabilityChainedMdls sebagai GUID. Atur parameter OutputBuffer ke parameter NULL dan OutputBufferSize ke 0.

  2. Periksa nilai NTSTATUS yang dikembalikan oleh USBD_QueryUsbCapability dan evaluasi hasilnya. Jika rutinitas berhasil diselesaikan, kemampuan MDL berantai didukung. Nilai lain menunjukkan bahwa kemampuan tidak didukung.

  3. Buat rantai MDL. Setiap MDL memiliki pointer Berikutnya yang menunjuk ke MDL lain.

    Driver dapat membangun MDL rantai dengan mengatur pointer Berikutnya secara manual.

    Dalam contoh sebelumnya, driver protokol mengirim paket sebagai MDL. Driver perantara dapat membuat MDL lain yang mereferensikan blok memori dengan data header. Untuk membuat rantai, driver perantara dapat mengarahkan penunjuk Berikutnya MDL header ke MDL yang diterima dari driver protokol. Driver perantara kemudian dapat meneruskan rantai dua MDL ke driver miniport, yang memasok referensi ke MDL berantai dalam URB untuk permintaan dan mengirimkan permintaan ke tumpukan driver USB. Untuk informasi selengkapnya, lihat Menggunakan MDL.

  4. Saat membangun URB untuk permintaan I/O yang menggunakan MDL berantai, atur anggota TransferBufferMDL dari struktur URB terkait (seperti _URB_BULK_OR_INTERRUPT_TRANSFER atau _URB_ISOCH_TRANSFER) ke MDL pertama dalam rantai, dan atur TransferBufferLength ke jumlah total byte yang akan ditransfer. Data dapat mencakup lebih dari satu entri MDL dalam rantai MDL.

    Dalam Windows 8, dua jenis fungsi URB baru telah ditambahkan yang memungkinkan driver klien menggunakan MDL berantai untuk transfer data. Jika Anda ingin menggunakan kemampuan ini, pastikan bahwa atur anggota Fungsi header URB diatur ke salah satu fungsi URB berikut:

    • URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER_USING_CHAINED_MDL
    • URB_FUNCTION_ISOCH_TRANSFER_USING_CHAINED_MDL

    Untuk informasi tentang fungsi URB tersebut, lihat _URB_HEADER.

Keterangan

Untuk contoh kode yang meminta tumpukan driver USB yang mendasarinya untuk menentukan apakah tumpukan driver dapat menerima MDL berantai, lihat USBD_QueryUsbCapability.