Partilhar via


Iniciar um dispositivo num controlador de função

Um driver de função define uma rotina IoComplete, passa uma solicitação de IRP_MN_START_DEVICE para baixo na pilha de dispositivos e adia suas operações de início até que todos os drivers inferiores tenham terminado com o IRP. Consulte Adiando o processamento de IRP PnP até que os drivers inferiores terminem para obter informações detalhadas sobre como usar um evento do kernel e uma rotina de IoCompletion para adiar o processamento de IRP.

Quando a rotina DispatchPnP recupera o controle depois de todos os drivers inferiores terem concluído com o IRP, o driver de função realiza as suas tarefas de inicialização do dispositivo. Um driver de função inicia o dispositivo com um procedimento como o seguinte:

  1. Se um driver de nível inferior falhou em processar o IRP (IoCallDriver devolveu um erro), não continue a processar o IRP. Faça qualquer limpeza necessária e retorne da rotina DispatchPnP (vá para a última etapa desta lista).

  2. Se controladores inferiores processaram o IRP com êxito, inicie o dispositivo.

    As etapas exatas para iniciar um dispositivo variam de dispositivo para dispositivo. Essas etapas podem incluir o mapeamento do espaço de E/S, a inicialização de registros de hardware, a configuração do dispositivo no estado de energia D0 e a conexão da interrupção com IoConnectInterrupt. Se o driver estiver a reiniciar um dispositivo após uma solicitação de IRP_MN_STOP_DEVICE, o driver pode precisar restaurar o estado do dispositivo.

    O dispositivo deve estar ligado antes que qualquer motorista possa acessá-lo. Consulte Ligar um dispositivo para obter mais informações.

    Se o dispositivo deve ser ativado para despertar, o proprietário da política de energia (geralmente o driver da função) deve enviar um IRP de aguarda/desperta depois de energizar o dispositivo e antes de concluir a solicitação de IRP_MN_START_DEVICE. Para obter detalhes, consulte Envio de um IRP de espera/despertar.

  3. Inicie IRPs na fila de retenção de IRP.

    Limpe o sinalizador de HOLD_NEW_REQUESTS definido pelo driver e inicie os IRPs na fila de retenção de IRP. Os drivers devem fazer isso ao iniciar um dispositivo pela primeira vez e ao reiniciar um dispositivo após uma parada de consulta ou interrupção do IRP. Consulte Retenção dos IRPs de entrada quando um dispositivo está em pausa para obter mais informações.

  4. [Opcional] Habilite interfaces para o dispositivo chamando IoSetDeviceInterfaceState.

    Habilite as interfaces, caso existam, que o driver registou anteriormente na sua rotina AddDevice (ou num INF ou por outro componente, como um co-instalador).

    No Windows 2000 e versões posteriores do Windows, o gerenciador PnP não envia notificação de chegadas da interface do dispositivo até que o IRP IRP_MN_START_DEVICE seja concluído, indicando que todos os drivers para o dispositivo concluíram suas operações de inicialização. O gerenciador PnP também falha em todas as solicitações de criação que chegam antes de todos os drivers para o dispositivo concluírem o IRP inicial.

  5. Preencha o IRP.

    A rotina de de do driver de função IoCompletion retornou STATUS_MORE_PROCESSING_REQUIRED, conforme descrito em Adiando o processamento de IRP PnP até que os drivers inferiores terminem, portanto, a rotina de DispatchPnP do driver de função deve chamar IoCompleteRequest para retomar o processamento de conclusão de E/S.

    Se as operações de início do driver de função foram bem-sucedidas, o driver define Irp->IoStatus.Status para STATUS_SUCCESS, chama IoCompleteRequest com um impulso de prioridade de IO_NO_INCREMENT e retorna STATUS_SUCCESS de sua rotina de DispatchPnP .

    Se o driver de função encontrar um erro durante as suas operações de início, o driver define um status de erro no IRP, chama IoCompleteRequest com IO_NO_INCREMENT e retorna o erro da sua rotina de DispatchPnP.

    Se um driver inferior falhar no IRP (IoCallDriver retornar um erro), o driver de função chama IoCompleteRequest com IO_NO_INCREMENT e retorna o erro IoCallDriver de sua rotina DispatchPnP. O driver de função não define Irp->IoStatus.Status neste caso porque o status já foi definido pelo driver inferior que falhou o IRP.

Quando um driver de função recebe uma solicitação de IRP_MN_START_DEVICE, deve examinar as estruturas em IrpSp->Parameters.StartDevice.AllocatedResources e IrpSp->Parameters.StartDevice.AllocatedResourcesTranslated, que descrevem os recursos brutos e traduzidos, respectivamente, que o gestor PnP atribuiu ao dispositivo. Como um auxílio de depuração, os drivers devem salvar uma cópia de cada lista de recursos na extensão do dispositivo.

As listas de recursos são estruturas emparelhadas CM_RESOURCE_LIST, em que cada elemento da lista bruta corresponde ao mesmo elemento da lista traduzida. Por exemplo, se AllocatedResources.List [0] descrever um intervalo de portas de E/S brutas, AllocatedResourcesTranslated.List[0] descreverá o mesmo intervalo após a tradução. Cada recurso traduzido inclui um endereço físico e o tipo de recurso.

Se um driver receber um recurso de memória traduzido (CmResourceTypeMemory), ele deverá chamar MmMapIoSpace para mapear o endereço físico em um endereço virtual através do qual ele possa acessar registros de dispositivos. Para que um motorista opere de forma independente da plataforma, ele deve verificar cada recurso devolvido e traduzido e mapeá-lo, se necessário.

Um driver de função deve fazer o seguinte ao receber um IRP_MN_START_DEVICE para garantir o acesso a todos os recursos do dispositivo:

  1. Copie IrpSp->Parameters.StartDevice.AllocatedResources para a extensão do dispositivo.

  2. Copiar IrpSp->Parameters.StartDevice.AllocatedResourcesTranslated para a extensão do dispositivo.

  3. Em um loop, inspecione cada elemento descritor em AllocatedResourcesTranslated. Se o tipo de descritor de recurso for CmResourceTypeMemory, chame MmMapIoSpace, passando o endereço físico e o comprimento do recurso traduzido.

Quando o driver recebe uma solicitação de IRP_MN_STOP_DEVICE, IRP_MN_REMOVE_DEVICEou IRP_MN_SURPRISE_REMOVAL, ele deve liberar os mapeamentos chamando MmUnmapIoSpace em um loop semelhante. O driver também deve chamar MmUnmapIoSpace se for necessário falhar na solicitação de IRP_MN_START_DEVICE.

Consulte Mapeamento de Bus-Relative Endereços para Endereços Virtuais para obter mais informações.