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

📄 readwrite.cpp

📁 Programming the Microsoft Windows Driver Model(2nd)
💻 CPP
📖 第 1 页 / 共 2 页
字号:


	// Clear any pending interrupts by writing 1's to any that are currently asserted



	ULONG intcsr = READ_PORT_ULONG((PULONG) (pdx->portbase + INTCSR));

	intcsr &= INTCSR_INTERRUPT_MASK;

	WRITE_PORT_ULONG((PULONG) (pdx->portbase + INTCSR), intcsr);

	}							// ResetDevice



///////////////////////////////////////////////////////////////////////////////



#pragma LOCKEDCODE



VOID SetupDevice(PDEVICE_EXTENSION pdx)

	{							// SetupDevice

	}							// SetupDevice



///////////////////////////////////////////////////////////////////////////////



#pragma PAGEDCODE



NTSTATUS StartDevice(PDEVICE_OBJECT fdo, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated)

	{							// StartDevice

	NTSTATUS status;

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;



	// Identify the I/O resources we're supposed to use.

	

	ULONG vector;

	KIRQL irql;

	KINTERRUPT_MODE mode;

	KAFFINITY affinity;

	BOOLEAN irqshare;

	BOOLEAN gotinterrupt = FALSE;



	PHYSICAL_ADDRESS portbase;

	BOOLEAN gotport = FALSE;

	

	if (!translated)

		return STATUS_DEVICE_CONFIGURATION_ERROR;		// no resources assigned??



	PCM_PARTIAL_RESOURCE_DESCRIPTOR resource = translated->PartialDescriptors;

	ULONG nres = translated->Count;

	for (ULONG i = 0; i < nres; ++i, ++resource)

		{						// for each resource

		switch (resource->Type)

			{					// switch on resource type



		case CmResourceTypePort:

			portbase = resource->u.Port.Start;

			pdx->nports = resource->u.Port.Length;

			pdx->mappedport = (resource->Flags & CM_RESOURCE_PORT_IO) == 0;

			gotport = TRUE;

			break;

	

		case CmResourceTypeInterrupt:

			irql = (KIRQL) resource->u.Interrupt.Level;

			vector = resource->u.Interrupt.Vector;

			affinity = resource->u.Interrupt.Affinity;

			mode = (resource->Flags == CM_RESOURCE_INTERRUPT_LATCHED)

				? Latched : LevelSensitive;

			irqshare = resource->ShareDisposition == CmResourceShareShared;

			gotinterrupt = TRUE;

			break;



		default:

			KdPrint((DRIVERNAME " - Unexpected I/O resource type %d\n", resource->Type));

			break;

			}					// switch on resource type

		}						// for each resource



	if (!(TRUE

		&& gotport

		&& gotinterrupt

		))

		{

		KdPrint((DRIVERNAME " - Didn't get expected I/O resources\n"));

		return STATUS_DEVICE_CONFIGURATION_ERROR;

		}

		

	// Determine bus type before proceeding, just so we don't have a bunch of cleanup

	// to do if this call fails



	INTERFACE_TYPE bustype;

	ULONG junk;

	status = IoGetDeviceProperty(pdx->Pdo, DevicePropertyLegacyBusType, sizeof(bustype),

		&bustype, &junk);

	if (!NT_SUCCESS(status))

		{

		KdPrint((DRIVERNAME " - IoGetDeviceProperty failed - %X\n", status));

		return status;

		}



	if (pdx->mappedport)

		{						// map port address for RISC platform

		pdx->portbase = (PUCHAR) MmMapIoSpace(portbase, pdx->nports, MmNonCached);

		if (!pdx->portbase)

			{

			KdPrint((DRIVERNAME " - Unable to map port range %I64X, length %X\n", portbase, pdx->nports));

			return STATUS_INSUFFICIENT_RESOURCES;

			}

		}						// map port address for RISC platform

	else

		pdx->portbase = (PUCHAR) portbase.QuadPart;



	// Configure a DMA adapter object



	DEVICE_DESCRIPTION dd;

	RtlZeroMemory(&dd, sizeof(dd));

	dd.Version = DEVICE_DESCRIPTION_VERSION;

	dd.InterfaceType = bustype;

	dd.MaximumLength = 0x1000;

	dd.Dma32BitAddresses = TRUE;

	dd.Master = TRUE;



	pdx->AdapterObject = IoGetDmaAdapter(pdx->Pdo, &dd, &pdx->nMapRegisters);

	if (!pdx->AdapterObject)

		{						// can't create adapter object

		KdPrint((DRIVERNAME " - Unable to create DMA adapter object\n"));

		if (pdx->portbase && pdx->mappedport)

			MmUnmapIoSpace(pdx->portbase, pdx->nports);

		pdx->portbase = NULL;

		return STATUS_UNSUCCESSFUL;

		}						// can't create adapter object



	ResetDevice(pdx);			// reset the device



	status = IoConnectInterrupt(&pdx->InterruptObject, (PKSERVICE_ROUTINE) OnInterrupt,

		(PVOID) pdx, NULL, vector, irql, irql, mode, irqshare, affinity, FALSE);

	if (!NT_SUCCESS(status))

		{

		KdPrint((DRIVERNAME " - IoConnectInterrupt failed - %X\n", status));

		if (pdx->portbase && pdx->mappedport)

			MmUnmapIoSpace(pdx->portbase, pdx->nports);

		pdx->portbase = NULL;

		if (pdx->AdapterObject)

			(*pdx->AdapterObject->DmaOperations->PutDmaAdapter)

				(pdx->AdapterObject);

		pdx->AdapterObject = NULL;

		return status;

		}



	// Initialize the device



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



	return STATUS_SUCCESS;

	}							// StartDevice



///////////////////////////////////////////////////////////////////////////////



#pragma LOCKEDCODE



VOID StartIo(IN PDEVICE_OBJECT fdo, IN PIRP Irp)

	{							// StartIo

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

	NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);

	if (!NT_SUCCESS(status))

		{

		CompleteRequest(Irp, status, 0);

		return;

		}

	

	PMDL mdl = Irp->MdlAddress;



	pdx->numxfer = 0;

	pdx->xfer = pdx->nbytes = MmGetMdlByteCount(mdl);

	pdx->vaddr = MmGetMdlVirtualAddress(mdl);



	ULONG nregs = ADDRESS_AND_SIZE_TO_SPAN_PAGES(pdx->vaddr, pdx->nbytes);

	if (nregs > pdx->nMapRegisters)

		{						// staged transfer needed

		nregs = pdx->nMapRegisters;

		pdx->xfer = nregs * PAGE_SIZE - MmGetMdlByteOffset(mdl);

		}						// staged transfer needed

	pdx->nMapRegistersAllocated = nregs; // save for deallocation later



	status = (*pdx->AdapterObject->DmaOperations->AllocateAdapterChannel)

		(pdx->AdapterObject, fdo, nregs, (PDRIVER_CONTROL) AdapterControl, pdx);

	if (!NT_SUCCESS(status))

		{

		KdPrint((DRIVERNAME " - AllocateAdapterChannel failed - %X\n", status));

		StartNextPacket(&pdx->dqReadWrite, fdo);

		CompleteRequest(Irp, status, 0);

		IoReleaseRemoveLock(&pdx->RemoveLock, Irp);

		}

	}							// StartIo



///////////////////////////////////////////////////////////////////////////////



#pragma LOCKEDCODE



VOID StartTransfer(PDEVICE_EXTENSION pdx, PHYSICAL_ADDRESS address, BOOLEAN isread)

	{							// StartTransfer

	ULONG mcsr = READ_PORT_ULONG((PULONG) (pdx->portbase + MCSR));

	ULONG intcsr = READ_PORT_ULONG((PULONG) (pdx->portbase + INTCSR));



	// Setup read or write transfer registers. Note that the S5933 calls a transfer

	// from memory to the device a "read"



	if (isread)

		{						// read from device

		mcsr |= MCSR_WRITE_NEED4 | MCSR_WRITE_ENABLE;

		intcsr |= INTCSR_WTCI_ENABLE;

		WRITE_PORT_ULONG((PULONG) (pdx->portbase + MWTC), pdx->xfer);

		WRITE_PORT_ULONG((PULONG) (pdx->portbase + MWAR), address.LowPart);

		}						// read from device

	

	else

		{						// write to device

		mcsr |= MCSR_READ_NEED4 | MCSR_READ_ENABLE;

		intcsr |= INTCSR_RTCI_ENABLE;

		WRITE_PORT_ULONG((PULONG) (pdx->portbase + MRTC), pdx->xfer);

		WRITE_PORT_ULONG((PULONG) (pdx->portbase + MRAR), address.LowPart);

		}						// write to device



	// Write modified INTCSR to enable the appropriate interrupt and MCSR to actually

	// start the transfer



	pdx->busy = TRUE;



	WRITE_PORT_ULONG((PULONG) (pdx->portbase + INTCSR), intcsr);

	WRITE_PORT_ULONG((PULONG) (pdx->portbase + MCSR), mcsr);

	}							// StartTransfer



///////////////////////////////////////////////////////////////////////////////



#pragma PAGEDCODE



VOID StopDevice(IN PDEVICE_OBJECT fdo, BOOLEAN oktouch /* = FALSE */)

	{							// StopDevice

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;



	if (pdx->InterruptObject)

		{						// disconnect interrupt

		if (oktouch)

			ResetDevice(pdx);

		IoDisconnectInterrupt(pdx->InterruptObject);

		pdx->InterruptObject = NULL;

		}						// disconnect interrupt



	if (pdx->portbase && pdx->mappedport)

		MmUnmapIoSpace(pdx->portbase, pdx->nports);

	pdx->portbase = NULL;



	if (pdx->AdapterObject)

		(*pdx->AdapterObject->DmaOperations->PutDmaAdapter)

			(pdx->AdapterObject);

	pdx->AdapterObject = NULL;

	}							// StopDevice

⌨️ 快捷键说明

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