Annullamento delle transazioni DMA
[Si applica solo a KMDF]
Se il driver è stato compilato con la versione 1.11 o successiva di KMDF ed è in esecuzione in Windows 8 o versione successiva usando l'accesso diretto alla memoria (DMA) versione 3, il driver può tentare di annullare una transazione DMA in sospeso chiamando il metodo WdfDmaTransactionCancel.
Quando si chiama WdfDmaTransactionCancel, il driver deve assicurarsi che la transazione DMA specificata non venga completata durante la chiamata. Il driver può usare la tecnica seguente per annullare in modo sicuro una transazione, prima dell'allocazione del canale DMA o dopo il completamento di alcune operazioni di trasferimento:
In uno dei gestori di richieste del driver il driver chiama WdfRequestMarkCancelableEx e fornisce una funzione di callback EvtRequestCancel per la richiesta di I/O. Il gestore della richiesta chiama quindi WdfDmaTransactionExecute.
La funzione di callback EvtRequestCancel del driver (che può iniziare a essere eseguita in un thread separato subito dopo la chiamata a WdfRequestMarkCancelableEx) chiama WdfDmaTransactionCancel.
Se la chiamata a WdfDmaTransactionCancel viene eseguita dopo la chiamata a WdfDmaTransactionExecute, ma prima che il metodo WdfDmaTransactionExecute abbia avviato l'allocazione DMA, l'annullamento delle transazioni ha esito positivo e WdfDmaTransactionCancel restituisce TRUE. In questo caso, la funzione di callback EvtRequestCancel del driver deve completare la transazione DMA. WdfDmaTransactionExecute restituisce un valore di errore.
Se il driver chiama WdfDmaTransactionCancel dopo che il metodo WdfDmaTransactionExecute ha avviato l'allocazione DMA, il tentativo di annullare la transazione ha esito negativo e WdfDmaTransactionCancel restituisce FALSE. In questo caso, WdfDmaTransactionExecute restituisce STATUS_SUCCESS e il gestore della richiesta del driver deve completare la transazione DMA.
A questo punto, se il driver usa DMA in modalità sistema, la funzione di callback EvtRequestCancel potrebbe chiamare WdfDmaTransactionStopSystemTransfer per tentare di arrestare il trasferimento DMA in modalità sistema in corso. Per un esempio di codice che illustra come eseguire questa operazione, vedere WdfDmaTransactionStopSystemTransfer.
Al termine dell'allocazione DMA del metodo WdfDmaTransactionExecute , il framework chiama la funzione di callback EvtProgramDma del driver, che può iniziare a essere eseguita in un thread separato immediatamente dopo la chiamata a WdfDmaTransactionExecute. A questo punto, una chiamata al metodo WdfDmaTransactionCancel restituirà FALSE.
In EvtProgramDma il driver può chiamare WdfRequestUnmarkCancelable per terminare la possibilità di annullamento della richiesta. Se WdfRequestUnmarkCancelable restituisce STATUS_SUCCESS, la funzione di callback deve programmare l'hardware per avviare il trasferimento. Se WdfRequestUnmarkCancelable restituisce STATUS_CANCELLED, la richiesta è stata annullata. In questo caso , EvtProgramDma deve chiamare WdfDmaTransactionDmaCompletedFinal per completare la transazione DMA.
Il driver può usare la stessa tecnica per annullare una transazione DMA dopo il completamento di alcune operazioni di trasferimento. In questo caso, il driver chiama WdfDmaTransactionCancel dopo che chiama WdfDmaTransactionDmaCompleted, ma prima che il framework chiami EvtProgramDma per programmare l'operazione di trasferimento successiva. Se il driver chiama WdfDmaTransactionCancel prima di chiamare WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompleted restituisce TRUE, a indicare che la transazione DMA è stata completata.