Compartir a través de


Rutina ReleaseQueue del controlador de clase storage

A menos que un controlador de clase de almacenamiento reenvíe los SrbFlags de una solicitud determinada con SRB_FLAGS_NO_QUEUE_FREEZE, el controlador de puerto del sistema inmoviliza una cola para una unidad lógica determinada después de cualquiera de las siguientes opciones:

  • Se produjo un restablecimiento de bus mientras la unidad lógica estaba ejecutando una solicitud.

  • La unidad lógica devuelta SCSISTAT_CHECK_CONDITION o SCSISTAT_COMMAND_TERMINATED, que el controlador de clase puede encontrar en el miembro ScsiStatus de SRB.

  • Se agotó el tiempo de espera de una solicitud.

  • Un comando de mensaje de bus finalizó una solicitud, como SCSIMESS_ABORT.

El controlador de puerto indica que una cola específica de LU se ha inmovilizado devolviendo una solicitud con SRB_STATUS_QUEUE_FROZEN en el miembro SrbStatus . Las nuevas solicitudes del controlador de clase se pueden insertar en la cola, pero solo las solicitudes de autosense se envían a la unidad lógica siempre que su cola esté inmovilizada.

La inmovilizar la cola en estas condiciones ofrece a cada controlador de clase de almacenamiento la oportunidad de analizar un error antes de que se ejecuten otros trabajos en cola. Por ejemplo, es posible que los trabajos en cola deban cancelarse si el medio ha cambiado. Para vaciar la cola, el controlador puede enviar una solicitud con SrbFlags ORed con SRB_FLAGS_BYPASS_FROZEN_QUEUE.

Una rutina ReleaseQueue asigna y configura un IRP y un SRB para liberar o vaciar una cola inmovilizada. El miembro Function del SRB debe establecerse en SRB_FUNCTION_RELEASE_QUEUE o SRB_FUNCTION_FLUSH_QUEUE, que libera una cola inmovilizada y cancela todas las solicitudes actualmente en cola para la unidad lógica de destino. El controlador de puerto completa todas las solicitudes de una cola vacía con sus miembros de SrbStatus establecidos en SRB_STATUS_REQUEST_FLUSHED.

Si no se libera una cola inmovilizada, el dispositivo no es accesible, por lo que la rutina ReleaseQueue de un controlador debe diseñarse para tener éxito incluso en condiciones de memoria baja. Una rutina ReleaseQueue primero debe intentar asignar memoria para un SRB llamando a ExAllocatePool con el tipo de memoria NonPagedPool y, si se produce un error en esa asignación, use un SRB que se asignó previamente durante la inicialización del controlador. Si el controlador asigna un SRB que se mantiene en reserva cuando inicializa su extensión de dispositivo, como se describe en Configuración de una extensión de dispositivo del controlador de clase de almacenamiento, su releaseQueue puede usar ese SRB si el grupo de memoria es bajo, con un mecanismo de sincronización adecuado en caso de que se necesiten varias operaciones de versión simultáneas.

Tenga en cuenta que la rutina ReleaseQueue de un controlador de clase se denomina de forma asincrónica, generalmente desde su rutina de IoCompletion . Una rutina de IoCompletion del controlador de clase no puede llamar a ReleaseQueue para vaciar una cola que no está inmovilizada. Sin embargo, puede llamar a ReleaseQueue para liberar una cola desfrozen y el controlador de puerto simplemente omite dicha solicitud.