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

📄 readwrite.cpp

📁 windows driver model开发的一个例子程序,适合初学者使用
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	// Reset signals to the S5933 itself don't need to be written back as zero. The
	// add-on function reset flag must, however, be cleared. Delay a short period of
	// time to allow the reset to occur, then write back a zero to the add-on reset bit

	LARGE_INTEGER timeout;
	timeout.QuadPart = -10 * 10000; // i.e., 10 milliseconds

	KeDelayExecutionThread(KernelMode, FALSE, &timeout);
	WRITE_PORT_ULONG((PULONG) (pdx->portbase + MCSR), 0);

	// 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->mappedport)
			{
			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 + -