處理裝置電源狀態的IRP_MN_SET_POWER
裝置組電源 IRP 會要求單一裝置的狀態變更,並傳送至裝置堆疊中的所有驅動程式。 這類 IRP 會在 I/O 堆疊位置的Power.Type成員中指定DevicePowerState。
當驅動程式向下移動堆疊時,驅動程式會處理關閉電源 IRP。 針對電源啟動 IRP,驅動程式會將 IoCompletion 常式設定為 IRP 向下移動堆疊,然後在 IOCompletion 常式中處理 IRP,因為 IRP 會備份堆疊。 一般裝置堆疊中的驅動程式會處理裝置集電源 IRP,如下所示:
大部分的篩選驅動程式都應該直接呼叫 IoMarkIrpPending、將 IRP 傳遞至下一個較低的驅動程式 (請參閱 傳遞 Power IRP) ,並從 DispatchPower 常式傳回STATUS_PENDING。 不過,某些篩選驅動程式可能必須先執行裝置特定工作,例如佇列傳入 IRP 或節省裝置電源狀態。
函式驅動程式會呼叫 IoMarkIrpPending、執行裝置特定工作 (例如完成擱置的 I/O 要求、佇列傳入 I/O 要求、儲存裝置內容或變更裝置電源) 、視需要設定 IoCompletion 常式,並將裝置電源 IRP 傳遞給下一個較低的驅動程式 (請參閱 傳遞 Power IRP) 。 它會從 其 DispatchPower 常式傳回STATUS_PENDING。
如果匯流排驅動程式能夠這麼做,請變更裝置電源,然後呼叫 PoSetPowerState 以通知電源管理員新的裝置電源狀態。 在 Windows Server 2003、Windows XP 和 Windows 2000 中,驅動程式也必須呼叫 PoStartNextPowerIrp ,以在設定電源狀態之後啟動下一個電源 IRP。 驅動程式接著會完成 IRP,並指定IO_NO_INCREMENT。 如果驅動程式無法立即完成 IRP,它會呼叫 IoMarkIrpPending、從其 DispatchPower 常式傳回STATUS_PENDING,稍後再完成 IRP。
即使目標裝置已處於要求的電源狀態,每個函式或篩選驅動程式都必須將 IRP 向下傳遞至下一個較低的驅動程式。 每個設定電源 IRP 都必須一路往下移動裝置堆疊,以完成它。
位於匯流排驅動程式上方的函式和篩選驅動程式不得使裝置集電源 IRP 失敗。 如果裝置已移除或正在移除,匯流排驅動程式可能會使裝置電源啟動 IRP 失敗。
驅動程式堆疊中的每個驅動程式 (函式、篩選和匯流排驅動程式) 都必須呼叫 PoSetPowerState ,以通知電源管理員其對應裝置物件的電源狀態變更。
就像與裝置電源啟動和關閉電源相關聯的其他驅動程式工作一樣,如果新狀態為 D0) ,或在裝置關閉電源 (之前,如果新狀態是任何其他狀態) ,則 呼叫 PoSetPowerState 必須發生于 (。
每個驅動程式都應該追蹤其裝置的電源狀態。 電源管理員不會將這項資訊提供給驅動程式。
處理裝置電源狀態 的IRP_MN_SET_POWER 要求時,驅動程式應該儘快從 DispatchPower 常式傳回。 驅動程式不得在其 DispatchPower 常式中等候處理相同 IRP 的程式碼發出訊號的核心事件。 因為電源 IRP 會在整個系統中同步處理,所以可能會發生死結。
為了確保最高層級的系統效能,特別是針對多媒體應用程式,驅動程式應該在中斷要求層級執行耗時的作業, (IRQL) 等於PASSIVE_LEVEL。 若要在 IRQL= PASSIVE_LEVEL執行作業,驅動程式可以使用 專用線程 或 系統背景工作執行緒。 如需優化多媒體平臺驅動程式效能的指導方針,請參閱 串流媒體裝置設計指南。
驅動程式必須採取才能處理電源 IRP 的確切步驟,取決於裝置是否啟動或關閉電源,如下列各節所述: