Trabajar con el GUID_DEVICE_RESET_INTERFACE_STANDARD
La interfaz GUID_DEVICE_RESET_INTERFACE_STANDARD define una manera estándar de que los controladores de función intenten restablecer y recuperar un dispositivo que no funciona correctamente.
Hay dos tipos de restablecimientos de dispositivo disponibles a través de esta interfaz:
Restablecimiento del dispositivo de nivel de función. En este caso, la operación de restablecimiento está restringida a un dispositivo específico y no es visible para otros dispositivos. El dispositivo permanece conectado al bus a lo largo del restablecimiento y vuelve a un estado válido (estado inicial) después del restablecimiento. Este tipo de restablecimiento tiene el menor impacto en el sistema.
- Este tipo de restablecimiento se puede implementar mediante el controlador de autobús o el firmware ACPI. El controlador de bus puede implementar un restablecimiento en el nivel de función si la especificación del bus define un mecanismo de restablecimiento en banda que cumple el requisito. El firmware ACPI puede invalidar opcionalmente un restablecimiento de nivel de función definido por el controlador de bus con su propia implementación.
Restablecimiento del dispositivo de nivel de plataforma. En este caso, la operación de restablecimiento hace que el dispositivo se notifique como que falta en el bus. La operación de restablecimiento afecta a un dispositivo específico y a todos los demás dispositivos conectados a él a través de la misma línea de restablecimiento o riel de alimentación. Este tipo de restablecimiento tiene el mayor impacto en el sistema. El sistema operativo anulará y recompilará las pilas de todos los dispositivos afectados para asegurarse de que todo se reinicia desde un estado en blanco.
A partir de Windows 10, estas entradas del Registro en la HKLM\SYSTEM\CurrentControlSet\Control\Pnp
clave configuran la operación de restablecimiento:
DeviceResetRetryInterval: período de tiempo antes de que se inicie la operación de restablecimiento. El valor predeterminado es de 3 segundos. El valor mínimo es de 100 milisegundos; el valor máximo es de 30 segundos.
DeviceResetMaximumRetries: número de veces que se intenta realizar la operación de restablecimiento.
Nota:
La interfaz GUID_DEVICE_RESET_INTERFACE_STANDARD está disponible a partir de Windows 10.
Uso de la interfaz de restablecimiento de dispositivo
Si un controlador de función detecta que el dispositivo no funciona correctamente, primero debe intentar un restablecimiento de nivel de función. Si un restablecimiento de nivel de función no corrige el problema, el controlador puede optar por intentar un restablecimiento de nivel de plataforma. Sin embargo, un restablecimiento de nivel de plataforma solo se debe usar como opción final.
Para consultar esta interfaz, un controlador de dispositivo envía una IRP_MN_QUERY_INTERFACE IRP a la pila de controladores. Para este IRP, el controlador establece el parámetro de entrada InterfaceType en GUID_DEVICE_RESET_INTERFACE_STANDARD. Al completar correctamente el IRP, el parámetro de salida interface es un puntero a una estructura de DEVICE_RESET_INTERFACE_STANDARD. Esta estructura contiene un puntero a la rutina DeviceReset, que se puede usar para solicitar un restablecimiento de nivel de función o de nivel de plataforma.
Compatibilidad con la interfaz de restablecimiento de dispositivos en controladores de función
Para admitir la interfaz de restablecimiento de dispositivos, la pila de dispositivos debe cumplir los siguientes requisitos.
El controlador de función debe controlar correctamente IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE y IRP_MN_SURPRISE_REMOVAL.
En la mayoría de los casos, cuando el controlador recibe IRP_MN_QUERY_REMOVE_DEVICE, debe devolver un éxito para que el dispositivo se pueda quitar de forma segura. Sin embargo, puede haber casos en los que el dispositivo no se pueda detener de forma segura, como si el dispositivo está bloqueado en un bucle escribiendo en un búfer de memoria. En tales casos, el controlador debe devolver STATUS_DEVICE_HUNG a IRP_MN_QUERY_REMOVE_DEVICE. El administrador de PnP continuará el proceso de IRP_MN_QUERY_REMOVE_DEVICE y IRP_MN_REMOVE_DEVICE, pero esa pila determinada no recibirá IRP_MN_REMOVE_DEVICE. En su lugar, la pila de dispositivos recibirá IRP_MN_SURPRISE_REMOVAL después de restablecer el dispositivo.
Para obtener más información sobre estas IRP, consulte:
Control de una solicitud de IRP_MN_QUERY_REMOVE_DEVICE
Control de una solicitud de IRP_MN_REMOVE_DEVICE
Control de una solicitud de IRP_MN_SURPRISE_REMOVAL
Compatibilidad con la interfaz de restablecimiento de dispositivos en controladores de filtro
Los controladores de filtro pueden interceptar IRP_MN_QUERY_INTERFACE IRP que tienen el tipo de interfaz GUID_DEVICE_RESET_INTERFACE_STANDARD. Al hacerlo, pueden seguir delegando en la interfaz GUID_DEVICE_RESET_INTERFACE_STANDARD, pero realizar operaciones específicas del dispositivo antes o después de la operación de restablecimiento. Como alternativa, pueden invalidar la interfaz GUID_DEVICE_RESET_INTERFACE_STANDARD devuelta por el controlador de autobús con su propia interfaz para proporcionar su propia operación de restablecimiento.
Compatibilidad con la interfaz de restablecimiento de dispositivos en controladores de bus
Los controladores de autobús que participan en el proceso de restablecimiento del dispositivo (es decir, los controladores de autobús asociados con el dispositivo que solicita el restablecimiento y los controladores de autobús asociados a los dispositivos que responden a la solicitud de restablecimiento) deben cumplir uno de los siguientes requisitos:
Ser compatible con enchufes calientes. El controlador de autobús debe ser capaz de detectar un dispositivo que se va a quitar del bus sin previo aviso, y un dispositivo que se conecta al bus.
Como alternativa, debe implementar la interfaz GUID_REENUMERATE_SELF_INTERFACE_STANDARD. Esto simula que un dispositivo se extrae de un bus y se conecta de nuevo. Los controladores de autobús integrados (como PCI y SDBUS) admiten esta interfaz. Por lo tanto, si el dispositivo que se restablece usa uno de estos autobuses, no es necesario realizar modificaciones en el controlador de autobús.
En el caso de los controladores de autobús basados en WDF, el marco WDF registra la interfaz de GUID_REENUMERATE_SELF_INTERFACE_STANDARD en nombre de los controladores. Por lo tanto, no es necesario registrar esta interfaz para esos controladores. Si el controlador de bus necesita realizar algunas operaciones antes de volver a enumerar sus dispositivos secundarios, debe registrarse para la rutina de devolución de llamada EvtChildListDeviceReenumerated y realizar las operaciones en esa rutina. Dado que se puede llamar a esta rutina de devolución de llamada en paralelo para todos los PDO, es posible que el código de la rutina tenga que protegerse contra las condiciones de carrera.
Firmware ACPI: Restablecimiento en el nivel de función
Para admitir el restablecimiento de dispositivo de nivel de función, debe haber un método _RST definido dentro del ámbito del dispositivo. Si está presente, este método invalidará la implementación del controlador de bus del restablecimiento de dispositivo de nivel de función (si está presente) para ese dispositivo. Cuando se ejecuta, el método _RST debe restablecer solo ese dispositivo y no debe afectar a otros dispositivos. Además, el dispositivo debe permanecer conectado en el bus.
Firmware ACPI: restablecimiento en el nivel de plataforma
Para admitir el restablecimiento de dispositivos de nivel de plataforma, hay dos opciones:
El firmware ACPI puede definir un PowerResource que implemente el método _RST, y todos los dispositivos afectados por este método de restablecimiento pueden hacer referencia a este PowerResource a través de un objeto _PRR definido en su ámbito de dispositivo.
El dispositivo puede declarar un objeto _PR3. En este caso, el controlador ACPI usará el ciclo de energía D3cold para realizar el restablecimiento y se determinarán las dependencias de restablecimiento entre dispositivos desde el objeto _PR3.
Si el objeto _PRR existe en el ámbito del dispositivo, el controlador ACPI usará el método _RST en el powerResource al que se hace referencia para realizar el restablecimiento. Si no se define ningún objeto _PRR pero se define el objeto _PR3, el controlador ACPI usará el ciclo de alimentación D3cold para realizar el restablecimiento. Si no se define el objeto _PRR o _PR3, el dispositivo no admite un restablecimiento de nivel de plataforma y el controlador ACPI notificará que el restablecimiento de nivel de plataforma no está disponible.
Comprobación del firmware ACPI en el sistema de prueba
Para probar el controlador que admite el restablecimiento y la recuperación del dispositivo, siga este procedimiento. En este procedimiento se supone que usa este archivo ASL de ejemplo.
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)
}
- Compile el archivo ASL de prueba en un AML mediante un compilador de ASL, como Asl.exe. Ejecutable incluido en el Kit de controladores de Windows (WDK).
Asl <test>.asl
El comando anterior genera SSDT.aml.
Cambie el nombre de SSDT.aml a acpitabl.dat.
Copie acpitabl.dat en %systemroot%\system32 en el sistema de prueba.
Habilite la firma de prueba en el sistema de prueba.
bcdedit /set testsigning on
Reinicie el sistema de prueba.
Compruebe que la tabla está cargada. En Windows Debugger, use estos comandos.
- !acpicache
- dt _DESCRIPTION_HEADER dirección de la tabla 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