Funzione WdfDmaTransactionExecute (wdfdmatransaction.h)
[Si applica solo a KMDF]
Il metodo WdfDmaTransactionExecute inizia l'esecuzione di una transazione DMA specificata.
Sintassi
NTSTATUS WdfDmaTransactionExecute(
[in] WDFDMATRANSACTION DmaTransaction,
[in, optional] WDFCONTEXT Context
);
Parametri
[in] DmaTransaction
Handle per un oggetto transazione DMA ottenuto dal driver da una chiamata precedente a WdfDmaTransactionCreate.
[in, optional] Context
Informazioni sul contesto definite dal driver. Il framework passa il valore specificato per Context, che può essere un puntatore, alla funzione di callback dell'evento EvtProgramDma del driver. Questo parametro è facoltativo e può essere NULL.
Valore restituito
WdfDmaTransactionExecute restituisce STATUS_SUCCESS se l'operazione ha esito positivo. In caso contrario, il metodo potrebbe restituire uno dei valori seguenti.
Codice restituito | Descrizione |
---|---|
|
Il driver precedentemente denominato WdfDmaTransactionSetImmediateExecution e le risorse necessarie per la richiesta non sono disponibili. |
|
La chiamata a WdfDmaTransactionExecute non è stata preceduta da una chiamata a WdfDmaTransactionInitialize o WdfDmaTransactionInitializeUsingRequest. |
|
Il dispositivo esegue trasferimenti a pacchetto singolo e il driver denominato WdfDmaTransactionExecute durante l'esecuzione di un'altra transazione. |
|
Il numero di elementi a dispersione/raccolta necessari al sistema operativo per gestire le dimensioni di trasferimento specificate è maggiore del valore specificato dalla chiamata del driver a WdfDmaEnablerSetMaximumScatterGatherElements specificato. Per ulteriori informazioni, vedere la sezione Osservazioni successiva. |
Questo metodo potrebbe anche restituire altri valori NTSTATUS.
Se il driver fornisce un handle di oggetto non valido, si verifica un controllo di bug.
Commenti
Il metodo WdfDmaTransactionExecute inizializza l'elenco di dispersione/raccolta di una transazione per il primo trasferimento DMA associato alla transazione DMA specificata. Per i trasferimenti a pacchetto singolo, l'elenco a dispersione/raccolta contiene un singolo elemento. Il metodo chiama quindi la funzione di callback dell'evento EvtProgramDma del driver e la funzione di callback può programmare il dispositivo per avviare il trasferimento.
I driver basati su framework in genere chiamano WdfDmaTransactionExecute dall'interno di una funzione di callback degli eventi della coda di I/O.
Dopo che un driver ha chiamato WdfDmaTransactionInitialize o WdfDmaTransactionInitializeUsingRequest per inizializzare una transazione DMA, il driver deve chiamare WdfDmaTransactionExecute una sola volta prima di completare la transazione DMA.
Se WdfDmaTransactionInitializeXxx restituisce esito positivo, ma WdfDmaTransactionExecute restituisce un valore di errore, il driver deve chiamare WdfDmaTransactionRelease.
Nelle versioni del framework precedenti alla 1.11, se il dispositivo esegue trasferimenti a pacchetto singolo, il sistema operativo può eseguire una sola transazione DMA alla volta. In questo caso, WdfDmaTransactionExecute restituisce STATUS_WDF_BUSY se è in esecuzione un'altra transazione.
Nelle versioni framework 1.11 e successive, se il driver usa DMA versione 3 per eseguire trasferimenti a pacchetto singolo, il sistema operativo può archiviare più transazioni DMA in una coda interna. In questo caso, il driver può chiamare WdfDmaTransactionExecute mentre è in esecuzione un'altra transazione. Per selezionare DMA versione 3, impostare il membro WdmDmaVersionOverride di WDF_DMA_ENABLER_CONFIG su 3.
Se il dispositivo esegue trasferimenti a dispersione/raccolta, il sistema operativo può eseguire più transazioni DMA contemporaneamente. In questo caso, il driver può chiamare WdfDmaTransactionExecute mentre è in esecuzione un'altra transazione.
Se il driver chiama WdfDmaTransactionDmaCompletedWithLength per segnalare un trasferimento parziale e se il driver ha specificato il buffer di dati della transazione DMA usando gli ELENCHI di dati concatenati (usando il membro Next della struttura MDL ), WdfDmaTransactionExecute può restituire STATUS_WDF_TOO_FRAGMENTED perché il framework potrebbe ricalcolare il numero e le dimensioni dei frammenti e potrebbe superare il numero di frammenti consentiti.
WdfDmaTransactionExecute restituisce STATUS_SUCCESS se la transazione è stata avviata correttamente. Per determinare se il framework ha inviato correttamente tutti i trasferimenti della transazione alla funzione di callback EvtProgramDma del driver, il driver deve chiamare WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompletedWithLength o WdfDmaTransactionDmaCompletedFinal.
Se il valore fornito dal parametro Context è un puntatore o un handle, la memoria a cui fa riferimento deve essere accessibile nella funzione di callback dell'evento EvtProgramDma del driver in IRQL = DISPATCH_LEVEL. È possibile usare il contesto dell'oggetto framework per soddisfare questo requisito.
Il driver può chiamare WdfDmaTransactionExecute in modo non bloccante se in precedenza ha chiamato WdfDmaTransactionSetImmediateExecution.
Per altre informazioni sulle transazioni DMA, vedere Avvio di una transazione DMA.
Esempio
L'esempio di codice seguente è tratto dal driver di esempio PCIDRV . In questo esempio viene creato e inizializzato un trasferimento DMA e viene avviata l'esecuzione.
NTSTATUS
NICInitiateDmaTransfer(
IN PFDO_DATA FdoData,
IN WDFREQUEST Request
)
{
WDFDMATRANSACTION dmaTransaction;
NTSTATUS status;
BOOLEAN bCreated = FALSE;
do {
status = WdfDmaTransactionCreate(
FdoData->WdfDmaEnabler,
WDF_NO_OBJECT_ATTRIBUTES,
&dmaTransaction
);
if(!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE,
"WdfDmaTransactionCreate failed %X\n", status);
break;
}
bCreated = TRUE;
status = WdfDmaTransactionInitializeUsingRequest(
dmaTransaction,
Request,
NICEvtProgramDmaFunction,
WdfDmaDirectionWriteToDevice
);
if(!NT_SUCCESS(status)) {
TraceEvents(
TRACE_LEVEL_ERROR,
DBG_WRITE,
"WdfDmaTransactionInitalizeUsingRequest failed %X\n",
status
);
break;
}
status = WdfDmaTransactionExecute(
dmaTransaction,
dmaTransaction
);
if(!NT_SUCCESS(status)) {
TraceEvents(
TRACE_LEVEL_ERROR,
DBG_WRITE,
"WdfDmaTransactionExecute failed %X\n",
status
);
break;
}
} while (FALSE);
if(!NT_SUCCESS(status)){
if(bCreated) {
WdfObjectDelete(dmaTransaction);
}
}
return status;
}
Requisiti
Requisito | Valore |
---|---|
Piattaforma di destinazione | Universale |
Versione KMDF minima | 1.0 |
Intestazione | wdfdmatransaction.h (include Wdf.h) |
Libreria | Wdf01000.sys (vedere Controllo delle versioni della libreria framework). |
IRQL | <=DISPATCH_LEVEL |
Regole di conformità DDI | DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf) |
Vedi anche
WdfDmaEnablerSetMaximumScatterGatherElements
WdfDmaTransactionDmaCompletedFinal
WdfDmaTransactionDmaCompletedWithLength