Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Неправильный IRQL в ф-ции завершения обработки D-IRP  (Прочитано 17258 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
WWX
Постоялец

ru
Offline Offline

« : 08-10-2021 14:50 » 

Доброго времени суток.

Для некоторой 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;
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 08-10-2021 17:12 » new

Доброго!
не совсем понял, что вы называете System IRP а что Device IRP?
IRP_MJ_SYSTEM_CONTROL и IRP_MJ_DEVICE_CONTROL???
или все таки обработку IRP_MJ_POWER когда  Parameters.Power.Typ = SystemPowerState или DevicePowerState?
последнее... ну вроде
Цитата
The power manager sends this IRP at IRQL = PASSIVE_LEVEL to device stacks that set the DO_POWER_PAGABLE flag in the PDO. Drivers in such stacks can touch paged code or data to complete the request.
но
Цитата
The power manager can send the IRP at IRQL = DISPATCH_LEVEL if the DO_POWER_INRUSH flag is set. Such drivers cannot directly or indirectly access any paged code or data.

Насчет завершение обработки - если я вас правильно понял и вы про обработку в CompletionRoutine? IoSetCompletionRoutine(Irp, CompletionRoutine,...)
тогда "A driver's IoCompletion routine executes in an arbitrary thread or DPC context, and at an IRQL that is less than or equal to DISPATCH_LEVEL"
и наверное на это не повлиять...
попробуйте переместить свою инициализацию прерывания в System Worker Threads к примеру, разместив свою процедуру через IoQueueWorkItem в системной нитке. Правда надо предусмотреть чтоб в промежутке никто не подумал к вашей плате обращаться как полностью готовой к работе. хотя там WorkItem исполнится довольно быстро, но формально надо учесть.
это нормальная практика.

Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
WWX
Постоялец

ru
Offline Offline

« Ответ #2 : 11-10-2021 12:00 » 

Цитата
или все таки обработку IRP_MJ_POWER когда  Parameters.Power.Typ = SystemPowerState или DevicePowerState?
последнее... ну вроде
Да, последнее.
(В каком-то старом DDK'шном примере использовалась такая терминология (S-IRP, D-IRP). Почему-то решил что это стандартная терминология, однако ж нет.)

Цитата
Насчет завершение обработки - если я вас правильно понял и вы про обработку в CompletionRoutine? IoSetCompletionRoutine(Irp, CompletionRoutine,...)
Именно так.

Цитата
тогда "A driver's IoCompletion routine executes in an arbitrary thread or DPC context, and at an IRQL that is less than or equal to DISPATCH_LEVEL"
А вот это именно то, что я почему-то прошляпил...
И объясняет почему могло работать раньше.

Цитата
попробуйте переместить свою инициализацию прерывания в System Worker Threads к примеру, разместив свою процедуру через IoQueueWorkItem в системной нитке. Правда надо предусмотреть чтоб в промежутке никто не подумал к вашей плате обращаться как полностью готовой к работе. хотя там WorkItem исполнится довольно быстро, но формально надо учесть.
это нормальная практика.

Про рабочие элементы думал (хотя раньше ими не особо пользовался), но мне это тогда казалось костыльным решением.
Сейчас сделал именно так - вроде работает.

Большое вам спасибо за быстрый ответ и помощь.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 11-10-2021 18:05 » 

пожалуйста)
Альтернатив особо нет по-моему. У меня была похожая проблема в CompletionRoutine, думал - ничего лучше не придумал, разве что свой процесс запускать с ожиданием WFSO, но это как-то избыточно ради одного вызова.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines