Noções básicas sobre o caminho dos IRPs de espera/ativação por meio de uma árvore de dispositivos

Em uma única pilha de dispositivos, o proprietário da política de energia envia um IRP de espera/ativação e todos os drivers lidam com o IRP de espera/ativação, conforme descrito em Visão geral da Operação de Espera/Ativação e detalhado em Enviar um IRP de Espera/Ativação e Receber um IRP de Espera/Ativação, respectivamente.

Dentro de uma ramificação da árvore de dispositivos (que compreende um devnode folha e os devnodes de seus pais, avós e assim por diante), os motoristas devem cooperar para garantir que um IRP de espera/ativação atinja um driver que possa habilitar todo o hardware necessário para ativação.

Em computadores ACPI, o ACPI é responsável por habilitar o registro gpe (evento de Uso Geral) específico do sistema associado ao sinal de ativação de cada dispositivo folha. Consequentemente, os drivers devem solicitar e encaminhar IRPs de espera/ativação até que um atinja um driver de filtro ACPI (inserido na pilha de dispositivos na inicialização) ou o driver de ACPI do Windows subjacente, Acpi.sys. Em resposta, o ACPI habilita o registro, mantém o IRP pendente até que o sinal chegue e conclua o IRP. Como o ACPI pode responder ao sinal de ativação, ele não encaminha o IRP para um driver inferior.

Os drivers de filtro ACPI, como o próprio driver ACPI subjacente, são transparentes para outros drivers. Para fornecer a máxima flexibilidade no design de hardware, a posição exata de um driver de filtro ACPI em qualquer pilha de dispositivos é específica do dispositivo e do sistema. Ao criar um driver, você não pode fazer nenhuma suposição sobre a presença ou posição de um filtro ACPI na pilha do dispositivo.

Tenha em mente que os drivers que enumeram filhos criam um PDO para cada dispositivo filho e um FDO para o dispositivo pai. Assim, o driver atua como o driver de barramento de um dispositivo filho e o driver de função/proprietário da política de um dispositivo pai. Portanto, sempre que um motorista de ônibus recebe um IRP de espera/ativação para um PDO filho, ele deve solicitar outro IRP de espera/ativação para seu PDO pai.

A figura a seguir mostra uma configuração de exemplo na qual essa situação ocorre.

diagrama ilustrando uma configuração usb de exemplo.

Na configuração de exemplo, o teclado e o modem são filhos do hub USB, que por sua vez é um filho do controlador de host USB, que é enumerado pelo barramento PCI. A figura a seguir mostra as pilhas de dispositivo para o teclado na configuração de exemplo.

diagrama ilustrando pilhas de dispositivos para a configuração de teclado usb de exemplo.

Como mostra a figura anterior, lendo de baixo para cima:

  1. O driver ACPI do Windows, Acpi.sys, cria o PDO para PCI.

  2. O driver PCI cria o PCI FDO e o PDO do controlador de host USB e possui a política para a pilha de dispositivos PCI.

  3. O driver do controlador de host USB (um par de driver de porta de host/miniport) cria o FDO do Controlador de Host USB e o PDO do Hub USB. Ele possui a política para a pilha de dispositivos do controlador de host USB. Observe que Acpi.sys cria um filtro DO nessa pilha também.

  4. O driver do hub USB cria o FDO do Hub USB e o PDO do teclado. Esse driver possui a política de energia para a pilha de dispositivos do hub USB.

  5. O driver de função para o teclado é o par driver/minidriver da classe HID USB. Esse driver cria o FDO para o teclado e possui sua política de energia. Como o teclado não tem dispositivos filho, esse driver não cria PDOs.

Observe que cada pilha de dispositivos pode incluir DOs de filtro opcionais adicionais que não são mostrados.

Para permitir que a entrada do teclado desperte o sistema, o proprietário da política para o teclado solicita um IRP_MN_WAIT_WAKE para seu PDO. Esse IRP define uma cadeia de outros IRPs de espera/ativação, conforme mostrado na figura a seguir.

solicitações de irp de espera/ativação para configuração usb de exemplo.

Quando um motorista de barramento recebe um IRP_MN_WAIT_WAKE direcionado a um PDO criado, ele deve solicitar outra IRP_MN_WAIT_WAKE para a pilha de dispositivos para a qual possui a política de energia e criou um FDO.

Como mostra a figura anterior:

  1. O driver de teclado chama PoRequestPowerIrp para enviar um IRP1 (IRP1) de espera/ativação para seu PDO.

    O power manager aloca o IRP e o envia pelo gerenciador de E/S para a parte superior da pilha do dispositivo para o teclado. Os drivers definem rotinas de IoCompletion e passam o IRP para baixo na pilha até atingir o PDO do teclado. O driver do hub USB, que atua como o driver de barramento para o teclado, mantém IRP1 pendente.

  2. Como o driver do hub USB não pode ativar o sistema quando o sinal de ativação chega, o driver do hub USB deve chamar PoRequestPowerIrp para solicitar um IRP (IRP2) de espera/ativação para a pilha de dispositivos do hub USB.

    O power manager envia esse IRP para a parte superior da pilha de dispositivos do hub USB. Os drivers nesta pilha definem rotinas IoCompletion e passam o IRP para baixo para o driver do controlador de host USB (que atua como o driver de ônibus para o hub USB). O driver do controlador de host USB mantém IRP2 pendente até que o teclado sinalize um evento de ativação.

  3. Da mesma forma, o driver do controlador de host USB não pode ativar o sistema, portanto, o driver do controlador de host USB chama PoRequestPowerIrp para enviar um IRP (IRP3) de espera/ativação para a pilha de dispositivos do controlador de host USB.

    O power manager envia esse IRP para a parte superior da pilha de dispositivos do controlador de host USB, em que os drivers definem rotinas de IoCompletion e passam o IRP para baixo para o driver PCI (que atua como o driver de ônibus para o hub USB). O driver PCI mantém IRP3 pendente até que o teclado sinalize um evento de ativação.

  4. O driver PCI não pode ativar o sistema, portanto, o driver PCI chama PoRequestPowerIrp para enviar um IRP (IRP4) de espera/ativação para a pilha de dispositivos PCI. Seu pai é o dispositivo raiz, para o qual o ACPI é o driver de ônibus.

    O power manager envia o IRP para a parte superior da pilha de dispositivos de barramento PCI; seus drivers definem rotinas de conclusão e passam o IRP para o driver ACPI do Windows, Acpi.sys.

  5. Acpi.sys pode ativar o sistema, portanto, ele não envia um IRP de espera/ativação para qualquer outro PDO. Acpi.sys mantém IRP4 pendente até que um sinal de ativação chegue.

Quando o teclado declara o sinal de ativação, Acpi.sys o intercepta. O ACPI, no entanto, não pode determinar que o teclado afirmou o sinal, apenas que o sinal veio por meio do dispositivo raiz. Acpi.sys conclui o IRP4 e o gerente de E/S chama rotinas de IoCompletion que viajam de volta para a pilha de dispositivos PCI. Quando IRP4 é concluído e todas as rotinas IoCompletion são executadas, a rotina de retorno de chamada do driver PCI é invocada. Em sua rotina de retorno de chamada, o driver PCI determina que o sinal veio por meio do controlador de host USB. Em seguida, o driver PCI conclui IRP3. A mesma sequência ocorre por meio da pilha do controlador de host USB e da pilha do hub USB, até que o driver de teclado receba IRP1. Neste ponto, o driver de teclado pode atender ao evento de ativação, conforme necessário.

Sempre que um driver envia um IRP de espera/ativação para um PDO pai, ele deve definir uma rotina Cancelar para seu próprio IRP. Definir uma rotina cancelar dá ao driver a oportunidade de cancelar o novo IRP se o IRP que o disparou for cancelado. No exemplo USB, se o driver de teclado cancelar o IRP de espera/ativação (desabilitando assim a ativação do teclado), o hub USB, o controlador de host USB e os drivers PCI deverão cancelar os IRPs enviados como consequência do IRP do teclado. Para obter mais informações, consulte Cancelar rotinas para IRPs de espera/ativação.

Embora um driver pai possa enumerar mais de um filho que pode ser habilitado para espera/ativação, apenas um IRP de espera/ativação pode estar pendente para um PDO. Nesses casos, o driver pai deve garantir que ele mantenha um IRP de espera/ativação pendente sempre que qualquer um de seus dispositivos estiver habilitado para ativação. Para fazer isso, o driver incrementa um contador interno sempre que recebe um IRP de espera/ativação. Sempre que o driver conclui um IRP de espera/ativação, ele diminui a contagem e, se o valor resultante não é zero, envia outro IRP de espera/ativação para sua pilha de dispositivos.

Por exemplo, na configuração USB mostrada anteriormente na figura Configuração USB de Exemplo, o hub USB enumera dois dispositivos, um teclado e um modem. Quando o driver do hub USB recebe um IRP de espera/ativação para o PDO do teclado, ele incrementa uma contagem de IRPs de espera/ativação antes de solicitar um IRP para seu próprio PDO. Se o proprietário da política do modem mais tarde habilitar a ativação para o modem, o driver do hub USB aguardará o novo IRP para o PDO do modem e incrementará sua contagem de referência de espera/ativação. No entanto, como o PDO do hub USB não pode ter dois IRPs de espera/ativação pendentes simultaneamente, o driver do hub USB não solicita um novo IRP de espera/ativação para o PDO do hub USB.

Quando um sinal de ativação chega do teclado ou modem, o driver do hub USB determina qual dispositivo sinalizou, conclui o IRP correspondente e diminui sua contagem de referência. Como ambos os dispositivos foram habilitados para ativação (e, portanto, sua contagem de referência não é zero), ele deve enviar sua própria pilha de dispositivos outro IRP de espera/ativação para "rearmar" seu próprio PDO para ativação. (O mesmo se aplica ao controlador de host USB e ao driver PCI.)

No entanto, um driver não envia um IRP para reabilitar a espera/ativação no mesmo dispositivo no qual um sinal de ativação acabou de chegar. Somente o gerenciador de políticas de energia do dispositivo pode fazer isso. A espera/ativação não é automática.