Udostępnij przez


Usuwanie urządzenia w sterowniku funkcji

Podczas usuwania urządzenia sterownik funkcji musi cofnąć wszystkie wykonywane operacje, aby dodać i uruchomić urządzenie. Ta dyskusja obejmuje sterowniki funkcji dla urządzeń peryferyjnych i sterowników funkcji dla urządzeń magistrali.

Sterownik funkcji usuwa urządzenie przy użyciu procedury, takiej jak poniżej w procedurze DispatchPnP:

  1. Czy jest to sterownik funkcji dla urządzenia magistrali?

    Jeśli tak, ewentualnie usuń wszystkie zaległe podrzędne obiekty PDOs dla urządzeń w magistrali.

    Jeśli kierowca autobusu obsłużył poprzednie żądanie IRP_MN_SURPRISE_REMOVAL dla urządzenia podrzędnego, ale nie otrzymał jeszcze kolejnego żądania IRP_MN_REMOVE_DEVICE, pozostawia PDO urządzenia podrzędnego nienaruszone. W późniejszym czasie, gdy wszystkie dojścia do urządzenia podrzędnego zostaną zamknięte, menedżer PnP wyśle usunięcie IRP dla urządzenia podrzędnego, a sterownik magistrali usunie podrzędny PDO w tym czasie.

    Jeśli kierowca magistrali obsłużył poprzednie żądanie IRP_MN_REMOVE_DEVICE dla urządzenia i nie było późniejszego żądania IRP_MN_SURPRISE_REMOVAL, wtedy kierowca magistrali usuwa podrzędny PDO. W takim przypadku menedżer PnP gwarantuje, że wszystkie funkcje i sterowniki filtrów zostały usunięte z urządzenia podrzędnego (FDO i odfiltrowane obiekty DO zostały usunięte) przed wysłaniem usunięcia IRP do urządzenia magistrali nadrzędnej. Podrzędny PDO może nadal być obecny, więc sterownik magistrali musi usunąć podrzędny PDO, zanim usunie urządzenie z magistrali.

  2. Czy sterownik obsługiwał już poprzednie żądanie IRP_MN_SURPRISE_REMOVAL dla tego FDO?

    Jeśli tak, wykonaj pozostałe czyszczenie i przejdź do kroku 8, IoCallDriver.

    Sterownik zwykle utrzymuje flagę w rozszerzeniu urządzenia, która wskazuje, czy sterownik obsłużył żądanie IRP_MN_SURPRISE_REMOVAL dla urządzenia.

  3. Jeśli sterownik wcześniej włączył urządzenie do budzenia, anuluj żądanie IRP_MN_WAIT_WAKE.

  4. Upewnij się, że urządzenie jest nieaktywne.

    Jeśli urządzenie nie zostało już wcześniej oznaczone jako nieaktywne w odpowiedzi na wcześniejsze IRP_MN_QUERY_REMOVE_DEVICE, sterownik musi oznaczyć urządzenie jako takie, które nie akceptuje nowych żądań i musi dokończyć realizację wszystkich żądań oczekujących w kolejce w tym sterowniku. Sterownik musi odrzucić wszystkie zaległe żądania, które wymagają dostępu do urządzenia.

    Sterownik może używać procedur IoXxxRemoveLockXxx, aby policzyć nierozliczone operacje we/wy i ustawić zdarzenie wskazujące, że przetwarzanie usuwania może kontynuować.

  5. Wykonaj wszystkie operacje wyłączania zasilania.

    Każdy sterownik urządzenia wykonuje operacje wyłączania zasilania, jeśli istnieje, gdy odbiera żądanie IRP_MN_REMOVE_DEVICE. Właściciel zasad zasilania urządzenia, zazwyczaj sterownik funkcji, nie wysyła oddzielnego żądania IRP_MN_SET_POWER, aby ustawić stan zasilania urządzenia na D3. Sterownik magistrali nadrzędnej zwykle wyłącza gniazdo i powiadamia menedżera zasilania za pomocą PoSetPowerState, gdy sterownik magistrali otrzymuje żądanie usunięcia IRP. Aby uzyskać dodatkowe informacje, zobacz Power Management.

  6. Wyłącz wszystkie interfejsy urządzeń, wywołując IoSetDeviceInterfaceState.

  7. Zwolnij wszelkie zasoby sprzętowe dla urządzenia, z którego korzysta sterownik.

    Dokładne operacje zależą od urządzenia i sterownika, ale mogą obejmować odłączenie przerwania z IoDisconnectInterrupt, zwalnianie zakresów adresów fizycznych za pomocą MmUnmapIoSpacei zwalnianie portów we/wy.

  8. Przekaż żądanie IRP_MN_REMOVE_DEVICE do następnego sterownika.

    Skonfiguruj lokalizację stosu IRP dla następnego niższego sterownika za pomocą IoSkipCurrentIrpStackLocation i przekaż IRP do następnego sterownika za pomocą IoCallDriver.

    Sterownik nie musi czekać, aż niższe sterowniki zakończą operacje usuwania, zanim wznowi swoje operacje usuwania.

  9. Usuń obiekt urządzenia ze stosu urządzeń za pomocą IoDetachDevice.

    Określ wskaźnik do następnego niższego obiektu urządzenia jako parametr TargetDevice. Sterownik otrzymuje taki wskaźnik z wywołania procedury AddDevice sterownika do IoAttachDeviceToDeviceStack.

  10. Wyczyść wszystkie alokacje specyficzne dla urządzenia, pamięć, zdarzenia itd.

  11. Zwolnij FDO za pomocą IoDeleteDevice.

  12. Wróć z procedury DispatchPnP, propagując stan powrotu z IoCallDriver.

Sterownik funkcji nie określa IoCompletion procedury usuwania IRP ani nie kończy IRP. IRP-y usuwania są wykonywane przez sterownik magistrali nadrzędnej.