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

📄 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 页
字号:
/*

ReadWrite.cpp

Sheldon Instruments, Inc.

Abstract:

	Read \ Write processors for WDM driver.  Handles calls to IRP_MJ_READ, IRP_MJ_WRITE,
	IRP_MJ_CREATE, IRP_MJ_CLOSE, and the interrupt handling for busmastered transfers.
	

Revision History:

    02Dec1998 - created by Robert Updike
	24Feb2000 - changed DoBusMasteredRead and DoBusMasteredWrite to not timeout if the value
				is zero.  Robert Updike
	20Mar2000 - added Sheldon_Cleanup.  Robert Updike
	2002-07-11: mik
		Better error checking on large counts.
	2002-07-22: mik
		DoBMRead/Write now correctly returning TRUE and FALSE.
		Commented out example WRITE_REGISTER_ULONG in ISR.

*/

#include "driver.h"
#include "../../common/siddkapi_win.h"

IO_ALLOCATION_ACTION SheldonReadAdapterControl(PDEVICE_OBJECT DeviceObject, \
											   PIRP Irp, \
											   PVOID MapRegisterBase, \
											   PVOID Context);
IO_ALLOCATION_ACTION SheldonWriteAdapterControl(PDEVICE_OBJECT DeviceObject, \
												PIRP Irp, \
												PVOID MapRegisterBase, \
												PVOID Context);
BOOLEAN DoBusMasteredRead(IN PDEVICE_EXTENSION pdx);
BOOLEAN DoBusMasteredWrite(IN PDEVICE_EXTENSION pdx);

/*

Function Name:

	Sheldon_Create

Routine Description:

	Handles create requests.

Arguments:

    fdo - pointer to a functional device object

Return Value:

    STATUS_SUCCESS

*/
NTSTATUS Sheldon_Create(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
	NTSTATUS ntStatus = STATUS_SUCCESS;

	KdPrint(("SIWDM - Entering Sheldon_Create: IRP_MJ_CREATE\n"));
	
	// Handling this IRP allows applications to open handles to the device.
	
	KdPrint(("SIWDM - Exiting Sheldon_Create (%x)\n", ntStatus));

	return CompleteRequest(Irp, ntStatus, 0);
}

/*

Function Name:

	Sheldon_Read

Routine Description:

	Handles read requests.

Arguments:

    fdo - pointer to a functional device object

	Irp - I/O request being serviced

Return Value:

    STATUS_SUCCESS

*/
NTSTATUS Sheldon_Read(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
	NTSTATUS ntStatus = STATUS_SUCCESS;

	KdPrint(("SIWDM - Entering Sheldon_Read: IRP_MJ_READ\n"));

	// This function would normally handle IRP_MJ_READ requests.

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

	return CompleteRequest(Irp, ntStatus, 0);
}

/*

Function Name:

	Sheldon_Write

Routine Description:

	Handles write requests.

Arguments:

    fdo - pointer to a functional device object

	Irp - I/O request being serviced

Return Value:

    STATUS_SUCCESS

*/
NTSTATUS Sheldon_Write(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
	NTSTATUS ntStatus = STATUS_SUCCESS;

	KdPrint(("SIWDM - Entering Sheldon_Write: IRP_MJ_WRITE\n"));

	// This function would normally handle IRP_MJ_WRITE requests.

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

	return CompleteRequest(Irp, ntStatus, 0);
}

/*

Function Name:

	Sheldon_Cleanup

Routine Description:

	Handles cleanup requests.

Arguments:

    fdo - pointer to a functional device object

	Irp - I/O request being serviced

Return Value:

    STATUS_SUCCESS

*/
NTSTATUS Sheldon_Cleanup(PDEVICE_OBJECT fdo, PIRP Irp)
{
	NTSTATUS ntStatus = STATUS_SUCCESS;
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

	KdPrint(("SIWDM - Entering Sheldon_Cleanup: IRP_MJ_CLEANUP\n"));
	
	CleanupRequests(&pdx->dqReadWrite, stack->FileObject, STATUS_CANCELLED);

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

	return CompleteRequest(Irp, ntStatus, 0);
}

/*

Function Name:

	Sheldon_Close

Routine Description:

	Handles close requests.

Arguments:

    fdo - pointer to a functional device object

	Irp - I/O request being serviced

Return Value:

    STATUS_SUCCESS

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

	KdPrint(("SIWDM - Entering Sheldon_Close: IRP_MJ_CLOSE\n"));
	
	// Handling this IRP allows applications to close handles to the device.
	ntStatus = SheldonUnMapDirect(pdx);

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

	return CompleteRequest(Irp, ntStatus, 0);
}

/*

Function Name:

	Sheldon_StartIo

Routine Description:

	Handles Irps sent by the I/O Manager.

Arguments:

    fdo - pointer to a functional device object

	Irp - I/O request being serviced

Return Value:

*/
VOID Sheldon_StartIo(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
	KIRQL oldirql;
	ULONG ControlCode;
	PIO_STACK_LOCATION IrpStack;
	NTSTATUS ntStatus;
	PMDL Mdl;

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

	if(!LockDevice(fdo))
	{
		CompleteRequest(Irp, STATUS_DELETE_PENDING, 0);
		return;
	}

	Mdl = Irp->MdlAddress;
	IrpStack = IoGetCurrentIrpStackLocation(Irp);

	ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;

	switch(ControlCode)
	{
		case IOCTL_SHELDON_BUSMASTERED_READ:
			KdPrint(("SIWDM - Sheldon_StartIo: SHELDON_BUSMASTERED_READ\n"));
						  
			pdx->ReadTransfer.pIrp = Irp;

			ntStatus = pdx->ReadTransfer.Adapter->DmaOperations->AllocateAdapterChannel
				(pdx->ReadTransfer.Adapter, fdo, pdx->ReadTransfer.NumberOfMapRegisters, 
				 SheldonReadAdapterControl, pdx);

			break;
		
		case IOCTL_SHELDON_BUSMASTERED_WRITE:
			KdPrint(("SIWDM - Sheldon_StartIo: SHELDON_BUSMASTERED_WRITE\n"));

			pdx->WriteTransfer.pIrp = Irp;

			ntStatus = pdx->WriteTransfer.Adapter->DmaOperations->AllocateAdapterChannel
				(pdx->WriteTransfer.Adapter, fdo, pdx->WriteTransfer.NumberOfMapRegisters,
				 SheldonWriteAdapterControl, pdx);

			break;
		
		default:
			KdPrint(("SIWDM - Sheldon_StartIo: DEFAULT\n"));
			ntStatus = STATUS_NOT_SUPPORTED;		
			break;
	}

	// something went wrong, either the code isn't supported or there was an error
	// in either case, retire this IRP

	if(!NT_SUCCESS(ntStatus))
	{
		StartNextPacket(&pdx->dqReadWrite, fdo);
		UnlockDevice(fdo);
		CompleteRequest(Irp, ntStatus, 0);
	}

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

/*

Function Name:

	OnCancel

Routine Description:

	Handles cancellation of active IRPs.

Arguments:

    fdo - pointer to a functional device object

	IRP - I/O request being serviced

Return Value:

*/
VOID OnCancel(PDEVICE_OBJECT fdo, PIRP Irp)
{
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
	CancelRequest(&pdx->dqReadWrite, Irp);
}

/*

Function Name:

	SheldonReadAdapterControl

Routine Description:

	Setup the Adapter Control for Busmastered Reads.

Arguments:

    DeviceObject - pointer to a device object

	Irp - I/O request being serviced

	MapRegisterBase - list of physical addresses and lengths of pages

	Context - pointer to a device extension

Return Value:

	STATUS_SUCCESS if adapter object has been allocated
	STATUS_INSUFFICIENT_RESOURCES if NumberOfMapRegisters larger than
		value returned by IoGetDmaAdapter

*/
IO_ALLOCATION_ACTION SheldonReadAdapterControl(PDEVICE_OBJECT DeviceObject, \
											   PIRP junk, \
											   PVOID MapRegisterBase, \
											   PVOID Context)
{
	KdPrint(("SIWDM - Entering SheldonReadAdapterControl\n"));

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) Context;
	PIRP Irp = GetCurrentIrp(&pdx->dqReadWrite);
	PMDL Mdl = Irp->MdlAddress;
	PULONG OP = pdx->base[AMCC_OPREGS];

	pdx->ReadTransfer.BytesRequested = MmGetMdlByteCount(Mdl);
	pdx->ReadTransfer.BytesRemaining = pdx->ReadTransfer.BytesRequested;
	pdx->ReadTransfer.LogicalAddress = (UCHAR *) MmGetMdlVirtualAddress(Mdl);
	pdx->ReadTransfer.MapRegisterBase = MapRegisterBase;
	pdx->ReadTransfer.Mdl = Mdl;

	// We now have the physical address and size of the first chunk to send
	// Let's now set up the PCI hardware so that when we load MWTC and MWAR 
	// a transfer will occur

/////////////////
// IO and memory mapped
/////////////////
	if( (ULONG)pdx->base[AMCC_OPREGS] & 0xffff0000 ) {
		// Disable Add-on to PCI FIFO Bus Mastering MCSR bit 10 set 0
		OP[AMCC_MCSR] = OP[AMCC_MCSR] & ~0x00000400;
		// Disable Ints from Transfer Count = 0  INTCSR bits 14 15 both zeroed
		OP[AMCC_INTCSR] = OP[AMCC_INTCSR] & ~AMCC_BUSMASTERED_READ_INT_ENABLE_MASK;
		// Clear FIFO MCSR bit 26 written with one
		// Will clear fifo before every transfer if executed(implementation dependent)
		// OP[AMCC_MCSR] = OP[AMCC_MCSR] | 0x04000000;
		// Define FIFO Management Scheme as go-on-half-way (4 words) MCSR bit 9 written as 1
		OP[AMCC_MCSR] = OP[AMCC_MCSR] | 0x00000200;
		// Define Read-Write Priority as equal (see ERRATA for AMCC chip) 
		// MCSR bit 8 one and 12 written as one
		OP[AMCC_MCSR] = (OP[AMCC_MCSR] & ~0x00001000) | 0x00000100;
		// Write zero into the MRTC
		OP[AMCC_MRTC] = 0x0000;
		
		// Set the transfer flag before allowing ints
		pdx->ReadTransfer.TransferInProgress = TRUE;

		// Ok, let's do the first call to the code which loads the registers and (re)starts 
		// the transfer.  Later calls will be made by the DPC after each interrupt, until 
		// the transfer is complete.

		DoBusMasteredRead(pdx);

		// Now re-enable the interrupts and set TIProgress

		// Enable Ints from Transfer Count = 0  INTCSR bits 14 15 both zeroed
		OP[AMCC_INTCSR] = OP[AMCC_INTCSR] | AMCC_BUSMASTERED_READ_INT_ENABLE_MASK;
		// Enable Add-on to PCI FIFO Bus Mastering MCSR bit 10 set 1
		OP[AMCC_MCSR] = OP[AMCC_MCSR] | 0x00000400;
	}
	else {
		// Disable Add-on to PCI FIFO Bus Mastering MCSR bit 10 set 0
		WRITE_PORT_ULONG(OP + AMCC_MCSR, READ_PORT_ULONG(OP + AMCC_MCSR) & ~0x00000400);
		// Disable Ints from Transfer Count = 0  INTCSR bits 14 15 both zeroed
		WRITE_PORT_ULONG(OP + AMCC_INTCSR, READ_PORT_ULONG(OP + AMCC_INTCSR) & ~AMCC_BUSMASTERED_READ_INT_ENABLE_MASK);
		// Clear FIFO MCSR bit 26 written with one
		// Will clear fifo before every transfer if executed(implementation dependent)
		// OP[AMCC_MCSR] = OP[AMCC_MCSR] | 0x04000000;
		// Define FIFO Management Scheme as go-on-half-way (4 words) MCSR bit 9 written as 1
		WRITE_PORT_ULONG(OP + AMCC_MCSR, READ_PORT_ULONG(OP + AMCC_MCSR) | 0x00000200);
		// Define Read-Write Priority as equal (see ERRATA for AMCC chip) 
		// MCSR bit 8 one and 12 written as one
		WRITE_PORT_ULONG(OP + AMCC_MCSR, (READ_PORT_ULONG(OP + AMCC_MCSR) & ~0x00001000) | 0x00000100);
		// Write zero into the MRTC
		WRITE_PORT_ULONG(OP + AMCC_MRTC, 0x0000);
		
		// Set the transfer flag before allowing ints
		pdx->ReadTransfer.TransferInProgress = TRUE;

		// Ok, let's do the first call to the code which loads the registers and (re)starts 
		// the transfer.  Later calls will be made by the DPC after each interrupt, until 
		// the transfer is complete.

		DoBusMasteredRead(pdx);

		// Now re-enable the interrupts and set TIProgress

		// Enable Ints from Transfer Count = 0  INTCSR bits 14 15 both zeroed
		WRITE_PORT_ULONG(OP + AMCC_INTCSR, READ_PORT_ULONG(OP + AMCC_INTCSR) | AMCC_BUSMASTERED_READ_INT_ENABLE_MASK);
		// Enable Add-on to PCI FIFO Bus Mastering MCSR bit 10 set 1
		WRITE_PORT_ULONG(OP + AMCC_MCSR, READ_PORT_ULONG(OP + AMCC_MCSR) | 0x00000400);
	}

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

	return DeallocateObjectKeepRegisters;
}

/*

Function Name:

	SheldonWriteAdapterControl

Routine Description:

	Setup the Adapter Control for Busmastered Writes.

Arguments:

    DeviceObject - pointer to a device object

	Irp - I/O request being serviced

	MapRegisterBase - list of physical addresses and lengths of pages

	Context - pointer to a device extension

Return Value:

	STATUS_SUCCESS if adapter object has been allocated
	STATUS_INSUFFICIENT_RESOURCES if NumberOfMapRegisters larger than
		value returned by IoGetDmaAdapter

*/
IO_ALLOCATION_ACTION SheldonWriteAdapterControl(PDEVICE_OBJECT DeviceObject, \

⌨️ 快捷键说明

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