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

📄 pcidp.c

📁 一个amccs5933芯片的驱动程序开发源程序和部分文档
💻 C
📖 第 1 页 / 共 2 页
字号:
		break;

	case IOCTL_PCIDP00_GET_PCI_CONFIG_REGS:
		PCIDPGetPCIRegs(
			IN DeviceObject,
			IN IrpStack->FileObject,
			IN OUT Irp,
			OUT IoBuffer,
			IN OutputBufferLength
		);
		break;

	case IOCTL_PCIDP00_SET_PCI_CONFIG_REGS:
		PCIDPSetPCIRegs(
			IN DeviceObject,
			IN IrpStack->FileObject,
			IN OUT Irp,
			IN IoBuffer,
			IN InputBufferLength
		);
		break;

	case IOCTL_PCIDP00_REGISTER_INTERRUPT:
		PCIDPRegisterInterrupt(
			IN DeviceObject,
			IN OUT Irp,
			IN IoBuffer,
			IN InputBufferLength,
			IN OutputBufferLength
		);
		break;

	case IOCTL_PCIDP00_UNREGISTER_INTERRUPT:
		PCIDPUnregisterInterrupt(
			IN DeviceObject,
			IN OUT Irp,
			IN IoBuffer,
			IN InputBufferLength
		);
		break;

	case IOCTL_PCIDP00_HELLO:
		break;

	case IOCTL_PCIDP00_GET_VERSION:
		PCIDPGetDriverVersion(
			IN OUT Irp,
			OUT IoBuffer,
			IN OutputBufferLength
		);
		break;

	default:
		Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
		break;
	}

	// Finish the I/O operation by simply completing the packet and returning
	// the same status as in the packet itself.  However, don't complete the I/O
	// if the status is pending (register interrupt only).
	NTStatus = Irp->IoStatus.Status;
	if(NTStatus != STATUS_PENDING)
		IoCompleteRequest(Irp, IO_NO_INCREMENT);

	// Debug exit point
	if(NTStatus != STATUS_PENDING)
		//DbgPrint("[PCIDP]->Leaving DeviceControl, status=0x%x...\n", NTStatus);	//debug
		//DbgBreakPoint();	//debug

	return NTStatus;
}



// ----------------------------------------------------------------------------
// PCIDPCreateClose.  Called by the I/O system when the device is opened or
// closed. No action is currently performed other than completing the request
// successfully.
// ----------------------------------------------------------------------------
NTSTATUS PCIDPCreateClose(
	IN PDEVICE_OBJECT DeviceObject,
	IN PIRP Irp
){

	// Debug entry point
	//DbgPrint("[PCIDP]->Entering CreateClose...\n");	//debug
	//DbgBreakPoint();	//debug

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;

	IoCompleteRequest( Irp, IO_NO_INCREMENT );

	return STATUS_SUCCESS;
}



// ----------------------------------------------------------------------------
// PCIDPCleanup. Called by the system when a file object handle representing
// the device is being released.  Cancel any pending interrupts assigned to 
// the file handle.
// ----------------------------------------------------------------------------
NTSTATUS PCIDPCleanup(
	IN PDEVICE_OBJECT DeviceObject, 
	IN PIRP Irp
){

	// Define variables.
	PPCIDP_EXTENSION ObjExt;
	PREGISTERED_INTERRUPT Interrupt;
	PIO_STACK_LOCATION CleanUpStack ;
	PIO_STACK_LOCATION IrpStack ;
	KIRQL CancelSpin;
	PLINKED_LIST CurrentLink;
	PLINKED_LIST FirstLink;

	// Debug entry point
	//DbgPrint("[PCIDP]->Entering Cleanup...\n");	//debug
	//DbgBreakPoint();	//debug

	// Initialize variables.
	ObjExt = (PPCIDP_EXTENSION)DeviceObject->DeviceExtension;

	// Search the driver's events linked list for an entry containing the 
	// user provided Irp.
	CleanUpStack = IoGetCurrentIrpStackLocation(Irp);
	CurrentLink = NULL;
	FirstLink = NULL;
	while(GetNextEntry(ObjExt, &FirstLink, &CurrentLink, &Interrupt) == TRUE){
		IrpStack = IoGetCurrentIrpStackLocation(Interrupt->Irp);

		// Cancel the IRP, then delete its linked list entry.
		if (IrpStack->FileObject == CleanUpStack->FileObject) {
			IoAcquireCancelSpinLock (&CancelSpin);
			Interrupt->Irp->Cancel = TRUE;
			//Interrupt->Irp->CancelIrql = CancelSpin;
			Interrupt->Irp->CancelRoutine = NULL;
			Interrupt->Irp->IoStatus.Status = STATUS_CANCELLED;
			Interrupt->Irp->IoStatus.Information = 0;
			IoReleaseCancelSpinLock (CancelSpin);
			IoReleaseCancelSpinLock (Interrupt->Irp->CancelIrql);

			IoCompleteRequest(Interrupt->Irp, IO_NO_INCREMENT);
			FreeEntry(ObjExt, CurrentLink);
		}
		else
			PutBackEntry(ObjExt, CurrentLink);
	}

	Irp->IoStatus.Information = 0;
	Irp->IoStatus.Status = STATUS_SUCCESS;
	IoCompleteRequest (Irp, IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}



// ----------------------------------------------------------------------------
// PCIDPUnload.  Called by the I/O system when unloading the driver.  No action
// is currently performed.
// ----------------------------------------------------------------------------
NTSTATUS PCIDPUnload(
  IN PDRIVER_OBJECT DriverObject
){

	// Debug entry point
	//DbgPrint("[PCIDP]->Entering Unload...\n");	//debug
	//DbgBreakPoint();	//debug

	return STATUS_SUCCESS;
}



// ----------------------------------------------------------------------------
// PCIDPCancelInterrupt.  Called when an IRP for an interrupt must be canceled
// normally due to a system shutdown.
// ----------------------------------------------------------------------------
VOID PCIDPCancelInterrupt( 
	IN PDEVICE_OBJECT DeviceObject,
	IN OUT PIRP Irp
){
	// Define variables.
	PPCIDP_EXTENSION ObjExt;
	PREGISTERED_INTERRUPT Interrupt;
	PLINKED_LIST CurrentLink;
	PLINKED_LIST FirstLink;

	// Debug entry point
	//DbgPrint("[PCIDP]->Entering CancelInterrupt...\n");	//debug
	//DbgBreakPoint();	//debug

	// Initialize variables.
	ObjExt = (PPCIDP_EXTENSION)DeviceObject->DeviceExtension;

	// Search the driver's events linked list for an entry containing the 
	// user provided Irp.
	CurrentLink = NULL;
	FirstLink = NULL;
	while(GetNextEntry(ObjExt, &FirstLink, &CurrentLink, &Interrupt) == TRUE){

		// Delete its linked list entry.
		if(Irp == Interrupt->Irp){
			FreeEntry(ObjExt, CurrentLink);
			break;
		}
		else
			PutBackEntry(ObjExt, CurrentLink);
	}

	//IoReleaseCancelSpinLock (Irp->CancelIrql);
	Irp->IoStatus.Information = 0;
	Irp->IoStatus.Status = STATUS_CANCELLED;
	IoCompleteRequest(Irp, IO_NO_INCREMENT) ;
}



// ----------------------------------------------------------------------------
// PCIDPForDpcIsr.  Deferred procedure call for the interrupt service routine.
// ----------------------------------------------------------------------------
VOID PCIDPForDpcIsr(
	IN PKDPC Dpc,
	IN PDEVICE_OBJECT DeviceObject,
	IN PIRP Irp,
	IN PVOID Context
){
	// Define variables.
	PPCIDP_EXTENSION ObjExt;
	PINTERRUPT_DATA IntData;
	PREGISTERED_INTERRUPT RegisteredInt;
	KIRQL CancelSpin;
	PLINKED_LIST CurrentLink;
	PLINKED_LIST FirstLink;

	// Debug
	//PULONG MemoryBase;

	// Initialize variables.
	ObjExt = (PPCIDP_EXTENSION)DeviceObject->DeviceExtension;
	IntData = &ObjExt->InterruptData;


	// Debug
	//MemoryBase = ObjExt->MemoryBase;
	//MemoryBase[0x1C53]++;

	//Service all of the recorded interrupts by checking to see if the interrupt 
	//type has been registered by the user.
	while(IntData->QueNew != IntData->QueNext){

		// Debug
		//MemoryBase[0x1C54]++;

		CurrentLink = NULL;
		FirstLink = NULL;
		while(GetNextEntry(ObjExt, &FirstLink, &CurrentLink, &RegisteredInt) == TRUE){

			// Debug
			//MemoryBase[0x1C55]++;

			if(IntData->Type[IntData->QueNew] == RegisteredInt->Type){

				// Debug
				//MemoryBase[0x1C56]++;

				// Found an entry.  Disable the cancel routine, complete the I/O for
				// this IRP, then delete the linked	list entry.
				IoAcquireCancelSpinLock (&CancelSpin);
				IoSetCancelRoutine(RegisteredInt->Irp, NULL);
				IoReleaseCancelSpinLock (CancelSpin);
				RegisteredInt->Irp->IoStatus.Status = STATUS_SUCCESS ;
				RegisteredInt->Irp->IoStatus.Information = 0 ;
				IoCompleteRequest(RegisteredInt->Irp, IO_NO_INCREMENT);

				FreeEntry(ObjExt, CurrentLink);
			}
			else
				PutBackEntry(ObjExt, CurrentLink);
		}

		IntData->QueNew++;
		if(IntData->QueNew == InterruptQueSize) IntData->QueNew = 0;
	}
}



// ----------------------------------------------------------------------------
// PCIDPISR.  Interrupt service routine.
// ----------------------------------------------------------------------------
BOOLEAN PCIDPISR(
  IN PKINTERRUPT Interrupt,
  IN OUT PVOID Context
){
	// Define variables.
	BOOLEAN Status;
	PDEVICE_OBJECT DeviceObject;
	PPCIDP_EXTENSION ObjExt;
	PINTERRUPT_DATA IntData;
	PULONG MemoryBase;
	ULONG HINTStatusReg;

	// Check the masked HINT for an active interrupt.  If it's not set, 
	// the PCIDP card did not cause the interrupt, so exit quick.
  DeviceObject = (PDEVICE_OBJECT)Context;
	ObjExt = (PPCIDP_EXTENSION)DeviceObject->DeviceExtension;
	MemoryBase = ObjExt->MemoryBase;

	// Debug
	//MemoryBase[0x1C50]++;

	HINTStatusReg = MemoryBase[HINT] & 0x03FF;
	if(HINTStatusReg == 0){

		// Debug
		//MemoryBase[0x1C51]++;

		Status = FALSE;
		goto ExitA;
	}

	// Initialize variables.
	DeviceObject = (PDEVICE_OBJECT)Context;
	IntData = &ObjExt->InterruptData;

	// This board caused the interrupt. Now determine what type of interrupt
	// was triggered.
	if(HINTStatusReg & PCIMasterAbort){
		IntData->Type[IntData->QueNext] = PCIMasterAbort;
		IntData->QueNext++;
		if(IntData->QueNext == InterruptQueSize) IntData->QueNext = 0;
	}

	if(HINTStatusReg & PCITargetAbort){
		IntData->Type[IntData->QueNext] = PCITargetAbort;
		IntData->QueNext++;
		if(IntData->QueNext == InterruptQueSize) IntData->QueNext = 0;
	}

	if(HINTStatusReg & I2OOutboundPostFIFONotEmpty){
		IntData->Type[IntData->QueNext] = I2OOutboundPostFIFONotEmpty;
		IntData->QueNext++;
		if(IntData->QueNext == InterruptQueSize) IntData->QueNext = 0;
	}

	if(HINTStatusReg & DMAComplete){
		IntData->Type[IntData->QueNext] = DMAComplete;
		IntData->QueNext++;
		if(IntData->QueNext == InterruptQueSize) IntData->QueNext = 0;

		// Debug
		//MemoryBase[0x1C52]++;

	}

	if(HINTStatusReg & LocalToHostExternalSignal){
		IntData->Type[IntData->QueNext] = LocalToHostExternalSignal;
		IntData->QueNext++;
		if(IntData->QueNext == InterruptQueSize) IntData->QueNext = 0;
	}

	if(HINTStatusReg & LocalToHostMailbox){
		IntData->Type[IntData->QueNext] = LocalToHostMailbox;
		IntData->QueNext++;
		if(IntData->QueNext == InterruptQueSize) IntData->QueNext = 0;
	}

	if(HINTStatusReg & I2OPCIFIFOOverflow){
		IntData->Type[IntData->QueNext] = I2OPCIFIFOOverflow;
		IntData->QueNext++;
		if(IntData->QueNext == InterruptQueSize) IntData->QueNext = 0;
	}

	// Clear all set interrupts as indicated in the status part of the
	// HINT register while preserving the enabled part of the HINT.  This
	// is done by writing a 1 to each active bit which just happens to
	// be value in HINTStatusReg.
	MemoryBase[HINT] |= HINTStatusReg;

	// Lastly, request the defered interrupt handler be queued for processing.
	IoRequestDpc(DeviceObject, NULL, NULL);
	Status = TRUE;

	ExitA:
	return Status;
}



// ----------------------------------------------------------------------------
// PCIDPCancelMapDMARoutine.  Called when an application that has mapped to DMA
// space fails to unmap from that space. 
// ----------------------------------------------------------------------------
VOID PCIDPCancelMapDMARoutine( 
	IN PDEVICE_OBJECT DeviceObject,
	IN OUT PIRP Irp
){
	// Define variables.
	PPCIDP_EXTENSION ObjExt;
	PREGISTERED_INTERRUPT Interrupt;
	PLINKED_LIST CurrentLink;
	PLINKED_LIST FirstLink;

	// Debug entry point
	//DbgPrint("[PCIDP]->Entering CancelMapDMARoutine...\n");	//debug
	//DbgBreakPoint();	//debug

	// Initialize variables.
	ObjExt = (PPCIDP_EXTENSION)DeviceObject->DeviceExtension;

	//ObjExt->MemoryBase[0x1C5B]++;	//debug

	// Search the driver's events linked list for an entry containing the 
	// user provided Irp.
	CurrentLink = NULL;
	FirstLink = NULL;
	while(GetNextEntry(ObjExt, &FirstLink, &CurrentLink, &Interrupt) == TRUE){

		//ObjExt->MemoryBase[0x1C5C]++;	//debug

		// Delete its linked list entry and unmap from DMA space.
		if(Irp == Interrupt->Irp){
			FreeEntry(ObjExt, CurrentLink);
			if(ObjExt->MDL){
				MmUnmapLockedPages((PVOID)Interrupt->Type, ObjExt->MDL);	//linear address in Type
			}

			//ObjExt->MemoryBase[0x1C5D]++;	//debug

			break;
		}
		else
			PutBackEntry(ObjExt, CurrentLink);
	}

	IoReleaseCancelSpinLock (Irp->CancelIrql);
	Irp->IoStatus.Information = 0;
	Irp->IoStatus.Status = STATUS_CANCELLED;
	IoCompleteRequest(Irp, IO_NO_INCREMENT) ;
}


⌨️ 快捷键说明

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