Функция WdfDmaTransactionExecute (wdfdmatransaction.h)
[Применяется только к KMDF]
Метод WdfDmaTransactionExecute начинает выполнение указанной транзакции DMA.
Синтаксис
NTSTATUS WdfDmaTransactionExecute(
[in] WDFDMATRANSACTION DmaTransaction,
[in, optional] WDFCONTEXT Context
);
Параметры
[in] DmaTransaction
Дескриптор объекта транзакции DMA, полученного драйвером при предыдущем вызове WdfDmaTransactionCreate.
[in, optional] Context
Сведения о контексте, определяемые драйвером. Платформа передает значение, указанное для context , которое может быть указателем, в функцию обратного вызова события EvtProgramDma драйвера. Этот параметр является необязательным и может иметь значение NULL.
Возвращаемое значение
WdfDmaTransactionExecute возвращает STATUS_SUCCESS, если операция выполнена успешно. В противном случае метод может вернуть одно из следующих значений.
Код возврата | Описание |
---|---|
|
Драйвер, который ранее назывался WdfDmaTransactionSetImmediateExecution , и ресурсы, необходимые для запроса, недоступны. |
|
Вызову WdfDmaTransactionExecute не предшествовал вызов WdfDmaTransactionInitialize или WdfDmaTransactionInitializeUsingRequest. |
|
Устройство выполняет передачу одного пакета, а драйвер с именем WdfDmaTransactionExecute во время выполнения другой транзакции. |
|
Количество элементов точечной и сборной, необходимое операционной системе для обработки указанного размера передачи, больше значения, указанного при вызове драйвера к WdfDmaEnablerSetMaximumScatterGatherElements . Дополнительные сведения см. в разделе "Примечания". |
Этот метод также может возвращать другие значения NTSTATUS.
Ошибка проверка возникает, если драйвер предоставляет недопустимый дескриптор объекта.
Комментарии
Метод WdfDmaTransactionExecute инициализирует список точечной или собираемой транзакции для первой передачи DMA , связанной с указанной транзакцией DMA. (Для передачи с одним пакетом список точечной и сборной содержит один элемент.) Затем метод вызывает функцию обратного вызова события EvtProgramDma драйвера, и функция обратного вызова может запрограммировать устройство, чтобы начать передачу.
Драйверы на основе платформы обычно вызывают WdfDmaTransactionExecute из функции обратного вызова событий очереди ввода-вывода.
После вызова драйвером WdfDmaTransactionInitialize или WdfDmaTransactionInitializeUsingRequest для инициализации транзакции DMA драйвер должен вызвать WdfDmaTransactionExecute только один раз перед завершением транзакции DMA.
Если WdfDmaTransactionInitializeXxx возвращает успешное выполнение, а WdfDmaTransactionExecute возвращает значение ошибки, драйвер должен вызвать WdfDmaTransactionRelease.
В версиях платформы до 1.11, если устройство выполняет передачу одного пакета, операционная система может выполнять только одну транзакцию DMA за раз. В этом случае WdfDmaTransactionExecute возвращает STATUS_WDF_BUSY, если выполняется другая транзакция.
В версии платформы 1.11 и более поздних версиях, если драйвер использует DMA версии 3 для передачи одного пакета, операционная система может хранить несколько транзакций DMA во внутренней очереди. В этом случае драйвер может вызывать WdfDmaTransactionExecute во время выполнения другой транзакции. Чтобы выбрать DMA версии 3, установите для элемента WdmDmaVersionOverrideWDF_DMA_ENABLER_CONFIG значение 3.
Если устройство выполняет передачу точечной и сборной данных, операционная система может одновременно выполнять несколько транзакций DMA. В этом случае драйвер может вызывать WdfDmaTransactionExecute во время выполнения другой транзакции.
Если драйвер вызывает WdfDmaTransactionDmaCompletedWithLength , чтобы сообщить о частичной передаче, и если драйвер указал буфер данных транзакции DMA с помощью связанных с ним многомерных списков (с помощью элемента Next структуры MDL ), WdfDmaTransactionExecute может вернуть STATUS_WDF_TOO_FRAGMENTED так как платформа может пересчитать количество и размер фрагментов и может превысить количество разрешенных фрагментов.
WdfDmaTransactionExecute возвращает STATUS_SUCCESS, если транзакция была успешно запущена. Чтобы определить, успешно ли платформа отправила все передачи транзакций в функцию обратного вызова EvtProgramDma драйвера, драйвер должен вызвать WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompletedWithLength или WdfDmaTransactionDmaCompletedFinal.
Если значение, которое предоставляет параметр Context , является указателем или дескриптором, память, на которую он ссылается, должна быть доступна в функции обратного вызова события EvtProgramDma драйвера по адресу IRQL = DISPATCH_LEVEL. Для удовлетворения этого требования можно использовать контекст объекта платформы .
Драйвер может вызывать WdfDmaTransactionExecute без блокировки, если он ранее вызывал WdfDmaTransactionSetImmediateExecution.
Дополнительные сведения о транзакциях DMA см. в разделе Запуск транзакции DMA.
Примеры
Следующий пример кода из примера драйвера PCIDRV . В этом примере создается и инициализируется передача DMA и начинается ее выполнение.
NTSTATUS
NICInitiateDmaTransfer(
IN PFDO_DATA FdoData,
IN WDFREQUEST Request
)
{
WDFDMATRANSACTION dmaTransaction;
NTSTATUS status;
BOOLEAN bCreated = FALSE;
do {
status = WdfDmaTransactionCreate(
FdoData->WdfDmaEnabler,
WDF_NO_OBJECT_ATTRIBUTES,
&dmaTransaction
);
if(!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE,
"WdfDmaTransactionCreate failed %X\n", status);
break;
}
bCreated = TRUE;
status = WdfDmaTransactionInitializeUsingRequest(
dmaTransaction,
Request,
NICEvtProgramDmaFunction,
WdfDmaDirectionWriteToDevice
);
if(!NT_SUCCESS(status)) {
TraceEvents(
TRACE_LEVEL_ERROR,
DBG_WRITE,
"WdfDmaTransactionInitalizeUsingRequest failed %X\n",
status
);
break;
}
status = WdfDmaTransactionExecute(
dmaTransaction,
dmaTransaction
);
if(!NT_SUCCESS(status)) {
TraceEvents(
TRACE_LEVEL_ERROR,
DBG_WRITE,
"WdfDmaTransactionExecute failed %X\n",
status
);
break;
}
} while (FALSE);
if(!NT_SUCCESS(status)){
if(bCreated) {
WdfObjectDelete(dmaTransaction);
}
}
return status;
}
Требования
Требование | Значение |
---|---|
Целевая платформа | Универсальное |
Минимальная версия KMDF | 1,0 |
Верхняя часть | wdfdmatransaction.h (включая Wdf.h) |
Библиотека | Wdf01000.sys (см. раздел Управление версиями библиотеки платформы). |
IRQL | <=DISPATCH_LEVEL |
Правила соответствия DDI | DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf) |
См. также раздел
WdfDmaEnablerSetMaximumScatterGatherElements
WdfDmaTransactionDmaCompletedFinal
WdfDmaTransactionDmaCompletedWithLength