Dela via


Ta bort en enhet i en funktionsdrivrutin

När du tar bort en enhet måste en funktionsdrivrutin ångra alla åtgärder som den utförde för att lägga till och starta enheten. Den här diskussionen innehåller funktionsdrivrutiner för kringutrustning och funktionsdrivrutiner för bussenheter.

En funktionsdrivrutin tar bort en enhet med hjälp av en procedur, till exempel följande i sin DispatchPnP-rutin :

  1. Är det här en drivrutin för en enhet på bussen?

    I så fall kan du eventuellt ta bort utestående underordnade PDO:er för enheter på bussen.

    Om bussdrivrutinen hanterade en tidigare IRP_MN_SURPRISE_REMOVAL begäran för den underordnade enheten, men drivrutinen ännu inte har fått den efterföljande IRP_MN_REMOVE_DEVICE begäran, lämnar bussdrivrutinen den underordnade PDO:n intakt. Vid ett senare tillfälle, när alla referenser till den underordnade enheten stängs, skickar PnP-chefen borttagnings-IRP för den underordnade enheten och busschauffören tar bort den underordnade PDO:n vid den tidpunkten.

    Om busschauffören hanterade en tidigare IRP_MN_REMOVE_DEVICE begäran för enheten och det inte har gjorts någon efterföljande IRP_MN_SURPRISE_REMOVAL begäran, tar busschauffören bort den underordnade PDO:n. I det här fallet ser PnP-hanteraren till att alla funktions- och filterdrivrutiner har tagits bort från den underordnade enheten (FDO och filter-DO har tagits bort) innan den skickar en borttagnings-IRP till den överordnade bussenheten. Den så kallade barn-PDO:n kan fortfarande finnas kvar, så busschauffören måste ta bort barn-PDO:n innan den tar bort bussanordningen.

  2. Har drivrutinen redan hanterat en tidigare IRP_MN_SURPRISE_REMOVAL begäran för denna FDO?

    I så fall utför du eventuell återstående rensning och går vidare till steg 8, IoCallDriver.

    En drivrutin har vanligtvis en flagga i enhetstillägget som anger om drivrutinen har hanterat en IRP_MN_SURPRISE_REMOVAL begäran för enheten.

  3. Om drivrutinen tidigare har aktiverat enheten för väckning, avbryt IRP_MN_WAIT_WAKE-begäran.

  4. Kontrollera att enheten är inaktiv.

    Om enheten inte redan är inaktiv som svar på en tidigare IRP_MN_QUERY_REMOVE_DEVICE måste drivrutinen markera enheten som att den inte accepterar nya begäranden och måste slutföra alla begäranden i kö i den här drivrutinen. Drivrutinen måste avvisa alla pågående förfrågningar som kräver åtkomst till enheten.

    En drivrutin kan använda IoXxxRemoveLockXxx-rutinerna för att räkna utestående I/O och ange en händelse för att indikera att borttagningsprocessen kan fortsätta.

  5. Utför eventuella avstängningsåtgärder.

    Varje drivrutin för enheten utför eventuella åtgärder när den tar emot IRP_MN_REMOVE_DEVICE begäran. Enhetens energiprincipägare, vanligtvis funktionsdrivrutinen, skickar inte en separat IRP_MN_SET_POWER begäran om att ange enhetens energitillstånd till D3. Den överordnade busschauffören stänger vanligtvis av facket och meddelar energihanteraren med PoSetPowerState när busschauffören får ta bort IRP. Mer information finns i Power Management.

  6. Inaktivera alla enhetsgränssnitt genom att anropa IoSetDeviceInterfaceState.

  7. Frigör eventuella maskinvaruresurser för den enhet som används av drivrutinen.

    De exakta åtgärderna beror på enheten och drivrutinen, men kan inkludera att koppla bort ett avbrott med IoDisconnectInterrupt, frigöra fysiska adressintervall med MmUnmapIoSpace samt frigöra I/O-portar.

  8. Skicka IRP_MN_REMOVE_DEVICE begäran till nästa drivrutin.

    Konfigurera IRP-stackplatsen för nästa lägre drivrutin med IoSkipCurrentIrpStackLocation och skicka IRP till nästa drivrutin med IoCallDriver.

    En drivrutin behöver inte vänta tills underliggande drivrutiner har slutfört sina borttagningsåtgärder innan den fortsätter sina egna borttagningsaktiviteter.

  9. Ta bort enhetsobjektet från enhetsstacken med IoDetachDevice.

    Ange en pekare till nästa lägre enhetsobjekt som parametern TargetDevice . Drivrutinen tar emot en sådan pekare från anropet till IoAttachDeviceToDeviceStack i drivrutinens AddDevice-rutin.

  10. Rensa alla enhetsspecifika allokeringar, minne, händelser och så vidare.

  11. Frigör FDO med IoDeleteDevice.

  12. Returnera från DispatchPnP-rutinen och sprid returstatusen från IoCallDriver.

En funktionsdrivrutin anger inte någon IoCompletion-rutin för en borttagnings-IRP och slutför inte heller IRP. Ta bort IP-adresser slutförs av den överordnade busschauffören.