tmx320c6412device.cpp

来自「网友写的一个PCI卡,基于PCI总线的驱动」· C++ 代码 · 共 1,276 行 · 第 1/3 页

CPP
1,276
字号
//		I - IRP containing IOCTL request
//
//	Return Value:
//		NTSTATUS - Status code indicating success or failure
//
//	Comments:
//		This routine implements the TMX320C6412_IOCTL_BASE0_READ function.
//		This routine runs at passive level.
//

NTSTATUS TMX320C6412Device::TMX320C6412_IOCTL_BASE0_READ_Handler(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering TMX320C6412Device::TMX320C6412_IOCTL_BASE0_READ_Handler, " << I << EOL;
// TODO:	Verify that the input parameters are correct
//			If not, return STATUS_INVALID_PARAMETER

// TODO:	Handle the the TMX320C6412_IOCTL_BASE0_READ request, or 
//			defer the processing of the IRP (i.e. by queuing) and set
//			status to STATUS_PENDING.

// TODO:	Assuming that the request was handled here. Set I.Information
//			to indicate how much data to copy back to the user.
	KMemory Mem(I.Mdl());
	PULONG pOutBuffer = (PULONG) Mem.MapToSystemSpace(); //输出缓冲区指针,传出读取的数据
	PULONG pInBuffer = (PULONG) I.IoctlBuffer(); //输入缓冲区,传来应用程序的一些参数
	                                             //以便通过应用程序指定读取的位置和数据个数
	ULONG offset = pInBuffer[0], count = pInBuffer[1];

	m_BASE0.ind (offset, pOutBuffer, count);

	I.Information() = count;

	return status;
}

////////////////////////////////////////////////////////////////////////
//  TMX320C6412Device::TMX320C6412_IOCTL_BASE0_WRITE_Handler
//
//	Routine Description:
//		Handler for IO Control Code TMX320C6412_IOCTL_BASE0_WRITE
//
//	Parameters:
//		I - IRP containing IOCTL request
//
//	Return Value:
//		NTSTATUS - Status code indicating success or failure
//
//	Comments:
//		This routine implements the TMX320C6412_IOCTL_BASE0_WRITE function.
//		This routine runs at passive level.
//

NTSTATUS TMX320C6412Device::TMX320C6412_IOCTL_BASE0_WRITE_Handler(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering TMX320C6412Device::TMX320C6412_IOCTL_BASE0_WRITE_Handler, " << I << EOL;
// TODO:	Verify that the input parameters are correct
//			If not, return STATUS_INVALID_PARAMETER

// TODO:	Handle the the TMX320C6412_IOCTL_BASE0_WRITE request, or 
//			defer the processing of the IRP (i.e. by queuing) and set
//			status to STATUS_PENDING.

// TODO:	Assuming that the request was handled here. Set I.Information
//			to indicate how much data to copy back to the user.
	PULONG pInBuffer  = (PULONG) I.IoctlBuffer(); //输入缓冲区,应用程序通过它来指定写入的参数
	                                              //参数包括要写入的偏移地址和数据个数
	ULONG offset = pInBuffer[0], count = pInBuffer[1];

	m_BASE0.outd (offset, pInBuffer+2, count);

	I.Information() = count;

	return status;
}

////////////////////////////////////////////////////////////////////////
//  TMX320C6412Device::TMX320C6412_IOCTL_BASE1_READ_Handler
//
//	Routine Description:
//		Handler for IO Control Code TMX320C6412_IOCTL_BASE1_READ
//
//	Parameters:
//		I - IRP containing IOCTL request
//
//	Return Value:
//		NTSTATUS - Status code indicating success or failure
//
//	Comments:
//		This routine implements the TMX320C6412_IOCTL_BASE1_READ function.
//		This routine runs at passive level.
//

NTSTATUS TMX320C6412Device::TMX320C6412_IOCTL_BASE1_READ_Handler(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering TMX320C6412Device::TMX320C6412_IOCTL_BASE1_READ_Handler, " << I << EOL;
// TODO:	Verify that the input parameters are correct
//			If not, return STATUS_INVALID_PARAMETER

// TODO:	Handle the the TMX320C6412_IOCTL_BASE1_READ request, or 
//			defer the processing of the IRP (i.e. by queuing) and set
//			status to STATUS_PENDING.

// TODO:	Assuming that the request was handled here. Set I.Information
//			to indicate how much data to copy back to the user.
	KMemory Mem(I.Mdl());
	PULONG pOutBuffer = (PULONG) Mem.MapToSystemSpace(); //输出缓冲区指针,传出读取的数据
	PULONG pInBuffer = (PULONG) I.IoctlBuffer(); //输入缓冲区,传来应用程序的一些参数
	                                             //以便通过应用程序指定读取的位置和数据个数
	ULONG offset = pInBuffer[0], count = pInBuffer[1];

	m_BASE1.ind (offset, pOutBuffer, count);

	I.Information() = count;

	return status;
}

////////////////////////////////////////////////////////////////////////
//  TMX320C6412Device::TMX320C6412_IOCTL_BASE1_WRITE_Handler
//
//	Routine Description:
//		Handler for IO Control Code TMX320C6412_IOCTL_BASE1_WRITE
//
//	Parameters:
//		I - IRP containing IOCTL request
//
//	Return Value:
//		NTSTATUS - Status code indicating success or failure
//
//	Comments:
//		This routine implements the TMX320C6412_IOCTL_BASE1_WRITE function.
//		This routine runs at passive level.
//

NTSTATUS TMX320C6412Device::TMX320C6412_IOCTL_BASE1_WRITE_Handler(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering TMX320C6412Device::TMX320C6412_IOCTL_BASE1_WRITE_Handler, " << I << EOL;
// TODO:	Verify that the input parameters are correct
//			If not, return STATUS_INVALID_PARAMETER

// TODO:	Handle the the TMX320C6412_IOCTL_BASE1_WRITE request, or 
//			defer the processing of the IRP (i.e. by queuing) and set
//			status to STATUS_PENDING.

// TODO:	Assuming that the request was handled here. Set I.Information
//			to indicate how much data to copy back to the user.
	PULONG pInBuffer  = (PULONG) I.IoctlBuffer(); //输入缓冲区,应用程序通过它来指定写入的参数
	                                              //参数包括要写入的偏移地址和数据个数
	ULONG offset = pInBuffer[0], count = pInBuffer[1];

	m_BASE1.outd (offset, pInBuffer+2, count);

	I.Information() = count;

	return status;
}

////////////////////////////////////////////////////////////////////////
//  TMX320C6412Device::TMX320C6412_IOCTL_BASE2_READ_Handler
//
//	Routine Description:
//		Handler for IO Control Code TMX320C6412_IOCTL_BASE2_READ
//
//	Parameters:
//		I - IRP containing IOCTL request
//
//	Return Value:
//		NTSTATUS - Status code indicating success or failure
//
//	Comments:
//		This routine implements the TMX320C6412_IOCTL_BASE2_READ function.
//		This routine runs at passive level.
//

NTSTATUS TMX320C6412Device::TMX320C6412_IOCTL_BASE2_READ_Handler(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering TMX320C6412Device::TMX320C6412_IOCTL_BASE2_READ_Handler, " << I << EOL;
// TODO:	Verify that the input parameters are correct
//			If not, return STATUS_INVALID_PARAMETER

// TODO:	Handle the the TMX320C6412_IOCTL_BASE2_READ request, or 
//			defer the processing of the IRP (i.e. by queuing) and set
//			status to STATUS_PENDING.

// TODO:	Assuming that the request was handled here. Set I.Information
//			to indicate how much data to copy back to the user.
	KMemory Mem(I.Mdl());
	PUCHAR pOutBuffer = (PUCHAR) Mem.MapToSystemSpace(); //输出缓冲区指针,传出读取的数据
	PULONG pInBuffer = (PULONG) I.IoctlBuffer(); //输入缓冲区,传来应用程序的一些参数
	                                             //以便通过应用程序指定读取的位置和数据个数
	ULONG offset = pInBuffer[0], count = pInBuffer[1], type = pInBuffer[2];

	if (type == 0)
		m_BASE2.inb (offset, pOutBuffer, count);
	else if (type == 1)
		m_BASE2.inw (offset, (PUSHORT)pOutBuffer, count);
	else
		m_BASE2.ind (offset, (PULONG)pOutBuffer, count);

	I.Information() = count;

	return status;
}

////////////////////////////////////////////////////////////////////////
//  TMX320C6412Device::TMX320C6412_IOCTL_BASE2_WRITE_Handler
//
//	Routine Description:
//		Handler for IO Control Code TMX320C6412_IOCTL_BASE2_WRITE
//
//	Parameters:
//		I - IRP containing IOCTL request
//
//	Return Value:
//		NTSTATUS - Status code indicating success or failure
//
//	Comments:
//		This routine implements the TMX320C6412_IOCTL_BASE2_WRITE function.
//		This routine runs at passive level.
//

NTSTATUS TMX320C6412Device::TMX320C6412_IOCTL_BASE2_WRITE_Handler(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering TMX320C6412Device::TMX320C6412_IOCTL_BASE2_WRITE_Handler, " << I << EOL;
// TODO:	Verify that the input parameters are correct
//			If not, return STATUS_INVALID_PARAMETER

// TODO:	Handle the the TMX320C6412_IOCTL_BASE2_WRITE request, or 
//			defer the processing of the IRP (i.e. by queuing) and set
//			status to STATUS_PENDING.

// TODO:	Assuming that the request was handled here. Set I.Information
//			to indicate how much data to copy back to the user.
	PUCHAR pInBuffer = (PUCHAR) I.IoctlBuffer(); //输入缓冲区,应用程序通过它来指定写入的参数
	                                             //参数包括要写入的偏移地址和数据个数
	PULONG pTmp = (PULONG)pInBuffer;
	ULONG offset = pTmp[0], count = pTmp[1], type = pTmp[2];

	if (type == 0)
		m_BASE2.outb (offset, pInBuffer+12, count);
	else if (type == 1)
		m_BASE2.outw (offset, (PUSHORT)(pInBuffer+12), count);
	else
		m_BASE2.outd (offset, (PULONG)(pInBuffer+12), count);

	I.Information() = count;

	return status;
}

////////////////////////////////////////////////////////////////////////////////
//  TMX320C6412Device_DriverManagedQueue::StartIo
//	
//	Routine Description:
//		This routine is called when an IRP is taken off
//		the Driver Managed Queue (used for serializing I/O) and
//		presented for processing.
//
//	Parameters:
//		I - IRP removed from queue
//
//	Return Value:
//		None
//
//	Comments:
//

VOID TMX320C6412Device_DriverManagedQueue::StartIo(KIrp I)
{
	t  << "Entering TMX320C6412Device_DriverManagedQueue StartIo, " << I;

	// The KDriverManagedQueueEx class gives us the Irp in a non-cancelable state
	// (cancel routine set to NULL) so we can process it without having to worry
	// about clearing the cancel routine first, as is the case with system queuing,
	// or the legacy class KDriverManagedQueue. You may want to set a different cancel
	// routine here, or at other points during the processing of this Irp.

	// Find the device class so we can call the serialized
	// routines in the device class.  The handlers can be
	// moved to the DriverManagedQueue class if it is more
	// convenient.
	TMX320C6412Device *pDev = (TMX320C6412Device *) KDevicePTR(I.DeviceObject());

	// Start processing request.

	// Switch on the IRP's function:
	switch (I.MajorFunction())
	{
		case IRP_MJ_DEVICE_CONTROL:
			switch (I.IoctlCode())
			{
				default:
					// We queued a request that shouldn't have been queued
					// (should never get here)
					ASSERT(FALSE);
					break;
			}
			break;

		default:
			// Error - unexpected IRP received
			// NextIrp completes this IRP and starts processing
			// for the next IRP in the queue.
			ASSERT(FALSE);
			I.Status() = STATUS_INVALID_PARAMETER;
			PnpNextIrp(I);
			break;
	}
}

////////////////////////////////////////////////////////////////////////
//  TMX320C6412Device::DpcFor_Irq
//
//	Routine Description:
//		Deferred Procedure Call (DPC) for Irq
//
//	Parameters:
//		Arg1 - User-defined context variable
//		Arg2 - User-defined context variable
//
//	Return Value:
//		None
//
//	Comments:
//		This function is called for secondary processing of an interrupt.
//		Most code that runs at elevated IRQL should run here rather than
//		in the ISR, so that other interrupt handlers can continue to run.
//

VOID TMX320C6412Device::DpcFor_Irq(PVOID Arg1, PVOID Arg2)
{
// TODO:	Typically, the interrupt signals the end of a data transfer
//			operation for a READ or WRITE operation. The following code
//			assumes the driver will handle the completion of the IRP
//			associated with this operation here.  It further assumes that the
//			IRP to be completed is the current IRP on the driver managed queue.
//			Modify or replace the code here to handle the function of your DPC.

	// Make a KIrp object to reference the current Irp
// TODO:	The Wizard creates a single queue for all Irps.
//			If you have created additional queues, select
//			the appropriate queue for this Irp here.
	KIrp I(m_DriverManagedQueue.CurrentIrp());
	if (!I.IsNull()) {

// TODO:	Set the Status and Information fields to reflect the
//			success and size of the transfer
		I.Status() = STATUS_SUCCESS;
		I.Information() = 0;

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

// TODO:	Enable further interrupts on the device.

	// The following macros simply allows compilation at Warning Level 4
	// If you reference these parameters in the function simply remove the macro.
	UNREFERENCED_PARAMETER(Arg1);
	UNREFERENCED_PARAMETER(Arg2);
}

////////////////////////////////////////////////////////////////////////
//  TMX320C6412Device::Isr_Irq
//
//	Routine Description:
//		Interrupt Service Routine (ISR) for IRQ Irq
//
//	Parameters:
//		None
// 
//	Return Value:
//		BOOLEAN		True if this is our interrupt
//
//	Comments:
//

BOOLEAN TMX320C6412Device::Isr_Irq(void)
{
// TODO:	Verify that the interrupt was caused by our device.
//			Replace "TRUE" in next line with actual test.
	if (TRUE)
	{
		// Return FALSE to indicate that this device did not cause the interrupt.
		return FALSE;
	}

// TODO:	Service the device.
//			Minimal processing may be done here in the ISR, but
//			most processing should be deferred to a DPC.
//			Generally, you should:
//				o  stop the device from generating interrupts
//				o  perform any additional time-critical functions
//				o  schedule a DPC to perform the bulk of the work.	
//

	// Request deferred procedure call
	// The arguments to Request may be any values that you choose
	if (!m_DpcFor_Irq.Request(NULL, NULL))
	{
// TODO:	Request is already in the queue
//			You may want to set flags or perform
//			other actions in this case
	}

	// Return TRUE to indicate that our device caused the interrupt
	return TRUE;
}


⌨️ 快捷键说明

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