Rotina ReleaseQueue do Driver de Classe de Armazenamento
A menos que um driver de classe de armazenamento ORs o SrbFlags para uma determinada solicitação com SRB_FLAGS_NO_QUEUE_FREEZE, o driver de porta do sistema congela uma fila para uma determinada unidade lógica após qualquer um dos seguintes:
Ocorreu uma redefinição de barramento enquanto a unidade lógica estava executando uma solicitação.
A unidade lógica retornou SCSISTAT_CHECK_CONDITION ou SCSISTAT_COMMAND_TERMINATED, que o driver de classe pode encontrar no membro ScsiStatus do SRB.
Uma solicitação atingiu o tempo limite.
Uma solicitação foi encerrada por um comando de mensagem de barramento, como SCSIMESS_ABORT.
O driver de porta indica que uma fila específica de LU foi congelada retornando uma solicitação com SRB_STATUS_QUEUE_FROZEN no membro SrbStatus . Novas solicitações do driver de classe podem ser inseridas na fila, mas apenas as solicitações de autosenseamento são enviadas para a unidade lógica, desde que sua fila esteja congelada.
Congelar a fila nessas condições dá a cada driver de classe de armazenamento a oportunidade de analisar um erro antes que outros trabalhos enfileirados sejam executados. Por exemplo, os trabalhos enfileirados podem precisar ser cancelados se a mídia tiver sido alterada. Para liberar a fila, o driver pode enviar uma solicitação com o SrbFlags ORed com SRB_FLAGS_BYPASS_FROZEN_QUEUE.
Uma rotina ReleaseQueue aloca e configura um IRP e um SRB para liberar ou liberar uma fila congelada. O membro Function do SRB deve ser definido como SRB_FUNCTION_RELEASE_QUEUE ou SRB_FUNCTION_FLUSH_QUEUE, que libera uma fila congelada e cancela todas as solicitações enfileiradas no momento para a unidade lógica de destino. O driver de porta conclui todas as solicitações em uma fila liberada com seus membros SrbStatus definidos como SRB_STATUS_REQUEST_FLUSHED.
A falha ao liberar uma fila congelada torna o dispositivo inacessível, portanto, a rotina ReleaseQueue de um driver deve ser projetada para ter sucesso mesmo em condições de memória baixa. Uma rotina ReleaseQueue deve primeiro tentar alocar memória para um SRB chamando ExAllocatePool com o tipo de memória NonPagedPool e, se essa alocação falhar, use um SRB que foi pré-alocado durante a inicialização do driver. Se o driver alocar um SRB para manter na reserva quando inicializar sua extensão de dispositivo, conforme descrito em Configurando uma Extensão de Dispositivo do Driver de Classe de Armazenamento, seu ReleaseQueue poderá usar esse SRB se o pool de memória estiver baixo, com um mecanismo de sincronização apropriado caso várias operações de liberação simultâneas possam ser necessárias.
Observe que a rotina ReleaseQueue de um driver de classe é chamada de forma assíncrona, geralmente de sua rotina IoCompletion . A rotina IoCompletion de um driver de classe não pode chamar ReleaseQueue para liberar uma fila que não está congelada. No entanto, ele pode chamar ReleaseQueue para liberar uma fila descongelada e o driver de porta simplesmente ignora essa solicitação.