Mengoordinasikan Permintaan I/O dengan Status Daya Komponen

[Hanya berlaku untuk KMDF]

Driver KMDF untuk perangkat multi-komponen hanya boleh mengirim permintaan ke komponen yang dalam keadaan aktif. Biasanya, driver menetapkan antrean I/O ke komponen atau set komponen.

Pertimbangkan terlebih dahulu antrean yang ditetapkan ke satu komponen. Driver memulai antrean ketika komponen menjadi aktif dan menghentikan antrean ketika komponen menjadi menganggur. Dengan demikian, ketika KMDF memanggil handler permintaan untuk antrean, perangkat berada dalam status menyala sepenuhnya (D0), dan komponen yang diperlukan aktif. Handler permintaan dapat mengakses perangkat keras komponen dengan aman.

Konsep yang sama berlaku untuk antrean yang ditetapkan ke sekumpulan komponen. Dalam hal ini, driver memulai antrean ketika semua komponen dalam set aktif. Driver menghentikan antrean ketika salah satu komponen menjadi menganggur.

Topik ini menjelaskan bagaimana driver KMDF untuk perangkat multi-komponen mungkin menerapkan dukungan tersebut dalam situasi yang melibatkan beberapa jenis permintaan yang memerlukan kombinasi komponen yang berbeda.

Contoh

Untuk setiap jenis permintaan yang didukung oleh driver, identifikasi komponen yang diperlukan. Misalnya, pertimbangkan perangkat yang memiliki tiga komponen: 0, 1 dan 2, di mana driver menerima tiga jenis permintaan: A, B, dan C. Persyaratan komponen permintaan adalah sebagai berikut:

Jenis permintaan Komponen yang diperlukan
A 0,2
B 1
C 0,1,2

Dalam contoh ini, ada tiga set komponen yang berbeda, satu untuk setiap jenis permintaan. Driver menyediakan satu antrean I/O default yang dikelola daya untuk perangkat, serta satu antrean tambahan yang dikelola daya yang sesuai dengan setiap set komponen. Dalam contoh di atas, driver membuat satu antrean utama dan tiga antrean sekunder, satu sesuai dengan setiap set komponen. Konfigurasi antrean ini diperlihatkan dalam diagram berikut:

Diagram memperlihatkan implementasi antrean untuk perangkat multi-komponen dengan jenis permintaan A, B, dan C.

Driver mempertahankan bitmask untuk setiap set komponen. Setiap bit dalam bitmask mewakili status aktif/menganggur dari salah satu komponen. Jika bit diatur, komponen aktif. Jika bit dibersihkan, komponen diam.

Ketika permintaan tiba, handler permintaan untuk antrean tingkat atas menentukan komponen mana yang dibutuhkan permintaan dan memanggil PoFxActivateComponent untuk masing-masing. Handler permintaan kemudian meneruskan permintaan ke antrean I/O sekunder yang sesuai dengan set komponen tersebut.

Ketika komponen menjadi aktif, kerangka kerja manajemen daya (PoFx) memanggil rutinitas ComponentActiveConditionCallback driver. Dalam panggilan balik ini, driver mengatur bit yang sesuai dengan komponen yang ditentukan, di setiap bitmask tempat komponen tersebut diwakili. Jika semua bit dalam bitmask tertentu diatur, semua komponen dalam set yang sesuai aktif. Untuk setiap set komponen yang sepenuhnya aktif, driver memanggil WdfIoQueueStart untuk memulai antrean I/O sekunder yang sesuai.

Misalnya, pertimbangkan perangkat hipotetis di atas. Misalkan komponen 0 aktif, sementara komponen 1 dan 2 menganggur. Ketika komponen 2 menjadi aktif, PoFx memanggil rutinitas ComponentActiveConditionCallback komponen tersebut. Jenis permintaan A dan C menggunakan komponen 2, sehingga driver memanipulasi bitmasks untuk dua jenis permintaan ini. Karena semua bit di bitmask untuk permintaan jenis A sekarang diatur, driver memulai antrean untuk jenis permintaan A. Namun, tidak semua bit diatur untuk jenis permintaan C (komponen 1 masih menganggur). Driver tidak memulai antrean untuk jenis permintaan C.

Ketika antrean I/O sekunder dimulai, kerangka kerja mulai mengirimkan permintaan yang disimpan dalam antrean. Dalam penangan permintaan untuk antrean I/O sekunder, driver dapat memproses permintaan dengan aman karena komponen aktif dan referensi daya telah diambil pada komponen untuk setiap permintaan.

Ketika driver selesai memproses permintaan, driver memanggil PoFxIdleComponent untuk setiap komponen yang digunakan permintaan, lalu menyelesaikan permintaan. Ketika tidak ada lagi permintaan menggunakan komponen, kerangka kerja daya memanggil rutinitas ComponentIdleConditionCallback driver.

Dalam panggilan balik ini, driver menghapus bit yang sesuai dengan komponen yang ditentukan, di setiap bitmask tempat komponen tersebut diwakili. Jika bitmask tertentu menunjukkan bahwa komponen adalah yang pertama dalam set yang sesuai ke transisi ke kondisi menganggur, driver memanggil WdfIoQueueStop untuk menghentikan antrean I/O sekunder yang sesuai. Dengan demikian, driver memastikan bahwa antrean tidak mengirimkan permintaan kecuali semua komponen dalam set yang sesuai aktif.

Pertimbangkan lagi contoh di atas. Misalkan semua komponen aktif dan oleh karena itu semua antrean dimulai. Ketika komponen 1 menjadi menganggur, PoFx memanggil rutinitas ComponentIdleConditionCallback untuk komponen 1. Dalam panggilan balik ini, driver memanipulasi bitmasks untuk jenis permintaan B dan C karena mereka menggunakan komponen 1. Karena komponen 1 adalah komponen pertama yang menganggur untuk kedua jenis permintaan ini, driver menghentikan antrean untuk jenis permintaan B dan C.

Misalkan pada titik ini, komponen 0 menjadi menganggur. Dalam ComponentIdleConditionCallback untuk komponen 0, driver memanipulasi bitmask untuk jenis permintaan A dan C. Karena komponen 0 adalah komponen pertama yang menganggur untuk permintaan tipe A (komponen 2 masih aktif), driver menghentikan antrean untuk jenis permintaan A. Namun, untuk jenis permintaan C, komponen 0 bukan komponen pertama yang menganggur. Driver tidak menghentikan antrean untuk permintaan jenis C (melakukannya sebelumnya).

Untuk menggunakan teknik yang dijelaskan dalam contoh ini, driver juga harus mendaftarkan fungsi panggilan balik EvtIoCanceledOnQueue untuk setiap antrean sekundernya. Jika permintaan dibatalkan saat berada dalam antrean sekunder, driver dapat menggunakan panggilan balik ini untuk memanggil PoFxIdleComponent untuk setiap komponen yang sesuai. Melakukannya merilis referensi daya yang diambil handler permintaan ketika disebut PoFxActivateComponent sebelum meneruskan permintaan ke antrean sekunder.