Доброго времени суток.
Для некоторой PCIe платы осуществляется обработка запросов IRP_MJ_POWER (управление энергопотреблением).
Насколько я понимаю для того, чтобы платы была в рабочем состоянии после выхода из сна необходимо запросить, а затем передать вниз D-IRP (Device IRP) управления энергопотреблением.
У меня они запрашиваются в ф-ции завершения обработки S-IRP (System IRP).
Засыпание происходит без особых проблем (ф-ция завершения обработки power down D-IRP мне не особо нужна).
Когда система (Windows 7x64) просыпается, то мне нужно заново включить прерывания (которые я выключал перед засыпанием).
Как я понял, это следует делать в ф-ции завершения обработки power up D-IRP, и вот тут начинаются проблемы.
IoConnectInterrupt может выполнятся только на PASSIVE_LEVEL.
А вот ф-ция завершения обработки power up D-IRP почему-то вызывается на каком-то другом IRQL.
(Хотя раньше в ней стоял макрос PAGED_CODE и всё работало под Windows 7 (правда это было давно, на другом ПК, и с другой PCI платой).)
При попытке вызвать
IoConnectInterrupt возникает BSoD (0x121: 1, 2, 0, 0).
(Вызов этой функции окружён зажиганием лампочек, которые показывают, что сбой произошёл именно на этой ф-ции.
Без этого вызова система нормально пробуждается; плата (за исключением прерываний) работает нормально.)
Можно ли как-то заставить систему вызывать ф-цию завершения обработки D-IRP на PASSIVE_LEVEL?
(Примечательно то, что ф-ции завершения обработки S-IRP вызываются именно на PASSIVE_LEVEL (в них стоят макросы PAGED_CODE).)
В ф-ции AddDevice устанавливается флаг:
fdo->Flags |= DO_POWER_PAGABLE;