阅读:1324回复:3
如何在驱动程序中读取或者配置PCI配置空间
是不是需要调用PciReadConfig
但这个函数需要的两个参数busNumber, 和deviceNumber 如何获得? 谢谢 |
|
沙发#
发布于:2003-08-02 03:06
here is the function you can just copy to your project:
///////////////////////////////////////////////////////// NTSTATUS ReadWriteConfigSpace( IN PDEVICE_OBJECT DeviceObject, //target device object IN ULONG ReadOrWrite, // 0 for read 1 for write IN PVOID Buffer, // caller allocated buffer to hold data IN ULONG Offset, // offset from 0 IN ULONG Length // how many bytes to R/W ) { 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 == READ_PCI_SPACE) { 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. // ULONG ulData; memcpy(&ulData,Buffer,sizeof(ulData)); //KdPrint((\"IRP:Buffer=0x%x, Offset=0x%x, Length=0x%x\\n\",ulData,Offset,Length)); 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; } ///////////////////////////////////////////////////////// |
|
板凳#
发布于:2003-08-04 10:21
是不是需要调用PciReadConfig 可以用直接端口操作的。 我是用查询Vender ID和Device ID的方式找到自己设备的busNumber和deviceNumber的。具体做法如下(以DOS下为例,如果在WDM中只要改相应的函数即可): for(i=0; i<5; i++) { for(j=0; j<32; j++) { bus = i; device = j; iobase = 0x80000000 + bus * 0x10000+ (device * 8 ) * 0x100; ioa0 = iobase + 0; _outpd(0xcf8, ioa0); iod = _inpd(0xcfc); if (iod != 0xffffffff) { printf(\"\\nBus# = %x\\n\", bus); printf(\"Device # = %x\\n\", device); printf(\"ID# = %lx\\n\", iod); for (io=0; io<=5; io++) { ioa0 = iobase + 0x10 + io*4; _outpd(0xcf8, ioa0); iod = _inpd(0xcfc); printf(\"Base%d = 0x%lx\\n\", io, iod); } ioa0 = iobase + 0x3c; _outpd(0xcf8, ioa0); iod = _inpd(0xcfc); printf(\"IRQ# = 0x%x\\n\", iod & 0xff); getch(); } } } 你不必每次打这么多东西出来,只要比较vendor Id 和Device ID是你的卡就记下Bus Number和Device Number就可以了。 |
|
|
地板#
发布于:2003-08-04 10:50
hong同志
是不是还要在程序中添加处理IRP_MN_READ_CONFIG和IRP_MN_WRITE_CONFIG的代码? 万分感谢 |
|