Uso di un interrupt per riattivare un dispositivo

Quando un dispositivo passa a uno stato a basso consumo, il framework si disconnette (o segnala come inattivi) interrupt usati per la gestione di I/O. A partire da KMDF 1.13 e UMDF 2.0 in esecuzione su Windows 8.1, un driver WDF può creare un oggetto interrupt del framework che rimane attivo quando il dispositivo passa a uno stato a basso consumo e può quindi essere usato per risvegliare il dispositivo e ripristinarlo completamente nello stato D0.

Se si sviluppa un driver WDF per una piattaforma System on a Chip (SoC), è possibile usare tale interrupt per risvegliare un dispositivo che non fornisce un meccanismo tradizionale di segnalazione della riattivazione. Per usare questa funzionalità, il dispositivo deve disporre del supporto hardware per gli interrupt di riattivazione, come esposto tramite ACPI. Il driver che crea l'interrupt deve essere il proprietario dei criteri di alimentazione del dispositivo.

Quando il dispositivo passa a uno stato a basso consumo, il framework non disconnette un interrupt identificato come con riattivazione. Quando il dispositivo viene interrotto, il framework chiama le routine di callback EvtDeviceD0Entry e EvtInterruptIsr in IRQL = PASSIVE_LEVEL.

Se il driver crea già un oggetto interrupt a livello passivo per la gestione di I/O, è consigliabile condividere lo stesso oggetto interrupt per la funzionalità di riattivazione. In questo scenario, la routine di callback EvtInterruptIsr del driver implementa la logica condizionale per eseguire la gestione degli interrupt correlati all'I/O, nonché la gestione della riattivazione.

Tuttavia, se il driver usa un interrupt che richiede la gestione del runtime di integrazione (DIRQL) del dispositivo, è consigliabile creare un oggetto interrupt del framework aggiuntivo per fornire funzionalità di riattivazione.

Seguire questa procedura per creare un oggetto interrupt con supporto per la riattivazione nel driver KMDF o UMDF:

  1. Chiamare WdfDeviceAssignS0IdleSettings, in genere da EvtDriverDeviceAdd, specificando IdleCanWakeFromS0 nel parametro IdleCaps .

  2. Facoltativamente, chiamare WdfDeviceInitSetPowerPolicyEventCallbacks per registrare le funzioni di callback degli eventi descritte in Supporto della riattivazione del sistema.

  3. Chiamare WDF_INTERRUPT_CONFIG_INIT per inizializzare una struttura WDF_INTERRUPT_CONFIG . Fornire una funzione di callback EvtInterruptIsr da chiamare a livello passivo. Nella struttura di configurazione impostare PassiveHandling e CanWakeDevice su TRUE. Chiamare quindi WdfInterruptCreate dalla funzione di callback EvtDevicePrepareHardware del driver per creare l'oggetto interrupt del framework.

  4. Chiama WdfDeviceAssignSxWakeSettings per configurare il dispositivo per riattivare il sistema da uno stato a basso 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. Quando il dispositivo passa a uno stato a basso consumo, il framework non chiama EvtInterruptDisable per l'interrupt con supporto per la riattivazione. Il framework chiama EvtDeviceArmWakeFromS0 se il driver ne ha fornito uno.

  6. Quando il dispositivo segnala l'interrupt di riattivazione, il framework chiama la routine di callback EvtDeviceD0Entry del driver.

  7. Se il callback EvtDeviceD0Entry del driver restituisce esito positivo, il framework chiama il callback EvtInterruptIsr del driver a livello passivo. Prima che il gestore di interrupt venga restituito, deve disattivare l'interrupt nel controller di interrupt. Se il driver restituisce un codice di errore da EvtDeviceD0Entry, il framework disconnette l'interrupt e chiama il callback EvtInterruptDisable del driver, se ne ha fornito uno.

  8. Il framework chiama le routine di callback degli eventi di riattivazione seguenti, se il driver ha fornito:

  9. Il framework continua con la normale sequenza di callback di alimentazione, come descritto in Power-Up Sequence per una funzione o un driver di filtro.

È possibile usare l'estensione del debugger !wdfkd.wdfinterrupt per indicare se è stato configurato un interrupt specifico per la riattivazione.

La funzionalità di interruzione della riattivazione non può essere usata insieme alla sospensione selettiva USB.