Rimozione di un dispositivo in un driver di funzione

Quando si rimuove un dispositivo, un driver di funzione deve annullare le operazioni eseguite per aggiungere e avviare il dispositivo. Questa discussione include driver di funzione per dispositivi periferiche e driver di funzione per i dispositivi del bus.

Un driver di funzione rimuove un dispositivo usando una procedura, ad esempio quanto segue nella routine DispatchPnP :

  1. Si tratta di un driver di funzione per un dispositivo bus?

    In tal caso, eliminare eventuali PDO figlio in sospeso per i dispositivi nel bus.

    Se il conducente del bus ha gestito una richiesta precedente IRP_MN_SURPRISE_REMOVAL per il dispositivo figlio, ma il driver non ha ancora ricevuto la successiva richiesta di IRP_MN_REMOVE_DEVICE, il driver del bus lascia intatto il pdO figlio. In un secondo momento, quando tutti gli handle al dispositivo figlio vengono chiusi, il gestore PnP invierà l'IRP rimosso per il dispositivo figlio e il driver del bus elimina il PDO figlio in quel momento.

    Se il driver del bus ha gestito una richiesta precedente di IRP_MN_REMOVE_DEVICE per il dispositivo e non è stata richiesta successiva IRP_MN_SURPRISE_REMOVAL , il driver del bus elimina il PDO figlio. In questo caso, il gestore PnP garantisce che tutti i driver di funzione e filtro siano stati rimossi dal dispositivo figlio (FDO e filtri DOs sono stati eliminati) prima di inviare un'IRP rimossa al dispositivo del bus padre. Il PDO figlio potrebbe essere ancora presente, quindi il driver del bus deve eliminare il PDO figlio prima di rimuovere il dispositivo del bus.

  2. Il driver ha già gestito una richiesta di IRP_MN_SURPRISE_REMOVAL precedente per questo FDO?

    In tal caso, eseguire qualsiasi pulizia rimanente e passare al passaggio 8, IoCallDriver.

    Un driver gestisce in genere un flag nell'estensione del dispositivo che indica se il driver ha gestito una richiesta di IRP_MN_SURPRISE_REMOVAL per il dispositivo.

  3. Se il driver ha abilitato in precedenza il dispositivo per la riattivazione, annullare la richiesta di IRP_MN_WAIT_WAKE .

  4. Assicurarsi che il dispositivo sia inattivo.

    Se il dispositivo non è già inattivo in risposta a un IRP_MN_QUERY_REMOVE_DEVICE precedente, il driver deve contrassegnare il dispositivo come non accettare nuove richieste e deve completare eventuali richieste accodate in questo driver. Il driver deve non riuscire in caso di richieste in sospeso che richiedono l'accesso al dispositivo.

    Un driver può usare le routine IoXxxRemoveLockXxx per contare le operazioni di I/O in sospeso e per impostare un evento che indica che la rimozione dell'elaborazione può continuare.

  5. Eseguire tutte le operazioni di risparmio energia.

    Ogni driver per il dispositivo esegue le operazioni di alimentazione, se presenti, quando riceve la richiesta di IRP_MN_REMOVE_DEVICE . Il proprietario dei criteri di alimentazione per il dispositivo, in genere il driver di funzione, non invia una richiesta di IRP_MN_SET_POWER separata per impostare lo stato di alimentazione del dispositivo su D3. Il driver del bus padre carica in genere lo slot e notifica al power manager con PoSetPowerState quando il driver del bus ottiene l'IRP rimosso. Per altre informazioni, vedere Power Management.

  6. Disabilitare tutte le interfacce del dispositivo chiamando IoSetDeviceInterfaceState.

  7. Liberare tutte le risorse hardware per il dispositivo in uso dal driver.

    Le operazioni esatte dipendono dal dispositivo e dal driver, ma possono includere la disconnessione di un interruzione con IoDisconnectInterrupt, liberando gli intervalli di indirizzi fisici con MmUnmapIoSpace e liberando porte di I/O.

  8. Passare la richiesta di IRP_MN_REMOVE_DEVICE fino al driver successivo.

    Configurare il percorso dello stack IRP per il driver inferiore successivo con IoSkipCurrentIrpStackLocation e passare l'IRP al driver successivo con IoCallDriver.

    Un driver non è necessario attendere che i driver sottostanti finisca le operazioni di rimozione prima di continuare con le attività di rimozione.

  9. Rimuovere l'oggetto dispositivo dallo stack di dispositivi con IoDetachDevice.

    Specificare un puntatore all'oggetto dispositivo inferiore successivo come parametro TargetDevice . Il driver riceve un puntatore di questo tipo dalla chiamata a IoAttachDeviceToDeviceStack nella routine AddDevice del driver.

  10. Pulire eventuali allocazioni specifiche del dispositivo, memoria, eventi e così via.

  11. Liberare l'oggetto FDO con IoDeleteDevice.

  12. Tornare dalla routine DispatchPnP , propagando lo stato restituito da IoCallDriver.

Un driver di funzione non specifica una routine IoCompletion per un'IRP rimossa , né completa l'IRP. Rimuovere i provider di integrazione vengono completati dal driver del bus padre.