共用方式為


使用元件電源狀態協調 I/O 要求

[僅適用于 KMDF]

多元件裝置的 KMDF 驅動程式只能將要求傳送至處於作用中狀態的元件。 一般而言,驅動程式會將 I/O 佇列指派給元件或元件集合。

請考慮先將指派給單一元件的佇列。 驅動程式會在元件變成作用中時啟動佇列,並在元件閒置時停止佇列。 因此,當 KMDF 呼叫佇列的要求處理常式時,裝置會完全處於 (D0) 狀態,且必要的元件為作用中。 要求處理常式可以安全地存取元件硬體。

相同的概念適用于指派給一組元件的佇列。 在此情況下,驅動程式會在集合中的所有元件都處於作用中狀態時啟動佇列。 驅動程式會在任一元件閒置時停止佇列。

本主題描述多元件裝置的 KMDF 驅動程式如何在需要不同元件組合的多個要求類型的情況下實作這類支援。

範例

針對驅動程式支援的每個要求類型,請識別必要的元件。 例如,假設有三個元件的裝置:0、1 和 2,驅動程式會收到三種類型的要求:A、B 和 C。要求的元件需求如下:

要求類型 需要的元件
A 0,2
B 1
C 0,1,2

在此範例中,有三組不同的元件,每個要求類型各有一組。 驅動程式會為裝置提供一個預設的電源受控 I/O 佇列,以及一個對應至每個元件集的額外電源管理佇列。 在上述範例中,驅動程式會建立一個主要佇列和三個次要佇列,一個對應至每個元件集。 下圖顯示此佇列組態:

此圖顯示具有要求類型 A、B 和 C 之多元件裝置的佇列實作。

驅動程式會維護每個元件集的位元遮罩。 位元遮罩中的每個位都代表其中一個元件的使用中/閒置狀態。 如果設定位,則元件為使用中。 如果清除位,元件就會閒置。

當要求送達時,最上層佇列 的要求處理常式 會決定要求需要哪些元件,並為每個元件呼叫 PoFxActivateComponent 。 然後,要求處理常式會將要求轉送至對應至該元件集合的次要 I/O 佇列。

當元件變成作用中時,電源管理架構會 (PoFx) 呼叫驅動程式的 ComponentActiveConditionCallback 常式。 在此回呼中,驅動程式會在表示該元件的每個位元遮罩中,設定對應至指定元件的位。 如果已設定指定位元遮罩中的所有位,對應集內的所有元件都會作用中。 對於完全作用中的每個元件集,驅動程式會呼叫 WdfIoQueueStart 來啟動對應的次要 I/O 佇列。

例如,請考慮上述假設裝置。 假設元件 0 為作用中,而元件 1 和 2 處於閒置狀態。 當元件 2 變成作用中時,PoFx 會呼叫該元件的 ComponentActiveConditionCallback 常式。 要求類型 A 和 C 會使用元件 2,因此驅動程式會操作這兩個要求類型的位元遮罩。 由於現在已設定要求類型 A 位元遮罩中的所有位,因此驅動程式會啟動要求類型 A 的佇列。不過,並非所有位都會針對要求類型 C (元件 1 設定為閒置) 。 驅動程式不會啟動要求類型 C 的佇列。

啟動次要 I/O 佇列時,架構會開始傳遞儲存在佇列中的要求。 在次要 I/O 佇列 的要求處理常式 中,驅動程式可以安全地處理要求,因為元件為使用中,而且已針對每個要求對元件採用電源參考。

當驅動程式完成處理要求時,它會針對要求所使用的每個元件呼叫 PoFxIdleComponent ,然後完成要求。 當沒有任何使用元件的要求時,Power Framework 會呼叫驅動程式的 ComponentIdleConditionCallback 常式。

在此回呼中,驅動程式會清除對應至指定元件的位,並在代表該元件的每個位元遮罩中清除。 如果指定的位元遮罩指出元件是對應集合中要轉換為閒置條件的第一個元件,驅動程式會呼叫 WdfIoQueueStop 來停止對應的次要 I/O 佇列。 如此一來,驅動程式可確保佇列不會分派要求,除非對應集合中的所有元件都處於作用中狀態。

再次考慮上述範例。 假設所有元件都處於作用中狀態,因此會啟動所有佇列。 當元件 1 閒置時,PoFx 會呼叫元件 1 的 ComponentIdleConditionCallback 常式。 在此回呼中,驅動程式會操作要求類型 B 和 C 的位元遮罩,因為它們使用元件 1。 因為元件 1 是這兩個要求類型變成閒置的第一個元件,所以驅動程式會停止要求類型 B 和 C 的佇列。

假設此時元件 0 會變成閒置狀態。 在元件 0 的 ComponentIdleConditionCallback 中,驅動程式會操作要求類型 A 和 C 的位元遮罩。因為元件 0 是要求類型第一個閒置的元件 A (元件 2 仍在作用中) ,所以驅動程式會停止要求類型 A 的佇列。不過,針對要求類型 C,元件 0 不是要變成閒置的第一個元件。 驅動程式不會停止要求類型 C 的佇列, (稍早) 。

若要使用此範例中所述的技術,驅動程式也必須為其每個次要佇列註冊 EvtIoCanceledOnQueue 回呼函式。 如果在次要佇列中取消要求,驅動程式可以使用此回呼來呼叫每個對應元件的 PoFxIdleComponent 。 這麼做會釋放要求處理常式在將要求轉送至次要佇列之前 ,呼叫 PoFxActivateComponent 時所花費的電源參考。