Scrittura di un ISR
I driver per i dispositivi fisici che generano interruzioni devono avere almeno una routine del servizio di interruzione (ISR). L'ISR deve eseguire qualsiasi operazione appropriata per il dispositivo per ignorare l'interruzione, eventualmente inclusa l'interruzione del dispositivo. Quindi, deve eseguire solo ciò che è necessario per salvare lo stato e accodare un DPC per completare l'operazione di I/O a una priorità inferiore (IRQL) rispetto a quella in cui viene eseguito l'ISR.
L'ISR di un driver viene eseguito in un contesto di interruzione, in un contesto di interruzione assegnato dal sistema, come specificato dal parametro SyncIrql a IoConnectInterruptEx.
Gli ISR sono interrotti. Un altro dispositivo con un DIRQL assegnato al sistema superiore può interrompere o un interruzione del sistema IRQL elevato può verificarsi in qualsiasi momento.
Prima che il sistema chiami un ISR, acquisisce il blocco di rotazione dell'interruzione in modo che l'ISR non possa eseguire simultaneamente in un altro processore. Dopo aver restituito l'ISR, il sistema rilascia il blocco di rotazione.
Poiché un ISR viene eseguito a un IRQL relativamente elevato, che maschera gli interruzioni con un irQL equivalente o inferiore nel processore corrente, dovrebbe restituire il controllo il più rapidamente possibile. Inoltre, l'esecuzione di un ISR in DIRQL limita il set di routine di supporto che l'ISR può chiamare. Per altre informazioni, vedere Gestione delle priorità hardware.
In genere, un ISR esegue i passaggi generali seguenti:
Se il dispositivo che ha causato l'interruzione non è supportato da ISR, l'ISR restituisce immediatamente FALSE.
In caso contrario, l'ISR cancella l'interruzione, se necessario, salvando il contesto del dispositivo e accoda un DPC per completare l'operazione di I/O in un irQL inferiore. Per altre informazioni, vedere Oggetti DPC e DPC . L'ISR deve quindi restituire TRUE.
In particolare, nei driver che non si sovrappongono le operazioni di I/O del dispositivo, l'ISR deve eseguire le operazioni seguenti:
Determinare se l'interruzione è spuria. In tal caso, restituire FALSE immediatamente in modo che l'ISR del dispositivo che ha interrotto verrà chiamato tempestivamente. In caso contrario, continuare l'elaborazione degli interruzioni.
Arrestare il dispositivo, se necessario.
Raccogliere qualsiasi informazione sul contesto della routine DpcForIsr (o CustomDpc) dovrà completare l'elaborazione di I/O per l'operazione corrente.
Archiviare questo contesto in un'area accessibile alla routine DpcForIsr o CustomDpc , in genere nell'estensione del dispositivo di destinazione per cui l'elaborazione della richiesta di I/O corrente ha causato l'interruzione.
Se un driver si sovrappone alle operazioni di I/O, le informazioni sul contesto devono includere un numero di richieste in sospeso necessarie per completare la routine DPC, insieme a qualsiasi contesto la routine DPC deve completare ogni richiesta. Se l'ISR viene chiamato per gestire un altro interruzione prima dell'esecuzione del DPC, non deve sovrascrivere il contesto salvato per una richiesta che non è ancora stata completata dal DPC.
Se il driver ha una routine DpcForIsr , chiamare IoRequestDpc con puntatori all'IRP corrente, all'oggetto dispositivo di destinazione e al contesto salvato. IoRequestDpc accoda la routine DpcForIsr da eseguire non appena IRQL scende sotto DISPATCH_LEVEL in un processore.
Se il driver ha una routine CustomDpc , chiamare KeInsertQueueDpc con un puntatore all'oggetto DPC (associato alla routine CustomDpc ) e ai puntatori a qualsiasi contesto salvato la routine CustomDpc dovrà completare l'operazione. In genere, l'ISR passa anche puntatori all'IRP corrente e all'oggetto dispositivo di destinazione. La routine CustomDpc viene eseguita non appena IRQL scende sotto DISPATCH_LEVEL in un processore.
Restituisce TRUE per indicare che il dispositivo ha generato l'interruzione.
In generale, un ISR non esegue alcuna elaborazione di I/O effettiva per soddisfare un'IRP. Impedisce al dispositivo di interrompere, configurare le informazioni sullo stato necessarie e accodare il DpcForIsr o CustomDpc del driver per eseguire qualsiasi elaborazione di I/O necessaria per soddisfare la richiesta corrente che ha causato l'interruzione del dispositivo.
Un ISR deve essere eseguito in DIRQL per l'intervallo più breve possibile. Seguendo questa linea guida aumenta la velocità effettiva di I/O per ogni dispositivo nel computer perché in esecuzione in DIRQL vengono disattivati tutti gli interruzioni a cui il sistema ha assegnato un valore IRQL minore o uguale.
SyncIrql degli oggetti di interruzione del driver, specificato quando il driver denominato IoConnectInterrupt determina il valore DIRQL in cui viene eseguito l'ISR del driver. Per altre informazioni, vedere Sincronizzazione dell'accesso ai dati del dispositivo.