Поделиться через


Отмена транзакций DMA

[Относится только к KMDF]

Если драйвер был создан с версией 1.11 или более поздней версии KMDF и работает на Windows 8 или более поздней версии с использованием прямого доступа к памяти (DMA) версии 3, драйвер может попытаться отменить ожидающую транзакцию DMA, вызвав метод WdfDmaTransactionCancel.

При вызове WdfDmaTransactionCancel драйвер должен убедиться, что указанная транзакция DMA не завершена во время вызова. Драйвер может использовать следующий метод для безопасной отмены транзакции до выделения канала DMA или после того, как некоторые операции передачи уже завершены:

  1. В одном из обработчиков запросов драйвера драйвер вызывает WdfRequestMarkCancelableEx и предоставляет функцию обратного вызова EvtRequestCancel для запроса ввода-вывода. Затем обработчик запросов вызывает WdfDmaTransactionExecute.

  2. Функция обратного вызова EvtRequestCancel драйвера (которая может начать выполняться в отдельном потоке сразу после вызова WdfRequestMarkCancelableEx) вызывает WdfDmaTransactionCancel.

  3. Если вызов WdfDmaTransactionCancel происходит после вызова WdfDmaTransactionExecute, но до того, как метод WdfDmaTransactionExecute начал выделение DMA, отмена транзакции завершается успешно и WdfDmaTransactionCancel возвращает значение TRUE. В этом случае функция обратного вызова EvtRequestCancel драйвера должна завершить транзакцию DMA. WdfDmaTransactionExecute возвращает значение ошибки.

  4. Если драйвер вызывает WdfDmaTransactionCancel после того, как метод WdfDmaTransactionExecute запустил выделение DMA, попытка отменить транзакцию завершается сбоем и WdfDmaTransactionCancel возвращает значение FALSE. В этом случае WdfDmaTransactionExecute возвращает STATUS_SUCCESS и обработчик запросов драйвера должен завершить транзакцию DMA.

    На этом этапе, если драйвер использует DMA в системном режиме, функция обратного вызова EvtRequestCancel может вызвать WdfDmaTransactionStopSystemTransfer , чтобы попытаться остановить выполняемую передачу DMA в системном режиме. Пример кода, показывающий, как это сделать, см. в разделе WdfDmaTransactionStopSystemTransfer.

  5. После того как метод WdfDmaTransactionExecute завершит выделение DMA, платформа вызывает функцию обратного вызова EvtProgramDma драйвера (которая может начать выполняться в отдельном потоке сразу после вызова WdfDmaTransactionExecute). На этом этапе вызов метода WdfDmaTransactionCancel возвращает значение FALSE.

    В EvtProgramDma драйвер может вызвать WdfRequestUnmarkCancelable , чтобы положить конец возможности отмены запроса. Если WdfRequestUnmarkCancelable возвращает STATUS_SUCCESS, функция обратного вызова должна запрограммировать оборудование для запуска передачи. Если WdfRequestUnmarkCancelable возвращает STATUS_CANCELLED, запрос был отменен. В этом случае EvtProgramDma должен вызвать WdfDmaTransactionDmaCompletedFinal для завершения транзакции DMA.

    Драйвер может использовать тот же метод для отмены транзакции DMA после того, как некоторые операции передачи уже завершены. В этом случае драйвер вызывает WdfDmaTransactionCancel после вызова WdfDmaTransactionDmaCompleted, но до того, как платформа вызывает EvtProgramDma для программирования следующей операции передачи. Если драйвер вызывает WdfDmaTransactionCancel перед вызовом WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompleted возвращает значение TRUE, указывающее, что транзакция DMA завершена.