Rutina BuildRequest del controlador de clase de almacenamiento
Al igual que todos los controladores de modo kernel de nivel superior, un controlador de clase de almacenamiento debe configurar la ubicación de pila de E/S de IRP para el controlador inferior siguiente al controlar solicitudes a periféricos de almacenamiento. En IRP que el controlador de clase configura con SRB para el controlador de puerto proporcionado por el sistema, la ubicación de la pila de E/S del controlador de puerto se establece con lo siguiente:
MajorFunction contiene IRP_MJ_SCSI
Parameters.Scsi.Srb contiene un puntero a la SRB.
Cada controlador de clase es responsable de asignar memoria para SRB, así como para configurarlas con CDB para el controlador de puerto de almacenamiento subyacente. El controlador de clase puede configurar una lista de búsqueda para sus SRB con ExInitializeNPageLookasideList o llamar a ExAllocatePool para memoria no paginada. Consulte Uso de listas de lookaside para obtener más información sobre el uso de listas de lookaside y grupo no paginado.
Tanto si asigna memoria del grupo como de una lista de apariencias creadas por el controlador, cada controlador de clase de almacenamiento es responsable de liberar la memoria que asigna para srBs. Las rutinas de IoCompletion de los controladores de clase de almacenamiento, que se describen en Rutinas de IoCompletion del controlador de clase de almacenamiento, suelen liberar la memoria asignada para SRB en una lista de búsqueda.
La rutina BuildRequest de un controlador de clase debe establecer los valores adecuados en los miembros de SRB, incluida la longitud de la CDB que ha configurado para comunicarse con su dispositivo. En el caso de las solicitudes que devuelven información de detección de solicitudes o que es posible que el controlador necesite reintentar, establece una rutina de IoCompletion en el IRP. En el caso de las solicitudes de lectura o escritura, se reenrutan los SrbFlags con la dirección de transferencia adecuada, SRB_FLAGS_DATA_IN o SRB_FLAGS_DATA_OUT, respectivamente.
Una rutina BuildRequest podría compartir la responsabilidad de configurar un SRB con un par de rutinas SendSrbSynchronous y SendSrbAsynchronous . Es decir, la rutina BuildRequest podría configurar los miembros de SRB que normalmente están configurados para todas las solicitudes, mientras que las rutinas SendSrbXxx establecen cada valor SRB pertinente solo para cada tipo de solicitud. Cuando se pasa un IRP al controlador de puerto desde una rutina SendSrbAsynchronous , el IRP debe configurarse con una rutina de IoCompletion proporcionada por el controlador.
Una vez cargado el controlador de clase, configura la mayoría de los SRB con el miembro Function establecido en SRB_FUNCTION_EXECUTE_SCSI, lo que indica que se enviará una solicitud de E/S del dispositivo a través del bus.
Para obtener más información sobre los miembros de SRB definidos por el sistema y sus valores, consulte SCSI_REQUEST_BLOCK.
Configuración de SRB para el sentido de la solicitud
Un controlador de clase puede solicitar que el controlador de puerto devuelva el sentido de solicitud SCSI o información equivalente cuando el controlador de destino devuelva una condición de comprobación. Para ello, el controlador de clase configura el puntero SenseInfoBuffer y SenseInfoBufferLength en el SRB, por lo que el controlador de puerto puede devolver la información de detección de solicitudes si se produce una condición de comprobación. El controlador de puerto indica que devolvió información del sentido de la solicitud estableciendo el miembro SrbStatus con SRB_STATUS_AUTOSENSE_VALID cuando devuelve el IRP. Para obtener más información sobre las rutinas InterpretSenseInfo , consulte Rutina InterpretRequestSense del controlador de clase de almacenamiento.
Reintentos
Los controladores de clase de almacenamiento son responsables de reintentar solicitudes que producen errores debido a errores de destino o controlador, restablecimientos de bus o tiempos de espera de solicitud. Por lo tanto, muchos controladores de clase mantienen un recuento de reintentos en su propia ubicación de pila de E/S del IRP. Esta rutina buildRequest del controlador de clase también puede inicializar el límite de reintentos para una solicitud determinada antes de configurar su rutina de IoCompletion y enviar el IRP al controlador de puerto. Para obtener más información sobre las rutinas RetryRequest , consulte Rutina retryRequest del controlador de clase de almacenamiento.