Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
[Применимо только к KMDF]
Как правило, функция обратного вызова EvtInterruptDpc драйвера завершает обработку каждой передачи DMA.
Во-первых, так как одновременно выполняется несколько транзакций DMA, функция обратного вызова EvtInterruptDpc должна определить, с какой транзакцией DMA связан завершенный перенос. Функция обратного вызова может сделать это, извлекая дескриптор транзакции, хранимый драйвером при запуске транзакции DMA. Чтобы получить расширение устройства, пример PLX9x5x определяет функцию PLxGetDeviceContext в своем заголовочном файле Private.h:
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_EXTENSION, PLxGetDeviceContext)
Затем в обратном вызове EvtInterruptDpc драйвера выполняется следующее:
WDFDMATRANSACTION dmaTransaction;
PDEVICE_EXTENSION devExt;
...
devExt = PLxGetDeviceContext(WdfInterruptGetDevice(Interrupt));
...
dmaTransaction = devExt->WriteDmaTransaction;
Затем функция обратного вызова EvtInterruptDpc должна сообщить платформе о завершении передачи, вызвав один из следующих методов завершения передачи:
WdfDmaTransactionDmaCompleted, если передача завершена успешно, а оборудование не сообщает количество переданных байтов.
WdfDmaTransactionDmaCompletedWithLength, если передача завершена успешно, а оборудование сообщает количество переданных байтов (или количество байтов, не передаваемых), или если драйвер обнаружил ошибку и указывает число передачи нулевого значения, чтобы повторить передачу. Если драйвер указывает число передачи равное нулю, фреймворк вычитает ноль из числа оставшихся байтов и таким образом отправляет ту же передачу в функцию обратного вызова EvtProgramDma.
WdfDmaTransactionDmaCompletedFinal, если оборудование сообщает о состоянии недостаточного запуска или сбоя.
Драйвер может вызвать WdfDmaTransactionGetCurrentDmaTransferLength , чтобы получить исходную длину завершенной передачи. Этот вызов полезен, если устройство сообщает количество байтов, которые не были переданы, так как драйвер может вычитать количество непереправляемых байтов из исходной длины передачи, а затем вызвать WdfDmaTransactionGetCurrentDmaTransferLength , чтобы сообщить о фактическом размере передачи.
Каждый из предыдущих методов завершения передачи сообщает платформе, что одна передача DMA (не вся транзакция DMA) завершена. После вызова одного из этих методов драйвер проверяет возвращаемое значение метода, чтобы определить, требует ли транзакция дополнительных передач.
Если возвращаемое значение метода завершения равно FALSE, платформа определила, что для завершения обработки транзакции DMA требуются дополнительные передачи DMA.
Как правило, функция обратного вызова EvtInterruptDpc драйвера возвращается. Платформа снова вызывает функцию обратного вызова EvtProgramDma драйвера, а функция обратного вызова может программировать оборудование для следующей передачи.
Методы завершения передачи возвращают статус, который всегда равен STATUS_MORE_PROCESSING_REQUIRED в этом случае.
Если возвращаемое значение равно TRUE, для транзакции DMA больше не будет выполняться передача.
Методы завершения передачи предоставляют значение состояния. Если значение состояния STATUS_SUCCESS, все передачи для транзакции DMA завершены, и драйвер должен завершить транзакцию DMA. Если значение состояния является чем-либо другим, произошла ошибка и транзакция DMA, возможно, не была завершена.
Если функция обратного вызова EvtInterruptDpc обнаруживает ошибку, обычно из-за истечения срока действия таймера или аппаратного прерывания, сигналящего об ошибке передачи, драйвер может перезапустить текущую передачу транзакции.
Чтобы перезапустить текущую передачу транзакции, функция обратного вызова EvtInterruptDpc драйвера может вызывать WdfDmaTransactionDmaCompletedWithLength с параметром TransferedLength , равным нулю.