Cancelando transações de DMA
[Aplica-se somente ao KMDF]
Se o driver tiver sido criado com a versão 1.11 ou posterior do KMDF e estiver em execução no Windows 8 ou posterior usando o DMA (acesso direto à memória) versão 3, o driver poderá tentar cancelar uma transação DMA pendente chamando o método WdfDmaTransactionCancel.
Ao chamar WdfDmaTransactionCancel, o driver deve garantir que a transação de DMA especificada não seja concluída durante a chamada. O driver pode usar a seguinte técnica para cancelar uma transação com segurança, antes da alocação de canal de DMA ou depois que algumas operações de transferência já tiverem sido concluídas:
Em um dos manipuladores de solicitação do driver, o driver chama WdfRequestMarkCancelableEx e fornece uma função de retorno de chamada EvtRequestCancel para a solicitação de E/S. Em seguida, o manipulador de solicitação chama WdfDmaTransactionExecute.
A função de retorno de chamada EvtRequestCancel do driver (que pode começar a ser executada em um thread separado imediatamente após a chamada para WdfRequestMarkCancelableEx) chamar WdfDmaTransactionCancel.
Se a chamada para WdfDmaTransactionCancel ocorrer após a chamada para WdfDmaTransactionExecute, mas antes que o método WdfDmaTransactionExecute inicie a alocação de DMA, o cancelamento da transação terá êxito e WdfDmaTransactionCancel retornará TRUE. Nesse caso, a função de retorno de chamada EvtRequestCancel do driver deve concluir a transação DMA. WdfDmaTransactionExecute retorna um valor de erro.
Se o driver chamar WdfDmaTransactionCancel depois que o método WdfDmaTransactionExecute tiver iniciado a alocação de DMA, a tentativa de cancelar a transação falhará e WdfDmaTransactionCancel retornará FALSE. Nesse caso, WdfDmaTransactionExecute retorna STATUS_SUCCESS e o manipulador de solicitação do driver deve concluir a transação de DMA.
Neste ponto, se o driver estiver usando o DMA do modo de sistema, a função de retorno de chamada EvtRequestCancel poderá chamar WdfDmaTransactionStopSystemTransfer para tentar interromper a transferência de DMA no modo de sistema em andamento. Para obter um exemplo de código que mostra como fazer isso, consulte WdfDmaTransactionStopSystemTransfer.
Depois que o método WdfDmaTransactionExecute conclui a alocação de DMA, a estrutura chama a função de retorno de chamada EvtProgramDma do driver (que pode começar a ser executada em um thread separado imediatamente após a chamada para WdfDmaTransactionExecute). Neste ponto, uma chamada para o método WdfDmaTransactionCancel retornaria FALSE.
No EvtProgramDma, o driver pode chamar WdfRequestUnmarkCancelable para acabar com a possibilidade de cancelamento de solicitação. Se WdfRequestUnmarkCancelable retornar STATUS_SUCCESS, a função de retorno de chamada deverá programar o hardware para iniciar a transferência. Se WdfRequestUnmarkCancelable retornar STATUS_CANCELLED, a solicitação será cancelada. Nesse caso, EvtProgramDma deve chamar WdfDmaTransactionDmaCompletedFinal para concluir a transação de AMD.
O driver pode usar a mesma técnica para cancelar uma transação de DMA depois que algumas operações de transferência já tiverem sido concluídas. Nesse caso, o driver chama WdfDmaTransactionCancel depois de chamar WdfDmaTransactionDmaCompleted, mas antes que a estrutura chame EvtProgramDma para programar a próxima operação de transferência. Se o driver chamar WdfDmaTransactionCancel antes de chamar WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompleted retornaráTRUE, indicando que a transação DMA foi concluída.