Een DMA-overdracht voltooien

[Alleen van toepassing op KMDF]

Normaal gesproken voltooit de callbackfunctie, EvtInterruptDpc, van uw stuurprogramma de verwerking van elke DMA-overdracht.

Ten eerste, omdat meerdere DMA-transacties gelijktijdig kunnen worden uitgevoerd, moet de callback-functie EvtInterruptDpc bepalen aan welke DMA-transactie de voltooide overdracht is gekoppeld. De callback-functie kan dit doen door de transactiehandle op te halen die het stuurprogramma heeft opgeslagen toen het de DMA-transactie startte. Om de apparaatextensie op te halen, definieert de voorbeeldcode PLX9x5x een functie genaamd PLxGetDeviceContext in het headerbestand Private.h.

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_EXTENSION, PLxGetDeviceContext)

Vervolgens, in de driver's EvtInterruptDpc callback, doet het het volgende:

WDFDMATRANSACTION   dmaTransaction;
PDEVICE_EXTENSION   devExt;
...
devExt  = PLxGetDeviceContext(WdfInterruptGetDevice(Interrupt));
...
dmaTransaction = devExt->WriteDmaTransaction;

Vervolgens moet de EvtInterruptDpc callback-functie het framework informeren dat een overdracht is voltooid, door een van de volgende methoden voor overdrachtsvoltooiing aan te roepen:

  • WdfDmaTransactionDmaCompleted, als de overdracht met succes is voltooid en de hardware geen aantal overgedragen bytes rapporteert.

  • #B0 #A1 WdfDmaTransactionDmaCompletedWithLength #A2 #A3, als de overdracht succesvol is voltooid en de hardware een telling rapporteert van overgedragen bytes (of het aantal bytes dat niet is overgedragen), of als het stuurprogramma een fout heeft gedetecteerd en een overdrachtsaantal van nul opgeeft om de overdracht opnieuw uit te voeren. Als het stuurprogramma een overdrachtsaantal van nul opgeeft, trekt het framework nul af van het aantal resterende bytes en stuurt de overdracht opnieuw naar de EvtProgramDma callback-functie.

  • #B0 #A1 WdfDmaTransactionDmaCompletedFinal #A2 #A3, als de hardware een underrun- of foutconditie rapporteert.

Uw stuurprogramma kan WdfDmaTransactionGetCurrentDmaTransferLength aanroepen om de oorspronkelijke lengte van de voltooide overdracht te verkrijgen. Deze aanroep is handig als uw apparaat een aantal bytes meldt dat niet is overgedragen, omdat het stuurprogramma het aantal niet-overgedragen bytes van de oorspronkelijke overdrachtslengte kan aftrekken en vervolgens WdfDmaTransactionGetCurrentDmaTransferLength kan oproepen om de werkelijke overdrachtsgrootte te rapporteren.

Elk van de voorgaande methoden voor het voltooien van overdrachten informeert het framework dat één DMA-overdracht voltooid is (niet de volledige DMA-transactie). Nadat uw stuurprogramma een van deze methoden heeft aangeroepen, controleert het stuurprogramma de retourwaarde van de methode om te zien of de transactie meer overdrachten vereist:

  • Als de terugkeerwaarde van de voltooiingsmethode FALSE is, heeft het framework vastgesteld dat er extra DMA-overdrachten nodig zijn om de DMA-transactie af te ronden.

    Normaal gesproken geeft de callback-functie EvtInterruptDpc van het stuurprogramma gewoon een waarde terug. Het framework roept opnieuw de EvtProgramDma callback-functie van de driver aan, en de callback-functie kan de hardware voor de volgende overdracht programmeren.

    De methoden voor het voltooien van de overdracht geven een statuswaarde, die in dit geval altijd STATUS_MORE_PROCESSING_REQUIRED is.

  • Als de retourwaarde TRUE is, worden er geen overdrachten meer uitgevoerd voor de DMA-transactie.

    De overdrachtsvoltooiingsmethoden bieden een statuswaarde. Als de statuswaarde STATUS_SUCCESS aangeeft, zijn alle overdrachten voor de DMA-transactie voltooid en moet het stuurprogramma de DMA-transactie voltooien. Als de statuswaarde iets anders is, is er een fout opgetreden en is de DMA-transactie mogelijk niet voltooid.

Als de #B0 #A1 EvtInterruptDpc #A2 #C3 callback-functie een fout detecteert, meestal doordat een timer is verlopen of een hardwareonderbreking een overdrachtsfout signaleert, kan het stuurprogramma de huidige overdracht van de transactie opnieuw starten.

Als u de huidige overdracht van de transactie opnieuw wilt starten, kan de #B0 #A1 EvtInterruptDpc #A2 #C3 callback-functie #B4 #A5 WdfDmaTransactionDmaCompletedWithLength-#A6 #C7 aanroepen met de parameter #B8 OvergedragenLength #C9 ingesteld op nul.