Condividi tramite


Funzione WdfDmaTransactionInitialize (wdfdmatransaction.h)

[Si applica solo a KMDF]

Il metodo WdfDmaTransactionInitialize inizializza una transazione DMA specificata.

Sintassi

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
);

Parametri

[in] DmaTransaction

Handle a un oggetto transazione DMA ottenuto dal driver da una chiamata precedente a WdfDmaTransactionCreate.

[in] EvtProgramDmaFunction

Puntatore alla funzione di callback dell'evento EvtProgramDma del driver.

[in] DmaDirection

Valore WDF_DMA_DIRECTION tipizzato.

[in] Mdl

Puntatore a un elenco di descrittori di memoria (MDL) che descrive il buffer che verrà usato per la transazione DMA. Per altre informazioni, vedere Osservazioni.

[in] VirtualAddress

Indirizzo virtuale del buffer che verrà usato per la transazione DMA.

[in] Length

Numero di byte da trasferire.

Valore restituito

WdfDmaTransactionInitialize restituisce STATUS_SUCCESS se l'operazione ha esito positivo. In caso contrario, il metodo potrebbe restituire uno dei valori seguenti.

Codice restituito Descrizione
STATUS_INSUFFICIENT_RESOURCES
Impossibile allocare un elenco di dispersione/raccolta.
STATUS_INVALID_PARAMETER
È stato rilevato un parametro non valido.
STATUS_WDF_TOO_FRAGMENTED
Il numero di elementi di dispersione/raccolta necessari per gestire la transazione è maggiore del valore specificato dalla chiamata del driver a WdfDmaEnablerSetMaximumScatterGatherElements .

Per le transazioni impostate per il singolo trasferimento, un modo per correggere questa operazione consiste nel copiare i dati in un buffer fisicamente contiguo e quindi inizializzare la transazione con tale buffer. Ad esempio, chiamare MmAllocateContiguousMemory, copiare i buffer originali nel nuovo, quindi chiamare di nuovo WdfDmaTransactionInitialize .

STATUS_WDF_NOT_ENOUGH_MAP_REGISTERS
Questo valore restituito si applica solo alle transazioni impostate per il trasferimento singolo.

Il numero di registri mappa necessari per eseguire il mapping della transazione è maggiore del numero riservato dell'adattatore DMA.

Per correggere, il driver potrebbe ridurre il numero di registri di mappa necessari combinando una catena MDL in un singolo MDL.

I driver che usano pacchetti e DMA di sistema possono chiamare WdfDmaTransactionAllocateResources per riservare un numero di registri mappa dal totale allocato al dispositivo. Si supponga che il driver riservato 4 su 8 registri totali della mappa, ma il trasferimento DMA richiede 6. In questo caso, WdfDmaTransactionInitialize ha esito negativo. Per correggere, chiamare WdfDmaTransactionFreeResources e quindi chiamare di nuovo WdfDmaTransactionInitialize .

I driver che usano DMA a dispersione/raccolta non possono riservare registri mappa.

STATUS_WDF_TOO_MANY_TRANSFERS
Questo valore restituito si applica solo alle transazioni impostate per il trasferimento singolo.

La lunghezza totale della transazione supera le dimensioni massime del trasferimento del dispositivo.

 

Questo metodo potrebbe restituire anche altri valori NTSTATUS.

Un controllo di bug si verifica se il driver fornisce un handle di oggetti non valido.

Commenti

Il metodo WdfDmaTransactionInitialize prepara un'operazione DMA per l'esecuzione, eseguendo operazioni di inizializzazione, ad esempio l'allocazione dell'elenco di dispersione/raccolta di una transazione. Dopo che il driver chiama WdfDmaTransactionInitialize, il driver deve chiamare WdfDmaTransactionExecute per iniziare a eseguire la transazione.

I driver basati su framework chiamano in genere WdfDmaTransactionInitialize dall'interno di una funzione di callback dell'evento di coda I/O.

Se si crea una transazione DMA basata su informazioni contenute in un oggetto richiesta framework, il driver deve chiamare WdfDmaTransactionInitializeUsingRequest. Se si crea una transazione DMA non basata su un oggetto request, usare WdfDmaTransactionInitialize o WdfDmaTransactionInitializeUsingOffset.

Il driver può specificare una catena MDL nel parametro Mdl di questo metodo. Una catena MDL è una sequenza di strutture MDL concatenate insieme dal driver usando il membro Next della struttura MDL. Nelle versioni del framework precedenti alla versione 1.11, solo i trasferimenti DMA a dispersione/raccolta possono usare catene MDL. A partire dalla versione 1.11, se il driver usa DMA versione 3, i trasferimenti a pacchetto singolo possono anche usare mdls concatenati.

Se il buffer specificato dal driver è maggiore della lunghezza massima di trasferimento specificata dal driver quando viene chiamato WdfDmaEnablerCreate o WdfDmaTransactionSetMaximumLength, il framework interrompe la transazione in più trasferimenti.

Per altre informazioni sulle transazioni DMA, vedere Creazione e inizializzazione di una transazione DMA.

Esempio

L'esempio di codice seguente è dal driver di esempio PLX9x5x5x . In primo luogo, l'esempio inizializza una struttura WDF_OBJECT_ATTRIBUTES e crea un oggetto transazione DMA. Ottiene quindi un MDL che rappresenta il buffer di input della richiesta di I/O ricevuto e ottiene l'indirizzo virtuale e la lunghezza del buffer. Infine, l'esempio chiama WdfDmaTransactionInitialize per inizializzare la transazione.

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;
}

Requisiti

Requisito Valore
Piattaforma di destinazione Universale
Versione KMDF minima 1,0
Intestazione wdfdmatransaction.h (include Wdf.h)
Libreria Wdf01000.sys (vedere Framework Library Versioning).
IRQL <=DISPATCH_LEVEL
Regole di conformità DDI DeferredRequestCompleted(kmdf), DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), MdlAfterReqCompletedIntIoctlA(kmdf), MdlAfterReqCompletedIoctlA(kmdf), MdlAfterReqCompletedReadA(kmdf), MdlAfterReqCompletedWriteA(kmdf), RequestCompletedLocal(kmdf)

Vedi anche

EvtProgramDma

MmGetMdlByteCount

MmGetMdlVirtualAddress

WDF_DMA_DIRECTION

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransactionCreate

WdfDmaTransactionExecute

WdfDmaTransactionInitializeUsingRequest