DEVICE_DESCRIPTIONdd;RtlZeroMemory(&dd,sizeof(dd));dd.Version=DEVICE_DESCRIPTION_VERSION;dd.Master=TRUE;dd.InterfaceType=InterfaceTypeUndefined;dd.MaximumLength=MAXTRANSFER;dd.Dma32BitAddresses=TRUE;pdx-AdapterObject=IoGetDmaAdapter(pdx-Pdo,&dd,&pdx-nMapRegisters);DEVICE_DESCRIPTION结构如下页:VOIDStopDevice(...){if(pdx-AdapterObject)(*pdx-AdapterObject-DmaOperations-PutDmaAdapter)(pdx-AdapterObject);pdx-AdapterObject=NULL;}FieldNameDescriptionRelevanttoDeviceVersionVersionnumberofstructure—initializetoDEVICE_DESCRIPTION_VERSIONAllMasterBus-masterdevice—setbasedonyourknowledgeofdeviceAllScatterGatherDevicesupportsscatter/gatherlist—setbasedonyourknowledgeofdeviceAllDemandModeUsesystemDMAcontroller’sdemandmode—setbasedonyourknowledgeofdeviceSlaveAutoInitializeUsesystemDMAcontroller’sautoinitializemode—setbasedonyourknowledgeofdeviceSlaveDma32BitAddressesCanuse32-bitphysicaladdressesAllIgnoreCountControllerdoesn’tmaintainanaccuratetransfercount—setbasedonyourknowledgeofdeviceSlaveReserved1Reserved—mustbeFALSEDma64BitAddressesCanuse64-bitphysicaladdressesAllDoNotUse2Reserved—mustbe0DmaChannelDMAchannelnumber—initializefromChannelattributeofresourcedescriptorSlaveInterfaceTypeBustype—initializetoInterfaceType-UndefinedAllDmaWidthWidthoftransfers—setbasedonyourknowledgeofdevicetoWidth8Bits,Width16Bits,orWidth32BitsSlaveDmaSpeedSpeedoftransfers—setbasedonyourknowledgeofdevicetoCompatible,TypeA,TypeB,TypeC,orTypeFSlaveMaximumLengthMaximumlengthofasingletransfer—setbasedonyourknowledgeofdevice(androunduptoamultipleofPAGE_SIZE)AllDmaPortMicrochannel-typebusportnumber—-initializefromPortattributeofresourcedescriptorSlavetypedefstruct_DEVICE_EXTENSION{PADAPTER_OBJECTAdapterObject;//device'sadapterobjectULONGnMapRegisters;//max#mapregistersULONGnMapRegistersAllocated;//#allocatedforthisxferULONGnumxfer;//#bytestransferredsofarULONGxfer;//#bytestotransferduringthisstageULONGnbytes;//#bytesremainingtotransferPVOIDvaddr;//virtualaddressforcurrentstagePVOIDregbase;//mapregisterbaseforthisstage}DEVICE_EXTENSION,*PDEVICE_EXTENSION;VOIDStartIo(PDEVICE_OBJECTfdo,PIRPIrp){PDEVICE_EXTENSIONpdx=(PDEVICE_EXTENSION)fdo-DeviceExtension;PMDLmdl=Irp-MdlAddress;pdx-numxfer=0;pdx-xfer=pdx-nbytes=MmGetMdlByteCount(mdl);pdx-vaddr=MmGetMdlVirtualAddress(mdl);ULONGnregs=ADDRESS_AND_SIZE_TO_SPAN_PAGES(pdx-vaddr,pdx-nbytes);if(nregspdx-nMapRegisters){nregs=pdx-nMapRegisters;pdx-xfer=nregs*PAGE_SIZE-MmGetMdlByteOffset(mdl);}pdx-nMapRegistersAllocated=nregs;NTSTATUSstatus=(*pdx-AdapterObject-DmaOperations-AllocateAdapterChannel)(pdx-AdapterObject,fdo,nregs,(PDRIVER_CONTROL)AdapterControl,pdx);if(!NT_SUCCESS(status)){CompleteRequest(Irp,status,0);StartNextPacket(&pdx-dqReadWrite,fdo);}}IO_ALLOCATION_ACTIONAdapterControl(PDEVICE_OBJECTfdo,PIRPjunk,PVOIDregbase,PDEVICE_EXTENSIONpdx){PIRPIrp=GetCurrentIrp(&pdx-dqReadWrite);//这里如何取得IRP要看排队机制PMDLmdl=Irp-MdlAddress;PIO_STACK_LOCATIONstack=IoGetCurrentIrpStackLocation(Irp);BOOLEANisread=stack-MajorFunction==IRP_MJ_READ;pdx-regbase=regbase;KeFlushIoBuffers(mdl,isread,TRUE);PHYSICAL_ADDRESSaddress=(*pdx-AdapterObject-DmaOperations-MapTransfer)(pdx-AdapterObject,mdl,regbase,pdx-vaddr,pdx-xfer,!isread);……returnDeallocateObjectKeepRegisters;}VOIDDpcForIsr(PKDPCDpc,PDEVICE_OBJECTfdo,PIRPjunk,PDEVICE_EXTENSIONpdx){PIRPIrp=GetCurrentIrp(&pdx-dqReadWrite);PMDLmdl=Irp-MdlAddress;BOOLEANisread=IoGetCurrentIrpStackLocation(Irp)-MajorFunction==IRP_MJ_READ;(*pdx-AdapterObject-DmaOperations-FlushAdapterBuffers)(pdx-AdapterObject,mdl,pdx-regbase,pdx-vaddr,pdx-xfer,!isread);pdx-nbytes-=pdx-xfer;pdx-numxfer+=pdx-xfer;NTSTATUSstatus=STATUS_SUCCESS;……判断是否读写正确的完成了if(pdx-nbytes&&NT_SUCCESS(status)){pdx-vaddr=(PVOID)((PUCHAR)pdx-vaddr+pdx-xfer);pdx-xfer=pdx-nbytes;ULONGnregs=ADDRESS_AND_SIZE_TO_SPAN_PAGES(pdx-vaddr,pdx-nbytes);if(nregspdx-nMapRegistersAllocated){nregs=pdx-nMapRegistersAllocated;pdx-xfer=nregs*PAGE_SIZE;}PHYSICAL_ADDRESSaddress=(*pdx-AdapterObject-DmaOperations-MapTransfer)(pdx-AdapterObject,mdl,pdx-regbase,pdx-vaddr,pdx-xfer,!isread);//这里是硬件特有的开始DMA传输的操作……}//如果出错了或者传输完成了else{ULONGnumxfer=pdx-numxfer;(*pdx-AdapterObject-DmaOperations-FreeMapRegisters)(pdx-AdapterObject,pdx-regbase,pdx-nMapRegistersAllocated);StartNextPacket(&pdx-dqReadWrite,fdo);//开始下一次传输,这于依赖于排队机制CompleteRequest(Irp,status,numxfer);}}//两个数据结构typedefstruct_SCATTER_GATHER_ELEMENT{PHYSICAL_ADDRESSAddress;ULONGLength;ULONG_PTRReserved;}SCATTER_GATHER_ELEMENT,*PSCATTER_GATHER_ELEMENT;typedefstruct_SCATTER_GATHER_LIST{ULONGNumberOfElements;ULONG_PTRReserved;SCATTER_GATHER_ELEMENTElements[];}SCATTER_GATHER_LIST,*PSCATTER_GATHER_LIST;//AddDevice中申请资源pdx-sglist=(PSCATTER_GATHER_LIST)ExAllocatePool(NonPagedPool,sizeof(SCATTER_GATHER_LIST)+MAXSG*sizeof(SCATTER_GATHER_ELEMENT));//adapterControl中如下;IO_ALLOCATION_ACTIONAdapterControl(PDEVICE_OBJECTfdo,PIRPjunk,PVOIDregbase,PDEVICE_EXTENSIONpdx){PIRPIrp=GetCurrentIrp(&pdx-dqReadWrite);PMDLmdl=Irp-MdlAddress;BOOLEANisread=IoGetCurren