Compartilhar via


Trabalhando com o GUID_DEVICE_RESET_INTERFACE_STANDARD

A interface GUID_DEVICE_RESET_INTERFACE_STANDARD define uma maneira padrão para os drivers de função tentarem redefinir e recuperar um dispositivo com defeito.

Dois tipos de redefinições de dispositivo estão disponíveis por meio dessa interface:

  • Redefinição de dispositivo no nível da função. Nesse caso, a operação de redefinição é restrita a um dispositivo específico e não é visível para outros dispositivos. O dispositivo permanece conectado ao barramento durante toda a redefinição e retorna a um estado válido (estado inicial) após a redefinição. Esse tipo de redefinição tem o menor impacto no sistema.

    • Esse tipo de redefinição pode ser implementado pelo driver de barramento ou pelo firmware ACPI. O driver de barramento poderá implementar uma redefinição no nível da função se a especificação do barramento definir um mecanismo de redefinição em banda que atenda ao requisito. O firmware ACPI pode, opcionalmente, substituir uma redefinição de nível de função definida pelo driver de barramento por sua própria implementação.
  • Redefinição de dispositivo no nível da plataforma. Nesse caso, a operação de redefinição faz com que o dispositivo seja relatado como ausente do barramento. A operação de redefinição afeta um dispositivo específico e todos os outros dispositivos que estão conectados a ele por meio do mesmo trilho de alimentação ou linha de redefinição. Esse tipo de redefinição tem o maior impacto no sistema. O sistema operacional removerá e recompilará as pilhas de todos os dispositivos afetados para garantir que tudo seja reiniciado de um estado em branco.

Começando no Windows 10, essas entradas do Registro sob a HKLM\SYSTEM\CurrentControlSet\Control\Pnp chave configuram a operação de redefinição:

  • DeviceResetRetryInterval: período antes do início da operação de redefinição. O valor padrão é 3 segundos. O valor mínimo é de 100 milissegundos; o valor máximo é de 30 segundos.

  • DeviceResetMaximumRetries: número de vezes que a operação de redefinição é tentada.

Observação

A interface GUID_DEVICE_RESET_INTERFACE_STANDARD está disponível a partir do Windows 10.

Usando a interface de redefinição de dispositivo

Se um driver de função detectar que o dispositivo não está funcionando corretamente, ele deverá primeiro tentar uma redefinição no nível da função. Se uma redefinição no nível da função não corrigir o problema, o driver poderá optar por tentar uma redefinição no nível da plataforma. No entanto, uma redefinição no nível da plataforma só deve ser usada como a opção final.

Para consultar essa interface, um driver de dispositivo envia um IRP IRP_MN_QUERY_INTERFACE na pilha do driver. Para esse IRP, o driver define o parâmetro de entrada InterfaceType como GUID_DEVICE_RESET_INTERFACE_STANDARD. Após a conclusão bem-sucedida do IRP, o parâmetro de saída interface é um ponteiro para uma estrutura DEVICE_RESET_INTERFACE_STANDARD. Essa estrutura contém um ponteiro para a rotina DeviceReset, que pode ser usada para solicitar uma redefinição no nível da função ou da plataforma.

Suporte à interface de redefinição de dispositivo em drivers de função

Para dar suporte à interface de redefinição de dispositivo, a pilha de dispositivos deve atender aos requisitos a seguir.

O driver de função deve lidar corretamente com IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE e IRP_MN_SURPRISE_REMOVAL.

Na maioria dos casos, quando o driver recebe IRP_MN_QUERY_REMOVE_DEVICE, ele deve retornar um sucesso para que o dispositivo possa ser removido com segurança. No entanto, pode haver casos em que o dispositivo não pode ser interrompido com segurança, como se o dispositivo estivesse preso em um loop gravando em um buffer de memória. Nesses casos, o driver deve retornar STATUS_DEVICE_HUNG para IRP_MN_QUERY_REMOVE_DEVICE. O gerenciador PnP continuará o processo de IRP_MN_QUERY_REMOVE_DEVICE e IRP_MN_REMOVE_DEVICE, mas essa pilha específica não receberá IRP_MN_REMOVE_DEVICE. Em vez disso, a pilha do dispositivo receberá IRP_MN_SURPRISE_REMOVAL após a redefinição do dispositivo.

Para obter mais informações sobre esses IRPs, consulte:

Manipulando uma solicitação de IRP_MN_QUERY_REMOVE_DEVICE

Manipulando uma solicitação de IRP_MN_REMOVE_DEVICE

Manipulando uma solicitação de IRP_MN_SURPRISE_REMOVAL

Suporte à interface de redefinição de dispositivo em drivers de filtro

Os drivers de filtro podem interceptar IRP_MN_QUERY_INTERFACE IRPs que têm o tipo de interface GUID_DEVICE_RESET_INTERFACE_STANDARD. Ao fazer isso, eles podem continuar a delegar à interface GUID_DEVICE_RESET_INTERFACE_STANDARD, mas executar operações específicas do dispositivo antes ou depois da operação de redefinição. Como alternativa, eles podem substituir a interface GUID_DEVICE_RESET_INTERFACE_STANDARD retornada pelo driver de barramento com sua própria interface para fornecer sua própria operação de redefinição.

Suporte à interface de redefinição de dispositivo em drivers de barramento

Os motoristas de ônibus que participam do processo de redefinição de dispositivo (ou seja, os motoristas de ônibus associados ao dispositivo que está solicitando a redefinição e os drivers de ônibus associados aos dispositivos que estão respondendo à solicitação de redefinição) devem atender a um dos seguintes requisitos:

  • Ter capacidade de plugue quente. O motorista do ônibus deve ser capaz de detectar um dispositivo sendo removido do ônibus sem aviso prévio, e um dispositivo sendo conectado ao ônibus.

  • Como alternativa, ele deve implementar a interface GUID_REENUMERATE_SELF_INTERFACE_STANDARD. Isso simula um dispositivo sendo retirado de um ônibus e sendo conectado novamente. Os drivers de ônibus internos (como PCI e SDBUS) dão suporte a essa interface. Portanto, se o dispositivo que está sendo redefinido usar um desses ônibus, nenhuma modificação de motorista de ônibus deverá ser necessária.

Para drivers de barramento baseados em WDF, a estrutura do WDF registra a interface GUID_REENUMERATE_SELF_INTERFACE_STANDARD em nome dos drivers. Portanto, o registro dessa interface não é necessário para esses drivers. Se o motorista do barramento precisar executar algumas operações antes que seus dispositivos filho sejam renumerados, ele deverá se registrar para a rotina de retorno de chamada EvtChildListDeviceReenumerated e executar as operações nessa rotina. Como essa rotina de retorno de chamada pode ser chamada em paralelo para todos os PDO, o código na rotina pode precisar proteger contra condições de corrida.

Firmware acpi: redefinição no nível da função

Para dar suporte à redefinição de dispositivo no nível da função, deve haver um método _RST definido dentro do escopo do dispositivo. Se presente, esse método substituirá a implementação do driver de barramento da redefinição de dispositivo no nível da função (se presente) para esse dispositivo. Quando executado, o método _RST deve redefinir apenas esse dispositivo e não deve afetar outros dispositivos. Além disso, o dispositivo deve permanecer conectado no barramento.

Firmware acpi: redefinição no nível da plataforma

Para dar suporte à redefinição de dispositivo no nível da plataforma, há duas opções:

  • O firmware ACPI pode definir um PowerResource que implementa o método _RST e todos os dispositivos afetados por esse método de redefinição podem se referir a esse PowerResource por meio de um objeto _PRR definido no escopo do dispositivo.

  • O dispositivo pode declarar um objeto _PR3. Nesse caso, o driver ACPI usará o ciclo de energia D3cold para executar a redefinição e as dependências de redefinição entre dispositivos serão determinadas do objeto _PR3.

Se o objeto _PRR existir no escopo do dispositivo, o driver ACPI usará o método _RST no PowerResource referenciado para executar a redefinição. Se nenhum objeto _PRR for definido, mas o objeto _PR3 for definido, o driver ACPI usará o ciclo de energia D3cold para executar a redefinição. Se nem o objeto _PRR ou _PR3 estiver definido, o dispositivo não dará suporte a uma redefinição no nível da plataforma e o driver ACPI relatará que a redefinição no nível da plataforma não está disponível.

Verificando o firmware acpi no sistema de teste

Para testar o driver que dá suporte à redefinição e recuperação do dispositivo, siga este procedimento. Este procedimento pressupõe que você esteja usando este arquivo ASL de exemplo.

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. Compile o arquivo ASL de teste em um AML usando um compilador ASL, como Asl.exe. O executável no incluído no WDK (Kit de Driver do Windows).
Asl <test>.asl

O comando anterior gera SSDT.aml.

  1. Renomeie SSDT.aml como acpitabl.dat.

  2. Copie acpitabl.dat para %systemroot%\system32 no sistema de teste.

  3. Habilite a assinatura de teste no sistema de teste.

bcdedit /set testsigning on
  1. Reinicialize o sistema de teste.

  2. Verifique se a tabela está carregada. No Depurador do Windows, use esses comandos.

  • !acpicache
  • dt _DESCRIPTION_HEADER endereço da tabela SSDT
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

Consulte Também

_DEVICE_RESET_INTERFACE_STANDARD