Partilhar via


Removendo um dispositivo em um driver de função

Ao remover um dispositivo, um driver de função deve desfazer todas as operações executadas para adicionar e iniciar o dispositivo. Essa discussão inclui drivers de função para dispositivos periféricos e drivers de função para dispositivos de ônibus.

Um driver de função remove um dispositivo usando um procedimento como o seguinte em sua rotina DispatchPnP :

  1. Este é um driver de função para um dispositivo de ônibus?

    Nesse caso, possivelmente exclua quaisquer PDOs filho pendentes para dispositivos no barramento.

    Se o motorista do ônibus lidou com uma solicitação de IRP_MN_SURPRISE_REMOVAL anterior para o dispositivo filho, mas o motorista ainda não recebeu a solicitação de IRP_MN_REMOVE_DEVICE subsequente, o motorista do ônibus deixa o PDO filho intacto. Posteriormente, quando todos os identificadores para o dispositivo filho forem fechados, o gerenciador PnP enviará o IRP de remoção para o dispositivo filho e o motorista do barramento excluirá o PDO filho nesse momento.

    Se o motorista do ônibus lidou com uma solicitação de IRP_MN_REMOVE_DEVICE anterior para o dispositivo e não houve nenhuma solicitação de IRP_MN_SURPRISE_REMOVAL subsequente, o motorista do ônibus excluirá o PDO filho. Nesse caso, o gerenciador de PnP garante que qualquer função e drivers de filtro tenham sido removidos do dispositivo filho (FDO e DOs de filtro foram excluídos) antes de enviar um IRP de remoção para o dispositivo de barramento pai. O PDO filho ainda pode estar presente, portanto, o motorista do barramento deve excluir o PDO filho antes de remover o dispositivo de barramento.

  2. O driver já lidou com uma solicitação de IRP_MN_SURPRISE_REMOVAL anterior para esse FDO?

    Nesse caso, execute qualquer limpo restante e pule para a etapa 8, IoCallDriver.

    Um driver normalmente mantém um sinalizador na extensão do dispositivo que indica se o driver lidou com uma solicitação de IRP_MN_SURPRISE_REMOVAL para o dispositivo.

  3. Se o driver habilitou anteriormente o dispositivo para ativação, cancele a solicitação de IRP_MN_WAIT_WAKE .

  4. Verifique se o dispositivo está inativo.

    Se o dispositivo ainda não estiver inativo em resposta a um IRP_MN_QUERY_REMOVE_DEVICE anterior, o driver deverá marcar o dispositivo como não aceitando novas solicitações e deve concluir todas as solicitações enfileiradas nesse driver. O driver deve falhar em todas as solicitações pendentes que exijam acesso ao dispositivo.

    Um driver pode usar as rotinas IoXxxRemoveLockXxx para contar E/S pendentes e definir um evento que indica que o processamento de remoção pode continuar.

  5. Executar qualquer operação de desligamento.

    Cada driver para o dispositivo executa suas operações de desligar, se houver, quando recebe a solicitação de IRP_MN_REMOVE_DEVICE . O proprietário da política de energia do dispositivo, normalmente o driver de função, não envia uma solicitação de IRP_MN_SET_POWER separada para definir o estado de energia do dispositivo como D3. O driver de barramento pai normalmente liga o slot e notifica o power manager com PoSetPowerState quando o driver de ônibus obtém o IRP de remoção. Para obter informações adicionais, consulte Gerenciamento de Energia.

  6. Desabilite todas as interfaces de dispositivo chamando IoSetDeviceInterfaceState.

  7. Libere todos os recursos de hardware para o dispositivo em uso pelo driver.

    As operações exatas dependem do dispositivo e do driver, mas podem incluir a desconexão de uma interrupção com IoDisconnectInterrupt, a liberação de intervalos de endereços físicos com MmUnmapIoSpace e a liberação de portas de E/S.

  8. Passe a solicitação de IRP_MN_REMOVE_DEVICE para o próximo driver.

    Configure o local da pilha IRP para o próximo driver inferior com IoSkipCurrentIrpStackLocation e passe o IRP para o próximo driver com IoCallDriver.

    Um driver não precisa esperar que os drivers subjacentes terminem suas operações de remoção antes de continuar com suas atividades de remoção.

  9. Remova o objeto de dispositivo da pilha de dispositivos com IoDetachDevice.

    Especifique um ponteiro para o próximo objeto de dispositivo inferior como o parâmetro TargetDevice . O driver recebe esse ponteiro da chamada para IoAttachDeviceToDeviceStack na rotina AddDevice do driver.

  10. Limpe todas as alocações específicas do dispositivo, memória, eventos e assim por diante.

  11. Libere o FDO com IoDeleteDevice.

  12. Retorne da rotina DispatchPnP, propagando a status de retorno de IoCallDriver.

Um driver de função não especifica uma rotina IoCompletion para um IRP de remoção, nem conclui o IRP. A remoção de IRPs é concluída pelo motorista do ônibus pai.