Mengirim IRP_MN_QUERY_POWER atau IRP_MN_SET_POWER untuk Status Daya Perangkat

Pemilik kebijakan daya perangkat mengirim IRP daya kueri perangkat (IRP_MN_QUERY_POWER) untuk menentukan apakah driver yang lebih rendah dapat mengakomodasi perubahan status daya perangkat, dan IRP set-power perangkat (IRP_MN_SET_POWER) untuk mengubah status daya perangkat. (Driver ini juga dapat mengirim IRP tunggu/bangun untuk memungkinkan perangkatnya terbangun sebagai respons terhadap sinyal eksternal; lihat Perangkat Pendukung yang Memiliki Kemampuan Wake-Up untuk detailnya.)

Driver harus mengirim permintaan IRP_MN_QUERY_POWER ketika salah satu hal berikut ini benar:

  • Driver menerima IRP daya kueri sistem.

  • Driver sedang bersiap untuk menempatkan perangkat diam dalam keadaan tidur, jadi harus meminta driver yang lebih rendah untuk mengetahui apakah melakukannya layak.

Driver harus mengirim permintaan IRP_MN_SET_POWER ketika salah satu hal berikut ini benar:

  • Driver telah menentukan bahwa perangkat diam dan dapat ditidur.

  • Perangkat sedang tidur dan harus memasuki kembali status kerja untuk menangani I/O yang menunggu.

  • Driver menerima IRP set-power sistem.

Driver tidak boleh mengalokasikan IRP dayanya sendiri; manajer daya menyediakan rutinitas PoRequestPowerIrp untuk tujuan ini. Seperti yang dijelaskan Aturan untuk Menangani Runtime Integrasi Daya , PoRequestPowerIrp mengalokasikan dan mengirim IRP, dan dalam kombinasi dengan IoCallDriver (di Windows 7 dan Windows Vista), atau PoCallDriver (di Windows Server 2003, Windows XP, dan Windows 2000), memastikan bahwa semua permintaan daya disinkronkan dengan benar. Penelepon PoRequestPowerIrp harus berjalan di IRQL <= DISPATCH_LEVEL.

Berikut ini adalah prototipe untuk rutinitas ini:

NTSTATUS
PoRequestPowerIrp (
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR MinorFunction,
    IN POWER_STATE PowerState,
    IN PREQUEST_POWER_COMPLETE CompletionFunction,
    IN PVOID Context,
    OUT PIRP *Irp OPTIONAL
    );

Untuk mengirim IRP, driver memanggil PoRequestPowerIrp, menentukan pointer ke objek perangkat target di DeviceObject, kode IRP kecil IRP_MN_SET_POWER atau IRP_MN_QUERY_POWER di MinorFunction, nilai DevicePowerState di PowerState. Ketik, dan status daya perangkat di PowerState. Negara bagian. Di Windows 98/Me, DeviceObject harus menentukan PDO perangkat yang mendasar; di Windows 2000 dan versi Windows yang lebih baru, nilai ini dapat menunjuk ke PDO atau FDO driver di tumpukan perangkat yang sama.

Jika driver harus melakukan tugas tambahan setelah semua driver lain menyelesaikan IRP, driver harus meneruskan pointer ke fungsi penyelesaian daya dalam CompletionFunction. Manajer I/O memanggil CompletionFunction setelah memanggil semua rutinitas IoCompletion yang ditetapkan oleh driver saat mereka melewati IRP ke bawah tumpukan.

Setiap kali pemilik kebijakan daya perangkat mengirim IRP kueri daya perangkat, pemilik kebijakan tersebut kemudian harus mengirim IRP set-power perangkat dari rutinitas panggilan balik (CompletionFunction) yang ditentukan dalam panggilan ke PoRequestPowerIrp. Jika kueri berhasil, IRP set-power menentukan status daya yang dikueri. Jika kueri gagal, set-power IRP menegaskan kembali status daya perangkat saat ini. Menegaskan kembali status saat ini penting karena driver mengantrekan I/O sebagai respons terhadap kueri; pemilik kebijakan harus mengirim IRP set-power untuk memberi tahu driver di tumpukan perangkatnya untuk mulai memproses permintaan I/O yang diantrekan.

Perlu diingat bahwa pemilik kebijakan untuk perangkat tidak hanya mengirim IRP daya perangkat tetapi juga menangani IRP saat diteruskan ke tumpukan perangkat. Oleh karena itu, driver seperti itu sering menetapkan rutinitas IoCompletion (dengan IoSetCompletionRoutine) sebagai bagian dari kode penanganan IRP-nya, terutama ketika perangkat menyala. Rutinitas IoCompletion dipanggil secara berurutan dengan rutinitas IoCompletion yang ditetapkan oleh driver lain dan sebelum CompletionFunction. Untuk informasi selengkapnya, lihat Rutinitas IoCompletion untuk Runtime integrasi Daya Perangkat.

Karena IRP telah diselesaikan oleh semua driver ketika CompletionFunction dipanggil, CompletionFunction tidak boleh memanggil IoCallDriver, PoCallDriver, atau PoStartNextPowerIrp dengan IRP asalnya. (Namun, mungkin, memanggil rutinitas ini untuk IRP daya yang berbeda.) Sebaliknya, rutinitas ini melakukan tindakan tambahan yang diperlukan oleh driver yang berasal dari IRP. Jika driver mengirim IRP perangkat sebagai respons terhadap IRP sistem, CompletionFunction mungkin menyelesaikan IRP sistem. Untuk informasi selengkapnya, lihat Menangani Sistem Set-Power IRP di Pemilik Kebijakan Daya Perangkat.

Menanggapi panggilan ke PoRequestPowerIrp, manajer daya mengalokasikan IRP daya dan mengirimkannya ke bagian atas tumpukan perangkat untuk perangkat. Manajer daya mengembalikan penunjuk ke IRP yang dialokasikan.

Jika tidak ada kesalahan yang terjadi, PoRequestPowerIrp mengembalikan STATUS_PENDING. Status ini berarti bahwa IRP telah berhasil dikirim dan tertunda penyelesaiannya. Panggilan gagal jika manajer daya tidak dapat mengalokasikan IRP atau jika pemanggil telah menentukan kode IRP daya minor yang tidak valid.

Permintaan untuk menyalakan perangkat harus ditangani terlebih dahulu oleh driver bus yang mendasar untuk perangkat dan kemudian oleh setiap driver yang berturut-turut lebih tinggi di tumpukan. Oleh karena itu, saat mengirim permintaan PowerDeviceD0 , driver harus memastikan bahwa CompletionFunction melakukan tugas yang diperlukan setelah IRP selesai dan perangkat dinyalakan.

Saat mematikan perangkat (PowerDeviceD3), setiap driver di tumpukan perangkat harus menyimpan semua konteks yang diperlukan dan melakukan pembersihan yang diperlukan sebelum mengirim IRP ke driver yang lebih rendah berikutnya. Sejauh mana informasi konteks dan pembersihan tergantung pada jenis driver. Driver fungsi harus menyimpan konteks perangkat keras; driver filter mungkin perlu menyimpan konteks perangkat lunaknya sendiri. CompletionFunction yang diatur dalam situasi ini dapat mengambil tindakan yang terkait dengan IRP daya yang telah selesai, tetapi driver tidak dapat mengakses perangkat.