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

📄 luojincdriv01device.cpp

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


#pragma warning(disable:4065) // Allow switch statement with no cases
		  
#include <vdw.h>

#include "LuojincDriv01.h"
#include "LuojincDriv01Device.h"
#include "..\LuojincDriv01ioctl.h"

#pragma hdrstop("LuojincDriv01.pch")

extern KDebugOnlyTrace t;	// Global driver trace object	

LuojincDriv01Device::LuojincDriv01Device(PDEVICE_OBJECT Pdo, ULONG Unit) :
	KPnpDevice(Pdo, NULL)
{
	t << "Entering LuojincDriv01Device::LuojincDriv01Device (constructor)\n";


	// Check constructor status
    if ( ! NT_SUCCESS(m_ConstructorStatus) )
	{
	    return;
	}

	// Remember our unit number
	m_Unit = Unit;

	// Initialize the lower device
	m_Lower.Initialize(this, Pdo);

    // Inform the base class of the lower edge device object
	SetLowerDevice(&m_Lower);

	// Initialize the PnP Policy settings to the "standard" policy
	SetPnpPolicy();

// TODO:	Customize the PnP Policy for this device by setting
//			flags in m_Policies.

	// Initialize the Power Policy settings to the "standard" policy
	SetPowerPolicy();

// TODO:	Customize the Power Policy for this device by setting
//			flags in m_PowerPolicies.

}



LuojincDriv01Device::~LuojincDriv01Device()
{
	t << "Entering LuojincDriv01Device::~LuojincDriv01Device() (destructor)\n";
}




inline NTSTATUS LuojincDriv01Device::DefaultPnp(KIrp I) 
{
	t << "Entering LuojincDriv01Device::DefaultPnp\n" << I << EOL;

	I.ForceReuseOfCurrentStackLocationInCalldown();
	return m_Lower.PnpCall(this, I);
}



inline NTSTATUS LuojincDriv01Device::DefaultPower(KIrp I) 
{
	t << "Entering LuojincDriv01Device::DefaultPower\n" << I << EOL;

	I.IndicatePowerIrpProcessed();
	I.CopyParametersDown();
	return m_Lower.PnpPowerCall(this, I);
}



inline NTSTATUS LuojincDriv01Device::SystemControl(KIrp I) 
{
	t << "Entering LuojincDriv01Device::SystemControl\n";

	I.ForceReuseOfCurrentStackLocationInCalldown();
	return m_Lower.PnpCall(this, I);
}



inline VOID LuojincDriv01Device::Invalidate()
{

	// For each memory mapped region, release the underlying system resoruce.
	m_MemoryRange0.Invalidate();
	m_MemoryRange2.Invalidate();
	m_MemoryRange3.Invalidate();

	// For each I/O port mapped region, release the underlying system resource.
	m_IoPortRange1.Invalidate();

	// For the interrupt, release the underlying system resource.
	m_Irq.Invalidate();

    m_pDmaAdapter->DmaOperations->FreeCommonBuffer(
        m_pDmaAdapter,m_MapRegisterCount*sizeof(PLX9656_DESCRIPTOR),
        *m_pCommBufferPa,m_pCommBufferVa,FALSE);
    m_pDmaAdapter->DmaOperations->PutDmaAdapter(m_pDmaAdapter);


}



inline NTSTATUS LuojincDriv01Device::OnStartDevice(KIrp I)
{
	t << "Entering LuojincDriv01Device::OnStartDevice\n";

	NTSTATUS status = STATUS_SUCCESS;

	I.Information() = 0;

	PCM_RESOURCE_LIST pResListRaw = I.AllocatedResources();

	PCM_RESOURCE_LIST pResListTranslated = I.TranslatedResources();

    #define MAX_DMA_LENGTH	0x800000	// 0x100000 is 1 MB

	DEVICE_DESCRIPTION dd;

	RtlZeroMemory(&dd, sizeof(dd));

	dd.Version = DEVICE_DESCRIPTION_VERSION;

	dd.Master = TRUE;

	dd.ScatterGather = FALSE;

	dd.DemandMode = FALSE;

	dd.AutoInitialize = FALSE;

	dd.Dma32BitAddresses = TRUE;

	dd.IgnoreCount = FALSE;

	dd.DmaChannel = 0;

	dd.InterfaceType = PCIBus;

	dd.DmaWidth = Width32Bits;	// PCI default width

	dd.DmaSpeed = Compatible;

	dd.MaximumLength = MAX_DMA_LENGTH;
    
	//申请DMA适配器

    PIRP  pCurrentIrp=PIRP(I);

    PIO_STACK_LOCATION pIoStackLocation = IoGetCurrentIrpStackLocation(pCurrentIrp);

    m_pDeviceObject    =    pIoStackLocation->DeviceObject;

    m_MapRegisterCount =(MAX_DMA_LENGTH / PAGE_SIZE) + 1;

    m_pDmaAdapter=NULL;
 
    m_pDmaAdapter =IoGetDmaAdapter( m_pDeviceObject,&dd, &m_MapRegisterCount);
   
    if(m_pDmaAdapter==NULL)
    {
	    return STATUS_INSUFFICIENT_RESOURCES;
    }

	//申请非分页连续内存

    m_pCommBufferVa=NULL;

    m_pCommBufferVa=(PUCHAR)m_pDmaAdapter->DmaOperations->AllocateCommonBuffer
   
	   (m_pDmaAdapter,m_MapRegisterCount*sizeof(PLX9656_DESCRIPTOR),m_pCommBufferPa,false);

    if(m_pCommBufferVa==NULL)
    {
	    return STATUS_INSUFFICIENT_RESOURCES;
    }
	// Create an instance of KPciConfiguration so we can map Base Address
	// Register indicies to ordinals for memory or I/O port ranges.
	KPciConfiguration PciConfig(m_Lower.TopOfStack());
 
	status = m_MemoryRange0.Initialize(
		pResListTranslated,
		pResListRaw,
		PciConfig.BaseAddressIndexToOrdinal(0)
		);

	if (!NT_SUCCESS(status))
	{
		Invalidate();
		return status;		
	}

	status = m_MemoryRange2.Initialize(
		pResListTranslated,
		pResListRaw,
		PciConfig.BaseAddressIndexToOrdinal(2)
		);

	if (!NT_SUCCESS(status))
	{
		Invalidate();
		return status;		
	}

	status = m_MemoryRange3.Initialize(
		pResListTranslated,
		pResListRaw,
		PciConfig.BaseAddressIndexToOrdinal(3)
		);

	if (!NT_SUCCESS(status))
	{
		Invalidate();
		return status;		
	}

	status = m_IoPortRange1.Initialize(
		pResListTranslated,
		pResListRaw,
		PciConfig.BaseAddressIndexToOrdinal(1)
		);
	
	if (!NT_SUCCESS(status))
	{
		Invalidate();
		return status;		
	}

	status = m_Irq.InitializeAndConnect(
		pResListTranslated, 
		LinkTo(Isr_Irq), 
		this
		);
	if (!NT_SUCCESS(status))
	{
		Invalidate();
		return status;		
	}

	m_DpcFor_Irq.Setup(LinkTo(DpcFor_Irq), this);

	return status;
}

 

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

	t << "Entering LuojincDriv01Device::OnStopDevice\n";
 
	Invalidate();
 
	return status;
 
	UNREFERENCED_PARAMETER(I);
}

 

inline NTSTATUS LuojincDriv01Device::OnRemoveDevice(KIrp I)
{
	t << "Entering LuojincDriv01Device::OnRemoveDevice\n";
 
	Invalidate();
 
	return STATUS_SUCCESS;
 
	UNREFERENCED_PARAMETER(I);
}

 	

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

	t << "Entering LuojincDriv01Device::OnDevicePowerUp\n";
 
	return status;
 
	UNREFERENCED_PARAMETER(I);
}

 	

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

	t << "Entering LuojincDriv01Device::OnDeviceSleep\n";

	return status;

	UNREFERENCED_PARAMETER(I);
}

 

inline VOID LuojincDriv01Device::CancelQueuedIrp(KIrp I)
{
	KDeviceQueue dq(DeviceQueue());

	// Test if the IRP is the current IRP.
	if ( (PIRP)I == CurrentIrp() )
	{
		CurrentIrp() = NULL;
		CancelSpinLock::Release(I.CancelIrql());
		t << "IRP canceled " << I << EOL;
	    I.Information() = 0;
		I.Status() = STATUS_CANCELLED;
		PnpNextIrp(I);
	}
	// See if the IRP can be removed from the device queue.
	else if (dq.RemoveSpecificEntry(I))
	{
		CancelSpinLock::Release(I.CancelIrql());
		t << "IRP canceled " << I << EOL;
	    I.Information() = 0;
		I.PnpComplete(this, STATUS_CANCELLED);
	}
	else
	{
		CancelSpinLock::Release(I.CancelIrql());
	}
}

 

inline VOID LuojincDriv01Device::StartIo(KIrp I)
{
	t << "Entering StartIo, " << I << EOL;
 
	if ( !I.TestAndSetCancelRoutine(
		LinkTo(CancelQueuedIrp),
		NULL,
		CurrentIrp()) )
	{

		return;
	}

	switch (I.MajorFunction())
	{
		case IRP_MJ_READ:
			SerialRead(I);
			break;
		case IRP_MJ_WRITE:
			SerialWrite(I);
			break;
		case IRP_MJ_DEVICE_CONTROL:
			switch (I.IoctlCode())
			{
				case ReadMemConfigReg:
					ReadMemConfigRegFunc(I);
					break;

				case ReadIoConfigReg:
					ReadIoConfigRegFunc(I);
					break;

				case WriteMemConfigReg:
					WriteMemConfigRegFunc(I);
					break;

				case WriteIoConfigReg:
					WriteIoConfigRegFunc(I);
					break;

				case ReadLocalSpace0:
					ReadLocalSpace0Func(I);
					break;

				case ReadLocalSpace1:
					ReadLocalSpace1Func(I);
					break;

				case WriteLocalSpace0:
					WriteLocalSpace0Func(I);
					break;

				case WriteLocalSpace1:
					WriteLocalSpace1Func(I);
					break;

				case GetDriverInfo:
					GetDriverInfoFunc(I);
					break;

				case SetDriverInfo:
					SetDriverInfoFunc(I);
					break;

				default:
 
					ASSERT(FALSE);
					break;
			}
			break;
		default:
			ASSERT(FALSE);
			PnpNextIrp(I);
			break;
	}
}

 
inline NTSTATUS LuojincDriv01Device::Create(KIrp I)
{
	NTSTATUS status;

	t << "Entering LuojincDriv01Device::Create, " << I << EOL;

	status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);

	t << "LuojincDriv01Device::Create Status " << (ULONG)status << EOL;

	return status;
}

 

inline NTSTATUS LuojincDriv01Device::Close(KIrp I)
{
	NTSTATUS status;

	t << "Entering LuojincDriv01Device::Close, " << I << EOL;

	status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);

	t << "LuojincDriv01Device::Close Status " << (ULONG)status << EOL;

    return status;
}

 

inline NTSTATUS LuojincDriv01Device::CleanUp(KIrp I)
{
	t << "Entering CleanUp, " << I << EOL;
    KDeviceQueue dq(DeviceQueue());
	dq.PnpCleanUp(this, I.FileObject());
	return I.PnpComplete(this, STATUS_SUCCESS);
}

 

inline void LuojincDriv01Device::SerialRead(KIrp I)
{
	t << "Entering LuojincDriv01Device::SerialRead, " << I << EOL;
	NTSTATUS status		= STATUS_SUCCESS;

	// Declare a memory object
	KMemory Mem(I.Mdl());
	// Use the memory object to create a pointer to the caller's buffer
	PUCHAR	pBuffer		= (PUCHAR) Mem.MapToSystemSpace();

	ULONG   dwTotalSize = I.ReadSize(CURRENT);	// Requested read size
	ULONG   dwBytesRead = 0;					// Count of bytes read
 

	I.Information() = dwBytesRead;

	I.Status() = status;

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

inline NTSTATUS LuojincDriv01Device::Read(KIrp I) 
{
	t << "Entering LuojincDriv01Device::Read, " << 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)		// If (Request is invalid)
	{
		// Invalid parameter in the Read request
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
	}

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

	// Queue the IRP for processing in StartIO
	// The read function is performed in SerialRead
	return QueueIrp(I, LinkTo(CancelQueuedIrp));
}
 

inline void LuojincDriv01Device::SerialWrite(KIrp I)
{
	t << "Entering LuojincDriv01Device::SerialWrite, " << I << EOL;
	NTSTATUS status		= STATUS_SUCCESS;

	// Declare a memory object
	KMemory Mem(I.Mdl());
	// Use the memory object to create a pointer to the caller's buffer
	PUCHAR	pBuffer		= (PUCHAR) Mem.MapToSystemSpace();

	ULONG   dwTotalSize = I.WriteSize(CURRENT);
	ULONG   dwBytesSent = 0;

	I.Information() = dwBytesSent;

⌨️ 快捷键说明

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