Поделиться через


Обработка IRP_MN_QUERY_POWER для состояний питания устройства

IRP с помощью запросов устройства запрашивает сведения об изменении состояния для одного устройства и отправляется всем драйверам в стеке устройства. Такой IRP указывает DevicePowerState в элементе Power.Type расположения стека ввода-вывода.

Драйверы обрабатывают irp мощности запросов по мере перемещения по стеку.

Драйвер функции или фильтра может не выполнить запрос IRP_MN_QUERY_POWER , если выполняется одно из следующих действий:

  • Устройство включено для пробуждения, и запрошенное состояние питания находится ниже состояния, из которого устройство может разбудить систему. Например, устройство, которое может разбудить систему из D2, но не из D3, не сможет выполнить запрос для D3, но успешно выполнить запрос для D2.

  • При вводе запрошенного состояния драйвер может отказаться от операции, которая приведет к потере данных, например при открытом модемном подключении. По этой причине драйвер редко завершает запрос; в большинстве случаев приложение обрабатывает такие случаи.

Чтобы не выполнить запрос IRP_MN_QUERY_POWER , драйвер выполняет следующие действия.

  1. Вызовите PoStartNextPowerIrp , чтобы указать, что драйвер готов к обработке следующего IRP питания. (Только Windows Server 2003, Windows XP и Windows 2000.)

  2. Задайте для параметра Irp-IoStatus.Status> состояние сбоя и вызовите IoCompleteRequest, указав IO_NO_INCREMENT. Драйвер не передает IRP дальше по стеку устройств.

  3. Возвращает состояние ошибки из подпрограммы DispatchPower .

Если драйвер успешно выполняет IRP, он не должен запускать какие-либо операции или предпринимать какие-либо другие действия, которые помешают успешному выполнению последующего IRP_MN_SET_POWER запроса к запрашиваемому состоянию питания.

Драйвер, который успешно выполняет IRP, должен подготовиться к IRP с заданной мощностью для запрашиваемого состояния и передать запрос IRP следующим образом:

  1. Завершите все невыполненные операции ввода-вывода.

  2. Очередь входящих запросов ввода-вывода.

  3. Избегайте запуска любых других новых действий, которые будут препятствовать переходу в указанное состояние питания. Однако драйвер не должен сохранять контекст устройства или предпринимать другие действия для завершения работы.

  4. Вызовите IoCopyCurrentIrpStackLocationToNext , чтобы задать расположение стека IRP для следующего ниже драйвера.

  5. Задайте подпрограмму IoCompletion . В процедуре IoCompletion вызовите PoStartNextPowerIrp (только Windows Server 2003, Windows XP и Windows 2000), чтобы указать готовность драйвера к обработке следующего IRP питания.

  6. Вызовите IoCallDriver (в Windows 7 и Windows Vista) или PoCallDriver (в Windows Server 2003, Windows XP и Windows 2000), чтобы передать IRP запроса следующему драйверу ниже. Не завершайте IRP.

  7. Возврат STATUS_PENDING. Драйвер не должен изменять значение в Irp-IoStatus.Status>.

Когда IRP с поддержкой запросов достигает драйвера шины, драйвер шины вызывает PoStartNextPowerIrp (только Windows Server 2003, Windows XP и Windows 2000) и задает Irp-IoStatus.Status> значение STATUS_SUCCESS, может ли драйвер изменить указанное состояние питания или задать состояние сбоя, если это невозможно. Затем водитель автобуса вызывает IoCompleteRequest, указывая IO_NO_INCREMENT.

Драйверы в типичном стеке устройств обрабатывают IRP с мощностью запросов устройства следующим образом:

  • Большинство драйверов фильтров должны просто передавать IRP в следующий драйвер ниже (см. раздел Передача irPs питания) и возвращать STATUS_PENDING. Однако некоторым драйверам фильтров может потребоваться выполнить задачи, относящиеся к конкретному устройству, такие как постановка в очередь входящих irP или экономия состояния питания устройства.

  • Драйвер-функция выполняет задачи, относящиеся к устройству (например, выполнение ожидающих запросов ввода-вывода, постановку в очередь входящих запросов ввода-вывода, сохранение контекста устройства или изменение питания устройства), устанавливает подпрограмму IoCompletion и передает IRP питания устройства следующему более низкому драйверу (см. раздел Передача power IRP). Он возвращает STATUS_PENDING из подпрограммы DispatchPower .

  • Драйвер шины вызывает PoStartNextPowerIrp (только Windows Server 2003, Windows XP и Windows 2000), чтобы запустить следующий IRP питания. Затем он завершает IRP, указывая IO_NO_INCREMENT. Если драйвер не может завершить IRP немедленно, он вызывает IoMarkIrpPending, возвращает STATUS_PENDING из своей подпрограммы DispatchPower и завершает IRP позже.

Даже если целевое устройство уже находится в запрашиваемом состоянии питания, каждый драйвер функции или фильтра должен поставить в очередь операции ввода-вывода и передать IRP следующему драйверу ниже. IRP должен пройти весь путь вниз по стеку устройства к водителю автобуса, который завершает его.

При обработке запроса IRP_MN_QUERY_POWER драйвер должен как можно быстрее вернуться из подпрограммы DispatchPower . Драйвер не должен ждать в своей подпрограмме DispatchPower события ядра, сигнализируют кодом, который обрабатывает тот же IRP. Так как поставщики интеграции питания синхронизируются по всей системе, может возникнуть взаимоблокировка.