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

📄 isp1581device_buf.cpp

📁 这是一个用ISP1581 USB2.0接口芯片作为图像采集接口的驱动程序。该驱动程序支持Endpoint1 Bulk方式 数据输入传输。实际传输速度可以达到24MBYTE/S
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	UNREFERENCED_PARAMETER(I);
}

////////////////////////////////////////////////////////////////////////
//  GnganfgDevice::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 GnganfgDevice::OnDeviceSleep(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering GnganfgDevice::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);
}

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

NTSTATUS GnganfgDevice::Create(KIrp I)
{
	NTSTATUS status=STATUS_SUCCESS;

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

	if( (m_HasBeenCreated == FALSE) || (m_AdapterNotificationEvent==NULL) )
	{
		m_HasBeenCreated = TRUE;

		KUnitizedName EventName;
		NotificationEventHandle = NULL;
													
		EventName.Initialize(L"\\BaseNamedObjects\\KINGF_ReadOperationCompEvent", m_Unit);
		m_AdapterNotificationEvent = IoCreateSynchronizationEvent(PUNICODE_STRING(EventName), &NotificationEventHandle);
	    // m_AdapterNotificationEvent = IoCreateNotificationEvent(PUNICODE_STRING(EventName), &NotificationEventHandle);
		if (m_AdapterNotificationEvent == NULL)
		{
			t << "Create Event Error!\n";
	        status = STATUS_NO_EVENT_PAIR;
			return status;
		}

		KeClearEvent(m_AdapterNotificationEvent);
	}

	if (!m_FPGAConfigSuccessful)
	{
		m_FPGAConfigSuccessful = TRUE;
		status = ConfigFpga();
	}

// 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, IO_NO_INCREMENT);

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

	return status;
}


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

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

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

// TODO: Add driver specific close handling code here
	m_HasBeenCreated = FALSE;
    if (NotificationEventHandle != NULL)
        ZwClose (NotificationEventHandle);

	// 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 << "GnganfgDevice::Close Status " << (ULONG)status << EOL;

    return status;
}

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

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

// TODO:	Insert your code to respond to the CLEANUP message.
	return I.PnpComplete(this, STATUS_SUCCESS);
}


////////////////////////////////////////////////////////////////////////
// Read (member of GnganfgDevice)		Handler for IRP_MJ_READ
// Input		I			Current IRP
// Output 		NTSTATUS	Result code
// Note   		This routine handles read requests.
//		The KPnpDevice class handles restricting IRP flow if the device is stopping or being removed.
NTSTATUS GnganfgDevice::Read(KIrp I) 
{
	t << "Entering GnganfgDevice::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);
	}

    ULONG dwTotalSize = I.ReadSize(CURRENT);	// dwTotalSize = 400k-Byte; 
	ULONG dwMaxSize = m_Endpoint5.MaximumTransferSize();

	// If the total requested read size is greater than the Maximum Transfer
	// Size for the Pipe, request to read only the Maximum Transfer Size since
	// the bus driver will fail an URB with a TransferBufferLength of greater
	// than the Maximum Transfer Size. 
	if ( (dwTotalSize != 640*640) || (dwTotalSize > dwMaxSize) )
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_INVALID_BUFFER_SIZE);
	}

	// Allocate a new context structure for Irp completion
	USB_COMPLETION_INFO* pCompInfo = new (NonPagedPool) USB_COMPLETION_INFO;
	if (pCompInfo == NULL)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
	}

	// Create an URB to do actual Bulk read from the pipe
	PURB pUrb = m_Endpoint5.BuildBulkTransfer(
			    	m_lpBufferToRead,   // Where is data coming from?
					dwMaxSize,  		// How much data to read? 405k_Bytes;
					TRUE,         		// direction (TRUE = IN)
					NULL,				// Link to next URB
					TRUE				// Allow a short transfer
					);        		

	if (pUrb == NULL)
	{
		delete pCompInfo;
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
	}

	// Initialize context structure
	pCompInfo->m_pClass = this;
	pCompInfo->m_pUrb = pUrb;

    // Submit the URB to our USB device
	NTSTATUS status;
	status = m_Endpoint5.SubmitUrb(I, pUrb, LinkTo(ReadComplete), pCompInfo, 0);
	return status;
}

////////////////////////////////////////////////////////////////////////
//  GnganfgDevice::ReadComplete
//	Routine Description:
//		Completion Handler for IRP_MJ_READ
//	Parameters:
//		I - IRP just completed by USB
//		pContext - Context structure containing pointer to Urb
//	Parameters:
//		NTSTATUS - STATUS_SUCCESS
//	Comments:
//		This routine is called when USBD completes the read request

NTSTATUS GnganfgDevice::ReadComplete(KIrp I, USB_COMPLETION_INFO* pContext)
{
	// Normal completion routine code to propagate pending flag

	if (I->PendingReturned) 
	{
		I.MarkPending();
	}

	NTSTATUS status = I.Status();
	PURB pUrb = pContext->m_pUrb;
	ULONG nBytesRead = 0;

	// Declare a memory object
	KMemory Mem(I.Mdl());
	PUCHAR	pIrpBuffer	= (PUCHAR) Mem.MapToSystemSpace();
	CHAR*	pBuffer;
	ULONG	dOffset = 5*1024;

	if ( NT_SUCCESS(status) ) 
	{
		nBytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
		pBuffer    = (CHAR*)pUrb->UrbBulkOrInterruptTransfer.TransferBuffer;
		pBuffer    += dOffset; // Offset 5k;

		if (nBytesRead == m_dwFrameLengthInByte )
		{
			nBytesRead -= dOffset; 
   			RtlCopyMemory(	pIrpBuffer,		//IN VOID UNALIGNED *Destination,
							pBuffer,		//IN CONST VOID UNALIGNED *Source,
							nBytesRead );	//IN ULONG Length
		}
		else
			nBytesRead = 0;
	}

	// Deallocate Urb and context structure
	delete pUrb;
	delete pContext;

	// set returned count
	I.Information() = nBytesRead;
	
	// Plug and Play accounting
	DecrementOutstandingRequestCount();

	if(m_AdapterNotificationEvent!=NULL)
		KeSetEvent(m_AdapterNotificationEvent,0,FALSE) ;
	// allow IRP completion processing
	return STATUS_SUCCESS;
}

////////////////////////////////////////////////////////////////////////
// Write (member of GnganfgDevice)		Handler for IRP_MJ_WRITE
// Input		I			Current IRP
// Output		NTSTATUS	Result code
// Note   		This routine handles write requests.
//		The KPnpDevice class handles restricting IRP flow if the device is stopping or being removed.

NTSTATUS GnganfgDevice::Write(KIrp I) 
{	
	NTSTATUS status;
	ULONG dwBytesWritten = 0;
	ULONG dwWriteTimes = 0;
	ULONG i;

	t << "Entering GnganfgDevice::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);
	}

	ULONG dwMaxTransferSize = m_Endpoint4.MaximumTransferSize();
	ULONG dwTotalSize = I.WriteSize(CURRENT);

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

	// Declare a memory object
	KMemory Mem(I.Mdl());
	PUCHAR	pBuffer		= (PUCHAR) Mem.MapToSystemSpace();

	// calculate the Write times needed to complete this read request
	dwWriteTimes = dwTotalSize/dwMaxTransferSize;
	if( dwTotalSize%dwMaxTransferSize )
		dwWriteTimes++;

	for( i = 0; i < dwWriteTimes; i ++ )
	{
		// Create an URB to do actual Bulk read from the pipe
		ULONG tempWriteSize = dwMaxTransferSize;
		if( (i == (dwWriteTimes - 1 )) && (dwTotalSize%dwMaxTransferSize) ) // last read and read length less than dwMaxTransferSize
		{
			tempWriteSize = dwTotalSize%dwMaxTransferSize;
		}

		PURB   pUrb = NULL;
		pUrb = m_Endpoint4.BuildBulkTransfer(
	    				pBuffer,      		// Where is data coming from?
						tempWriteSize, 	    // How much data to write.
						FALSE,         		// direction (TRUE = IN)
						NULL,				// Link to next URB
						FALSE);  
		
		if (pUrb == NULL)
		{
			I.Information() = 0;
			return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
		}

		// Allow a short transfer
		pUrb->UrbBulkOrInterruptTransfer.TransferFlags =
			(USBD_TRANSFER_DIRECTION_OUT | USBD_SHORT_TRANSFER_OK);

		// Submit the URB to our USB device
		status = m_Endpoint4.SubmitUrb( pUrb, NULL, NULL, 1000);
	
		// if successful then calculate the amount of the read bytes
		if ( NT_SUCCESS(status) ) 
		{
			dwBytesWritten = dwBytesWritten + 
						 pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;

			delete pUrb;
			// adjust the buffer pointer
			pBuffer = pBuffer + tempWriteSize;

		}
		else
		{
			break;
		}
	}

	I.Information() = dwBytesWritten;
	return I.PnpComplete(this, status);
}

////////////////////////////////////////////////////////////////////////
// WriteComplete (member of GnganfgDevice)		Completion Handler for IRP_MJ_WRITE
// Input		I			IRP just completed by USB
//				pContext	Context structure containing pointer to Urb
// Output  		NTSTATUS	STATUS_SUCCESS
// Note   		This routine is called when USBD completes the write request

NTSTATUS GnganfgDevice::WriteComplete(KIrp I, USB_COMPLETION_INFO* pContext)
{
	NTSTATUS status = I.Status();
	PURB pUrb = pContext->m_pUrb;
	ULONG nBytesWritten = 0;

	if ( NT_SUCCESS(status) ) 
	{
		nBytesWritten = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
		if (nBytesWritten > 0) 
			t << "Wrote " << nBytesWritten	<< " bytes to USB\n";
    }

	// Deallocate Urb and context structure
	delete pUrb;
	delete pContext;

	// set returned count
	I.Information() = nBytesWritten;
	
	// Plug and Play accounting
	DecrementOutstandingRequestCount();

	// allow IRP completion processing
	return STATUS_SUCCESS;
}

////////////////////////////////////////////////////////////////////////
// DeviceControl (member of GnganfgDevice)
//
//		Handler for IRP_MJ_DEVICE_CONTROL
//
// Input
//		I		Current IRP
// 
// Output
//		None
//
// Notes:
//		This routine is the first handler for Device Control requests.
//		The KPnpDevice class handles restricting IRP flow
//		if the device is stopping or being removed.
//
NTSTATUS GnganfgDevice::DeviceControl(KIrp I) 
{
	NTSTATUS status;

	t << "Entering GnganfgDevice::Device Control, " << I << EOL;
	switch (I.IoctlCode())
	{
		// Vendor request.
		case FzGdi_IOCTL_SetDeviceCommands:
			status = KBUSBDEV_IOCTL_SetDeviceCommands_Handler(I);
			break;

		// Vendor request.
			case FzGdi_IOCTL_GetDeviceStatus:
			status = KBUSBDEV_IOCTL_GetDeviceStatus_Handler(I);
			break;

		// Calss request.	
		case FzGdi_IOCTL_GetDeviceID:
			status = KBUSBDEV_IOCTL_GetDeviceID_Handler(I);
			break;

		// Calss request.	
		case FzGdi_IOCTL_GetPortStatus:
			status = KBUSBDEV_IOCTL_GetPortStatus_Handler(I);
			break;

		// Calss request.	
		case FzGdi_IOCTL_SoftReset:
			status = KBUSBDEV_IOCTL_SoftReset_Handler(I);
			break;


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

⌨️ 快捷键说明

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