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
STATUS_INSUFFICIENT_RESOURCES
Il driver precedentemente denominato WdfDmaTransactionSetImmediateExecution e le risorse necessarie per la richiesta non sono disponibili.
STATUS_INVALID_DEVICE_REQUEST
La chiamata a WdfDmaTransactionExecute non è stata preceduta da una chiamata a WdfDmaTransactionInitialize o WdfDmaTransactionInitializeUsingRequest.
STATUS_WDF_BUSY
Il dispositivo esegue trasferimenti a pacchetto singolo e il driver denominato WdfDmaTransactionExecute durante l'esecuzione di un'altra transazione.
STATUS_WDF_TOO_FRAGMENTED
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

EvtProgramDma

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompleted

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionInitialize

WdfDmaTransactionInitializeUsingRequest

WdfDmaTransactionSetImmediateExecution