共用方式為


使用 GUID_DEVICE_RESET_INTERFACE_STANDARD

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要求

處理IRP_MN_REMOVE_DEVICE要求

處理IRP_MN_SURPRISE_REMOVAL要求

支援篩選驅動程式中的裝置重設介面

篩選驅動程式可能會攔截具有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)
}
  1. 使用 ASL 編譯器將測試 ASL 檔案編譯至 AML,例如 Asl.exe。 Windows 驅動程式套件 (WDK) 中包含的可執行檔。
Asl <test>.asl

上述命令會產生 SSDT.aml。

  1. 將 SSDT.aml 重新命名為 acpitabl.dat。

  2. 將 acpitabl.dat 複製到測試系統上的 %systemroot%\system32。

  3. 在測試系統上啟用測試簽署。

bcdedit /set testsigning on
  1. 重新開機測試系統。

  2. 確認已載入資料表。 在 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

另請參閱

_DEVICE_RESET_INTERFACE_STANDARD