Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
En drivrutin som använder system-DMA-styrenhetens autoinitieringsläge måste allokera minne för en buffert till vilken eller från vilken DMA-överföringar kan utföras. Drivrutinen anropar AllokeraCommonBuffer för att hämta den här bufferten, vanligtvis från DispatchPnP-rutinen som hanterar en IRP_MN_START_DEVICE begäran. Följande bild visar hur en drivrutin allokerar bufferten och mappar dess virtuella adressintervall till systemets fysiska minne.
Som föregående bild visar utför en drivrutin följande steg för att allokera en buffert för system-DMA:
Drivrutinen anropar AllocateCommonBuffer och skickar en pekare till adapterobjektet som returnerades av IoGetDmaAdapter, tillsammans med längden i byte som begärdes för bufferten. Om du vill använda minnet ekonomiskt bör indatalängdsvärdet för bufferten antingen vara mindre än eller lika med PAGE_SIZE eller vara en integrerad multipel av PAGE_SIZE.
Om AllokeraCommonBuffer returnerar en NULL-pekare bör drivrutinen frigöra alla systemresurser som den redan har begärt och returnera STATUS_INSUFFICIENT_RESOURCES som svar på IRP_MN_START_DEVICE begäran.
Annars allokerar AllocateCommonBuffer den begärda mängden minne i systemets virtuella adressutrymme och returnerar två olika typer av pekare till bufferten:
LogicalAddress för bufferten (BufferLogicalAddress i föregående bild), för vilken drivrutinen måste tillhandahålla lagring men som ska ignoreras efter det
Buffertens virtuella adress (BufferVirtualAddress i föregående bild), som drivrutinen också måste lagra så att den kan skapa en MDL som beskriver bufferten för DMA-åtgärder
Drivrutinen bör lagra dessa pekare i enhetsförlängningen eller annat permanent minne som har allokerats av drivrutinen.
Drivrutinen anropar IoAllocateMdl för att allokera en MDL för bufferten. Drivrutinen skickar VirtualAddress för bufferten som returneras av AllocateCommonBuffer och Längden på bufferten för att allokera en MDL.
Drivrutinen anropar MmBuildMdlForNonPagedPool med pekaren som returneras av IoAllocateMdl för att mappa det virtuella adressintervallet för dess residerande buffert till systemets fysiska minne.
När du har allokerat en gemensam buffert och mappat dess virtuella adressintervall kan drivrutinen för en underordnad enhet börja bearbeta en IRP som begär en DMA-överföring. För att göra det anropar föraren följande allmänna sekvens med supportrutiner:
Efter författarens gottfinnande kan drivrutinen använda RtlMoveMemory för att kopiera data från en låst användarbuffert till den drivrutinsallokerade gemensamma bufferten för överföring till enheten.
AllokeraAdapterChannel när drivrutinen är redo att programmera sin enhet för DMA och behöver system-DMA-styrenheten
MapTransfer, med MDL som beskriver den drivrutinsallokerade gemensamma bufferten, för att konfigurera systemets DMA-kontroller för överföringsåtgärden
Observera att drivrutinen bara anropar MapTransfer en gång för att konfigurera system-DMA-styrenheten för att använda sin gemensamma buffert. Under en överföring kan drivrutinen anropa ReadDmaCounter för att avgöra hur många byte som återstår att överföra och vid behov anropa RtlMoveMemory för att kopiera mer data till eller från en användarbuffert.
FlushAdapterBuffers när drivrutinen har slutfört sin DMA-överföring till eller från den underordnade enheten.
FreeAdapterChannel så snart alla begärda data har överförts eller om drivrutinen måste avbryta IRP på grund av ett enhets-I/O-fel
Den adapterobjektpekare som returneras av IoGetDmaAdapter är en obligatorisk parameter för var och en av dessa supportrutiner förutom RtlMoveMemory.
Enskilda drivrutiner anropar den här sekvensen av supportrutiner vid olika tidpunkter, beroende på hur varje drivrutin implementeras för att betjäna enheten. Till exempel kan en drivrutins StartIo-rutin göra anropet till AllocateAdapterChannel, en annan drivrutin kan göra det här anropet från en rutin som tar bort IRPs från en drivrutinskapad låsad kö, och ytterligare en drivrutin kan göra det här anropet när dess underordnade DMA-enhet anger att den är redo att överföra data.