PCIe设备漫游记----寄存器读写篇
上篇中,我们设备打开函数已经得到了我们PCIe设备的句柄了。接下来我们来看看,设备打开之后,上层软件是怎样利用该句柄实现对设备上具体寄存器的访问的。
1:寄存器写操作
上层应用程序写操作函数代码:
NTSTATUS TSTDPciReadBaseUlong( PDEMOPCI_DEVICE_EXT pDevExt, PIRP pIrp ) {NTSTATUSstatus = STATUS_SUCCESS;PIO_STACK_LOCATIONpIrpStack;PORT_ACCESS*pBuffer;ULONGulInBufferSize, ulOutBufferSize;pIrpStack = IoGetCurrentIrpStackLocation(pIrp);ulInBufferSize= pIrpStack->Parameters.DeviceIoControl.InputBufferLength;ulOutBufferSize= pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;pBuffer= (PORT_ACCESS *)pIrp->AssociatedIrp.SystemBuffer;bar = pBuffer->bar;if(bar < 6){pBuffer->u.ldata=0;if( pDevExt->base[bar].WhichMapped == TYPE_MEM ){DebugPrint("TYPE_MEM\n");if( ( (pBuffer->offs) + sizeof(ULONG) ) > ( pDevExt->base[bar].MemorySize ) ){status=STATUS_INVALID_PARAMETER;}else{DebugPrint("base[%d].MemoryMappedAddress+(pBuffer->offs): %x\n",bar,((PUCHAR)pDevExt->base[bar].MemoryMappedAddress+(pBuffer->offs)));DebugPrint("pBuffer->u.ldata: %x\n",pBuffer->u.ldata);DebugPrint("pDevExt->base[bar].MemorySize = %lx\n", pDevExt->base[bar].MemorySize);pBuffer->u.ldata = READ_REGISTER_ULONG( (PULONG)((PUCHAR)pDevExt->base[bar].MemoryMappedAddress+(pBuffer->offs)) );}}else if( pDevExt->base[bar].WhichMapped == TYPE_IO ){DebugPrint("TYPE_IO\n");if( ( (pBuffer->offs) + sizeof(ULONG) ) > ( pDevExt->base[bar].IoPortSize ) ){status=STATUS_INVALID_PARAMETER;}else{DebugPrint("base[%d].IoPortMappedAddress+(pBuffer->offs): %x\n",bar, ((PUCHAR)pDevExt->base[bar].IoPortMappedAddress+(pBuffer->offs)));DebugPrint("pBuffer->u.ldata: %x\n",pBuffer->u.ldata);pBuffer->u.ldata = READ_PORT_ULONG( (PULONG)((PUCHAR)pDevExt->base[bar].IoPortMappedAddress+(pBuffer->offs)) );}}else{status=STATUS_UNSUCCESSFUL;}}else{status=STATUS_INVALID_PARAMETER;}if(status == STATUS_SUCCESS)pIrp->IoStatus.Information = sizeof(PORT_ACCESS);elsepIrp->IoStatus.Information = 0;return (status);}