WDM Power IRP 講解 (一)

    xuexi 居然不能發???

    電源管理是WDM驅動的一個重點和難點,需要處理好,否則在測試、使用過程中很容易出現各種異常。最嚴重的就是 bug check 0x9F 相關的各種BSOD。

這裏簡單介紹下,power Irp包括兩類,一類是系統狀態相關power Irp(system-irp),另一類是設備狀態相關power Irp(device-irp)。我們在Driver Entry中註冊的dispatch可以接受上述system-irp和device-irp。本文下面提到的system-irp/device-irp都是指system power irp/device power irp。

    本節只介紹下面四種power相關Irp,包括 IRP_MN_QUERY_POWER System-Irp,IRP_MN_QUERY_POWER Device-Irp,IRP_MN_SET_POWER System-Irp,IRP_MN_SET_POWER Device-Irp。

    上述四種power相關Irp,系統在轉換power state時會首先下發system-Irp,設備的 function driver收到後,會產生一個與之對應的device-Irp,並通過系統下發到power dispatch。處理的流程是首先將system-Irp設置爲pending,在device-Irp處理完畢後,依據返回狀態設置system-Irp的status,再complete此 system-Irp。具體的處理流程可以參考後面的詳細介紹。

    上述四種power相關Irp可以依據不同的標準劃分,可以劃分爲system、device相關,還可以劃分爲 query、se、wakeup相關。本節只討論query、set相關的power Irp。這裏簡單描述下query和set的區別。Query通常是用於系統詢問設備,是否可以進入某種power狀態。Set通常在query之後發送,是系統明確要求設備進入某種power狀態。

    下面依據query、set的分類來描述下上述Irp的處理過程。


IRP_MN_QUERY_POWER :

1)    系統會下發IRP_MN_QUERY_POWER system-irp

2a)  Function Driver收到 IRP_MN_QUERY_POWER system-irp

-function driver設置I/O completion call back,以便在底層bus driver返回時做一些必要的處理

-function driver將此Irp繼續向底層driver發送

-function driver返回STATUS_PENDING

在底層bus driver處理完畢,complete此system-irp後,會call到上述的I/O completion call back A函數


2b) 2a)中提到的I/O completion call back A中需要請求Power Manager依據上述IRP_MN_QUERY_POWER system-irp的內容,發送一個IRP_MN_QUERY_POWER device-irp。在請求PM下發IRP_MN_QUERY_POWER device-irp的同時,設置completion call back B函數,同時返回STATUS_MORE_PROCESSING_REQUIRED。


2c) function driver收到IRP_MN_QUERY_POWER device-irp,可以complete with Success(可以允許device進入要求的狀態) or fail(禁止device進入要求的狀態)。

在這之後,系統會call到2b)中提到的completion call back B。


2d) 在completion call back B中將IRP_MN_QUERY_POWER system-irp的status設置爲IRP_MN_QUERY_POWER device-irp的status。同時complete IRP_MN_QUERY_POWER system-irp。


2c)中提到的允許/禁止系統進入想要進入的狀態並非always生效,在某些情況下系統可以不care這些result直接通過IRP_MN_SET_POWER來要求device進入相應的狀態。 


IRP_MN_SET_POWER :

3)    系統會下發IRP_MN_SET_POWER system-irp

4a)  Function Driver收到 IRP_MN_SET_POWER system-irp

-function driver設置I/O completion call back,以便在底層bus driver返回時做一些必要的處理

-function driver將此Irp繼續向底層driver發送

-function driver返回STATUS_PENDING

在底層bus driver處理完畢,complete此system-irp後,會call到上述的I/O completion call back C函數


4b) 4a)中提到的I/O completion call back A中需要請求Power Manager依據上述IRP_MN_SET_POWER system-irp的內容,發送一個IRP_MN_QUERY_POWER device-irp。在請求PM下發IRP_MN_SET_POWER device-irp的同時,設置completion call back D函數,同時返回STATUS_MORE_PROCESSING_REQUIRED。


4c) function driver收到IRP_MN_SET_POWER device-irp,需要明確Set power的state,確認是power-up還是power-down。


4c1) 如果是power-up irp,首先需要將此irp下發至底層bus driver,因爲device首先需要底層bus供電。除此之外,function driver還需要等待所有pending irp結束後方可開始操作。當然function driver不可以直接阻塞等待,因爲會影響到系統的運行。通常的做法是:

-function driver將此device-irp設置爲pending,並設置I/O completion call back E,在底層bus driver處理完畢後會call到此call back。之後將此irp下發至底層driver,並返回STATUS_PENDING,此時system-irp、device-irp都處於pending狀態

-在bus driver complete上述device-irp後,會call上述I/O completion call back E,此時function driver仍然需要等待之前處於pending的irp結束。由於在completion call back中無法死等,因此需要透過system work thread在PASSIVE_LEVEL來處理。可以設置一個workitem A,並返回STATUS_MORE_PROCESSING_REQUIRED。

-system worker thread會在PASSIVE_LEVEL調用上述workitem A,可以等待所有處於pending的irp結束後在返回。最終會complete上述device-irp。


4c2) 如果是power-down irp,function driver需要在下發此device-irp之前做一些必要的處理,因爲一旦bus driver斷電後,resume時所需的一些必要操作將變得不可訪問。

-function driver可以通過設置workitem B,並返回SSTATUS_PENDING。而在system worker thread PASSIVE_LEVEL中做一些必要的backup操作。

-system worker thread會在PASSIVE_LEVEL調用上述workitem B,在backup動作完成後,將此device-irp下發至底層driver。


4d) 在completion call back D中將IRP_MN_QUERY_POWER system-irp的status設置爲IRP_MN_QUERY_POWER device-irp的status。同時complete IRP_MN_QUERY_POWER system-irp。


sample可以參考WDK
WinDDK\7600.16385.1\src\general\toaster\wdm\func\featured1
發佈了67 篇原創文章 · 獲贊 12 · 訪問量 57萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章