阅读:2141回复:6
读写PCI config reg 问题
各位好,我刚接触 pci驱动,读写PCI CONFIG REG遇到问题,麻烦各位帮我看一下,谢谢!
代码如下:(网上下的) typedef struct _IOCTL_DATA { ULONG value1;//offset ULONG value2;//return value ULONG value3;//length }IOCTLDATA,*PIOCTLDATA; NTSTATUS ReadWriteConfigSpace( IN PDEVICE_OBJECT DeviceObject, IN ULONG ReadOrWrite, // 0 for read 1 for write IN PVOID Buffer, IN ULONG Offset, IN ULONG Length ) { KEVENT event; NTSTATUS status; PIRP irp; IO_STATUS_BLOCK ioStatusBlock; PIO_STACK_LOCATION irpStack; PDEVICE_OBJECT targetObject; PAGED_CODE(); KeInitializeEvent( &event, NotificationEvent, FALSE ); targetObject = IoGetAttachedDeviceReference( DeviceObject ); irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP, targetObject, NULL, 0, NULL, &event, &ioStatusBlock ); if (irp == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; goto End; } irpStack = IoGetNextIrpStackLocation( irp ); if (ReadOrWrite == 0) { irpStack->MinorFunction = IRP_MN_READ_CONFIG; }else { irpStack->MinorFunction = IRP_MN_WRITE_CONFIG; } irpStack->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG; irpStack->Parameters.ReadWriteConfig.Buffer = Buffer; irpStack->Parameters.ReadWriteConfig.Offset = Offset; irpStack->Parameters.ReadWriteConfig.Length = Length; // // Initialize the status to error in case the bus driver does not // set it correctly. // irp->IoStatus.Status = STATUS_NOT_SUPPORTED ; status = IoCallDriver( targetObject, irp ); if (status == STATUS_PENDING) { KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL ); status = ioStatusBlock.Status; } End: // // Done with reference // ObDereferenceObject( targetObject ); return status; } 调用如下: DeviceIoControl(PDEVICE_OBJECT fdo,PIRP pIrp) { ULONG value,offset; NTSTATUS status; PIOCTLDATA pIoBuffer; PDEVICE_EXTENSION pdx; PIO_STACK_LOCATION pStack; ULONG Length; PVOID Buffer=NULL; pdx = fdo->DeviceExtension; pStack = IoGetCurrentIrpStackLocation(pIrp); pIoBuffer = pIrp->AssociatedIrp.SystemBuffer; pIrp->IoStatus.Information = sizeof(IOCTLDATA); switch (pStack->Parameters.DeviceIoControl.IoControlCode) { case READ_PCI_REG: //在此读写取PCI配置寄存器,暂时先把读弄懂 offset = pIoBuffer->value1; Length = pIoBuffer->value3; status =ReadWriteConfigSpace(fdo, 0, Buffer,offset,Length); pIoBuffer->value2=(ULONG)Buffer; break; default: KdPrint((\"Unsupported IOCTL_Xxx (0x%08x)\\n\",pStack->Parameters.DeviceIoControl.IoControlCode)); } if (status == STATUS_PENDING) return STATUS_PENDING; pIrp->IoStatus.Status = status; IoCompleteRequest(pIrp,IO_NO_INCREMENT); return status; } } 问题: 只要一读取READ_PCI_REG就死机? |
|
沙发#
发布于:2005-04-01 11:25
补充一点,我用的系统是win2000sp4+vc6.0+win2kddk.
谢谢! |
|
板凳#
发布于:2005-04-02 16:37
读写PCI的配置寄存器,要自己创建一个IRP,再发到下层的总线驱动程序,由它完成。
|
|
地板#
发布于:2005-04-02 22:28
读写PCI的配置寄存器,要自己创建一个IRP,再发到下层的总线驱动程序,由它完成。 谢谢楼上的! micosoft网站也是这么说的,我上面哪个程序大概也是这个思路吧(呵呵,我自己理解的),\"创建一个IRP,再发到下层的总线驱动程序\".楼上的能说详细一点吗?最好是能给个例程,谢谢! |
|
地下室#
发布于:2005-04-04 20:37
过两天给你整一个出来
|
|
5楼#
发布于:2005-04-05 12:13
/******************************************************************************
* * Function : PciConfigRegisterRead * * Description: Read a config register * ******************************************************************************/ NTSTATUS PciConfigRegisterRead( PDEVICE_OBJECT fdo, U32 *pReadValue, U16 offset, U8 Length ) { PIRP pIrp; KEVENT event; NTSTATUS status; PIO_STACK_LOCATION stack; U8 ReadLen; /* Although it is not documented in the WDM DDK, it would appear that the correct way to access a PCI configuration register in Windows 98 is to send down a PnP packet to the bus driver. The bus driver, provided by Microsoft, will perform the actual PCI configuration access and return the value. */ pIrp = IoAllocateIrp( fdo->StackSize, FALSE ); if (pIrp == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } // Initialize kernel event KeInitializeEvent( &event, NotificationEvent, FALSE ); stack = IoGetNextIrpStackLocation( pIrp ); switch ( Length ) { case 1: ReadLen = sizeof(UCHAR); break; case 2: ReadLen = sizeof(USHORT); break; case 4: ReadLen = sizeof(ULONG); break; default: ReadLen = sizeof(ULONG); break; } // Fill the IRP pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED; stack->MajorFunction = IRP_MJ_PNP; stack->MinorFunction = IRP_MN_READ_CONFIG; stack->Parameters.ReadWriteConfig.WhichSpace = 0; stack->Parameters.ReadWriteConfig.Buffer = pReadValue; stack->Parameters.ReadWriteConfig.Offset = offset; stack->Parameters.ReadWriteConfig.Length = ReadLen; IoSetCompletionRoutine( pIrp, (PIO_COMPLETION_ROUTINE)OnRequestComplete, (PVOID)&event, TRUE, TRUE, TRUE ); // Send the packet status = IoCallDriver( fdo, pIrp ); if (status == STATUS_PENDING) { // Wait for completion KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL ); status = pIrp->IoStatus.Status; } // Release the IRP IoFreeIrp( pIrp ); return status; } /****************************************************************************** * * Function : OnRequestComplete * * Description: Set an event when a lower driver complete an IRP. * ******************************************************************************/ NTSTATUS OnRequestComplete( PDEVICE_OBJECT fdo, PIRP pIrp, PKEVENT pKEvent ) { KeSetEvent( pKEvent, 0, FALSE ); return STATUS_MORE_PROCESSING_REQUIRED; } |
|
6楼#
发布于:2005-04-06 12:27
非常感谢cch7701,按照你的程序问题搞定。我是初学者,刚开始做PCI驱动,这个问题困惑了我好长时间。
我的分不多,送上20分。再次感谢! |
|