Bagikan melalui


Pengoperan Power IRPs

IRP Daya harus diteruskan ke seluruh tumpukan perangkat hingga ke PDO untuk memastikan bahwa transisi daya dikelola dengan baik. Driver menangani IRP yang mengurangi daya perangkat saat IRP turun ke dalam tumpukan perangkat. Driver menangani IRP yang menerapkan daya perangkat dalam rutinitas IoCompletion saat IRP berjalan kembali ke atas tumpukan perangkat.

Gambar berikut menunjukkan langkah-langkah yang perlu diambil driver untuk melewati IRP daya ke tumpukan perangkat di Windows 7 dan Windows Vista.

diagram yang mengilustrasikan penerusan power IRP di Windows Vista.

Seperti yang ditunjukkan oleh gambar sebelumnya, di Windows 7 dan Windows Vista, driver harus melakukan hal berikut:

  1. Panggil IoCopyCurrentIrpStackLocationToNext jika mengatur rutinitas IoCompletion , atau IoSkipCurrentIrpStackLocation jika tidak mengatur rutinitas IoCompletion .

    Kedua rutinitas ini mengatur lokasi tumpukan IRP untuk driver di bawahnya. Menyalin lokasi tumpukan saat ini memastikan bahwa penunjuk tumpukan IRP diatur ke lokasi yang benar saat rutinitas IoCompletion dijalankan.

    Jika driver yang buruk perancangannya membuat kesalahan dengan memanggil IoSkipCurrentIrpStackLocation dan kemudian menetapkan rutin penyelesaian, driver ini mungkin menimpa rutin penyelesaian yang diatur oleh driver di lapisan bawahnya.

  2. Panggil IoSetCompletionRoutine untuk mengatur rutinitas IoCompletion , jika diperlukan rutinitas lengkap.

  3. Panggil IoCallDriver untuk meneruskan IRP ke driver berikutnya yang lebih rendah di tumpukan.

Gambar berikut menunjukkan langkah-langkah yang perlu diambil oleh pengemudi untuk mengoper IRP daya ke dalam tumpukan perangkat di Windows Server 2003, Windows XP, dan Windows 2000.

meneruskan power irp (windows server 2003, windows xp, dan windows 2000).

Seperti yang ditunjukkan oleh gambar sebelumnya, driver harus melakukan hal berikut:

  1. Tergantung pada jenis driver, mungkin memanggil PoStartNextPowerIrp. Untuk informasi selengkapnya, lihat Memanggil PoStartNextPowerIrp.

  2. Panggil IoCopyCurrentIrpStackLocationToNext jika mengatur rutinitas IoCompletion , atau IoSkipCurrentIrpStackLocation jika tidak mengatur rutinitas IoCompletion .

    Kedua rutin ini menetapkan lokasi tumpukan IRP untuk driver tingkat lebih rendah berikutnya. Menyalin lokasi tumpukan saat ini memastikan bahwa penunjuk tumpukan IRP diatur ke lokasi yang benar saat rutinitas IoCompletion berjalan.

  3. Panggil IoSetCompletionRoutine untuk mengatur rutinitas IoCompletion . Dalam rutinitas IoCompletion , sebagian besar driver memanggil PoStartNextPowerIrp untuk menunjukkan bahwa ia siap untuk menangani IRP daya berikutnya.

  4. Panggil PoCallDriver untuk meneruskan IRP ke driver berikutnya yang lebih rendah di tumpukan.

    Driver harus menggunakan PoCallDriver, bukan IoCallDriver (seperti untuk IRP lainnya) untuk memastikan bahwa sistem menyinkronkan RUN daya dengan benar. Untuk informasi selengkapnya, lihat Memanggil IoCallDriver vs. Memanggil PoCallDriver.

Ingatlah bahwa rutinitas IoCompletion dapat dipanggil di IRQL = DISPATCH_LEVEL. Oleh karena itu, jika driver memerlukan pemrosesan tambahan di IRQL = PASSIVE_LEVEL setelah driver tingkat bawah selesai dengan IRP, rutinitas penyelesaian driver harus mengantre item kerja dan kemudian mengembalikan STATUS_MORE_PROCESSING_REQUIRED. Utas pekerja harus menyelesaikan IRP.

Di Windows 98/Me, driver harus menyelesaikan permintaan daya IRP pada IRQL = PASSIVE_LEVEL.

Jangan Ubah Kode Fungsi dalam Power IRP

Selain aturan biasa yang mengatur pemrosesan IRP, IRP_MJ_POWER IRP memiliki persyaratan khusus berikut: Driver yang menerima IRP terkait daya tidak boleh mengubah kode fungsi utama dan minor di lokasi tumpukan I/O mana pun dalam IRP yang telah ditetapkan oleh pengelola daya atau oleh driver tingkat yang lebih tinggi. Manajer daya mengandalkan kode fungsi ini agar tetap tidak berubah sampai IRP selesai. Pelanggaran aturan ini dapat menyebabkan masalah yang sulit di-debug. Misalnya, sistem operasi mungkin berhenti merespons, atau "macet."

Jangan Memblokir Saat Menangani Power IRP

Pengemudi tidak boleh menyebabkan penundaan lama saat menangani IRP daya.

Saat meneruskan IRP daya, driver harus kembali dari rutinitas DispatchPower sesegera mungkin setelah memanggil IoCallDriver (di Windows 7 dan Windows Vista) atau PoCallDriver (di Windows Server 2003, Windows XP, dan Windows 2000). Driver tidak boleh menunggu kejadian kernel atau menunda sebelum kembali. Jika driver tidak dapat menangani IRP daya dalam waktu yang singkat, driver sebaiknya mengembalikan STATUS_PENDING dan mengantrekan semua IRP masuk sampai IRP daya selesai. (Perhatikan bahwa perilaku ini berbeda dari IRP PnP dan rutinitas DispatchPnP , yang diizinkan untuk memblokir.)

Jika driver harus menunggu aksi daya oleh driver lain yang berada lebih jauh ke bawah dalam tumpukan perangkat, driver harus mengembalikan STATUS_PENDING dari rutinitas DispatchPower dan harus mengatur rutinitas IoCompletion untuk IRP daya. Driver dapat melakukan tugas apa pun yang diperlukan dalam rutinitas IoCompletion , lalu memanggil PoStartNextPowerIrp (Hanya Windows Server 2003, Windows XP, dan Windows 2000) dan IoCompleteRequest.

Misalnya, pemilik kebijakan daya untuk perangkat biasanya mengirim IRP daya perangkat sambil menahan IRP daya sistem untuk mengatur status daya perangkat yang sesuai untuk status daya sistem yang diminta.

Dalam situasi ini, pemilik kebijakan daya harus menetapkan rutinitas IoCompletion dalam IRP daya sistem, meneruskan IRP daya sistem ke driver yang lebih rendah berikutnya, dan mengembalikan STATUS_PENDING dari rutinitas DispatchPower-nya .

Dalam rutinitas IoCompletion , ia memanggil PoRequestPowerIrp untuk mengirim IRP daya perangkat, meneruskan pointer ke rutinitas panggilan balik dalam permintaan. Rutinitas IoCompletion harus mengembalikan STATUS_MORE_PROCESSING_REQUIRED.

Akhirnya, driver memproses lebih lanjut paket permintaan I/O dari rutinitas panggilan balik. Seorang driver tidak boleh menunggu peristiwa kernel dalam rutinitas DispatchPower dan memberikan sinyal dengan rutinitas IoCompletion untuk IRP yang sedang ditangani; kebuntuan sistem mungkin terjadi. Untuk informasi selengkapnya, lihat Menangani Sistem Set-Power IRP di Pemilik Kebijakan Daya Perangkat.

Dalam situasi yang sama, ketika sistem akan tidur, pemilik kebijakan daya mungkin perlu menyelesaikan beberapa I/O yang tertunda sebelum mengirim IRP perangkat untuk mematikan perangkatnya. Daripada memberi sinyal peristiwa ketika I/O selesai dan menunggu pada rutinitas DispatchPower, driver harus mengantre item kerja dan mengembalikan STATUS_PENDING dari rutinitas DispatchPower. Di utas pekerja, ia menunggu I/O selesai dan kemudian mengirim IRP daya perangkat. Untuk informasi selengkapnya, lihat IoAllocateWorkItem.