by jonh lan:
http://www.microsoft.com/whdc/driver/kernel/dma.mspx host a very good article interpreting NT DMA model,
during the digesting process, I got a question, what's the system routine used to flush DMA buffer after a
DMA op completion? this article says the system will call FlushAdatperBuffers, a callback to accomplish
this work, so i made a simple dig into it...
kd> bp nt!IoGetDmaAdapter
kd> g
Breakpoint 0 hit
nt!IoGetDmaAdapter:
808bedd4 mov edi,edi
kd> k
ChildEBP RetAddr
fcd6e544 fc6ce91a nt!IoGetDmaAdapter
fcd6e5a4 fca37459 NDIS!NdisMAllocateMapRegisters+0x128
fcd6e5d8 fc6c8b4a pcntpci5!LanceAllocateAdapterMemory+0x59
fcd6e5e4 fca3da04 NDIS!NdisCloseConfiguration+0x26
fcd6e748 fc6cb05c pcntpci5!LanceInitialize+0x76a
fcd6e900 fc6cb72c NDIS!ndisMInitializeAdapter+0x3b7
fcd6e9d4 fc6cb61a NDIS!ndisInitializeAdapter+0xb9
fcd6ea08 fc6cbcfc NDIS!ndisPnPStartDevice+0xd6
fcd6ea38 80828c95 NDIS!ndisPnPDispatch+0x306
fcd6ea4c 808ef45b nt!IofCallDriver+0x45
fcd6ea78 808da132 nt!IopSynchronousCall+0xbe
fcd6eabc 808da176 nt!IopStartDevice+0x4d
fcd6ead8 808da1b5 nt!PipProcessStartPhase1+0x4e
fcd6ed30 808cd141 nt!PipProcessDevNodeTree+0x1db
fcd6ed58 8080aa36 nt!PiProcessStartSystemDevices+0x3a
fcd6ed80 808203bd nt!PipDeviceActionWorker+0x186
fcd6edac 80905d2c nt!ExpWorkerThread+0xeb
fcd6eddc 80828499 nt!PspSystemThreadStartup+0x2e
00000000 00000000 nt!KiThreadStartup+0x16
kd> bp /1 /c @$csp @$ra;g
Breakpoint 2 hit
pci!PciPnpGetDmaAdapter+0x2b:
fc8a60c7 pop ebp
kd> dt hal!*dma*
hal!_DMA_ADAPTER
hal!_DMA_OPERATIONS
hal!_DMA_ADAPTER
hal!_DMA_OPERATIONS
kd> dt @eax hal!_DMA_ADAPTER -r
+0x000 Version : 1
+0x002 Size : 0x68
+0x004 DmaOperations : 0x80a6c230
+0x000 Size : 0x40
+0x004 PutDmaAdapter : 0x80a6fc1e hal!HalPutDmaAdapter+0
+0x008 AllocateCommonBuffer : 0x80a6f776 hal!HalAllocateCommonBuffer+0
+0x00c FreeCommonBuffer : 0x80a6f7e4 hal!HalFreeCommonBuffer+0
+0x010 AllocateAdapterChannel : 0x80a74c32 hal!IoAllocateAdapterChannel+0
+0x014 FlushAdapterBuffers : 0x80a70a04 hal!IoFlushAdapterBuffers+0
+0x018 FreeAdapterChannel : 0x80a6f9d0 hal!IoFreeAdapterChannel+0
+0x01c FreeMapRegisters : 0x80a6face hal!IoFreeMapRegisters+0
+0x020 MapTransfer : 0x80a70996 hal!IoMapTransfer+0
+0x024 GetDmaAlignment : 0x80a70d96 hal!HalGetDmaAlignment+0
+0x028 ReadDmaCounter : 0x80a7074e hal!HalReadDmaCounter+0
+0x02c GetScatterGatherList : 0x80a7019e hal!HalGetScatterGatherList+0
+0x030 PutScatterGatherList : 0x80a700a2 hal!HalPutScatterGatherList+0
+0x034 CalculateScatterGatherList : 0x80a6f7fc hal!HalCalculateScatterGatherListSize+0
+0x038 BuildScatterGatherList : 0x80a6fdf6 hal!HalBuildScatterGatherList+0
+0x03c BuildMdlFromScatterGatherList : 0x80a6fc96 hal!HalBuildMdlFromScatterGatherList+0
strictly speaking, the routine depends on how the IoGetDmaAdatper fill the filed, which need a reverse engineering
of IoGetDmaAdatper, though. but we can have a quick peer inside the fill result.