Usar una interrupción para reactivar un dispositivo

Cuando un dispositivo pasa a un estado de bajo consumo, el marco desconecta (o informa como inactivo) interrupciones que se usan para el control de E/S. A partir de KMDF 1.13 y UMDF 2.0 que se ejecuta en Windows 8.1, un controlador WDF puede crear un objeto de interrupción del marco que permanece activo cuando el dispositivo pasa a un estado de bajo consumo y, a continuación, se puede usar para despertar el dispositivo y restaurarlo a su estado D0 totalmente activado.

Si está desarrollando un controlador WDF para un sistema en una plataforma de chip (SoC), puede usar esta interrupción para despertar un dispositivo que no proporciona un mecanismo de señalización de reactivación tradicional. Para usar esta funcionalidad, el dispositivo debe tener compatibilidad de hardware con interrupciones de reactivación, tal como se expone a través de ACPI. El controlador que crea la interrupción debe ser el propietario de la directiva de energía del dispositivo.

Cuando el dispositivo pasa a un estado de bajo consumo, el marco no desconecta una interrupción que se ha identificado como compatible con reactivación. Cuando el dispositivo se interrumpe, el marco llama a las rutinas de devolución de llamada EvtDeviceD0Entry y EvtInterruptIsr del controlador en IRQL = PASSIVE_LEVEL.

Si el controlador ya crea un objeto de interrupción de nivel pasivo para el control de E/S, se recomienda compartir ese mismo objeto de interrupción para la funcionalidad de reactivación. En este escenario, la rutina de devolución de llamada EvtInterruptIsr del controlador implementa lógica condicional para realizar el control de interrupciones relacionadas con E/S, así como el control de reactivación.

Sin embargo, si el controlador usa una interrupción que requiere el control en irQL (DIRQL) del dispositivo, se recomienda crear un objeto de interrupción de marco adicional para proporcionar funcionalidad de reactivación.

Siga estos pasos para crear un objeto de interrupción compatible con reactivación en el controlador KMDF o UMDF:

  1. Llame a WdfDeviceAssignS0IdleSettings, normalmente desde EvtDriverDeviceAdd, especificando IdleCanWakeFromS0 en el parámetro IdleCaps .

  2. Opcionalmente, llame a WdfDeviceInitSetPowerPolicyEventCallbacks para registrar las funciones de devolución de llamada de eventos descritas en Compatibilidad con reactivación del sistema.

  3. Llame a WDF_INTERRUPT_CONFIG_INIT para inicializar una estructura de WDF_INTERRUPT_CONFIG . Proporcione una función de devolución de llamada EvtInterruptIsr , a la que se llamará en el nivel pasivo. En la estructura de configuración, establezca PassiveHandling y CanWakeDevice en TRUE. A continuación, llame a WdfInterruptCreate desde la función de devolución de llamada EvtDevicePrepareHardware del controlador para crear el objeto de interrupción del marco.

  4. Llama a WdfDeviceAssignSxWakeSettings para configurar el dispositivo para reactivar el sistema desde un estado de bajo consumo.

    WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_INIT(&wakeSettings);
    wakeSettings.DxState = PowerDeviceD3;
    wakeSettings.UserControlOfWakeSettings = WakeDoNotAllowUserControl;
    wakeSettings.Enabled = WdfTrue;
    
    status = WdfDeviceAssignSxWakeSettings(Device, &wakeSettings);
    if (!NT_SUCCESS(status)) {
        Trace(TRACE_LEVEL_ERROR,"WdfDeviceAssignSxWakeSettings failed %x\n", status);
        return status;
    }
    
  5. Cuando el dispositivo pasa a un estado de bajo consumo, el marco no llama a EvtInterruptDisable para la interrupción compatible con reactivación. El marco llama a EvtDeviceArmWakeFromS0 si el controlador ha proporcionado uno.

  6. Cuando el dispositivo señala la interrupción de reactivación, el marco llama a la rutina de devolución de llamada EvtDeviceD0Entry del controlador.

  7. Si la devolución de llamada EvtDeviceD0Entry del controlador devuelve éxito, el marco llama a la devolución de llamada EvtInterruptIsr del controlador en el nivel pasivo. Antes de que el controlador de interrupción vuelva, debe silenciar la interrupción en el controlador de interrupción. Si el controlador devuelve un código de error de EvtDeviceD0Entry, el marco desconecta la interrupción y llama a la devolución de llamada EvtInterruptDisable del controlador, si el controlador ha proporcionado uno.

  8. El marco llama a las siguientes rutinas de devolución de llamada de eventos de reactivación, si el controlador ha proporcionado alguno:

  9. El marco continúa con la secuencia de devolución de llamada de encendido normal, como se describe en Secuencia de encendido para una función o un controlador de filtro.

Puede usar la extensión del depurador !wdfkd.wdfinterrupt para mostrar si se ha configurado una interrupción específica para que sea compatible con reactivación.

La funcionalidad de interrupción de reactivación no se puede usar junto con la suspensión selectiva USB.