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

📄 plugplay.cpp

📁 The PCI Local bus concept was developed to break the PC data I/O bottleneck and clearly opens the d
💻 CPP
📖 第 1 页 / 共 2 页
字号:

Return Value:

    STATUS_SUCCESS if successful
	NTSTATUS code otherwise

*/
NTSTATUS CancelStopDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
	NTSTATUS ntStatus;

	Irp->IoStatus.Status = STATUS_SUCCESS;

	if(pdx->state == PENDINGSTOP)
	{

		// Wait for lower level drivers.
		ntStatus = ForwardAndWait(pdx, Irp);

		if(NT_SUCCESS(ntStatus))
		{
			pdx->state = WORKING;

			if(&pdx->dqReadWrite)
				RestartRequests(&pdx->dqReadWrite, pdx->DeviceObject);
		}
		
		return CompleteRequest(Irp, ntStatus, 0);
	}

	IoSkipCurrentIrpStackLocation(Irp);
	return IoCallDriver(pdx->LowerDeviceObject, Irp);
}

/*

Function name:

	StopDevice

Routine Description:

    Stops the device - IRP_MN_STOP_DEVICE.

Arguments:

    pdx - pointer to device extension

    Irp -  I/O request being serviced

Return Value:

    STATUS_SUCCESS if successful
	NTSTATUS code otherwise

*/
NTSTATUS StopDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
	Irp->IoStatus.Status = STATUS_SUCCESS;

	if(pdx->state != PENDINGSTOP)
	{
		if(&pdx->dqReadWrite)
			AbortRequests(&pdx->dqReadWrite, STATUS_DELETE_PENDING);
	}

	ReleaseResources(pdx);
	pdx->state = STOPPED;

	IoSkipCurrentIrpStackLocation(Irp);
	return IoCallDriver(pdx->LowerDeviceObject, Irp);
}

/*

Function name:

	QueryRemoveDevice

Routine Description:

    Determines if the device can handle a IRP_MN_REMOVE_DEVICE request.

Arguments:

    pdx - pointer to the device extension

    Irp -  I/O request being serviced

Return Value:

    STATUS_SUCCESS if successful
	NTSTATUS code otherwise

*/
NTSTATUS QueryRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
	Irp->IoStatus.Status = STATUS_SUCCESS;

	if(pdx->state == WORKING)
	{
		if((!IoIsWdmVersionAvailable(1, 0x10)) && pdx->DeviceObject->ReferenceCount)
		{
			KdPrint(("SIWDM - QueryRemoveDevice: Failing due to open handles\n"));
			return CompleteRequest(Irp, STATUS_DEVICE_BUSY, 0);
		}

		if(&pdx->dqReadWrite)
		{
			StallRequests(&pdx->dqReadWrite);
			WaitForCurrentIrp(&pdx->dqReadWrite);
		}
	}

	pdx->oldstate = pdx->state;
	pdx->state = PENDINGREMOVE;

	IoSkipCurrentIrpStackLocation(Irp);
	return IoCallDriver(pdx->LowerDeviceObject, Irp);
}

/*

Function name:

	CancelRemoveDevice

Routine Description:

    Cancels the previous query to remove the device - IRP_MN_CANCEL_REMOVE_DEVICE.

Arguments:

    pdx - pointer to the device extension

    Irp -  I/O request being serviced

Return Value:

    STATUS_SUCCESS if successful
	NTSTATUS code otherwise

*/
NTSTATUS CancelRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
	NTSTATUS ntStatus;

	Irp->IoStatus.Status = STATUS_SUCCESS;

	if(pdx->state == PENDINGREMOVE)
	{
		ntStatus = ForwardAndWait(pdx, Irp);

		if(NT_SUCCESS(ntStatus))
		{
			if((pdx->state = pdx->oldstate) == WORKING)
			{
				if(&pdx->dqReadWrite)
					RestartRequests(&pdx->dqReadWrite, pdx->DeviceObject);
			}
		}

		return CompleteRequest(Irp, ntStatus, 0);
	}
	
	IoSkipCurrentIrpStackLocation(Irp);
	return IoCallDriver(pdx->LowerDeviceObject, Irp);
}

/*

Function name:

	RemoveDevice

Routine Description:

    Removes the device - IRP_MN_REMOVE_DEVICE request.

Arguments:

    fdo - pointer to the device object

    Irp -  I/O request being serviced

Return Value:

    STATUS_SUCCESS if successful
	NTSTATUS code otherwise

*/
NTSTATUS RemoveDevice(PDEVICE_OBJECT fdo, PIRP Irp)
{
	NTSTATUS ntStatus;
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	Irp->IoStatus.Status = STATUS_SUCCESS;

	if(&pdx->dqReadWrite)
		AbortRequests(&pdx->dqReadWrite, STATUS_DELETE_PENDING);

	ReleaseResources(pdx);

	pdx->state = REMOVED;

	IoSkipCurrentIrpStackLocation(Irp);
	ntStatus = IoCallDriver(pdx->LowerDeviceObject, Irp);

	if(pdx)
		UnlockDeviceAndWait(pdx);

	if(pdx->LowerDeviceObject)
		IoDetachDevice(pdx->LowerDeviceObject);

	IoDeleteDevice(fdo);

	return ntStatus;
}

/*

Function name:

	SupriseRemovalDevice

Routine Description:

    Removes the device in cases of a suprise removal- IRP_MN_SUPRISE_REMOVAL request.

Arguments:

    pdx - pointer to the device extension

    Irp -  I/O request being serviced

Return Value:

    STATUS_SUCCESS if successful
	NTSTATUS code otherwise

*/
NTSTATUS SurpriseRemovalDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
	Irp->IoStatus.Status = STATUS_SUCCESS;

	if(&pdx->dqReadWrite)
		AbortRequests(&pdx->dqReadWrite, STATUS_DELETE_PENDING);

	pdx->state = SURPRISEREMOVED;

	ReleaseResources(pdx);

	IoSkipCurrentIrpStackLocation(Irp);
	return IoCallDriver(pdx->LowerDeviceObject, Irp);
}

/*

Function name:

	ReleaseResources

Routine Description:

    Releases the resources and resets the hardware.

Arguments:

    pdx - pointer to the device extension

Return Value:

*/
VOID ReleaseResources(IN PDEVICE_EXTENSION pdx)
{
	ULONG i;

	if(pdx->InterruptObject)
	{
		ResetDevice(pdx);
		IoDisconnectInterrupt(pdx->InterruptObject);
		pdx->InterruptObject = NULL;
	}

	SheldonUnMapDirect(pdx);

	for(i=0;i<PCI_TYPE0_ADDRESSES;i++)
		if(pdx->mem_mapped[i])
		{
			MmUnmapIoSpace(pdx->base[i], pdx->base_len[i]);
			pdx->mem_mapped[i] = NULL;
		}
}

/*

Function name:

	ResetDevice

Routine Description:

    Resets the hardware.

Arguments:

    pdx - pointer to the device extension

Return Value:

*/
VOID ResetDevice(PDEVICE_EXTENSION pdx)
{
	LARGE_INTEGER timeout;

	// Reset the board
/////////////////
// IO and memory mapped
/////////////////
	if( (ULONG)pdx->base[AMCC_OPREGS] & 0xffff0000 ) {
		WRITE_REGISTER_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_MCSR), AMCC_MCSR_RESET);

		// Delay to allow the add-on to reset
		timeout.QuadPart = -10 * 10000;
		KeDelayExecutionThread(KernelMode, FALSE, &timeout);

		// Clear the reset for the benefit of the add-on
		WRITE_REGISTER_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_MCSR), 0);

		// Clear any interrupts
		WRITE_REGISTER_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_INTCSR), AMCC_INTCSR_INTERRUPT_MASK);
	}
	else {
		WRITE_PORT_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_MCSR), AMCC_MCSR_RESET);

		// Delay to allow the add-on to reset
		timeout.QuadPart = -10 * 10000;
		KeDelayExecutionThread(KernelMode, FALSE, &timeout);

		// Clear the reset for the benefit of the add-on
		WRITE_PORT_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_MCSR), 0);

		// Clear any interrupts
		WRITE_PORT_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_INTCSR), AMCC_INTCSR_INTERRUPT_MASK);
	}

/////////////////
// Memory mapped Only
/////////////////
//	WRITE_REGISTER_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_MCSR), AMCC_MCSR_RESET);
//
//	// Delay to allow the add-on to reset
//	timeout.QuadPart = -10 * 10000;
//	KeDelayExecutionThread(KernelMode, FALSE, &timeout);
//
//	// Clear the reset for the benefit of the add-on
//	WRITE_REGISTER_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_MCSR), 0);
//
//	// Clear any interrupts
//	WRITE_REGISTER_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_INTCSR), AMCC_INTCSR_INTERRUPT_MASK);

}

/*

Function name:

	DisableDevice

Routine Description:

    Prevents the device from generating interrupts.

Arguments:

    pdx - pointer to the device extension

Return Value:

    TRUE

*/
BOOLEAN DisableDevice(IN PDEVICE_EXTENSION pdx)
{
	KdPrint(("SIWDM - DisableDevice\n"));
	
/////////////////
// IO and memory mapped
/////////////////
	if( (ULONG)pdx->base[AMCC_OPREGS] & 0xffff0000 )
		WRITE_REGISTER_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_INTCSR), AMCC_INTCSR_INTERRUPT_MASK);
	else
		WRITE_PORT_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_INTCSR), AMCC_INTCSR_INTERRUPT_MASK);

/////////////////
// Memory mapped Only
/////////////////
//	WRITE_REGISTER_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_INTCSR), AMCC_INTCSR_INTERRUPT_MASK);
	pdx->enabled = FALSE;
	return TRUE;
}

/*

Function name:

	EnableDevice

Routine Description:

    Allows the device to generate interrupts.

Arguments:

    pdx - pointer to the device extension

Return Value:

    TRUE

*/
BOOLEAN EnableDevice(IN PDEVICE_EXTENSION pdx)
{
	KdPrint(("SIWDM - EnableDevice\n"));
	
	// Add code here to allow device to generate interrupts
	
	pdx->enabled = TRUE;
	return TRUE;
}

⌨️ 快捷键说明

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