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

📄 readwrite.cpp

📁 The PCI Local bus concept was developed to break the PC data I/O bottleneck and clearly opens the d
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				pdx->WriteTransfer.NumberOfMapRegisters);

			// Close out this IRP
			Irp = pdx->WriteTransfer.pIrp;
			Irp->IoStatus.Information=
				pdx->WriteTransfer.BytesRequested - pdx->WriteTransfer.BytesRemaining
				+ pdx->WriteTransfer.CurrentTransferSize
				- READ_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MRTC);

			Irp->IoStatus.Status = STATUS_IO_TIMEOUT;
		
			// This one's done. Begin working on the next
			StartNextPacket(&pdx->dqReadWrite, pdx->DeviceObject);
			UnlockDevice(pdx);
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
		}
		else {
			mcsr = READ_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR);
			// shut off go signal for writes
			mcsr &= ~AMCC_BUSMASTERED_WRITE_ENABLE_MASK;
			WRITE_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR, mcsr);

			// shut off the hardware ints
			intCSR = READ_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR);
			// clear the "write 1 clear" bits to avoid problems
			intCSR &= AMCC_PRESERVE_INTCSR_MASK;
			// shut off ints for writes
			intCSR &= ~AMCC_BUSMASTERED_WRITE_INT_ENABLE_MASK;
			// clear the write int bit
			intCSR |= AMCC_BUSMASTERED_WRITE_INT_OCCURRED_MASK;
			WRITE_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR, intCSR);

			// set the internal state to inactive
			pdx->WriteTransfer.TransferInProgress = FALSE;

			// Conclude the previous "DMA" Transfer
			pdx->WriteTransfer.Adapter->DmaOperations->FlushAdapterBuffers(
				pdx->WriteTransfer.Adapter,
				pdx->WriteTransfer.Mdl,
				pdx->WriteTransfer.MapRegisterBase,
				pdx->WriteTransfer.LogicalAddress,
				pdx->WriteTransfer.CurrentTransferSize,
				TRUE);

			pdx->WriteTransfer.Adapter->DmaOperations->FreeMapRegisters(
				pdx->WriteTransfer.Adapter,
				pdx->WriteTransfer.MapRegisterBase,
				pdx->WriteTransfer.NumberOfMapRegisters);

			// Close out this IRP
			Irp = pdx->WriteTransfer.pIrp;
			Irp->IoStatus.Information=
				pdx->WriteTransfer.BytesRequested - pdx->WriteTransfer.BytesRemaining
				+ pdx->WriteTransfer.CurrentTransferSize
				- READ_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MRTC);

			Irp->IoStatus.Status = STATUS_IO_TIMEOUT;
		
			// This one's done. Begin working on the next
			StartNextPacket(&pdx->dqReadWrite, pdx->DeviceObject);
			UnlockDevice(pdx);
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
		}
		
	}

	KdPrint(("SIWDM - Exiting SheldonTimerRoutine\n"));
}

/*

Function Name:

	SheldonIsr

Routine Description:

	This function processes interrupts from the PCI Device.

Arguments:

	Interrupt -	pointer to the Interrupt object

	ServiceContext - pointer to the Device Extension 

Return Value:

	TRUE if we handled the interrupt
	FALSE if not our interrupt

*/
BOOLEAN SheldonIsr(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext)
{
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) ServiceContext;
	ULONG intCSR;
	static int count = 0;

	KdPrint(("SIWDM - Entering SheldonIsr\n"));

/////////////////
// IO and memory mapped
/////////////////
	if( (ULONG)pdx->base[AMCC_OPREGS] & 0xffff0000 ) {

		// get the int register to determine IRQ cause
		intCSR = READ_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR);

		// BUSMASTERED READ
		if(pdx->ReadTransfer.TransferInProgress && (intCSR & AMCC_BUSMASTERED_READ_INT_OCCURRED_MASK))
		{
			pdx->int_cause = intCSR;
			// clear the interrupt occurance bit

			// clear the "write 1 clear" bits to avoid problems
			intCSR &= AMCC_PRESERVE_INTCSR_MASK;
			// clear the reads int bit
			intCSR |= AMCC_BUSMASTERED_READ_INT_OCCURRED_MASK;
			WRITE_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR, intCSR);
		
			// request the DPC
			IoRequestDpc(pdx->DeviceObject, pdx->ReadTransfer.pIrp, (PVOID) pdx);

			KdPrint(("SIWDM - Exiting SheldonIsr: BusMastered Read\n"));
			return TRUE;
		}

		// BUSMASTERED WRITE	
		if(pdx->WriteTransfer.TransferInProgress && (intCSR & AMCC_BUSMASTERED_WRITE_INT_OCCURRED_MASK))
		{
			pdx->int_cause = intCSR;
			// clear the int occurance bit

			// clear the "write 1 clear" bits to avoid problems
			intCSR &= AMCC_PRESERVE_INTCSR_MASK;
			// clear the write int bit
			intCSR |= AMCC_BUSMASTERED_WRITE_INT_OCCURRED_MASK;
			WRITE_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR, intCSR);

			// do the real work in the DPC
			IoRequestDpc(pdx->DeviceObject, pdx->WriteTransfer.pIrp, (PVOID) pdx);

			KdPrint(("SIWDM - Exiting SheldonIsr: BusMastered Write\n"));
			return TRUE;
		}

		// INT Callback Event
		if(intCSR & AMCC_NON_BUSMASTERED_INT_ENABLE_MASK)
		{
			pdx->int_cause = intCSR;

			//	dummy read mailbox to clear interrupt on 5920
			//	For real application, this should be replaced with the action
			//		that shuts off the interrupt. For example, if the hardware
			//		deasserts INTA (add on interrupt) by polling the mailbox, 
			//		the mailbox action should be taken here so that INTA is
			//		deasserted. If INTA is not deasserted here, unpredictable 
			//		result will occur, such as continuous interrupt or lockup.
			//WRITE_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_IMB4, intCSR);
				
			// clear the "write 1 clear" bits to avoid problems
			intCSR &= AMCC_PRESERVE_INTCSR_MASK;
			intCSR |= AMCC_NON_BUSMASTERED_INT_ENABLE_MASK;
			WRITE_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR, intCSR);

			// do the real work in the DPC
			IoRequestDpc(pdx->DeviceObject, pdx->WriteTransfer.pIrp, (PVOID) pdx);

			KdPrint(("SIWDM - Exiting SheldonIsr: Callback Event\n"));
			return TRUE;
		}
	}
	else {
		// get the int register to determine IRQ cause
		intCSR = READ_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR);

		// BUSMASTERED READ
		if(pdx->ReadTransfer.TransferInProgress && (intCSR & AMCC_BUSMASTERED_READ_INT_OCCURRED_MASK))
		{
			pdx->int_cause = intCSR;
			// clear the interrupt occurance bit

			// clear the "write 1 clear" bits to avoid problems
			intCSR &= AMCC_PRESERVE_INTCSR_MASK;
			// clear the reads int bit
			intCSR |= AMCC_BUSMASTERED_READ_INT_OCCURRED_MASK;
			WRITE_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR, intCSR);
		
			// request the DPC
			IoRequestDpc(pdx->DeviceObject, pdx->ReadTransfer.pIrp, (PVOID) pdx);

			KdPrint(("SIWDM - Exiting SheldonIsr: BusMastered Read\n"));
			return TRUE;
		}

		// BUSMASTERED WRITE	
		if(pdx->WriteTransfer.TransferInProgress && (intCSR & AMCC_BUSMASTERED_WRITE_INT_OCCURRED_MASK))
		{
			pdx->int_cause = intCSR;
			// clear the int occurance bit

			// clear the "write 1 clear" bits to avoid problems
			intCSR &= AMCC_PRESERVE_INTCSR_MASK;
			// clear the write int bit
			intCSR |= AMCC_BUSMASTERED_WRITE_INT_OCCURRED_MASK;
			WRITE_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR, intCSR);

			// do the real work in the DPC
			IoRequestDpc(pdx->DeviceObject, pdx->WriteTransfer.pIrp, (PVOID) pdx);

			KdPrint(("SIWDM - Exiting SheldonIsr: BusMastered Write\n"));
			return TRUE;
		}

		// INT Callback Event
		if(intCSR & AMCC_NON_BUSMASTERED_INT_ENABLE_MASK)
		{
			pdx->int_cause = intCSR;

			//	dummy read mailbox to clear interrupt on 5920
			//	For real application, this should be replaced with the action
			//		that shuts off the interrupt. For example, if the hardware
			//		deasserts INTA (add on interrupt) by polling the mailbox, 
			//		the mailbox action should be taken here so that INTA is
			//		deasserted. If INTA is not deasserted here, unpredictable 
			//		result will occur, such as continuous interrupt or lockup.
			//WRITE_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_IMB4, intCSR);
				
			// clear the "write 1 clear" bits to avoid problems
			intCSR &= AMCC_PRESERVE_INTCSR_MASK;
			intCSR |= AMCC_NON_BUSMASTERED_INT_ENABLE_MASK;
			WRITE_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR, intCSR);

			// do the real work in the DPC
			IoRequestDpc(pdx->DeviceObject, pdx->WriteTransfer.pIrp, (PVOID) pdx);

			KdPrint(("SIWDM - Exiting SheldonIsr: Callback Event\n"));
			return TRUE;
		}
	}

	KdPrint(("SIWDM - Exiting SheldonIsr\n"));

	return FALSE;
}

/*

Function Name:

	SheldonDpcForIsr

Routine Description:

	This function processes delayed procedure calls for interrupts.

Arguments:

	Dpc -	pointer to the dpc object

	pDeviceObj - pointer to the Device Object

	Irp - I/O request being serviced

	Context - pointer to the device extension

Return Value:

*/
VOID SheldonDpcForIsr(IN PKDPC Dpc, IN PDEVICE_OBJECT pDeviceObj, \
					  IN PIRP Irp, IN PVOID Context)
{
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) Context;
	ULONG cause;
	NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
	BOOLEAN done = FALSE;
	ULONG mcsr;
	static int count = 0;

	KdPrint(("SIWDM - Entering SheldonDpcForIsr\n"));

	// get the int register to determine IRQ cause
	cause = pdx->int_cause;

	// BUSMASTERED READ
	if
	(
			pdx->ReadTransfer.TransferInProgress 
		&&	(AMCC_BUSMASTERED_READ_INT_OCCURRED_MASK & cause)
	)
	{
		// Stop the TimeOut Timer
		KeCancelTimer(&pdx->ReadTransfer.Timer);
			
		// Conclude the previous "DMA" Transfer
		pdx->ReadTransfer.Adapter->DmaOperations->FlushAdapterBuffers
		(
			pdx->ReadTransfer.Adapter,
			pdx->ReadTransfer.Mdl,
			pdx->ReadTransfer.MapRegisterBase,
			pdx->ReadTransfer.LogicalAddress,
			pdx->ReadTransfer.CurrentTransferSize,
			FALSE
		);
		
		// Adjust the bytes remaining to reflect the block just transfered
		pdx->ReadTransfer.BytesRemaining -= 
			pdx->ReadTransfer.CurrentTransferSize;
												   
		// Tell the OS that more bytes have been transfered
		Irp->IoStatus.Information = 
				pdx->ReadTransfer.BytesRequested 
			-	pdx->ReadTransfer.BytesRemaining;

		// now that the last transfer is wrapped up, let's think about the next
		if(pdx->ReadTransfer.BytesRemaining > 0)
		{
			// advance the address pointer to its new location
			pdx->ReadTransfer.LogicalAddress += 
				pdx->ReadTransfer.CurrentTransferSize;

			KeSynchronizeExecution
			(
				pdx->InterruptObject,
				(PKSYNCHRONIZE_ROUTINE) DoBusMasteredRead, 
				pdx
			);

			done = FALSE;
			ntStatus = STATUS_PENDING;
		}
		else
		{
			// turn off the transfer
			pdx->ReadTransfer.TransferInProgress = FALSE;

			// disable busmastered reads
/////////////////
// IO and memory mapped
/////////////////
			if( (ULONG)pdx->base[AMCC_OPREGS] & 0xffff0000 ) {
				mcsr = READ_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR);
				// shut off go signal for reads
				mcsr &= ~AMCC_BUSMASTERED_READ_ENABLE_MASK;
				WRITE_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR, mcsr);
			}
			else {
				mcsr = READ_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR);
				// shut off go signal for reads
				mcsr &= ~AMCC_BUSMASTERED_READ_ENABLE_MASK;
				WRITE_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR, mcsr);
			}

			done = TRUE;
			ntStatus = STATUS_SUCCESS;

			pdx->ReadTransfer.Adapter->DmaOperations->FreeMapRegisters
			(
				pdx->ReadTransfer.Adapter,
				pdx->ReadTransfer.MapRegisterBase,
				pdx->ReadTransfer.NumberOfMapRegisters
			);
		}
	}

	// BUSMASTERED WRITE	
	if
	(
			pdx->WriteTransfer.TransferInProgress 
		&& (AMCC_BUSMASTERED_WRITE_INT_OCCURRED_MASK & cause)
	)
	{
		// Stop the TimeOut Timer
		KeCancelTimer(&pdx->WriteTransfer.Timer);

		// Conclude the previous "DMA" Transfer
		pdx->WriteTransfer.Adapter->DmaOperations->FlushAdapterBuffers
		(
			pdx->WriteTransfer.Adapter,
			pdx->WriteTransfer.Mdl,
			pdx->WriteTransfer.MapRegisterBase,
			pdx->WriteTransfer.LogicalAddress,
			pdx->WriteTransfer.CurrentTransferSize,
			TRUE
		);

		// Adjust the bytes remaining to reflect the block just transfered
		pdx->WriteTransfer.BytesRemaining -= 
			pdx->WriteTransfer.CurrentTransferSize;

		// Tell the OS that more bytes have been transfered
		Irp->IoStatus.Information = 
				pdx->WriteTransfer.BytesRequested 
			-	pdx->WriteTransfer.BytesRemaining;


		// now that the last transfer is wrapped up, let's think about the next
		if(pdx->WriteTransfer.BytesRemaining > 0)
		{
			// advance the address pointer to its new location
			pdx->WriteTransfer.LogicalAddress += 
				pdx->WriteTransfer.CurrentTransferSize;

			KeSynchronizeExecution
			(
				pdx->InterruptObject, 
				(PKSYNCHRONIZE_ROUTINE) DoBusMasteredWrite, 
				pdx
			);

			done = FALSE;
			ntStatus = STATUS_PENDING;

		}
		else
		{
			// stop the transfer
			pdx->WriteTransfer.TransferInProgress=FALSE;

/////////////////
// IO and memory mapped
/////////////////
			if( (ULONG)pdx->base[AMCC_OPREGS] & 0xffff0000 ) {
				mcsr = READ_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR);
				// shut off go signal for writes
				mcsr &= ~AMCC_BUSMASTERED_WRITE_ENABLE_MASK;
				WRITE_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR, mcsr);
			}
			else {
				mcsr = READ_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR);
				// shut off go signal for writes
				mcsr &= ~AMCC_BUSMASTERED_WRITE_ENABLE_MASK;
				WRITE_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR, mcsr);
			}

			done = TRUE;
			ntStatus = STATUS_SUCCESS;

			pdx->WriteTransfer.Adapter->DmaOperations->FreeMapRegisters
			(
				pdx->WriteTransfer.Adapter,
				pdx->WriteTransfer.MapRegisterBase,
				pdx->WriteTransfer.NumberOfMapRegisters
			);
		}
	}

	// Callback
	if(AMCC_NON_BUSMASTERED_INT_ENABLE_MASK & cause)
	{
		ntStatus = STATUS_SUCCESS;

		if(pdx->Callback_Event)			
			KeSetEvent((PKEVENT) pdx->Callback_Event, 0, FALSE);

		done = FALSE;
	}

	// Close out this IRP
	if(done)
	{
		Irp->IoStatus.Status = ntStatus;

		// This one's done. Begin working on the next
		StartNextPacket(&pdx->dqReadWrite, pDeviceObj);
		UnlockDevice(pdx);
		IoCompleteRequest(Irp, IO_DISK_INCREMENT);
	}

	KdPrint(("SIWDM - Exiting SheldonDpcForIsr (%x)\n", ntStatus));
}

⌨️ 快捷键说明

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