Функция WdfDmaTransactionInitialize (wdfdmatransaction.h)
[Применяется только к KMDF]
Метод WdfDmaTransactionInitialize инициализирует указанную транзакцию DMA.
Синтаксис
NTSTATUS WdfDmaTransactionInitialize(
[in] WDFDMATRANSACTION DmaTransaction,
[in] PFN_WDF_PROGRAM_DMA EvtProgramDmaFunction,
[in] WDF_DMA_DIRECTION DmaDirection,
[in] PMDL Mdl,
[in] PVOID VirtualAddress,
[in] size_t Length
);
Параметры
[in] DmaTransaction
Дескриптор объекта транзакции DMA, полученного драйвером при предыдущем вызове WdfDmaTransactionCreate.
[in] EvtProgramDmaFunction
Указатель на функцию обратного вызова события EvtProgramDma драйвера.
[in] DmaDirection
WDF_DMA_DIRECTION типизированное значение.
[in] Mdl
Указатель на список дескрипторов памяти (MDL), описывающий буфер, который будет использоваться для транзакции DMA. Дополнительные сведения см. в разделе Примечания.
[in] VirtualAddress
Виртуальный адрес буфера, который будет использоваться для транзакции DMA.
[in] Length
Число передаваемых байтов.
Возвращаемое значение
WdfDmaTransactionInitialize возвращает STATUS_SUCCESS, если операция выполнена успешно. В противном случае метод может вернуть одно из следующих значений.
Код возврата | Описание |
---|---|
|
Не удалось выделить точечный или собирающий список. |
|
Обнаружен недопустимый параметр. |
|
Количество элементов точечной и сборной, необходимых для обработки транзакции, больше значения, указанного в вызове драйвера wdfDmaEnablerSetMaximumScatterGatherElements .
Для транзакций, которые были настроены для одной передачи, один из способов исправить это — скопировать данные в физически непрерывный буфер, а затем инициализировать транзакцию этим буфером. Например, вызовите MmAllocateContiguousMemory, скопируйте исходные буферы в новый, а затем снова вызовите WdfDmaTransactionInitialize . |
|
Это возвращаемое значение применяется только к транзакциям, которые были заданы для одной передачи.
Количество регистров карты, необходимых для сопоставления транзакции, больше, чем количество зарезервированных адаптером DMA. Чтобы устранить эту проблему, драйвер может уменьшить количество необходимых регистров карты, объединяя цепочку MDL в один MDL. Драйверы, использующие пакетные и системные DMA, могут вызывать WdfDmaTransactionAllocateResources , чтобы зарезервировать количество регистров карты из общего объема, выделенного устройству. Предположим, что ваш драйвер зарезервировал 4 из 8 регистров карты, но для передачи DMA требуется 6. В этом случае происходит сбой WdfDmaTransactionInitialize . Чтобы исправить это, вызовите WdfDmaTransactionFreeResources , а затем снова вызовите WdfDmaTransactionInitialize . Драйверы, использующие точечную или сборную DMA, не могут резервировать регистры карт. |
|
Это возвращаемое значение применяется только к транзакциям, которые были заданы для одной передачи.
Общая длина транзакции превышает максимальный размер передачи устройства. |
Этот метод также может возвращать другие значения NTSTATUS.
Ошибка проверка возникает, если драйвер предоставляет недопустимый дескриптор объекта.
Комментарии
Метод WdfDmaTransactionInitialize подготавливает операцию DMA к выполнению путем выполнения операций инициализации, таких как выделение точечных и сборных списков транзакций. После вызова драйвером WdfDmaTransactionInitialize драйвер должен вызвать WdfDmaTransactionExecute , чтобы начать выполнение транзакции.
Драйверы на основе платформы обычно вызывают WdfDmaTransactionInitialize из функции обратного вызова событий очереди ввода-вывода.
Если вы создаете транзакцию DMA, основанную на сведениях, содержащихся в объекте запроса платформы, драйвер должен вызвать WdfDmaTransactionInitializeUsingRequest. Если вы создаете транзакцию DMA, которая не основана на объекте запроса, используйте WdfDmaTransactionInitialize или WdfDmaTransactionInitializeUsingOffset.
Драйвер может указать цепочку MDL в параметре Mdl этого метода. Цепочка MDL — это последовательность структур MDL, связанных драйвером с помощью элемента Next структуры MDL. В версиях платформ до 1.11 цепочки MDL могут использоваться только передачи точечной и сборной DMA. Начиная с версии 1.11, если драйвер использует DMA версии 3, передача одного пакета также может использовать связанные многомерные выражения.
Если указанный драйвером буфер больше максимальной длины передачи, указанной драйвером при вызове WdfDmaEnablerCreate или WdfDmaTransactionSetMaximumLength, платформа разбивает транзакцию на несколько передач.
Дополнительные сведения о транзакциях DMA см. в статье Создание и инициализация транзакции DMA.
Примеры
Следующий пример кода из примера драйвера PLX9x5x . Сначала в примере инициализируется структура WDF_OBJECT_ATTRIBUTES и создается объект транзакции DMA. Затем он получает MDL, представляющий входной буфер полученного запроса ввода-вывода, и получает виртуальный адрес и длину буфера. Наконец, в примере вызывается WdfDmaTransactionInitialize для инициализации транзакции.
WDF_OBJECT_ATTRIBUTES attributes;
PMDL mdl;
PVOID virtualAddress;
ULONG length;
NTSTATUS status;
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(
&attributes,
TRANSACTION_CONTEXT
);
status = WdfDmaTransactionCreate(
devExt->DmaEnabler,
&attributes,
&dmaTransaction
);
if(!NT_SUCCESS(status)) {
goto CleanUp;
}
status = WdfRequestRetrieveInputWdmMdl(
Request,
&mdl
);
if (!NT_SUCCESS(status)) {
goto CleanUp;
}
virtualAddress = MmGetMdlVirtualAddress(mdl);
length = MmGetMdlByteCount(mdl);
status = WdfDmaTransactionInitialize(
dmaTransaction,
PLxEvtProgramWriteDma,
WdfDmaDirectionWriteToDevice,
mdl,
virtualAddress,
length
);
if(!NT_SUCCESS(status)) {
goto CleanUp;
}
Требования
Требование | Значение |
---|---|
Целевая платформа | Универсальное |
Минимальная версия KMDF | 1,0 |
Верхняя часть | wdfdmatransaction.h (включая Wdf.h) |
Библиотека | Wdf01000.sys (см. раздел Управление версиями библиотеки платформы). |
IRQL | <=DISPATCH_LEVEL |
Правила соответствия DDI | DeferredRequestCompleted(kmdf), DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), MdlAfterReqCompletedIntIoctlA(kmdf), MdlAfterReqCompletedIoctlA(kmdf), MdlAfterReqCompletedReadA(kmdf), MdlAfterReqCompletedWriteA(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf) |