wwm_820924
驱动牛犊
驱动牛犊
  • 注册日期2004-07-04
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望169点
  • 贡献值1点
  • 好评度22点
  • 原创分0分
  • 专家分0分
阅读:2022回复:6

读写PCI config reg 问题

楼主#
更多 发布于:2005-04-01 11:20
各位好,我刚接触 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就死机?

wwm_820924
驱动牛犊
驱动牛犊
  • 注册日期2004-07-04
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望169点
  • 贡献值1点
  • 好评度22点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-04-01 11:25
补充一点,我用的系统是win2000sp4+vc6.0+win2kddk.
谢谢!
cch7701
驱动牛犊
驱动牛犊
  • 注册日期2002-08-25
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分60分
  • 威望8点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-04-02 16:37
读写PCI的配置寄存器,要自己创建一个IRP,再发到下层的总线驱动程序,由它完成。
wwm_820924
驱动牛犊
驱动牛犊
  • 注册日期2004-07-04
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望169点
  • 贡献值1点
  • 好评度22点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-04-02 22:28
读写PCI的配置寄存器,要自己创建一个IRP,再发到下层的总线驱动程序,由它完成。


谢谢楼上的!
micosoft网站也是这么说的,我上面哪个程序大概也是这个思路吧(呵呵,我自己理解的),\"创建一个IRP,再发到下层的总线驱动程序\".楼上的能说详细一点吗?最好是能给个例程,谢谢!
cch7701
驱动牛犊
驱动牛犊
  • 注册日期2002-08-25
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分60分
  • 威望8点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-04-04 20:37
过两天给你整一个出来
cch7701
驱动牛犊
驱动牛犊
  • 注册日期2002-08-25
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分60分
  • 威望8点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
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;
}
wwm_820924
驱动牛犊
驱动牛犊
  • 注册日期2004-07-04
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望169点
  • 贡献值1点
  • 好评度22点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2005-04-06 12:27
非常感谢cch7701,按照你的程序问题搞定。我是初学者,刚开始做PCI驱动,这个问题困惑了我好长时间。
我的分不多,送上20分。再次感谢!
游客

返回顶部