Démarrage d’une transaction DMA

[S’applique uniquement à KMDF]

Une fois que votre pilote a créé et initialisé une transaction DMA, il peut appeler la méthode WdfDmaTransactionExecute pour démarrer la transaction. Cette méthode génère une liste de points/regroupements pour le premier transfert DMA associé à la transaction. Ensuite, la méthode appelle la fonction de rappel EvtProgramDma que le pilote a inscrite pour la transaction. La fonction de rappel programme le matériel DMA pour démarrer le transfert.

Avant que votre pilote appelle WdfDmaTransactionExecute, le pilote doit stocker le handle de transaction DMA afin qu’il puisse être récupéré ultérieurement lorsque le pilote termine chaque transfert DMA associé à la transaction. Un bon emplacement pour stocker le handle de transaction est dans la mémoire contextuelle d’un objet framework, généralement l’objet d’appareil framework de l’appareil. Pour plus d’informations sur l’utilisation de la mémoire de contexte d’objet, consultez Espace de contexte d’objet framework.

L’exemple de code suivant de l’exemple PLX9x5x montre comment initialiser, puis exécuter une transaction DMA. Ce code apparaît dans le fichier Read.c .

VOID PLxEvtIoRead(
    IN WDFQUEUE         Queue,
    IN WDFREQUEST       Request,
    IN size_t           Length
    )
{
    NTSTATUS            status = STATUS_UNSUCCESSFUL;
    PDEVICE_EXTENSION   devExt;
    // Get the DevExt from the queue handle
    devExt = PLxGetDeviceContext(WdfIoQueueGetDevice(Queue));
    do {
        // Validate the Length parameter.
        if (Length > PCI9656_SRAM_SIZE)  {
            status = STATUS_INVALID_BUFFER_SIZE;
            break;
        }
        // Initialize the DmaTransaction.
        status = 
           WdfDmaTransactionInitializeUsingRequest(
                 devExt->ReadDmaTransaction,
                 Request, 
                 PLxEvtProgramReadDma, 
                 WdfDmaDirectionReadFromDevice 
           );
        if(!NT_SUCCESS(status)) {
            . . . //Error-handling code omitted
            break; 
        }
        // Execute this DmaTransaction.
        status = WdfDmaTransactionExecute( devExt->ReadDmaTransaction, 
                                           WDF_NO_CONTEXT);
        if(!NT_SUCCESS(status)) {
            . . . //Error-handling code omitted
            break; 
        }
        // Indicate that the DMA transaction started successfully.
        // The DPC routine will complete the request when the DMA
        // transaction is complete.
        status = STATUS_SUCCESS;
    } while (0);
    // If there are errors, clean up and complete the request.
    if (!NT_SUCCESS(status )) {
        WdfDmaTransactionRelease(devExt->ReadDmaTransaction); 
        WdfRequestComplete(Request, status);
    }
    return;
}