⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 luojincdriv01device.cpp

📁 PLX9656驱动程序模型 实现DMA 可修改成其他芯片的驱动 plx9656driver with DMA
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	I.Status() = status;

	// PnpNextIrp completes this IRP and starts  
	// processing for the next IRP in the queue.
	PnpNextIrp(I);
}
 

inline NTSTATUS LuojincDriv01Device::Write(KIrp I) 
{
	t << "Entering LuojincDriv01Device::Write, " << I << EOL;
// TODO:	Check the incoming request.  Replace "FALSE" in the following
//			line with a check that returns TRUE if the request is not valid.
    if (FALSE)
	{
		// Invalid parameter in the Write request
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
	}

	// Always ok to write 0 elements.
	if (I.WriteSize() == 0)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_SUCCESS);
	}

	// Queue the IRP for processing in StartIO
	// The write function is performed in SerialWrite
	return QueueIrp(I, LinkTo(CancelQueuedIrp));
}
 
inline NTSTATUS LuojincDriv01Device::DeviceControl(KIrp I) 
{
	NTSTATUS status;

	t << "Entering LuojincDriv01Device::Device Control, " << I << EOL;
	switch (I.IoctlCode())
	{
		case ReadMemConfigReg:
			// Queue this request for serialized handling through StartIo
			status = QueueIrp(I, LinkTo(CancelQueuedIrp));
			break;

		case ReadIoConfigReg:
			// Queue this request for serialized handling through StartIo
			status = QueueIrp(I, LinkTo(CancelQueuedIrp));
			break;

		case WriteMemConfigReg:
			// Queue this request for serialized handling through StartIo
			status = QueueIrp(I, LinkTo(CancelQueuedIrp));
			break;

		case WriteIoConfigReg:
			// Queue this request for serialized handling through StartIo
			status = QueueIrp(I, LinkTo(CancelQueuedIrp));
			break;

		case ReadLocalSpace0:
			// Queue this request for serialized handling through StartIo
			status = QueueIrp(I, LinkTo(CancelQueuedIrp));
			break;

		case ReadLocalSpace1:
			// Queue this request for serialized handling through StartIo
			status = QueueIrp(I, LinkTo(CancelQueuedIrp));
			break;

		case WriteLocalSpace0:
			// Queue this request for serialized handling through StartIo
			status = QueueIrp(I, LinkTo(CancelQueuedIrp));
			break;

		case WriteLocalSpace1:
			// Queue this request for serialized handling through StartIo
			status = QueueIrp(I, LinkTo(CancelQueuedIrp));
			break;

		case GetDriverInfo:
			// Queue this request for serialized handling through StartIo
			status = QueueIrp(I, LinkTo(CancelQueuedIrp));
			break;

		case SetDriverInfo:
			// Queue this request for serialized handling through StartIo
			status = QueueIrp(I, LinkTo(CancelQueuedIrp));
			break;

		default:
			// Unrecognized IOCTL request
			status = STATUS_INVALID_PARAMETER;
			break;
	}
	if (status == STATUS_PENDING)
	{
		return status;
	}
	else
	{
		return I.PnpComplete(this, status);
	}
}

inline VOID LuojincDriv01Device::ReadMemConfigRegFunc(KIrp I)
{
    NTSTATUS status = STATUS_SUCCESS;
	KMemory Mem(I.Mdl());
	PULONG	pOutBuffer		= (PULONG) Mem.MapToSystemSpace();
	PULONG  pInBuffer       = (PULONG) I.IoctlBuffer();
	ULONG   Offset=0;
	ULONG   count;
	Offset   = *pInBuffer;
	count    = *(pInBuffer+1);
	m_MemoryRange0.ind(Offset,pOutBuffer,count);
	I.Information() = count;
	I.Status() = status;
    PnpNextIrp(I);
}
inline VOID LuojincDriv01Device::ReadIoConfigRegFunc(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering LuojincDriv01Device::ReadIoConfigRegFunc, " << I << EOL;
	I.Information() = 0;
	I.Status() = status;
	PnpNextIrp(I);
}

inline VOID LuojincDriv01Device::WriteMemConfigRegFunc(KIrp I)
{
    NTSTATUS status = STATUS_SUCCESS;
	KMemory Mem(I.Mdl());
	PULONG	pOutBuffer		= (PULONG) Mem.MapToSystemSpace();
	PULONG  pInBuffer       = (PULONG) I.IoctlBuffer();
	ULONG   Offset=0;
	ULONG   count;
	Offset   = *pInBuffer;
	count    = *(pInBuffer+1);
	m_MemoryRange0.outd(Offset,pOutBuffer,count);
	I.Information() = count;
	I.Status() = status;
    PnpNextIrp(I);	
}

inline VOID LuojincDriv01Device::WriteIoConfigRegFunc(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering LuojincDriv01Device::WriteIoConfigRegFunc, " << I << EOL;
	I.Information() = 0;
	I.Status() = status;
	PnpNextIrp(I);
}




inline VOID LuojincDriv01Device::ReadLocalSpace1Func(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering LuojincDriv01Device::ReadLocalSpace1Func, " << I << EOL;
	I.Information() = 0;
	I.Status() = status;
	PnpNextIrp(I);
}

inline VOID LuojincDriv01Device::WriteLocalSpace0Func(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering LuojincDriv01Device::WriteLocalSpace0Func, " << I << EOL;
	I.Information() = 0;
	I.Status() = status;
	PnpNextIrp(I);
}

inline VOID LuojincDriv01Device::WriteLocalSpace1Func(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering LuojincDriv01Device::WriteLocalSpace1Func, " << I << EOL;
	I.Information() = 0;
	I.Status() = status;
	PnpNextIrp(I);
}

inline VOID LuojincDriv01Device::GetDriverInfoFunc(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering LuojincDriv01Device::GetDriverInfoFunc, " << I << EOL;
	I.Information() = 0;
	I.Status() = status;
	PnpNextIrp(I);
}

inline VOID LuojincDriv01Device::SetDriverInfoFunc(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering LuojincDriv01Device::SetDriverInfoFunc, " << I << EOL;
	I.Information() = 0;
	I.Status() = status;
	PnpNextIrp(I);
}
//----------------------读Local数据-------------------//

inline VOID LuojincDriv01Device::ReadLocalSpace0Func(KIrp I)
{
    NTSTATUS status;

    PIRP  pCurrentIrp=PIRP(I);

    PIO_STACK_LOCATION pIoStackLocation = IoGetCurrentIrpStackLocation(pCurrentIrp);

    m_pMdl = pCurrentIrp->MdlAddress;

    m_pTransferVa =  (PUCHAR)MmGetMdlVirtualAddress(m_pMdl);

	m_nBytesTransfered=0;

    m_nBytesRequested = m_nBytesRemaining = MmGetMdlByteCount(m_pMdl);

	status =  m_pDmaAdapter->DmaOperations->AllocateAdapterChannel

		(m_pDmaAdapter,m_pDeviceObject,m_MapRegisterCount,AdapterControl,this);
	 
	if (!NT_SUCCESS(status))
	{
		I.Information() = 0;

		I.Status() = status;

		PnpNextIrp(I);
	}
}

//----------------------适配器回调例程-------------------//

inline IO_ALLOCATION_ACTION 
AdapterControl(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp,IN PVOID MapRegisterBase,IN PVOID pContext ) 
{
    LuojincDriv01Device* pThis    = (LuojincDriv01Device*)pContext;

    pThis->m_pMapRegisterBase   =  MapRegisterBase;

    //	KeFlushIoBuffers( pThis->m_pMdl,TRUE, TRUE );	

    PPLX9656_DESCRIPTOR pDescriptorVa = (PPLX9656_DESCRIPTOR)pThis->m_pCommBufferVa;

	ULONG  CommBufferPa = pThis->m_pCommBufferPa->LowPart;

    ULONG BytesLeftInBuffer;

    ULONG SegMentSize;

    ULONG MapRegisterIndex=0;

    PUCHAR SegmentVa;

    PHYSICAL_ADDRESS     PciAddr;

   ////////////////////////////////////////

   BytesLeftInBuffer =  pThis -> m_nBytesRemaining;

   SegmentVa = pThis -> m_pTransferVa;

   pThis ->m_nTransferSize=0;

   while(MapRegisterIndex < pThis->m_MapRegisterCount && BytesLeftInBuffer > 0)
   {
      SegMentSize = BytesLeftInBuffer;
   
      PciAddr=pThis->m_pDmaAdapter->DmaOperations->

	  MapTransfer( pThis->m_pDmaAdapter, pThis->m_pMdl , MapRegisterBase,	
				     pThis->m_pTransferVa , &SegMentSize  ,   false );

   	  pThis->SetSgDesc( pDescriptorVa,//PPLX9656_DESCRIPTOR pDesc
                        PciAddr.LowPart,//PciLowPart
			        	0,//PciHighPart,
				    	0,//LocalAddr,
				    	SegMentSize,//Length
				    	true,//bValid? 
				    	false,//bEnd?
				    	CommBufferPa+(MapRegisterIndex+1)*sizeof(PLX9656_DESCRIPTOR)//NextDescPtrPa
					   );  
       pDescriptorVa++;

	   MapRegisterIndex++;

	   BytesLeftInBuffer-=SegMentSize;

	   SegmentVa+=SegMentSize;

       pThis ->m_nTransferSize+=SegMentSize;
   }
   pDescriptorVa--;

   pThis->SetSgDesc( pDescriptorVa,//PPLX9656_DESCRIPTOR pDesc
                     PciAddr.LowPart,//PciLowPart
			         0,//PciHighPart,
				     0,//LocalAddr,
				     SegMentSize,//Length
				     true,//bValid? 
				     true,//bEnd?
				     0    //NextDescPtrPa
					);  

   pDescriptorVa = (PPLX9656_DESCRIPTOR)pThis->m_pCommBufferVa;

   pThis->SetFirstSgDma(pDescriptorVa);

   pThis->SetSgDmaMode();

   pThis->EnableDMA0Interrupt(true); 
   
   pThis->StartDma();

   return DeallocateObjectKeepRegisters;
}
//----------------------中断服务例程-------------------//

inline BOOLEAN LuojincDriv01Device::Isr_Irq(void)
{
   if((m_MemoryRange0[PLX9656_INTCSR] &= PLX9656_INTCSR_DMA0IA)==0)

   { return false;}

   else
   {
	   EnableDMA0Interrupt(false);

	   ClearDMA0Interrupt();

	   if(!m_DpcFor_Irq.Request(NULL, NULL))
	   {
		   KIrp I(CurrentIrp());

	       I.Status()=STATUS_UNSUCCESSFUL;

	       I.Information()=0;

	       PnpNextIrp(I);
	   }
       return true;
   }
}
//----------------------中断延迟调用-------------------//

inline VOID LuojincDriv01Device::DpcFor_Irq(PVOID Arg1, PVOID Arg2)
{
	//缓冲区刷新

	m_pDmaAdapter->DmaOperations->FlushAdapterBuffers

	(m_pDmaAdapter,m_pMdl,m_pMapRegisterBase,	m_pTransferVa,m_nTransferSize,false);

	//数据更新

   	m_nBytesTransfered+=m_nTransferSize;

	m_pTransferVa+=m_nTransferSize;

    m_nBytesRemaining-=m_nTransferSize;

	if (m_nBytesRemaining > 0) 
	{
		//局部变量

        ULONG SegMentSize;

        ULONG MapRegisterIndex=0;

        PUCHAR SegmentVa;

        PHYSICAL_ADDRESS     PciAddr;

        PPLX9656_DESCRIPTOR pDescriptorVa = (PPLX9656_DESCRIPTOR)m_pCommBufferVa;

    	ULONG  CommBufferPa = m_pCommBufferPa->LowPart;

        ULONG BytesLeftInBuffer=m_nBytesRemaining;

        SegmentVa = m_pTransferVa;

        m_nTransferSize=0;

        while(MapRegisterIndex < m_MapRegisterCount && BytesLeftInBuffer > 0)
        {
		   SegMentSize = BytesLeftInBuffer;
   
           PciAddr=m_pDmaAdapter->DmaOperations->

	       MapTransfer( m_pDmaAdapter, m_pMdl , m_pMapRegisterBase,	
				     m_pTransferVa , &SegMentSize  ,   false );

   	       SetSgDesc(   pDescriptorVa,//PPLX9656_DESCRIPTOR pDesc
                        PciAddr.LowPart,//PciLowPart
			        	0,//PciHighPart,
				    	0,//LocalAddr,
				    	SegMentSize,//Length
				    	true,//bValid? 
				    	false,//bEnd?
				    	CommBufferPa+(MapRegisterIndex+1)*sizeof(PLX9656_DESCRIPTOR)//NextDescPtrPa
					 );  
            pDescriptorVa++;

	        MapRegisterIndex++;

	        BytesLeftInBuffer-=SegMentSize;

	        SegmentVa+=SegMentSize;

            m_nTransferSize+=SegMentSize;
		}
        pDescriptorVa--;

        SetSgDesc(   pDescriptorVa,//PPLX9656_DESCRIPTOR pDesc
                     PciAddr.LowPart,//PciLowPart
			         0,//PciHighPart,
				     0,//LocalAddr,
				     SegMentSize,//Length
				     true,//bValid? 
				     true,//bEnd?
				     0    //NextDescPtrPa
				);  

        pDescriptorVa = (PPLX9656_DESCRIPTOR)m_pCommBufferVa;

        SetFirstSgDma(pDescriptorVa);

        EnableDMA0Interrupt(true); 
   
        StartDma();
	}
	else
	{
		m_pDmaAdapter->DmaOperations->FreeMapRegisters(m_pDmaAdapter,m_pMapRegisterBase,m_MapRegisterCount);
        
		KIrp I(CurrentIrp());

        I.Status()=STATUS_SUCCESS;

        I.Information()=m_nBytesTransfered;

        PnpNextIrp(I);
	}
    UNREFERENCED_PARAMETER(Arg1);UNREFERENCED_PARAMETER(Arg2);
}
//-------------------------启动DMA----------------------//

inline VOID LuojincDriv01Device::StartDma(void)
{
	m_MemoryRange0[PLX9656_DMACSR0] |= (UCHAR)(PLX9656_DMACSR0_E | PLX9656_DMACSR0_S);
}
//----------------------使能DMA0中断-------------------//

inline void  LuojincDriv01Device::EnableDMA0Interrupt(bool YesOrNo)
{
	if(YesOrNo)
	{
		m_MemoryRange0[PLX9656_INTCSR]=PLX9656_INTCSR_DMA0IE|PLX9656_INTCSR_IE;
	}
    else
	{
		m_MemoryRange0[PLX9656_INTCSR]=(ULONG)0;
	}
}
//----------------------清除DMA0中断-------------------//

inline void  LuojincDriv01Device::ClearDMA0Interrupt(void)
{
    m_MemoryRange0[PLX9656_DMACSR0]=PLX9656_DMACSR0_CI;	
}
//---------------------描述符表项记录------------------//

inline void LuojincDriv01Device::SetSgDesc(
		        PPLX9656_DESCRIPTOR pDesc, 
				ULONG PciLowPart, 
				ULONG PciHighPart,
				ULONG LocalAddr, 
				ULONG Length, 
				bool bValid, 
				bool bEnd, 
				ULONG DescPtr)
{
	pDesc->PciAddrLow = PciLowPart;

	pDesc->PciAddrHigh =PciHighPart;

	pDesc->LocalAddr = LocalAddr;

	pDesc->Size = Length | (bValid ? PLX9656_DMASIZ0_V : 0);

	pDesc->NextDescPtr = DescPtr |PLX9656_DMADPR0_DT| PLX9656_DMADPR0_DL | (bEnd ? PLX9656_DMADPR0_EC : 0);
}
//-------------------设置DMA传输寄存器----------------//

inline void LuojincDriv01Device::SetFirstSgDma(PPLX9656_DESCRIPTOR pDescriptorVa)
{
		m_MemoryRange0[PLX9656_DMAPADR0] = pDescriptorVa->PciAddrLow;

		m_MemoryRange0[PLX9656_DMADAC0] =  pDescriptorVa->PciAddrHigh;

		m_MemoryRange0[PLX9656_DMALADR0] = pDescriptorVa->LocalAddr;

		m_MemoryRange0[PLX9656_DMASIZ0] = pDescriptorVa->Size;

		m_MemoryRange0[PLX9656_DMADPR0] = pDescriptorVa->NextDescPtr;
}
//---------------设置DMA Scatter/Gather模式-------------//

inline void LuojincDriv01Device::SetSgDmaMode(void)
{
		m_MemoryRange0[PLX9656_DMAMODE0] = PLX9656_DMAMODE0_IS    | PLX9656_DMAMODE0_EOTEL |
		        	PLX9656_DMAMODE0_CCM | PLX9656_DMAMODE0_DIE   | PLX9656_DMAMODE0_SGM   |
			        PLX9656_DMAMODE0_LBE | PLX9656_DMAMODE0_TARIE | Plx9656BitSize32;
}
//-----------------------结束,谢谢---------------------//

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -