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

📄 usblptpd11.c

📁 usb driver, sample for usb driver develop. rised for reference
💻 C
📖 第 1 页 / 共 2 页
字号:
	}

  	/* And restore Interrupts */
	
	if (DeviceExtension->Vector) IoDisconnectInterrupt(DeviceExtension->InterruptObject);
		
	Irp->IoStatus.Information = 0;
	Irp->IoStatus.Status = STATUS_SUCCESS;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}


NTSTATUS
USBLPTPD11DeviceControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP pIrp
    )
{
    PIO_STACK_LOCATION  irpSp;
    NTSTATUS            ntStatus = STATUS_SUCCESS;

    ULONG               inBufLength; 	/* Input buffer length */
    ULONG               outBufLength; 	/* Output buffer length */
    PUCHAR 				CharBuffer; 	/* Pointer to Char Formatted Buffer */
    PULONG				LongBuffer;		/* Pointer to Long Formatted Buffer */
    PVOID 				ioBuffer;		/* pointer to Input and output buffer */

    UCHAR				Count;
    UCHAR 				Buffer[40];

	PLOCAL_DEVICE_INFO DeviceExtension = DeviceObject->DeviceExtension;

    irpSp = IoGetCurrentIrpStackLocation( pIrp );

    inBufLength  = irpSp->Parameters.DeviceIoControl.InputBufferLength;
    outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength;

    ioBuffer     = pIrp->AssociatedIrp.SystemBuffer;

    CharBuffer   = (PUCHAR) ioBuffer;
    LongBuffer   = (PULONG) ioBuffer;

    switch ( irpSp->Parameters.DeviceIoControl.IoControlCode )
     {
      case IOCTL_DETECT_DEVICE:
				KdPrint( ("USBLPTPD11: IOCTL_DETECT_DEVICE") );

				/* Clear ECP's Extended Control Register Setting Port to Standard Mode */
				outportb(DeviceExtension->PortAddress + 0x402, 0x00);
				
				ntStatus = DetectDevice(DeviceExtension->PortAddress);
				pIrp->IoStatus.Information = 0; /* Output Buffer Size */
				pIrp->IoStatus.Status = ntStatus;
				IoCompleteRequest( pIrp, IO_NO_INCREMENT );  
				break;

	  case IOCTL_INIT_I2C:
				KdPrint( ("USBLPTPD11: IOCTL_I2C_INIT\n") );

				ntStatus = I2C_Init(DeviceExtension->PortAddress);
				
				pIrp->IoStatus.Information = 0; /* Output Buffer Size */
				pIrp->IoStatus.Status = ntStatus;
				IoCompleteRequest( pIrp, IO_NO_INCREMENT );
				break;

	  case IOCTL_READ_I2C:
		  		ntStatus = STATUS_BUFFER_TOO_SMALL;
				pIrp->IoStatus.Information = 0;

				if (inBufLength >= 2) { /* Safe to retreive byCount Value */
	  					KdPrint( ("USBLPTPD11: READ_I2C, byDevID = 0x%02X, byCount = 0x%02X\n",CharBuffer[0],CharBuffer[1]) );
						Count = CharBuffer[1];
				
						if (outBufLength >= Count) { /* Safe to call I2C_Read Operation */  
							 ntStatus = I2C_Read( ioBuffer, CharBuffer[0], CharBuffer[1], DeviceExtension->PortAddress);
							 pIrp->IoStatus.Information = Count; /* Output Buffer Size */
						}
				}
				pIrp->IoStatus.Status = ntStatus;
				IoCompleteRequest( pIrp, IO_NO_INCREMENT );
				break;

	  case IOCTL_WRITE_I2C:
				ntStatus = STATUS_BUFFER_TOO_SMALL;

				if (inBufLength >= 2) { /* Safe to retreive byCount Value */
	  					KdPrint( ("USBLPTPD11: Write_I2C, byDevID = 0x%02X, byCount = 0x%02X\n",CharBuffer[0],CharBuffer[1]) );
						Count = CharBuffer[1] + 2;
						if (inBufLength >= Count) /* Safe to call I2C_Write Operation */ 
							 ntStatus = I2C_Write(CharBuffer[0], &CharBuffer[2], CharBuffer[1], DeviceExtension->PortAddress);
				}
				pIrp->IoStatus.Information = 0; /* Output Buffer Size */
				pIrp->IoStatus.Status = ntStatus;
				IoCompleteRequest( pIrp, IO_NO_INCREMENT );	  
				break;

	  case IOCTL_STATUS_LED:
				KdPrint( ("USBLPTPD11: IOCTL_STATUS_LED") );

				if (inBufLength >= 1) {
							if (CharBuffer[0]) SetStatus(DeviceExtension->PortAddress);
							else               ClearStatus(DeviceExtension->PortAddress);
							ntStatus = STATUS_SUCCESS;
				} else ntStatus = STATUS_BUFFER_TOO_SMALL;
				
				pIrp->IoStatus.Information = 0; /* Output Buffer Size */
				pIrp->IoStatus.Status = ntStatus;
				IoCompleteRequest( pIrp, IO_NO_INCREMENT );	  
				break;

	  case IOCTL_GET_SUSPEND:
				KdPrint( ("USBLPTPD11: IOCTL_GET_SUSPEND") ); 		

				if (outBufLength >= 1) {
						*(PUCHAR)ioBuffer = GetSuspend(DeviceExtension->PortAddress);
						pIrp->IoStatus.Information = 1; /* Output Buffer Size */
						ntStatus = STATUS_SUCCESS;
				} else {
						pIrp->IoStatus.Information = 0;
						ntStatus = STATUS_BUFFER_TOO_SMALL;
				}
				pIrp->IoStatus.Status = ntStatus;
				IoCompleteRequest( pIrp, IO_NO_INCREMENT );  
				break;

	  case IOCTL_GET_INT:
				KdPrint( ("USBLPTPD11: IOCTL_GET_INT") ); 
		  		
				if (outBufLength >= 1) {
						*(PUCHAR)ioBuffer = GetInt(DeviceExtension->PortAddress);
						pIrp->IoStatus.Information = 1; /* Output Buffer Size */
						ntStatus = STATUS_SUCCESS;
				} else {
						pIrp->IoStatus.Information = 0;
						ntStatus = STATUS_BUFFER_TOO_SMALL;
				}
				pIrp->IoStatus.Status = ntStatus;
				IoCompleteRequest( pIrp, IO_NO_INCREMENT );  
				break;

	  case IOCTL_WAIT_INTERRUPT:
				
				if (inBufLength >= 4) {
		  		        KdPrint( ("USBLPTPD11: Wait for Interrupt, Timeout = %duS\n",LongBuffer[0]) );
						DeviceExtension->IntTimer_uS = RtlConvertLongToLargeInteger(0 - LongBuffer[0]); 

						/* Check if IRQ line (nAck) already High. If this is the case, return immediately */
						if ((inportb(DeviceExtension->PortAddress + 1) & 0x40) | (DeviceExtension->Vector == 0)){
							    pIrp->IoStatus.Information = 0; /* Output Buffer Size */
        						pIrp->IoStatus.Status = STATUS_SUCCESS;
        						IoCompleteRequest( pIrp, IO_NO_INCREMENT );	  
	        					ntStatus = STATUS_SUCCESS;
								}
						else {
  								/* Mark IRP as pending and place in queue */
								IoMarkIrpPending(pIrp);
								IoStartPacket(DeviceObject, pIrp, NULL, NULL);
								ntStatus = STATUS_PENDING;
								}
				} else {
				ntStatus = STATUS_BUFFER_TOO_SMALL;
				pIrp->IoStatus.Information = 0; /* Output Buffer Size */
        		pIrp->IoStatus.Status = ntStatus;
        		IoCompleteRequest( pIrp, IO_NO_INCREMENT );	  
				}
	        	break;

	  default:
				KdPrint( ("USBLPTPD11: Unsupported IOCTL Call\n") );
			
				ntStatus = STATUS_UNSUCCESSFUL;
				pIrp->IoStatus.Status = ntStatus;
				pIrp->IoStatus.Information = 0;
				IoCompleteRequest(pIrp, IO_NO_INCREMENT);	
				break;
     }
	return ntStatus;
}


VOID USBLPTPD11Unload(IN PDRIVER_OBJECT DriverObject)
{

	PDEVICE_OBJECT              CurrentDevice;
	PLOCAL_DEVICE_INFO			DeviceExtension;
	KEVENT                      event;
	PIRP                        irp;
	IO_STATUS_BLOCK             ioStatus;
	NTSTATUS					status;
   	WCHAR						Win32DeviceBuffer[52];
	WCHAR						NumberBuffer[6];
	UNICODE_STRING			    uniWin32Device = {0, sizeof(Win32DeviceBuffer)/sizeof(WCHAR), Win32DeviceBuffer};
	UNICODE_STRING				uniNumber = {0, sizeof(NumberBuffer)/sizeof(WCHAR), NumberBuffer};

	CurrentDevice = DriverObject->DeviceObject;

    while( CurrentDevice ) {
        
        DeviceExtension = CurrentDevice->DeviceExtension;
        
	    KdPrint( ("USBLPTPD11: USBLPT-PD11 is Unloading Device %d, DeviceObject %x",DeviceExtension->DeviceNumber, CurrentDevice ) );

      	/* Disable Parallel Port IRQ's */
		outportb(DeviceExtension->PortAddress+2, inportb(DeviceExtension->PortAddress+2) & 0xEF); 

		// Convert Device Number to Unicode String
		uniNumber.Length = 0;
		uniWin32Device.Length = 0;
		RtlIntegerToUnicodeString(DeviceExtension->DeviceNumber, 10, &uniNumber);
		RtlAppendUnicodeToString(&uniWin32Device, WIN32_DEVICE_NAME); 
		RtlAppendUnicodeStringToString(&uniWin32Device, &uniNumber);

		IoDeleteSymbolicLink (&uniWin32Device);

        IoDeleteDevice(CurrentDevice);

        CurrentDevice = DriverObject->DeviceObject;
    }

}


VOID USBLPTPD11StartIo(PDEVICE_OBJECT DeviceObject, PIRP pIrp)
{
	PLOCAL_DEVICE_INFO DeviceExtension = DeviceObject->DeviceExtension;

	/* Enable Parallel Port IRQ's */
	outportb(DeviceExtension->PortAddress+2, inportb(DeviceExtension->PortAddress+2) | 0x10); 

   	/* Set up timers for Interrupt Time Out */
	KeInitializeDpc(&DeviceExtension->IntTimerDPC,
  					USBLPTPD11TimeOutDPC,
					DeviceObject);

    KeSetTimer(&DeviceExtension->IntTimer,
   			   DeviceExtension->IntTimer_uS,
               &DeviceExtension->IntTimerDPC);

}

VOID USBLPTPD11TimeOutDPC(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
{
	PDEVICE_OBJECT deviceObject;
  	PLOCAL_DEVICE_INFO deviceExtension;
	PIRP pIrp;

	deviceObject = DeferredContext;
	pIrp = deviceObject->CurrentIrp;
	deviceExtension = deviceObject->DeviceExtension;

    KdPrint( ("USBLPTPD11: ISRTimeOutDPC, pIrp = 0x%08X\n",pIrp) );

  	if (pIrp != NULL)
		{
		 pIrp->IoStatus.Information = 0;
		 pIrp->IoStatus.Status = STATUS_IO_TIMEOUT;
		 IoCompleteRequest(pIrp, IO_NO_INCREMENT);
		 IoStartNextPacket(deviceObject, FALSE);
		}

}

BOOLEAN USBLPTPD11Isr(IN PKINTERRUPT Interrupt, IN OUT PVOID Context)
{
	PDEVICE_OBJECT deviceObject = Context;

	KdPrint( ("USBLPTPD11: Interrupt Service Routine\n") );

	/* We should check if the interrupt comes from us and return */
	
	if (!(deviceObject->CurrentIrp == NULL)) {
  			IoRequestDpc(deviceObject,
		 				 deviceObject->CurrentIrp,
						 NULL);
			}
	
	return TRUE;
}

VOID USBLPTPD11DpcRoutine(IN PKDPC Dpc, PDEVICE_OBJECT deviceObject, IN PIRP Irp, IN PVOID Context)
{
	PLOCAL_DEVICE_INFO deviceExtension;
	PIRP pIrp;

	pIrp = deviceObject->CurrentIrp;
	deviceExtension = deviceObject->DeviceExtension;

	if (pIrp != NULL)
		{
		 KdPrint( ("USBLPTPD11: DPC Routine Valid IRP - Completing Request\n") );
		 pIrp->IoStatus.Information = 0;
		 pIrp->IoStatus.Status = STATUS_SUCCESS;
		 IoCompleteRequest(pIrp, IO_NO_INCREMENT);
		 KeCancelTimer(&deviceExtension->IntTimer);
		 IoStartNextPacket(deviceObject, FALSE);
		}
	return;
}

NTSTATUS I2C_Read(unsigned char * pbyData, unsigned char byDevId, unsigned char byCount, unsigned long PortAddress) {

	unsigned char byRetVal = 0;

	while(1) {

		if(!Start(PortAddress)) return STATUS_DATA_ERROR;

		if( !ByteOut( byDevId |= I2C_CTL_READ, PortAddress ) ) return STATUS_DATA_ERROR;

		while(byCount) {
			ByteIn( pbyData+byRetVal, PortAddress );
			byCount--;
			byRetVal++;
			if(byCount) {
         		SetAck(PortAddress);
               }
			else {
         		SetNak(PortAddress);
               }
		}
		Stop(PortAddress);
		break;
	}
	return STATUS_SUCCESS;
}

NTSTATUS I2C_Write(unsigned char byDevId, unsigned char * pbyData, unsigned char byCount, unsigned long PortAddress) {

	unsigned char byRetVal = 0;

  	if( !Start(PortAddress) ) return STATUS_DATA_ERROR;

	if( !ByteOut( byDevId &= I2C_CTL_WRITE, PortAddress) ) return STATUS_DATA_ERROR;

	while(byCount) {
		if( !ByteOut( *(pbyData+byRetVal), PortAddress ) ) return STATUS_DATA_ERROR;
		byCount--;
		byRetVal++;
		}
     
	Stop(PortAddress);
	return STATUS_SUCCESS;
}

NTSTATUS I2C_Init(unsigned long PortAddress) {
	Idle(PortAddress);
	if (GetSDA(PortAddress) && GetSCL(PortAddress))  return STATUS_SUCCESS;
	else			 		   return STATUS_DATA_ERROR;
}

unsigned char Start(unsigned long PortAddress) {
	if( !(GetSCL(PortAddress) && GetSDA(PortAddress)) )
     {
		Stop(PortAddress);
		if( !(GetSCL(PortAddress) && GetSDA(PortAddress)) )
			return I2C_FALSE;
  	 	}
	ClearSDA(PortAddress);
	return I2C_TRUE;
}

unsigned char ByteOut(unsigned char byData, unsigned long PortAddress) {
	unsigned char i;
    unsigned char AckWait=0;
	for (i=0x80; i>0; i>>=1) {
		ClearSCL(PortAddress);
		if (byData & i) SetSDA(PortAddress);   
		else            ClearSDA(PortAddress); 
		SetSCL(PortAddress);
		}

	// Check for ACK
  	ClearSCL(PortAddress);
	SetSDA(PortAddress);
	SetSCL(PortAddress);
      if (GetSDA(PortAddress)) {
		  ClearSCL(PortAddress);
	      return I2C_FALSE;
         }
  	ClearSCL(PortAddress);
    return I2C_TRUE;   // ACK was detected if here
}

void ByteIn(unsigned char * pbyData, unsigned long PortAddress) {
  unsigned char i;
  unsigned char byTemp=0;

  for (i=0; i<8; i++) {
		ClearSCL(PortAddress);
		byTemp |= GetSDA(PortAddress);
		SetSCL(PortAddress);
		if (i != 7) byTemp <<= 1;
  }
  *pbyData = byTemp;
}

NTSTATUS DetectDevice(LONG PortAddress) 
{
	/* Set XD1 and check */
    outportb(PortAddress, inportb(PortAddress) |  XD1);
    if (!(inportb(PortAddress+1) & XERROR)) return STATUS_UNSUCCESSFUL;

	/* Clear XD1 and Check */
	outportb(PortAddress, inportb(PortAddress) & ~XD1);		
	if (inportb(PortAddress+1) & XERROR) return STATUS_UNSUCCESSFUL;

    /* Set SDA and Check Loopback */
	SetSDA(PortAddress);
	if (!GetSDA(PortAddress)) return STATUS_UNSUCCESSFUL;

	/* Clear SDA and Check Loopback */
	ClearSDA(PortAddress);
	if (GetSDA(PortAddress)) return STATUS_UNSUCCESSFUL;

	/* Set SCL and Check Loopback */
	SetSCL(PortAddress);
	if (!GetSCL(PortAddress)) return STATUS_UNSUCCESSFUL;

	/* Clear SCL and Check Loopback */
	ClearSCL(PortAddress);
	if (GetSCL(PortAddress)) return STATUS_UNSUCCESSFUL; 

	return STATUS_SUCCESS;
}

⌨️ 快捷键说明

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