Função WdfDmaTransactionInitialize (wdfdmatransaction.h)
[Aplica-se somente ao KMDF]
O método WdfDmaTransactionInitialize inicializa uma transação de DMA especificada.
Sintaxe
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
);
Parâmetros
[in] DmaTransaction
Um identificador para um objeto de transação DMA que o driver obteve de uma chamada anterior para WdfDmaTransactionCreate.
[in] EvtProgramDmaFunction
Um ponteiro para a função de retorno de chamada de evento EvtProgramDma do driver.
[in] DmaDirection
Um valor de tipo WDF_DMA_DIRECTION.
[in] Mdl
Um ponteiro para uma MDL (lista de descritores de memória) que descreve o buffer que será usado para a transação de DMA. Veja mais informações em Comentários.
[in] VirtualAddress
O endereço virtual do buffer que será usado para a transação de DMA.
[in] Length
O número de bytes a serem transferidos.
Retornar valor
WdfDmaTransactionInitialize retornará STATUS_SUCCESS se a operação for bem-sucedida. Caso contrário, o método pode retornar um dos valores a seguir.
Código de retorno | Descrição |
---|---|
|
Não foi possível alocar uma lista de dispersão/coleta. |
|
Um parâmetro inválido foi detectado. |
|
O número de elementos de dispersão/coleta necessários para lidar com a transação foi maior do que o valor especificado pela chamada do driver para WdfDmaEnablerSetMaximumScatterGatherElements .
Para transações que foram definidas para transferência única, uma maneira de corrigir isso é copiar os dados para um buffer fisicamente contíguo e, em seguida, inicializar a transação com esse buffer. Por exemplo, chame MmAllocateContiguousMemory, copie os buffers originais para o novo e chame WdfDmaTransactionInitialize novamente. |
|
Esse valor retornado aplica-se somente a transações que foram definidas para transferência única.
O número de registros de mapa necessários para mapear a transação é maior do que o número reservado pelo adaptador de DMA. Para corrigir, o driver pode reduzir o número de registros de mapa necessários combinando uma cadeia de MDL em um único MDL. Os drivers que usam o DMA do sistema e pacote podem chamar WdfDmaTransactionAllocateResources para reservar vários registros de mapa do total alocado para o dispositivo. Suponha que o driver tenha reservado 4 de 8 registros totais de mapa, mas a transferência de DMA requer 6. Nesse caso, wdfDmaTransactionInitialize falha. Para corrigir, chame WdfDmaTransactionFreeResources e chame WdfDmaTransactionInitialize novamente. Os drivers que usam o AMD de dispersão/coleta não podem reservar registros de mapa. |
|
Esse valor retornado aplica-se somente a transações que foram definidas para transferência única.
O tamanho total da transação excede o tamanho máximo de transferência do dispositivo. |
Esse método também pode retornar outros valores NTSTATUS.
Um bug marcar ocorrerá se o driver fornecer um identificador de objeto inválido.
Comentários
O método WdfDmaTransactionInitialize prepara uma operação de DMA para execução, executando operações de inicialização, como alocar a lista de dispersão/coleta de uma transação. Depois que o driver chamar WdfDmaTransactionInitialize, o driver deverá chamar WdfDmaTransactionExecute para começar a executar a transação.
Drivers baseados em estrutura normalmente chamam WdfDmaTransactionInitialize de dentro de uma função de retorno de chamada de evento de fila de E/S.
Se você estiver criando uma transação de DMA baseada em informações que um objeto de solicitação de estrutura contém, seu driver deverá chamar WdfDmaTransactionInitializeUsingRequest. Se você estiver criando uma transação DMA que não se baseia em um objeto de solicitação, use WdfDmaTransactionInitialize ou WdfDmaTransactionInitializeUsingOffset.
O driver pode especificar uma cadeia MDL no parâmetro Mdl desse método. Uma cadeia MDL é uma sequência de estruturas MDL que o driver encadeou usando o membro Next da estrutura MDL. Em versões de estrutura anteriores à 1.11, somente transferências de DMA de dispersão/coleta podem usar cadeias de MDL. A partir da versão 1.11, se o driver estiver usando o DMA versão 3, as transferências de pacote único também poderão usar MDLs encadeados.
Se o buffer especificado pelo driver for maior que o comprimento máximo de transferência especificado pelo driver quando ele chamou WdfDmaEnablerCreate ou WdfDmaTransactionSetMaximumLength, a estrutura dividirá a transação em várias transferências.
Para obter mais informações sobre transações de DMA, consulte Criando e inicializando uma transação de DMA.
Exemplos
O exemplo de código a seguir é do driver de exemplo PLX9x5x . Primeiro, o exemplo inicializa uma estrutura WDF_OBJECT_ATTRIBUTES e cria um objeto de transação DMA. Em seguida, ele obtém um MDL que representa o buffer de entrada de uma solicitação de E/S recebida e obtém o endereço virtual e o comprimento do buffer. Por fim, o exemplo chama WdfDmaTransactionInitialize para inicializar a transação.
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;
}
Requisitos
Requisito | Valor |
---|---|
Plataforma de Destino | Universal |
Versão mínima do KMDF | 1.0 |
Cabeçalho | wdfdmatransaction.h (include Wdf.h) |
Biblioteca | Wdf01000.sys (consulte Controle de versão da biblioteca de estrutura.) |
IRQL | <=DISPATCH_LEVEL |
Regras de conformidade da DDI | DeferredRequestCompleted(kmdf), DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), MdlAfterReqCompletedIntIoctlA(kmdf), MdlAfterReqCompletedIoctlA(kmdf), MdlAfterReqCompletedReadA(kmdf), MdlAfterReqCompletedWriteA(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf) |