Control de bloques de solicitudes de flujo
El sistema operativo envía todas las solicitudes de E/S en el dispositivo al controlador de clase. A su vez, el controlador de clase solicita información específica del hardware desde el minidriver pasando SRB al minidriver. El controlador de clase especifica la operación que solicita en el miembro Command del bloque de solicitud de secuencia.
Tanto el minidriver como un todo, como cada secuencia dentro del minidriver, pueden recibir solicitudes de E/S. El minidriver debe proporcionar una rutina StrMiniReceiveDevicePacket para controlar las solicitudes de todo el dispositivo. Cada secuencia debe admitir dos rutinas para controlar las solicitudes de E/S: una para las solicitudes de datos y otra para las solicitudes de control. El controlador de clase llama a la devolución de llamada de solicitud de datos, StrMiniReceiveStreamDataPacket, para controlar todas las solicitudes de lectura y escritura en una secuencia. Todas las demás solicitudes de una secuencia se pasan a StrMiniReceiveStreamControlPacket.
Si el controlador de clase controla la sincronización del minidriver, pone en cola las solicitudes de transmisión y los envía al minidriver de uno en uno. El controlador de clase mantiene tres colas independientes: una para las solicitudes de dispositivo y otra para los datos de flujo y las solicitudes de control. El minidriver puede indicar que está listo para una nueva solicitud de una de estas colas de la siguiente manera:
Tipo de solicitud | Rutina | Parámetro NotificationType de rutina |
---|---|---|
solicitud de dispositivo |
ReadyForNextDeviceRequest |
|
solicitud de control de flujo |
ReadyForNextStreamControlRequest |
|
solicitud de datos de flujo |
ReadyForNextStreamDataRequest |
Cuando el controlador de clase llama a StrMiniReceiveXXXPacket, entrega el bloque de solicitud de secuencia al minidriver. La rutina del minidriver tiene acceso exclusivo al bloque de solicitud de flujo hasta que señala al controlador de clase que ha completado la solicitud.
Cuando el minidriver termina de procesar una solicitud, debe indicar al controlador de clase que ha completado la solicitud de la siguiente manera:
El minidriver debe establecer el estado de la solicitud en el campo Estado del bloque de solicitud de secuencia.
El minidriver debe indicar que ha completado la solicitud mediante una llamada a StreamClassDeviceNotification o StreamClassStreamNotification. Para completar una solicitud de dispositivo, el minidriver llama a StreamClassDeviceNotification con un parámetro NotificationType de DeviceRequestComplete. Para completar una solicitud de secuencia, el minidriver llama a StreamClassStreamNotification con un parámetro NotificationType de StreamRequestComplete.
Si el controlador de clase controla la sincronización y el minidriver aún no ha señalado al controlador de clase que está listo para otra solicitud en esta cola, debería hacerlo ahora.
El minidriver puede combinar 2 y 3 llamando a StreamClassCompleteRequestAndMarkQueueReady.
El minidriver procesa las solicitudes de forma asincrónica, por lo que es posible que el controlador de clase tenga que cancelar o agotar el tiempo de espera de una solicitud. Para estos fines, el minidriver debe proporcionar una rutina StrMiniCancelPacket y StrMiniRequestTimeout . El controlador de clase llama a la rutina de minidriver correspondiente cuando cancela o agota el tiempo de espera de una solicitud.
El controlador de clase cancela una solicitud cuando el sistema operativo cancela la solicitud de E/S subyacente. El controlador de clase agota el tiempo de espera de las solicitudes que tardan demasiado tiempo en procesarse; disminuye un contador de cuántos segundos hasta que agota el tiempo de espera de una solicitud en el miembro TimeoutCounter del bloque de solicitud de flujo. Si el minidriver debe aplazar el procesamiento en una solicitud durante un largo período de tiempo, debe establecer el miembro TimeoutCounter en cero; el controlador de clase no agotará el tiempo de espera de la solicitud. Una vez que el minidriver reanuda el procesamiento de la solicitud, debe restablecer TimeoutCounter para que sea igual al miembro TimeoutOriginal del bloque de solicitud de secuencia. El minidriver puede restablecer TimeoutOriginal para cambiar el tiempo antes de que se agote el tiempo de espera de la solicitud. Consulte HW_STREAM_REQUEST_BLOCK para obtener más información.