Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
[Alleen van toepassing op KMDF]
In dit onderwerp wordt de functionaliteit beschreven die een KMDF-stuurprogramma voor een DMA-apparaat met busmaster doorgaans biedt in de functie EvtProgramDma event callback. Als uw stuurprogramma gebruikmaakt van de DMA-ondersteuning van het framework, moet u deze callback opgeven. Deze informatie is ook van toepassing op een KMDF-stuurprogramma voor een DMA-apparaat in de systeemmodus met een hardware-interrupt.
De callback-functie EvtProgramDma, die wordt aangeroepen bij IRQL = DISPATCH_LEVEL, programmeert het apparaat om een DMA-overdracht te starten. De invoerparameters voor deze callback-functie leveren de richting van de overdracht (invoer of uitvoer) en een spreidings-/verzamellijst. Als de overdracht bestaat uit één pakket, bevat de spreidings-/verzamellijst één element.
De callback-functie EvtProgramDma programmeert het apparaat met behulp van de hardwarebronnen die de EvtDevicePrepareHardware callback-functie van het stuurprogramma heeft ontvangen. Als de callback-functie EvtProgramDma de hardware met succes programmeert, retourneert de functie TRUE.
Nadat de hardware de DMA-overdracht heeft voltooid, treedt er doorgaans een interrupt op en roept het systeem de callback-functie EvtInterruptIsr van het stuurprogramma aan. De callback-functie EvtInterruptIsr van het stuurprogramma wordt meestal:
Hiermee wordt de hardwareonderbreking gewist.
Slaat de contextinformatie van de interrupt op als dit nodig is. Deze informatie kan verloren gaan nadat de callback-functie werd uitgevoerd en het systeem de IRQL verlaagt, omdat het verlagen van de IRQL extra interrupts toestaat.
Roept WdfInterruptQueueDpcForIsr aan om een EvtInterruptDpc-callbackfunctie te plannen.
De callback-functie EvtInterruptDpcvoltooit de DMA-overdracht met behulp van contextinformatie die de callback-functie EvtInterruptIsr heeft opgeslagen.
Als de callback-functie EvtProgramDma een fout detecteert, kan het stuurprogramma de transactie stoppen.
Als u een transactie wilt stoppen wanneer het stuurprogramma een fout detecteert, moet de callbackfunctie EvtProgramDma :
Roep WdfDmaTransactionDmaCompletedFinal aan.
Roep WdfObjectDelete aan om het DMA-transactieobject te verwijderen of roep WdfDmaTransactionRelease aan om het DMA-transactieobject vrij te geven en opnieuw te gebruiken.
De I/O-aanvraag opnieuw in de wachtrij brengen of de I/O-aanvraag voltooien als de transactie is gekoppeld aan een frameworkaanvraagobject. Om een handle naar het verzoek op te halen, kan de driver WdfDmaTransactionGetRequest aanroepen.
Geef FALSE terug.
Stap 1 en 4 worden geïllustreerd in het volgende codevoorbeeld, genomen uit de functie EvtProgramDma van het PLX9x5x-voorbeeld voor callback voor leesaanvragen in het bestand Read.c.
// If errors occur in the EvtProgramDma callback,
// release the DMA transaction object and complete the request.
if (errors) {
NTSTATUS status;
//
// Must abort the transaction before deleting.
//
(VOID) WdfDmaTransactionDmaCompletedFinal(Transaction, 0, &status);
ASSERT(NT_SUCCESS(status));
PLxReadRequestComplete( Transaction, STATUS_INVALID_DEVICE_STATE );
TraceEvents(TRACE_LEVEL_ERROR, DBG_READ,
"<-- PLxEvtProgramReadDma: errors ****");
return FALSE;
}
In het voorbeeld wordt de functie PLxReadRequestComplete aangeroepen om stap 2 en 3 uit te voeren:
VOID
PLxReadRequestComplete(
IN WDFDMATRANSACTION DmaTransaction,
IN NTSTATUS Status
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
WDFREQUEST request;
size_t bytesTransferred;
//
// Get the associated request from the transaction.
//
request = WdfDmaTransactionGetRequest(DmaTransaction);
ASSERT(request);
//
// Get the final bytes transferred count.
//
bytesTransferred = WdfDmaTransactionGetBytesTransferred( DmaTransaction );
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC,
"PLxReadRequestComplete: Request %p, Status %!STATUS!, "
"bytes transferred %d\n",
request, Status, (int) bytesTransferred );
WdfDmaTransactionRelease(DmaTransaction);
//
// Complete this Request.
//
WdfRequestCompleteWithInformation( request, Status, bytesTransferred);
}