Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В одном стеке устройств владелец политики питания отправляет IRP ожидания и пробуждения, а все драйверы обрабатывают IRP ожидания и пробуждения, как описано в разделе "Обзор операции ожидания и пробуждения" и подробно описано в разделе "Отправка IRP ожидания и пробуждения", а также "Получение IRP ожидания и пробуждения" соответственно.
В ветви дерева устройств (которая состоит из конечного devnode и devnodes своих родителей, бабушек и дедушек и т. д.), драйверы должны сотрудничать, чтобы убедиться, что IRP ожидания/пробуждения достигает драйвера, который может активировать все необходимое оборудование для пробуждения.
На компьютерах ACPI ACPI отвечает за включение регистра событий общего назначения (GPE), связанного с сигналом пробуждения с каждого конечного устройства. Следовательно, драйверы должны запрашивать и перенаправлять запросы на ожидание и пробуждение, пока они не достигнут либо драйвера фильтра ACPI (вставленного в стек устройства при запуске), либо базового драйвера Windows ACPI, Acpi.sys. В ответ ACPI включает регистр, удерживает IRP в ожидании до прибытия сигнала, а затем завершает IRP. Так как ACPI может реагировать на сигнал пробуждения, он не перенаправит IRP на более низкий драйвер.
Драйверы фильтров ACPI, такие как базовый драйвер ACPI, прозрачны для других драйверов. Чтобы обеспечить максимальную гибкость в проектировании оборудования, точное положение драйвера фильтра ACPI в любом стеке устройств зависит от устройства и системы. При проектировании драйвера нельзя делать никаких предположений о присутствии или расположении фильтра ACPI в стеке устройств.
Помните, что драйверы, перечисляющие дочерние элементы, создают PDO для каждого дочернего устройства и FDO для родительского устройства. Таким образом, драйвер выступает в качестве драйвера шины устройства для дочернего устройства и драйвера функции/обладателя политики для родительского устройства. Таким образом, всякий раз, когда водитель автобуса получает IRP ожидания и пробуждения для дочернего PDO, он должен запросить другой идентификатор ожидания и пробуждения для родительского PDO.
На следующем рисунке показан пример конфигурации, в которой возникает такая ситуация.
В примере конфигурации клавиатура и модем являются дочерними элементами USB-концентратора, который, в свою очередь, является дочерним элементом USB-хост-контроллера, который распознается шиной PCI. На следующем рисунке показаны стеки устройств для клавиатуры в примере конфигурации.
Как показано на предыдущем рисунке, рассматривая снизу вверх:
Драйвер Windows ACPI, Acpi.sys, создает PDO для PCI.
Драйвер PCI создает FDO PCI и PDO контроллера USB и управляет политикой для стека PCI-устройств.
Драйвер контроллера USB-узла (пара драйверов порта узла или мини-порта) создает FDO контроллера USB-узла и PDO USB-концентратора. Она управляет политикой для стека устройств контроллера USB. Обратите внимание, что Acpi.sys также создает фильтр DO в этом стеке.
Драйвер USB-концентратора создает FDO USB-концентратора и PDO клавиатуры. Этот драйвер отвечает за политику питания для стека устройств USB-концентратора.
Драйвер функции для клавиатуры — это пара драйвера класса USB HID и минидрайвера. Этот драйвер создает FDO для клавиатуры и владеет политикой питания. Поскольку клавиатура не имеет дочерних устройств, этот драйвер не создает PDOs.
Обратите внимание, что каждый стек устройств может включать дополнительные необязательные объекты фильтрации, которые не отображаются.
Чтобы разрешить пробуждение системы при помощи ввода с клавиатуры, владелец политики клавиатуры запрашивает IRP_MN_WAIT_WAKE для ее PDO. Этот IRP запускает цепочку других IRP ожидания и пробуждения, как показано на следующем рисунке.
Когда драйвер шины получает IRP_MN_WAIT_WAKE, предназначенный для созданного им PDO, он должен запросить другой IRP_MN_WAIT_WAKE для стека устройств, для которого он отвечает за политику энергопитания и создал FDO.
Как показано на предыдущем рисунке:
Драйвер клавиатуры вызывает PoRequestPowerIrp , чтобы отправить IRP ожидания и пробуждения (IRP1) в его PDO.
Диспетчер питания выделяет IRP и отправляет его через диспетчер ввода-вывода на вершину стека устройств к клавиатуре. Драйверы устанавливают подпрограммы IoCompletion и передают IRP вниз по стеку, пока он не достигнет PDO клавиатуры. Драйвер USB-концентратора, который выступает в качестве драйвера шины для клавиатуры, оставляет IRP1 в состоянии ожидания.
Поскольку драйвер USB-концентратора не может пробудить систему, когда поступает сигнал пробуждения, он должен вызвать PoRequestPowerIrp, чтобы запросить IRP ожидания и пробуждения (IRP2) для стека устройств USB-концентратора.
Диспетчер питания отправляет этот IRP в верхнюю часть стека устройств USB-концентратора. Драйверы в этом стеке устанавливают подпрограммы IoCompletion и передают IRP в драйвер контроллера USB-узла (который выступает в качестве драйвера шины для USB-концентратора). Драйвер контроллера хоста USB удерживает выполнение IRP2 до тех пор, пока клавиатура не сигнализирует о событии пробуждения.
Аналогичным образом драйвер контроллера USB-хоста не может пробудить систему, поэтому драйвер контроллера USB-хоста вызывает PoRequestPowerIrp для отправки IRP ожидания/пробуждения (IRP3) в стек устройства контроллера USB.
Диспетчер питания отправляет этот IRP в верхнюю часть стека устройств контроллера USB, где драйверы устанавливают подпрограммы IoCompletion и передают IRP драйверу PCI (который выступает в качестве драйвера шины для USB-концентратора). Драйвер PCI удерживает IRP3 в ожидании, пока клавиатура не оповестит о событии пробуждения.
Драйвер PCI не может проснуть систему, поэтому драйвер PCI вызывает PoRequestPowerIrp для отправки IRP ожидания и пробуждения (IRP4) в стек устройств PCI. Его родитель — корневое устройство, для которого ACPI является драйвером шины.
Диспетчер питания отправляет IRP в верхнюю часть стека устройств шины PCI; его драйверы устанавливают подпрограммы завершения и передают IRP в драйвер Windows ACPI, Acpi.sys.
Acpi.sys может пробудить систему, поэтому он не отправляет IRP ожидания и пробуждения ни на один другой PDO. Acpi.sys удерживает IRP4 в ожидании до поступления сигнала пробуждения.
Когда клавиатура подает сигнал пробуждения, Acpi.sys его перехватывает. Однако ACPI не может определить, что клавиатура передавала сигнал, только то, что сигнал прошел через корневое устройство. Acpi.sys затем завершает IRP4, а диспетчер операций ввода-вывода вызывает подпрограммы IoCompletion , перемещающие резервные копии стека устройств PCI. После завершения IRP4 и выполнения всех подпрограмм IoCompletion вызывается подпрограмма обратного вызова драйвера PCI. В рамках процедуры обратного вызова драйвер PCI определяет, что сигнал прошел через контроллер USB-узла. Затем драйвер PCI завершает IRP3. Эта же последовательность происходит через стек хост-контроллера USB и стек USB-концентратора, пока драйвер клавиатуры не получит IRP1. На этом этапе драйвер клавиатуры может обслуживать событие пробуждения по мере необходимости.
Каждый раз, когда драйвер отправляет IRP ожидания и пробуждения в родительский PDO, он должен задать подпрограмму Отмены для собственного IRP. Установка подпрограммы отмены дает драйверу возможность отменить новый IRP, если IRP, вызвавший его, был отменен. В примере USB, если драйвер клавиатуры отменяет его IRP ожидания и пробуждения (таким образом отключая пробуждение клавиатуры), USB-концентратор, контроллер USB-узла и драйверы PCI должны отменить irPs, которые они отправили в результате клавиатуры IRP. Дополнительные сведения см. в разделе "Отмена подпрограмм для ожидания и пробуждения irps".
Хотя родительский драйвер может перечислить несколько дочерних элементов, которые могут быть включены для ожидания и пробуждения, для PDO может быть в состоянии ожидания только один IRP ожидания или пробуждения. В таких случаях родительский драйвер должен убедиться, что запрос на ожидание/пробуждение (IRP) остается в состоянии ожидания всякий раз, когда любое из его устройств включено для пробуждения. Для этого драйвер увеличивает внутренний счетчик каждый раз, когда он получает IRP ожидания и пробуждения. Каждый раз, когда драйвер завершает IRP ожидания и пробуждения, он уменьшает счетчик и, если результирующее значение ненулевое, отправляет другой IRP ожидания и пробуждения в стек устройств.
Например, в конфигурации USB, показанной ранее на рисунке "Пример конфигурации USB ", USB-концентратор перечисляет два устройства, клавиатуру и модем. Когда драйвер USB-концентратора получает IRP ожидания и пробуждения для PDO клавиатуры, он увеличивает количество запросов irps ожидания и пробуждения перед запросом IRP для собственного PDO. Если владелец политики модема позже включает пробуждение для модема, драйвер USB-концентратора записает новый IRP для модема PDO и увеличивает число ссылок на ожидание и пробуждение. Тем не менее, поскольку у PDO USB-концентратора не может быть два одновременно ожидающих IRP ожидания/пробуждения, драйвер USB-концентратора не запрашивает новый IRP ожидания/пробуждения для PDO USB-концентратора.
Когда сигнал пробуждения поступает из клавиатуры или модема, драйвер USB-концентратора определяет, какое устройство сигнализирует, завершает соответствующий IRP и уменьшает его количество ссылок. Так как оба устройства были настроены для пробуждения (и, следовательно, его счетчик ссылок ненулевой), оно должно отправить своему собственному стеку устройств другой IRP ожидания/пробуждения, чтобы перенастроить свой собственный PDO для пробуждения. (То же самое относится к контроллеру USB-узла и драйверу PCI.)
Тем не менее драйвер не отправляет себе IRP для повторного включения ожидания/пробуждения на том же устройстве, на котором только что был получен сигнал пробуждения. Это можно сделать только диспетчером политик питания устройства. Повторное включение режима ожидания/пробуждения не происходит автоматически.