GUID_DEVICE_RESET_INTERFACE_STANDARD介面會定義標準方式,讓函式驅動程式嘗試重設和復原故障的裝置。
有兩種類型的裝置重設可透過此介面取得:
功能層級的裝置重設。 在此情況下,重設作業僅限於特定裝置,而其他裝置則看不到。 裝置會在整個重設期間維持與總線的連線,並在重設後回到有效的狀態(初始狀態)。 這種類型的重設對系統的影響最小。
這種類型的重設可由總線驅動程式或ACPI韌體實作。 如果總線規格定義符合需求的頻內重設機制,則總線驅動程式可以實作函式層級重設。 ACPI 韌體可以選擇性地使用自己的實作覆蓋總線驅動程式定義的功能層級重設。
平臺層級裝置重設。 在此情況下,重設操作會使裝置被報告為在連接的總線上遺失。 重設作業會影響特定裝置,以及透過相同電源軌或重設線路連線到它的其他所有裝置。 這種類型的重設對系統的影響最大。 OS 會卸除並重建所有受影響裝置的堆疊,以確保所有項目都會從空白狀態重新啟動。
從 Windows 10 開始,這些在 HKLM\SYSTEM\CurrentControlSet\Control\Pnp 機碼下的登錄項目會設定重設作業:
DeviceResetRetryInterval:重設作業開始前的時間週期。 預設值為 3 秒。 最小值為 100 毫秒;最大值為30秒。
DeviceResetMaximumRetries:嘗試重設作業的次數。
備註
從 Windows 10 開始,即可使用 GUID_DEVICE_RESET_INTERFACE_STANDARD 介面。
使用裝置重設介面
如果函式驅動程式偵測到裝置無法正常運作,則應該先嘗試函式層級重設。 如果函式層級重設無法修正此問題,驅動程式可能會選擇嘗試平臺層級重設。 不過,平臺層級重設應該只做為最終選項。
若要查詢此介面,裝置驅動程式會將IRP_MN_QUERY_INTERFACE IRP 傳送至驅動程式堆疊。 針對此 IRP,驅動程式會將 InterfaceType 輸入參數設定為 GUID_DEVICE_RESET_INTERFACE_STANDARD。 順利完成 IRP 時,介面輸出參數是DEVICE_RESET_INTERFACE_STANDARD結構的指標。 此結構包含 DeviceReset 例程的指標,可用來要求函式層級或平臺層級重設。
支援功能驅動程式中的裝置重設介面
若要支援裝置重設介面,裝置堆疊必須符合下列需求。
函式驅動程式必須正確處理IRP_MN_QUERY_REMOVE_DEVICE、IRP_MN_REMOVE_DEVICE和IRP_MN_SURPRISE_REMOVAL。
在大部分情況下,當驅動程式收到IRP_MN_QUERY_REMOVE_DEVICE時,它應該會傳回成功,以便安全地移除裝置。 不過,在某些情況下,裝置無法安全地停止,例如,如果裝置卡在寫入記憶體緩衝區的迴圈中。 在這種情況下,驅動程式應將 STATUS_DEVICE_HUNG 傳回給 IRP_MN_QUERY_REMOVE_DEVICE。 PnP 管理員會繼續IRP_MN_QUERY_REMOVE_DEVICE和IRP_MN_REMOVE_DEVICE流程,但該特定堆疊不會收到IRP_MN_REMOVE_DEVICE。 相反地,裝置堆疊會在裝置重設之後收到 IRP_MN_SURPRISE_REMOVAL。
如需這些 IRP 的詳細資訊,請參閱:
處理IRP_MN_QUERY_REMOVE_DEVICE要求
在篩選驅動程式中支援裝置重設介面
篩選驅動程式可能會攔截具有GUID_DEVICE_RESET_INTERFACE_STANDARD介面類型的IRP_MN_QUERY_INTERFACE IRP。 如此一來,他們可以繼續將控制委派給 GUID_DEVICE_RESET_INTERFACE_STANDARD 介面,但可以在重設操作之前或之後執行裝置特定的操作。 或者,開發者可以使用自己的介面來覆蓋總線驅動程式所傳回的 GUID_DEVICE_RESET_INTERFACE_STANDARD 介面,以便提供自己的重設操作。
支援總線驅動程式中的裝置重設介面
參與裝置重設程式的總線驅動程式(也就是與要求重設要求之裝置相關聯的總線驅動程式,以及與回應重設要求之裝置相關聯的總線驅動程式)必須符合下列其中一項需求:
支援熱插即用。 公車司機必須能夠偵測到未經通知地從公車上移除的裝置,以及插入公車的裝置。
或者,它必須實作 GUID_REENUMERATE_SELF_INTERFACE_STANDARD 介面。 這會模擬將裝置從匯流排中移除並重新插回去。 內建總線驅動程式(例如PCI和SDBUS)支援此介面。 因此,如果重設的裝置會使用這些總線的其中一個,就不需要修改任何總線驅動程式。
針對以WDF為基礎的總線驅動程式,WDF 架構會代表驅動程式註冊GUID_REENUMERATE_SELF_INTERFACE_STANDARD介面。 因此,這些驅動程式不需要註冊此介面。 如果總線驅動程式需要在其子裝置被重新列舉之前執行特定操作,則必須註冊 EvtChildListDeviceReenumerated 回呼例程,並在該例程中執行這些操作。 由於此回呼例程可能會針對所有 PDO 平行呼叫,因此例程中的程式代碼可能需要防範競爭狀況。
ACPI 韌體:函式層級重設
若要支援函式層級的裝置重設,必須在裝置範圍內定義_RST方法。 如果存在,此方法將覆蓋總線驅動程式針對該裝置(若存在)的函數層級裝置重設的實現。 執行時,_RST方法只能重設該裝置,而且不得影響其他裝置。 此外,裝置必須在總線上保持連線。
ACPI 韌體:平臺層級重設
若要支援平臺層級的裝置重設,有兩個選項:
ACPI 韌體可以定義實作_RST方法的 PowerResource,而受此重設方法影響的所有裝置都可以透過在其裝置範圍下定義的_PRR對象來參考此 PowerResource。
裝置可以宣告_PR3物件。 在此情況下,ACPI 驅動程式會使用 D3cold 電源迴圈來執行重設,而裝置之間的重設相依性將會從 _PR3 對象決定。
如果裝置範圍中有_PRR物件,ACPI 驅動程式會使用所參考 PowerResource 中的 _RST 方法來執行重設。 如果未定義_PRR物件,但已定義_PR3物件,則ACPI驅動程式會使用 D3cold 電源迴圈來執行重設。 如果未定義_PRR或_PR3物件,則裝置不支援平臺層級重設,而 ACPI 驅動程式會報告平臺層級重設無法使用。
確認測試系統上的ACPI韌體
若要測試支援裝置重設和復原的驅動程式,請遵循此程式。 此程式假設您使用這個範例 ASL 檔案。
DefinitionBlock("SSDT.AML", "SSDT", 0x01, "XyzOEM", "TestTabl", 0x00001000)
{
Scope(\_SB_)
{
PowerResource(PWFR, 0x5, 0x0)
{
Method(_RST, 0x0, NotSerialized) { }
// Placeholder methods as power resources need _ON, _OFF, _STA.
Method(_STA, 0x0, NotSerialized)
{
Return(0xF)
}
Method(_ON_, 0x0, NotSerialized) { }
Method(_OFF, 0x0, NotSerialized) { }
} // PowerResource()
} // Scope (\_SB_)
// Assumes WiFi device is declared under \_SB.XYZ.
Scope(\_SB_.XYZ.WIFI)
{
// Declare PWFR as WiFi reset power rail
Name(_PRR, Package(One)
{
\_SB_.PWFR
})
} // Scope (\_SB)
}
- 使用 ASL 編譯程式將測試 ASL 檔案編譯成 AML,例如 Asl.exe。 包含在 Windows 驅動程式套件 WDK 中的可執行檔。
Asl <test>.asl
上述命令會產生 SSDT.aml。
將 SSDT.aml 重新命名為 acpitabl.dat。
將acpitabl.dat複製到測試系統上 %systemroot%\system32。
在測試系統上啟用測試簽署。
bcdedit /set testsigning on
重新啟動測試系統。
確認數據表已載入。 在 Windows 調試程式中,使用這些命令。
- !acpicache
- SSDT 數據表的 dt _DESCRIPTION_HEADER 位址
0: kd> !acpicache
Dumping cached ACPI tables...
SSDT @(ffffffffffd03018) Rev: 0x1 Len: 0x000043 TableID: TestTabl
XSDT @(ffffffffffd05018) Rev: 0x1 Len: 0x000114 TableID: HSW-FFRD
...
...
0: kd> dt _DESCRIPTION_HEADER ffffffffffd03018
ACPI!_DESCRIPTION_HEADER
+0x000 Signature : 0x54445353
+0x004 Length : 0x43
+0x008 Revision : 0x1 ''
+0x009 Checksum : 0x37 '7'
+0x00a OEMID : [6] "XyzOEM"
+0x010 OEMTableID : [8] "TestTabl"
+0x018 OEMRevision : 0x1000
+0x01c CreatorID : [4] "MSFT"
+0x020 CreatorRev : 0x5000000