pengpengwei
驱动牛犊
驱动牛犊
  • 注册日期2003-07-30
  • 最后登录2003-12-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1324回复:3

如何在驱动程序中读取或者配置PCI配置空间

楼主#
更多 发布于:2003-07-30 14:46
是不是需要调用PciReadConfig
但这个函数需要的两个参数busNumber, 和deviceNumber 如何获得?

谢谢
hong
驱动小牛
驱动小牛
  • 注册日期2001-09-19
  • 最后登录2005-12-16
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于: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;
}

/////////////////////////////////////////////////////////
grant
驱动老牛
驱动老牛
  • 注册日期2001-05-14
  • 最后登录2007-04-13
  • 粉丝0
  • 关注0
  • 积分350分
  • 威望35点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-08-04 10:21
是不是需要调用PciReadConfig
但这个函数需要的两个参数busNumber, 和deviceNumber 如何获得?
谢谢

可以用直接端口操作的。
我是用查询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就可以了。
助人乃快乐之本 有人给分就更快乐了 :-)
pengpengwei
驱动牛犊
驱动牛犊
  • 注册日期2003-07-30
  • 最后登录2003-12-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-08-04 10:50
hong同志
是不是还要在程序中添加处理IRP_MN_READ_CONFIG和IRP_MN_WRITE_CONFIG的代码?
万分感谢
游客

返回顶部