Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
[Применимо только к KMDF]
В этом разделе описывается функциональность, которая драйвер KMDF для устройства с шиной-мастер DMA обычно предоставляет в функции обратного вызова события EvtProgramDma . Если драйвер использует поддержку DMA платформы, необходимо предоставить этот обратный вызов. Эта информация также относится к драйверу KMDF для устройства DMA в системном режиме , имеющего аппаратное прерывание.
Функция обратного вызова EvtProgramDma, которая вызывается на уровне IRQL = DISPATCH_LEVEL, программирует устройство для запуска передачи DMA . Входные параметры для этой функции обратного вызова включают направление передачи (вход или выход) и список рассеивания/сбора. Если передача состоит из одного пакета, список scatter/gather содержит один элемент.
Функция обратного вызова EvtProgramDma программируют устройство с помощью аппаратных ресурсов, полученных драйвером EvtDevicePrepareHardware функции обратного вызова. Если функция обратного вызова EvtProgramDma успешно программирует оборудование, она возвращает TRUE.
После завершения передачи DMA оборудованием обычно происходит генерация прерывания, и система вызывает функцию обратного вызова драйвера EvtInterruptIsr. Обычно функция обратного вызова драйвера EvtInterruptIsr:
Очищает аппаратное прерывание.
Сохраняет сведения о контексте прерывания, если это необходимо. Эта информация может быть потеряна после выполнения функции обратного вызова, когда система снижает уровень IRQL (поскольку снижение уровня IRQL позволяет происходить дополнительным прерываниям).
Вызывает функцию WdfInterruptQueueDpcForIsr для планирования обратного вызова EvtInterruptDpc.
Функция обратного вызова EvtInterruptDpc завершает передачу DMA , используя сведения о контексте, которые были сохранены функцией обратного вызова EvtInterruptIsr.
Если функция обратного вызова EvtProgramDma обнаруживает ошибку, драйвер может остановить транзакцию.
Чтобы остановить транзакцию при обнаружении ошибки драйвером, необходимо выполнить функцию обратного вызова EvtProgramDma:
Вызовите WdfObjectDelete для удаления объекта транзакции DMA или вызова WdfDmaTransactionRelease для освобождения и повторного использования объекта транзакции DMA.
повторно запросить ввод-вывод или завершите запрос ввода-вывода, если транзакция связана с объектом запроса фреймворка. Чтобы получить дескриптор запроса, драйвер может вызвать WdfDmaTransactionGetRequest.
Возвращает значение FALSE.
Шаги 1 и 4 показаны в следующем примере кода, взятом из PLX9x5xфункции обратного вызова EvtProgramDma для запросов на чтение в файле Read.c.
// If errors occur in the EvtProgramDma callback,
// release the DMA transaction object and complete the request.
if (errors) {
NTSTATUS status;
//
// Must abort the transaction before deleting.
//
(VOID) WdfDmaTransactionDmaCompletedFinal(Transaction, 0, &status);
ASSERT(NT_SUCCESS(status));
PLxReadRequestComplete( Transaction, STATUS_INVALID_DEVICE_STATE );
TraceEvents(TRACE_LEVEL_ERROR, DBG_READ,
"<-- PLxEvtProgramReadDma: errors ****");
return FALSE;
}
В примере вызывается функция PLxReadRequestComplete для выполнения шагов 2 и 3:
VOID
PLxReadRequestComplete(
IN WDFDMATRANSACTION DmaTransaction,
IN NTSTATUS Status
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
WDFREQUEST request;
size_t bytesTransferred;
//
// Get the associated request from the transaction.
//
request = WdfDmaTransactionGetRequest(DmaTransaction);
ASSERT(request);
//
// Get the final bytes transferred count.
//
bytesTransferred = WdfDmaTransactionGetBytesTransferred( DmaTransaction );
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC,
"PLxReadRequestComplete: Request %p, Status %!STATUS!, "
"bytes transferred %d\n",
request, Status, (int) bytesTransferred );
WdfDmaTransactionRelease(DmaTransaction);
//
// Complete this Request.
//
WdfRequestCompleteWithInformation( request, Status, bytesTransferred);
}