Praktik Terbaik: Menggunakan URL

Topik ini menjelaskan praktik terbaik untuk driver klien untuk mengalokasikan, membangun, dan mengirim URB ke tumpukan driver USB yang disertakan dengan Windows 8.

Windows 8 menyertakan tumpukan driver USB baru untuk mendukung perangkat Universal Serial Bus (USB) 3.0. Tumpukan driver USB 3.0 baru mengimplementasikan beberapa kemampuan baru, sesuai spesifikasi USB 3.0. Selain itu, tumpukan driver mencakup kemampuan lain yang memungkinkan driver klien untuk melakukan tugas umum secara efisien. Misalnya, tumpukan driver baru menerima MDL berantai yang memungkinkan driver klien mengirim buffer transfer di halaman yang tidak berdampingan dalam memori fisik.

Sebelum driver klien dapat menggunakan kemampuan baru tumpukan driver USB untuk Windows 8, driver harus mendaftarkan dirinya dengan tumpukan driver USB yang mendasar yang dimuat oleh Windows untuk perangkat. Untuk mendaftarkan driver klien, panggil USBD_CreateHandle dan tentukan versi kontrak. Jika driver klien dimaksudkan untuk membangun, menjalankan, dan menggunakan peningkatan dan kemampuan baru pada Windows 8, versi kontrak klien USBD_CLIENT_CONTRACT_VERSION_602.

Untuk driver klien versi USBD_CLIENT_CONTRACT_VERSION_602, tumpukan driver USB mengasumsikan bahwa driver klien sesuai dengan serangkaian aturan berikut:

Tumpukan driver USB melakukan validasi pada permintaan yang diterima dan menangani pelanggaran jika memungkinkan. Kegagalan untuk melakukannya dapat menyebabkan perilaku yang tidak ditentukan.

Jangan mengirim permintaan I/O dengan menggunakan handel pipa basi atau tidak valid

Driver klien tidak boleh menggunakan handel pipa kedaluarsa untuk mengirim permintaan I/O ke tumpukan driver USB. Handel pipa kedaluarsa mengacu pada handel pipa yang diperoleh dalam permintaan untuk memilih konfigurasi, antarmuka, atau pengaturan alternatif yang tidak lagi dipilih di perangkat. Untuk menghindari handel pipa kedaluarsa, setiap kali driver klien memilih konfigurasi atau antarmuka, driver harus menyegarkan cache handel pipanya (biasanya disimpan dalam konteks perangkat). Kondisi balapan tertentu juga dapat mengakibatkan handel pipa kedaluarsa. Misalnya, driver klien mengirim permintaan I/O dengan menggunakan handel pipa pada antarmuka yang dipilih. Sebelum permintaan selesai, driver klien memilih pengaturan alternatif yang tidak menggunakan titik akhir yang sama yang terkait dengan handel pipa yang digunakan. Kedua permintaan yang tertunda tersebut dapat menyebabkan kondisi perlombaan membuat handel pipa tidak valid.

Alokasikan URL dengan memanggil rutinitas alokasi di Windows 8

Windows 8 menyediakan rutinitas baru untuk mengalokasikan, membangun, dan merilis Blok Permintaan USB (URL). Untuk mengalokasikan URB, driver klien Windows Driver Model (WDM) harus selalu menggunakan rutinitas baru yang diperlihatkan dalam daftar berikut:

Rutinitas dalam daftar sebelumnya mungkin melampirkan konteks URB buram ke URB yang dialokasikan untuk meningkatkan pelacakan dan pemrosesan. Driver klien tidak dapat melihat atau mengubah konten konteks URB. Untuk informasi selengkapnya tentang alokasi URB di Windows 8, lihat Mengalokasikan dan Membangun URL.

Jika driver klien Windows Driver Framework (WDF) yang mengidentifikasi versinya sebagai USBD_CLIENT_CONTRACT_VERSION_602 selama pendaftaran (lihat WdfUsbTargetDeviceCreateWithParameters), tumpukan driver USB mengharapkan driver klien mengalokasikan memori untuk URB dengan memanggil WdfUsbTargetDeviceCreateUrb baru.

Jangan gunakan kembali URL aktif yang terkait dengan permintaan yang tertunda

Tumpukan driver USB sengaja melakukan pemeriksaan bug jika mendeteksi bahwa URB aktif yang telah dikirim ulang sebelum permintaan yang terkait dengan URB. URB aktif selama permintaan tertunda, dan rutinitas penyelesaian IRP driver klien belum dipanggil. Jangan lakukan tugas berikut pada URB aktif.

  • Jangan mengirim ulang URB aktif untuk permintaan lain (kaitkan URB dengan IRP lain).
  • Jangan ubah isi URB aktif.
  • Jangan membebaskan URB aktif.

Setelah rutinitas penyelesaian driver klien dipanggil, driver dapat mengirim ulang URL untuk jenis permintaan tertentu dalam rutinitas penyelesaian. Aturan berikut berlaku untuk pengiriman ulang:

  • Driver klien tidak boleh menggunakan kembali URB yang dialokasikan oleh USBD_SelectConfigUrbAllocateAndBuild untuk semua jenis permintaan selain permintaan konfigurasi pilih untuk memilih konfigurasi yang sama.

  • Driver klien tidak boleh menggunakan kembali URB yang dialokasikan oleh USBD_SelectInterfaceUrbAllocateAndBuild untuk semua jenis permintaan selain permintaan antarmuka-pilih untuk memilih pengaturan alternatif yang sama dalam antarmuka. Misalnya, lihat Komentar di USBD_SelectInterfaceUrbAllocateAndBuild.

  • URB yang dialokasikan oleh USBD_IsochUrbAllocate harus digunakan kembali hanya untuk permintaan transfer isochronous. Sebaliknya, URB yang dialokasikan untuk jenis permintaan I/O lainnya (kontrol, massal, atau interupsi) tidak boleh digunakan untuk permintaan isochronous.

    Misalnya, driver klien mengalokasikan dan membangun struktur URB untuk permintaan transfer massal. Driver klien juga ingin mengirim data ke titik akhir isochronous di perangkat. Setelah permintaan transfer massal selesai, driver klien tidak boleh memformat ulang dan mengirimkan URB untuk permintaan isochronous. Itu karena URB yang terkait dengan permintaan isochronous, memiliki panjang variabel tergantung pada jumlah paket. Selain itu, paket diperlukan untuk memulai dan mengakhiri batas bingkai. URB yang dialokasikan (untuk transfer massal) mungkin tidak sesuai dengan tata letak buffer yang diperlukan untuk transfer isochronous dan permintaan mungkin gagal.

  • URB yang dialokasikan oleh USBD_UrbAllocate tidak boleh digunakan kembali untuk isochronous, select-configuration, atau select-interface request. URB dapat digunakan kembali untuk memilih konfigurasi NULL untuk menonaktifkan konfigurasi yang dipilih di perangkat. URB tidak boleh aktif dan driver klien harus memformat ulang URB dengan memanggil makro UsbBuildSelectConfigurationRequest dan meneruskan NULL dalam parameter ConfigurationDescriptor .

  • Sebelum mengirim ulang URB, driver klien harus memformat ulang URB dengan menggunakan makro UsbBuildXxx yang sesuai yang ditentukan untuk jenis permintaan. Penting bagi driver untuk memformat URB, karena tumpukan USB mungkin telah mengubah beberapa kontennya.

    Misalnya, driver memanggil UsbBuildInterruptOrBulkTransferRequest untuk menginisialisasi URB untuk permintaan transfer massal (lihat _URB_BULK_OR_INTERRUPT_TRANSFER). Jika driver menginisialisasi anggota TransferBufferMDL dari struktur URB ke NULL, tumpukan driver USB menggunakan buffer transfer, yang ditentukan TransferBuffer, untuk bertukar data dengan perangkat alih-alih MDL. Namun, secara internal, tumpukan driver USB mungkin membuat MDL, menyimpan pointer ke MDL di TransferBufferMDL, dan menggunakan MDL untuk meneruskan data ke tumpukan. Meskipun tumpukan driver USB membebaskan memori MDL, TransferBufferMDL mungkin bukan NULL ketika driver klien memproses URB dalam rutinitas penyelesaian. Untuk memastikan bahwa anggota URB diformat dengan benar, driver harus memanggil UsbBuildInterruptOrBulkTransferRequest lagi untuk memformat ulang URB sebelum mengirimkan permintaan,

Jangan gunakan periode polling yang lebih besar dari 8 untuk transfer isochronous berkecepatan tinggi dan SuperSpeed

Tumpukan driver USB mendukung kecepatan tinggi dan pipa isochronous SuperSpeed dengan nomor periode polling 1, 2, 4, atau 8. Driver klien tidak boleh mengirim IO ke titik akhir yang memiliki periode lebih besar dari 8. Melakukannya dapat menyebabkan bugcheck.

Pastikan jumlah paket isochronous yang merupakan kelipatan dari jumlah paket per bingkai

Untuk transfer isochronous berkecepatan tinggi dan SuperSpeed, jumlah paket isochronous per bingkai dihitung sebagai periode 8 /polling. Driver klien harus memastikan bahwa nilai NumberOfPackets yang ditentukan dalam URB (lihat _URB_ISOCH_TRANSFER) adalah kelipatan jumlah paket per bingkai.

Tumpukan driver USB tidak mendukung URB transfer isochronous di mana NumberOfPackets bukan kelipatan jumlah paket per bingkai.

Memanggil rutinitas di tingkat IRQL yang didokumenkan

Jika Anda mendaftarkan driver klien Anda dengan USBD_CLIENT_CONTRACT_VERSION_602 sebagai versi kontrak, tumpukan driver USB mengasumsikan bahwa driver klien mengirim permintaan pada tingkat IRQL yang sesuai. Jika driver klien mengirim permintaan di DISPATCH_LEVEL, yang harus dikirim pada PASSIVE_LEVEL. Setelah menerima permintaan, dalam beberapa kasus, tumpukan driver USB memvalidasi nilai IRQL dan gagal dalam permintaan. Namun, dalam kasus lain, tumpukan driver USB mungkin menghasilkan bugcheck.

Mengirim Permintaan ke Perangkat USB