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

📄 bpskdevice.cpp

📁 PCI9054驱动
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
//		The base class passes the irp to the lower device.
//

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

	t << "Entering BPSKDevice::OnStopDevice\n";

	// Device stopped, release the system resources.
	Invalidate();

// TODO:	Add device-specific code to stop your device   

	return status;
	
	// The following macro simply allows compilation at Warning Level 4
	// If you reference this parameter in the function simply remove the macro.
	UNREFERENCED_PARAMETER(I);
}

////////////////////////////////////////////////////////////////////////
//  BPSKDevice::OnRemoveDevice
//
//	Routine Description:
//		Handler for IRP_MJ_PNP subfcn IRP_MN_REMOVE_DEVICE
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result code
//
//	Comments:
//		The system calls this when the device is removed.
//		Our PnP policy will take care of 
//			(1) giving the IRP to the lower device
//			(2) detaching the PDO
//			(3) deleting the device object
//

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

	// Device removed, release the system resources.
	m_Irq.Disconnect();
	
	// Device removed, release the system resources.
	m_Irq.Invalidate();
	Invalidate();

// TODO:	Add device-specific code to remove your device   

	return STATUS_SUCCESS;

	// The following macro simply allows compilation at Warning Level 4
	// If you reference this parameter in the function simply remove the macro.
	UNREFERENCED_PARAMETER(I);
}
VOID BPSKDevice::CancelQueuedIrp(KIrp I)
{
	KDeviceQueue dq(DeviceQueue());

	// Test if the IRP is the current IRP如果请求的IRP是当前IRP就直接将他删除.
	if ( (PIRP)I == CurrentIrp() )
	{
		CurrentIrp() = NULL;
		CancelSpinLock::Release(I.CancelIrql());
	    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());
	    I.Information() = 0;
		I.PnpComplete(this, STATUS_CANCELLED);
	}
	//如果请求取消的IRP不在对列中,释放对IRP的请求
	else
	{
		CancelSpinLock::Release(I.CancelIrql());
	}
}

VOID BPSKDevice::StartIo(KIrp I)
{
	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;
		default:
			ASSERT(FALSE);
			PnpNextIrp(I);
			break;
	}
}

////////////////////////////////////////////////////////////////////////
//  BPSKDevice::OnDevicePowerUp
//
//	Routine Description:
//		Handler for IRP_MJ_POWER with minor function IRP_MN_SET_POWER
//		for a request to go to power on state from low power state
//
//	Parameters:
//		I - IRP containing POWER request
//
//	Return Value:
//		NTSTATUS - Status code indicating success or failure
//
//	Comments:
//		This routine implements the OnDevicePowerUp function.
//		This function was called by the framework from the completion
//		routine of the IRP_MJ_POWER dispatch handler in KPnpDevice.
//		The bus driver has completed the IRP and this driver can now
//		access the hardware device.  
//		This routine runs at dispatch level.
//	

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

	t << "Entering BPSKDevice::OnDevicePowerUp\n";

// TODO:	Service the device.
//			Restore any context to the hardware device that
//			was saved during the handling of a power down request.
//			See the OnDeviceSleep function.
//			Do NOT complete this IRP.
//
	return status;

	// The following macro simply allows compilation at Warning Level 4
	// If you reference this parameter in the function simply remove the macro.
	UNREFERENCED_PARAMETER(I);
}

////////////////////////////////////////////////////////////////////////
//  BPSKDevice::OnDeviceSleep
//
//	Routine Description:
//		Handler for IRP_MJ_POWER with minor function IRP_MN_SET_POWER
//		for a request to go to a low power state from a high power state
//
//	Parameters:
//		I - IRP containing POWER request
//
//	Return Value:
//		NTSTATUS - Status code indicating success or failure
//
//	Comments:
//		This routine implements the OnDeviceSleep function.
//		This function was called by the framework from the IRP_MJ_POWER 
//		dispatch handler in KPnpDevice prior to forwarding to the PDO.
//		The hardware has yet to be powered down and this driver can now
//		access the hardware device.  
//		This routine runs at passive level.
//	

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

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

// TODO:	Service the device.
//			Save any context to the hardware device that will be required 
//			during a power up request. See the OnDevicePowerUp function.
//			Do NOT complete this IRP.  The base class handles forwarding
//			this IRP to the PDO.
//
	return status;

	// The following macro simply allows compilation at Warning Level 4
	// If you reference this parameter in the function simply remove the macro.
	UNREFERENCED_PARAMETER(I);
}

////////////////////////////////////////////////////////////////////////
//  BPSKDevice::Create
//
//	Routine Description:
//		Handler for IRP_MJ_CREATE
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result code
//
//	Comments:
//

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

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

// TODO: Add driver specific create handling code here

	// Generally a create IRP is targeted at our FDO, so we don't need
	// to pass it down to the PDO.  We have found for some devices, the
	// PDO is not expecting this Irp and returns an error code.
	// The default wizard code, therefore completes the Irp here using
	// PnpComplete().  The following commented code could be used instead
	// of PnpComplete() to pass the Irp to the PDO, which would complete it.
	//
//	I.ForceReuseOfCurrentStackLocationInCalldown();
//	status = m_Lower.PnpCall(this, I);

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

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

	return status;
}

////////////////////////////////////////////////////////////////////////
//  BPSKDevice::Close
//
//	Routine Description:
//		Handler for IRP_MJ_CLOSE
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result code
//
//	Comments:
//

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

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

// TODO: Add driver specific close handling code here

	// Generally a close IRP is targeted at our FDO, so we don't need
	// to pass it down to the PDO.  We have found for some devices, the
	// PDO is not expecting this Irp and returns an error code.
	// The default wizard code, therefore completes the Irp here using
	// PnpComplete().  The following commented code could be used instead
	// of PnpComplete() to pass the Irp to the PDO, which would complete it.
	//
//	I.ForceReuseOfCurrentStackLocationInCalldown();
//	status = m_Lower.PnpCall(this, I);

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

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

    return status;
}

////////////////////////////////////////////////////////////////////////
//  BPSKDevice::Cleanup
//
//	Routine Description:
//		Handler for IRP_MJ_CLEANUP	
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result code
//
//	Comments:
//

NTSTATUS BPSKDevice::CleanUp(KIrp I)
{
	t << "Entering CleanUp, " << I << EOL;

// TODO:	Insert your code to respond to the CLEANUP message.
//			This code cleans up the single Wizard created queue.  If you
//			have created additional queues,	or have any outstanding Irps
//			stored in some other fashion in your driver, you should clean
//			these up as well for the file object specified in the cleanup Irp.
	KDeviceQueue dq(DeviceQueue());
	dq.PnpCleanUp(this, I.FileObject());
	return I.PnpComplete(this, STATUS_SUCCESS);
}

////////////////////////////////////////////////////////////////////////
//  BPSKDevice::SerialRead
//	
//	Routine Description:
//		Handler for serialized READ
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		None
//
//	Comments:
//		This routine is called when the IRP is removed from the
//		STARTIO queue.  This guarantees that multiple requests are
//		never processed simultaneously.
//
//		This routine is called at dispatch level.
//

void BPSKDevice::SerialRead(KIrp I)
{
	t << "Entering BPSKDevice::SerialRead, " << I << EOL;
	NTSTATUS status		= STATUS_SUCCESS;
//进行DMA传输

	m_CurrentTransfer=new(NonPagedPool)KDmaTransfer(this,&m_Dma);
	if(m_CurrentTransfer==NULL)
	{
		status=STATUS_INSUFFICIENT_RESOURCES;
		t<<"unable to allocate transfer object:"<<status<<EOL;
		I.Information()=0;
		I.Status()=status;
		PnpNextIrp(I);
	}
/*	status=m_CurrentTransfer->Initiate(I.Mdl(),(I.MajorFunction()==IRP_MJ_READ)?
								FromDeviceToMemory:FromMemoryToDevice,
								LinkTo(OnDmaReady)
										);
*/
	status=m_CurrentTransfer->Initiate(this,&m_Dma,I.Mdl(),(I.MajorFunction()==IRP_MJ_READ)?
					FromDeviceToMemory:FromMemoryToDevice,
					LinkTo(OnDmaReady),&m_Buffer
				   );

	// If the transfer cannot be initiated, complete it with an error status.
	if ( ! NT_SUCCESS(status) )
	{
		t<<"unable to initiate transfer: "<< status<<EOL;

		delete m_CurrentTransfer;
		m_CurrentTransfer = NULL;

		I.Information() = 0;
		I.Status() = status;
		PnpNextIrp(I);
	}
}


////////////////////////////////////////////////////////////////////////
//  BPSKDevice::Read
//
//	Routine Description:
//		Handler for IRP_MJ_READ
//
//	Parameters:
//		I			Current IRP
//
//	Return Value:
//		NTSTATUS	Result code
//
//	Comments:
//		This routine handles read requests.
//
//		The KPnpDevice class handles restricting IRP flow
//		if the device is stopping or being removed.
//

NTSTATUS BPSKDevice::Read(KIrp I) 
{
	t << "Entering BPSKDevice::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 (I.ReadSize() == 0)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_SUCCESS);
	}

	return QueueIrp(I, LinkTo(CancelQueuedIrp));

/*原来的框架
    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);
	}
	NTSTATUS status		= STATUS_SUCCESS;

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

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

// TODO:	If the read can be satisfied immediately, set the Information
//			and Status fields now, then call NextIrp to complete this IRP
//			and start processing the next IRP in the queue.

// TODO:	If the data is not yet available, initiate a request to the
//			physical device here, and defer the Information, Status,
//			and NextIrp handling until the hardware indicates that the
//			read is complete.  Typically, this might be handled in a
//			DPC that is called after the hardware finishes transferring
//			the data.

// TODO:	To satisfy the read now, transfer data from the device to
//			caller's buffer at "pBuffer".  Then, indicate how much data was
//			transferred:

	I.Information() = dwBytesRead;

	return I.PnpComplete(this, status);
	*/
}

////////////////////////////////////////////////////////////////////////
//  BPSKDevice::SerialWrite
//	
//	Routine Description:
//		Handler for serialized WRITE
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		None
//
//	Comments:
//		This routine is called when the IRP is removed from the
//		STARTIO queue.  This guarantees that multiple requests are
//		never processed simultaneously.
//

void BPSKDevice::SerialWrite(KIrp I)
{
	NTSTATUS status		= STATUS_SUCCESS;
//	ULONG i;

	// 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;
	//清空FIFO
	//m_IoPortRange1.outb(0,0);
	//用I/O输出命令往FIFO写数据
	//for (i=0;i<dwTotalSize;i++) m_IoPortRange1.outb(0x4,*pBuffer++);//自己修改的0x04:Local Base Address (Remap) for PCI-to-Local Address Space 0

	I.Information() = dwBytesSent;
	I.Status() = status;

	PnpNextIrp(I);
}


////////////////////////////////////////////////////////////////////////
//  BPSKDevice::Write
//
//	Routine Description:
//		Handler for IRP_MJ_WRITE
//
//	Parameters:

⌨️ 快捷键说明

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