Функция 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, если операция выполнена успешно. В противном случае метод может вернуть одно из следующих значений.

Код возврата Описание
STATUS_INSUFFICIENT_RESOURCES
Драйвер, который ранее назывался WdfDmaTransactionSetImmediateExecution , и ресурсы, необходимые для запроса, недоступны.
STATUS_INVALID_DEVICE_REQUEST
Вызову WdfDmaTransactionExecute не предшествовал вызов WdfDmaTransactionInitialize или WdfDmaTransactionInitializeUsingRequest.
STATUS_WDF_BUSY
Устройство выполняет передачу одного пакета, а драйвер с именем WdfDmaTransactionExecute во время выполнения другой транзакции.
STATUS_WDF_TOO_FRAGMENTED
Количество элементов точечной и сборной, необходимое операционной системе для обработки указанного размера передачи, больше значения, указанного при вызове драйвера к 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)

См. также раздел

EvtProgramDma

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompleted

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionInitialize

WdfDmaTransactionInitializeUsingRequest

WdfDmaTransactionSetImmediateExecution