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

📄 bpskdevice.cpp

📁 PCI9054驱动
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// BPSKDevice.cpp
// Implementation of BPSKDevice device class
//
// Generated by DriverWizard version DriverStudio 3.1.0 (Build 1722)
// Requires Compuware's DriverWorks classes
//
#pragma warning(disable:4065) // Allow switch statement with no cases
		  
#include <vdw.h>
#include "BPSKDeviceinterface.h"

#include "BPSK.h"
#include "BPSKDevice.h"
#include "BPSKioctl.h"

#pragma hdrstop("BPSK.pch")

extern KDebugOnlyTrace t;	// Global driver trace object	

GUID BPSKDevice_Guid = BPSKDevice_CLASS_GUID;

#define INTCSR    0x68  //中断控制地址
#define DMAMODE0  0x80  //DMA0通道
#define DMAPADR0  0x84  //DMA0通道PCI地址
#define DMALADR0  0x88  //DMA0通道本地地址
#define DMASIZ0   0x8C  //DMA0通道传输字节计数
#define DMADPR0   0x90  //DMA0通道指针
#define DMACSR0   0xA8  //DMA(0、1)通道状态


////////////////////////////////////////////////////////////////////////
//  BPSKDevice::BPSKDevice
//
//	Routine Description:
//		This is the constructor for the Functional Device Object, or FDO.
//		It is derived from KPnpDevice, which builds in automatic
//	    dispatching of subfunctions of IRP_MJ_POWER and IRP_MJ_PNP to
//		virtual member functions.
//
//	Parameters:
//		Pdo - Physical Device Object - this is a pointer to a system
//			device object that represents the physical device.
//
//		Unit - Unit number. This is a number to append to the device's
//			base device name to form the Logical Device Object's name
//
//	Return Value:
//		None   
//
//	Comments:
//		The object being constructed contains a data member (m_Lower) of type
//		KPnpLowerDevice. By initializing it, the driver binds the FDO to the
//		PDO and creates an interface to the upper edge of the system class driver.
//
BPSKDevice::BPSKDevice(PDEVICE_OBJECT Pdo, ULONG Unit) :
	KPnpDevice(Pdo, &BPSKDevice_Guid)
{
	t << "Entering BPSKDevice::BPSKDevice (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.

}


////////////////////////////////////////////////////////////////////////
//  BPSKDevice::~BPSKDevice
//
//	Routine Description:
//		This is the destructor for the Functional Device Object, or FDO.
//
//	Parameters:
//		None
//
//	Return Value:
//		None
//
//	Comments:
//		None
//

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


char *PNPMinorFunctionName(ULONG mn)
{
	static char* minors[] = {
		"IRP_MN_START_DEVICE",
		"IRP_MN_QUERY_REMOVE_DEVICE",
		"IRP_MN_REMOVE_DEVICE",
		"IRP_MN_CANCEL_REMOVE_DEVICE",
		"IRP_MN_STOP_DEVICE",
		"IRP_MN_QUERY_STOP_DEVICE",
		"IRP_MN_CANCEL_STOP_DEVICE",
		"IRP_MN_QUERY_DEVICE_RELATIONS",
		"IRP_MN_QUERY_INTERFACE",
		"IRP_MN_QUERY_CAPABILITIES",
		"IRP_MN_QUERY_RESOURCES",
		"IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
		"IRP_MN_QUERY_DEVICE_TEXT",
		"IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
		"<unknown minor function>",
		"IRP_MN_READ_CONFIG",
		"IRP_MN_WRITE_CONFIG",
		"IRP_MN_EJECT",
		"IRP_MN_SET_LOCK",
		"IRP_MN_QUERY_ID",
		"IRP_MN_QUERY_PNP_DEVICE_STATE",
		"IRP_MN_QUERY_BUS_INFORMATION",
		"IRP_MN_DEVICE_USAGE_NOTIFICATION",
		"IRP_MN_SURPRISE_REMOVAL"
	};

	if (mn > IRP_MN_SURPRISE_REMOVAL) 
		return "<unknown minor function>";
	else
		return minors[mn];
}


////////////////////////////////////////////////////////////////////////
//  BPSKDevice::DefaultPnp
//
//	Routine Description:
//		Default handler for IRP_MJ_PNP
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result returned from lower device
//
//	Comments:
//		This routine just passes the IRP through to the lower device. It is 
//		the default handler for IRP_MJ_PNP. IRPs that correspond to
//		any virtual members of KpnpDevice that handle minor functions of
//		IRP_MJ_PNP and that are not overridden get passed to this routine.
//

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

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

////////////////////////////////////////////////////////////////////////
//  BPSKDevice::DefaultPower
//
//	Routine Description:
//		Default handler for IRP_MJ_POWER 
//  
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result returned from lower device
//
//	Comments:
//		This routine just passes the IRP through to the lower device. It is 
//		the default handler for IRP_MJ_POWER.
//

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

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

////////////////////////////////////////////////////////////////////////////////
//  BPSKDevice::SystemControl
//
//	Routine Description:
//		Default handler for IRP_MJ_SYSTEM_CONTROL
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result returned from lower device
//
//	Comments:
//		This routine just passes the IRP through to the next device since this driver
//		is not a WMI provider.
//

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

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

////////////////////////////////////////////////////////////////////////
//  BPSKDevice::Invalidate
//
//	Routine Description:
//		Calls Invalidate methods for system resources
//
//	Parameters:
//		None
//
//	Return Value:
//		None
//
//	Comments:
//		This function is called from OnStopDevice, OnRemoveDevice and
//		OnStartDevice (in error conditions).  It calls the Invalidate
//		member funcitons for each resource to free the underlying system
//		resource if allocated.  It is safe to call Invalidate more than
//		once for a resource, or for an uninitialized resource.

VOID BPSKDevice::Invalidate()
{

	// It is not necessary to release the system resource for the DMA adapter
	// object, since NT provides no mechanism for this.
	//不需要释放DMA适配器对象即m_Dma;
	if(m_Buffer.IsValid())
	m_Buffer.Invalidate();//添加
	// For each memory mapped region, release the underlying system resoruce.
	m_MemoryRange0.Invalidate();

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

	// For the interrupt, release the underlying system resource.
//	m_Irq.Invalidate();
	if(m_pEvent)
		delete m_pEvent;
	if(m_pEvent1)
		delete m_pEvent1;

}

////////////////////////////////////////////////////////////////////////
//  BPSKDevice::OnStartDevice
//
//	Routine Description:
//		Handler for IRP_MJ_PNP subfcn IRP_MN_START_DEVICE
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result code
//
//	Comments:
//		Initialize the physical device. Typically, the driver initializes
//		physical resources here.  Call I.AllocatedResources() for a list
//		of the raw resources that the system has assigned to the device,
//		or I.TranslatedResources() for the translated resource list.
//

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

	NTSTATUS status = STATUS_SUCCESS;

	I.Information() = 0;

	// The default Pnp policy has already cleared the IRP with the lower device
	// Initialize the physical device object.

	// Get the list of raw resources from the IRP
	PCM_RESOURCE_LIST pResListRaw = I.AllocatedResources();
	// Get the list of translated resources from the IRP
	PCM_RESOURCE_LIST pResListTranslated = I.TranslatedResources();

// TODO:	Check to ensure that the following parameters are correct for your hardware
//
#define MAX_DMA_LENGTH	0x100000	// 0x100000 is 1 MB
//DMA对象
	// Initialize the device descriptor for the DMA object using the assigned resource
	DEVICE_DESCRIPTION dd;
	RtlZeroMemory(&dd, sizeof(dd));
	dd.Version = DEVICE_DESCRIPTION_VERSION;
	dd.Master = TRUE;
	dd.ScatterGather = FALSE;
	dd.DemandMode = FALSE;//Indicates whether to use the system DMA controller's demand mode. Not used for busmaster DMA. 
	dd.AutoInitialize = FALSE;
	dd.Dma32BitAddresses = TRUE;
	dd.IgnoreCount = FALSE;
	dd.DmaChannel = 0;
	dd.InterfaceType = PCIBus;
	dd.DmaWidth = Width32Bits;	// PCI default width 32bit
	dd.DmaSpeed = Compatible;
	dd.MaximumLength = MAX_DMA_LENGTH;

	// Initialize the DMA adapter object
	m_Dma.Initialize(&dd, m_Lower.TopOfStack());
	m_Buffer.Initialize(&m_Dma,1024*64);//初始化KCommonDmaBuffer类对象大小64k
	KPciConfiguration PciConfig(m_Lower.TopOfStack());

	// For each memory mapped region, initialize the memory mapped range
	// using the resources provided by NT. Once initialized, each memory
	// range's base virtual address in system space can be obtained by calling
	// member Base(). Each memory range's physical address in CPU space can
	// obtained by calling CpuPhysicalAddress(). To access the memory mapped
	// range use member functions such as inb/outb, or the array element operator. 
	status = m_MemoryRange0.Initialize(
		pResListTranslated,
		pResListRaw,
		PciConfig.BaseAddressIndexToOrdinal(0)
			);

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

	// For each I/O port mapped region, initialize the I/O port range using
	// the resources provided by NT. Once initialized, use member functions such as
	// inb/outb, or the array element operator to access the ports range.
	status = m_IoPortRange0.Initialize(
		pResListTranslated,
		pResListRaw,
		PciConfig.BaseAddressIndexToOrdinal(1)
		);
	
	if (!NT_SUCCESS(status))
	{
		Invalidate();
		return status;		
	}

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

	// Initialize and connect the interrupt
	status = m_Irq.InitializeAndConnect(
		pResListTranslated, 
		LinkTo(Isr_Irq), 
		this
		);
	if (!NT_SUCCESS(status))
	{
		Invalidate();
		return status;		
	}

	// Setup the DPC to be used for interrupt processing
	m_DpcFor_Irq.Setup(LinkTo(DpcFor_Irq), this);

// TODO:	Add device-specific code to start your device.

    // The base class will handle completion

	return status;
}

////////////////////////////////////////////////////////////////////////
//  BPSKDevice::DeviceControl
//
//	Routine Description:
//		Handler for IRP_MJ_DEVICE_CONTROL
//
//	Parameters:
//		I - Current IRP
// 
//	Return Value:
//		None
//
//	Comments:
//		This routine is the first handler for Device Control requests.
//		Some function codes may be handled immediately, 
//		while others may be serialized through the StartIo routine.
//		
//		The KPnpDevice class handles restricting IRP flow
//		if the device is stopping or being removed.
//

NTSTATUS BPSKDevice::DeviceControl(KIrp I) 
{
	NTSTATUS status;

	t << "Entering BPSKDevice::Device Control, " << I << EOL;
	switch (I.IoctlCode())
	{
		case CONFIG_SYMBOL_RATE:
			status = CONFIG_SYMBOL_RATE_Handler(I);
			break;

		case MODULATE_MODE:
			status = MODULATE_MODE_Handler(I);
			break;

		case SET_IF_FRE:
			status = SET_IF_FRE_Handler(I);
			break;

		case CTRL_AD9851_INIT:
			status = CTRL_AD9851_INIT_Handler(I);
			break;

		case IOCTL_SET_NOTIFICATION_EVENT:
			status = IOCTL_SET_NOTIFICATION_EVENT_Handler(I);
			break;

		case START_COLLECT:
			status = START_COLLECT_Handler(I);
			break;
		case STOP_COLLECT:
			status = STOP_COLLECT_Handler(I);
			break;

		default:
			// Unrecognized IOCTL request
			status = STATUS_INVALID_PARAMETER;
			break;
	}

	// If the IRP was queued, or its IOCTL handler deferred processing using some
	// driver specific scheme, the status variable is set to STATUS_PENDING.
	// In this case we simply return that status, and the IRP will be completed
	// later.  Otherwise, complete the IRP using the status returned by the
	// IOCTL handler.
	if (status == STATUS_PENDING)
	{
		return status;
	}
	else
	{
		return I.PnpComplete(this, status);
	}
}


////////////////////////////////////////////////////////////////////////
//  BPSKDevice::OnStopDevice
//
//	Routine Description:
//		Handler for IRP_MJ_PNP subfcn IRP_MN_STOP_DEVICE
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result code
//
//	Comments:
//		The system calls this when the device is stopped.
//		The driver should release any hardware resources
//		in this routine.

⌨️ 快捷键说明

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