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 |
---|---|
|
Impossibile allocare un elenco di dispersione/raccolta. |
|
È stato rilevato un parametro non valido. |
|
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 . |
|
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. |
|
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) |