Подпрограмма releaseQueue драйвера класса хранилища
Если драйвер класса хранения не определяет SrbFlags для заданного запроса с SRB_FLAGS_NO_QUEUE_FREEZE, драйвер системного порта замораживает очередь для заданной логической единицы после любого из следующих действий:
Сброс шины произошел, когда логическая единица выполняла запрос.
Логическая единица возвращает SCSISTAT_CHECK_CONDITION или SCSISTAT_COMMAND_TERMINATED, которые драйвер класса может найти в элементе ScsiStatus SRB.
Истекло время ожидания запроса.
Запрос был завершен командой сообщения шины, например SCSIMESS_ABORT.
Драйвер порта указывает, что очередь lu-specific была заблокирована, возвращая запрос с SRB_STATUS_QUEUE_FROZEN в элементе SrbStatus . Новые запросы от драйвера класса можно вставить в очередь, но в логическую единицу отправляются только запросы автосенсии, если ее очередь зависла.
Замораживание очереди в этих условиях дает каждому драйверу класса хранения возможность проанализировать ошибку перед выполнением других заданий в очереди. Например, если носитель изменился, может потребоваться отменить задания, помещенные в очередь. Чтобы очистить очередь, драйвер может отправить запрос с SrbFlags ORed с SRB_FLAGS_BYPASS_FROZEN_QUEUE.
Подпрограмма ReleaseQueue выделяет и настраивает IRP и SRB для освобождения или очистки заблокированной очереди. Член функции SRB должен иметь значение SRB_FUNCTION_RELEASE_QUEUE или SRB_FUNCTION_FLUSH_QUEUE, что одновременно освобождает замороженную очередь и отменяет все текущие запросы в очереди для целевой логической единицы. Драйвер порта выполняет все запросы в очереди с очисткой с элементами SrbStatus , для SRB_STATUS_REQUEST_FLUSHED.
Если не выпустить замороженную очередь, устройство станет недоступным, поэтому подпрограмма ReleaseQueue драйвера должна быть разработана таким образом, чтобы она была успешной даже в условиях нехватки памяти. Подпрограмма ReleaseQueue должна сначала попытаться выделить память для SRB, вызвав ExAllocatePool с типом памяти NonPagedPool, и в случае сбоя выделения используйте SRB, который был предварительно выделен во время инициализации драйвера. Если драйвер выделяет SRB для хранения в резерве при инициализации расширения устройства, как описано в разделе Настройка расширения устройства драйвера класса хранилища, его ReleaseQueue может использовать этот SRB, если пул памяти имеет низкий уровень, с соответствующим механизмом синхронизации на случай, если может потребоваться несколько параллельных операций выпуска.
Обратите внимание, что подпрограмма ReleaseQueue драйвера класса называется асинхронно, как правило, из ее процедуры IoCompletion . Подпрограмма IoCompletion драйвера класса не может вызвать ReleaseQueue для очистки незамороженной очереди. Однако он может вызвать ReleaseQueue , чтобы освободить незамороженную очередь, и драйвер порта просто игнорирует такой запрос.