Routine ReleaseQueue du pilote de classe de stockage
À moins qu’un pilote de classe de stockage ne génère des requêtes SrbFlags pour une requête donnée avec SRB_FLAGS_NO_QUEUE_FREEZE, le pilote de port système fige une file d’attente pour une unité logique donnée après l’une des opérations suivantes :
Une réinitialisation de bus s’est produite pendant que l’unité logique exécutait une requête.
L’unité logique retournée SCSISTAT_CHECK_CONDITION ou SCSISTAT_COMMAND_TERMINATED, que le pilote de classe peut trouver dans le membre ScsiStatus du SRB.
Une demande a été expirée.
Une requête a été arrêtée par une commande de message de bus telle que SCSIMESS_ABORT.
Le pilote de port indique qu’une file d’attente spécifique à une unité logique a été figée en retournant une requête avec SRB_STATUS_QUEUE_FROZEN dans le membre SrbStatus . Les nouvelles demandes du pilote de classe peuvent être insérées dans la file d’attente, mais seules les demandes d’autosense sont envoyées à l’unité logique tant que sa file d’attente est figée.
Le gel de la file d’attente dans ces conditions permet à chaque pilote de classe de stockage d’analyser une erreur avant l’exécution d’autres travaux en file d’attente. Par exemple, les travaux mis en file d’attente peuvent devoir être annulés si le média a changé. Pour vider la file d’attente, le pilote peut envoyer une requête avec L’ORed SrbFlags avec SRB_FLAGS_BYPASS_FROZEN_QUEUE.
Une routine ReleaseQueue alloue et configure un IRP et un SRB pour libérer ou vider une file d’attente figée. Le membre Function du SRB doit être défini sur SRB_FUNCTION_RELEASE_QUEUE ou SRB_FUNCTION_FLUSH_QUEUE, ce qui libère une file d’attente figée et annule toutes les demandes actuellement en file d’attente pour l’unité logique cible. Le pilote de port termine toutes les requêtes dans une file d’attente vidée avec ses membres SrbStatus définis sur SRB_STATUS_REQUEST_FLUSHED.
Le fait de ne pas libérer une file d’attente figée rend l’appareil inaccessible. La routine ReleaseQueue d’un pilote doit donc être conçue pour réussir même dans des conditions de mémoire insuffisante. Une routine ReleaseQueue doit d’abord essayer d’allouer de la mémoire pour un SRB en appelant ExAllocatePool avec le type de mémoire NonPagedPool et, si cette allocation échoue, utiliser un SRB qui a été préalloué lors de l’initialisation du pilote. Si le pilote alloue un SRB à conserver en réserve lorsqu’il initialise son extension de périphérique, comme décrit dans Configuration d’une extension de périphérique du pilote de classe de stockage, sa version ReleaseQueue peut utiliser ce SRB si le pool de mémoires est faible, avec un mécanisme de synchronisation approprié au cas où plusieurs opérations de mise en production simultanées pourraient être nécessaires.
Notez que la routine ReleaseQueue d’un pilote de classe est appelée de manière asynchrone, généralement à partir de sa routine IoCompletion . La routine IoCompletion d’un pilote de classe ne peut pas appeler ReleaseQueue pour vider une file d’attente qui n’est pas figée. Toutefois, il peut appeler ReleaseQueue pour libérer une file d’attente d’annulation de l’efferdition, et le pilote de port ignore simplement une telle demande.