Escritura de un ISR
Los controladores de los dispositivos físicos que generan interrupciones deben tener al menos una rutina de servicio de interrupción (ISR). El ISR debe hacer lo que sea adecuado para el dispositivo para descartar la interrupción, posiblemente incluyendo detener la interrupción del dispositivo. A continuación, solo debe hacer lo necesario para guardar el estado y poner en cola un DPC para finalizar la operación de E/S con una prioridad inferior (IRQL) que la en la que se ejecuta el ISR.
El ISR de un controlador se ejecuta en un contexto de interrupción, en algún DIRQL asignado por el sistema, según lo especificado por el parámetro SynchronizeIrql en IoConnectInterruptEx.
Los ISR son interrumpibles. Otro dispositivo con un DIRQL asignado por el sistema superior puede interrumpir o puede producirse una interrupción del sistema IRQL alta en cualquier momento.
Antes de que el sistema llame a un ISR, adquiere el bloqueo de giro de la interrupción para que el ISR no se pueda ejecutar simultáneamente en otro procesador. Una vez devuelto el ISR, el sistema libera el bloqueo de número.
Dado que un ISR se ejecuta en un IRQL relativamente alto, que enmascara las interrupciones con un IRQL equivalente o inferior en el procesador actual, debe devolver el control lo más rápido posible. Además, la ejecución de un ISR en DIRQL restringe el conjunto de rutinas de soporte técnico a las que puede llamar el ISR. Para obtener más información, consulte Administración de prioridades de hardware.
Normalmente, un ISR realiza los siguientes pasos generales:
Si el dispositivo que provocó la interrupción no es uno compatible con el ISR, el ISR devuelve inmediatamente FALSE.
De lo contrario, el ISR borra la interrupción si es necesario, guarda el contexto del dispositivo y pone en cola un DPC para completar la operación de E/S en un IRQL inferior. Para obtener más información, consulte DPC Objects and DPCs (Objetos DPC y DPC ). A continuación, el ISR debe devolver TRUE.
En concreto, en los controladores que no se superponen a las operaciones de E/S del dispositivo, el ISR debe hacer lo siguiente:
Determine si la interrupción es falsa. Si es así, devuelva FALSE inmediatamente para que se llame inmediatamente al ISR del dispositivo que se interrumpió. De lo contrario, continúe con el procesamiento de interrupciones.
Detenga la interrupción del dispositivo, si es necesario.
Recopile la información de contexto que necesite la rutina DpcForIsr (o CustomDpc) para completar el procesamiento de E/S para la operación actual.
Almacene este contexto en un área accesible para la rutina DpcForIsr o CustomDpc , normalmente en la extensión de dispositivo del objeto de dispositivo de destino para el que el procesamiento de la solicitud de E/S actual provocó la interrupción.
Si un controlador se superpone a las operaciones de E/S, la información de contexto debe incluir un recuento de solicitudes pendientes que se necesita para completar la rutina DPC, junto con el contexto que la rutina DPC necesita para completar cada solicitud. Si se llama al ISR para controlar otra interrupción antes de que se haya ejecutado el DPC, no debe sobrescribir el contexto guardado de una solicitud que el DPC aún no ha completado.
Si el controlador tiene una rutina DpcForIsr , llame a IoRequestDpc con punteros al IRP actual, el objeto de dispositivo de destino y el contexto guardado. IoRequestDpc pone en cola la rutina DpcForIsr que se ejecutará en cuanto IRQL se encuentre por debajo de DISPATCH_LEVEL en un procesador.
Si el controlador tiene una rutina CustomDpc , llame a KeInsertQueueDpc con un puntero al objeto DPC (asociado a la rutina CustomDpc ) y punteros a cualquier contexto guardado, la rutina CustomDpc deberá completar la operación. Normalmente, el ISR también pasa punteros al IRP actual y al objeto de dispositivo de destino. La rutina CustomDpc se ejecuta en cuanto IRQL cae por debajo de DISPATCH_LEVEL en un procesador.
Devuelve TRUE para indicar que su dispositivo generó la interrupción.
En general, un ISR no realiza ningún procesamiento de E/S real para satisfacer un IRP. En su lugar, impide que su dispositivo interrumpa, configure la información de estado necesaria y pone en cola el DpcForIsr del controlador o CustomDpc para hacer cualquier procesamiento de E/S necesario para satisfacer la solicitud actual que provocó que el dispositivo se interrumpa.
Un ISR debe ejecutarse en DIRQL para el intervalo más corto posible. Siguiendo esta guía, aumenta el rendimiento de E/S para cada dispositivo de la máquina porque se ejecuta en máscaras DIRQL desactiva todas las interrupciones a las que el sistema ha asignado un valor IRQL menor o igual.
SynchronizeIrql de los objetos de interrupción del controlador, especificados cuando el controlador llamado IoConnectInterrupt, determina el DIRQL en el que se ejecuta el ISR del controlador. Para obtener más información, consulte Sincronizar el acceso a los datos del dispositivo.