Функция 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
Указатель на функцию обратного вызова события драйвера EvtProgramD ma.
[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 — это последовательность структур MDL, которые драйвер объединяет с помощью Next член структуры MDL. В версиях платформы до версии 1.11 передача DMA может использовать только цепочки MDL. Начиная с версии 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 (include 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) |