zephy
驱动牛犊
驱动牛犊
  • 注册日期2003-10-11
  • 最后登录2005-05-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1758回复:11

Win2000下如何取得板卡的插槽??

楼主#
更多 发布于:2004-04-08 01:00
  我想在WDM中得到机箱中各个板卡的插槽、总线、功能等资源,DS有KPciSlot类提供这种函数,类定义如下:

class KPciSlot
{

// Construction
public:
SAFE_DESTRUCTORS
#if ! _WDM_
KPciSlot(ULONG bus, ULONG device, ULONG function);
KPciSlot(KPciSlot* pSlot=NULL);
VOID Initialize(void);
VOID Invalidate(void){ MarkInvalid(); }
BOOLEAN IsValid(void);
#else // ! _WDM_
KPciSlot(PDEVICE_OBJECT TopOfStackDevice) { Initialize(TopOfStackDevice); }
VOID Initialize(PDEVICE_OBJECT TopOfStackDevice);
VOID Invalidate(void){ m_TopOfStackDevice = NULL; }
BOOLEAN IsValid(void){ return (m_TopOfStackDevice != NULL); }
#endif // ! _WDM_

// Methods
public:
#if ! _WDM_
ULONG Slot(void);
ULONG Bus(void);
ULONG Device(void);
ULONG Function(void);
VOID Increment(void);
VOID IncrementDevice(void);
VOID IncrementBus(void);
VOID MarkInvalid(void);
#endif // ! _WDM_

// Data
protected:
#if ! _WDM_
ULONG m_bus;
PCI_SLOT_NUMBER m_slot;
#else // ! _WDM_
PDEVICE_OBJECT m_TopOfStackDevice;
#endif // ! _WDM_
};

我声明KPciSlot变量,初始化后没法使用其成员函数,如上类定义,难道成员函数 Slot(void), Bus(void),Device(void),Function(void)只能用于非WDM的驱动程序??如果是这样,那么在Win2000下的WDM中怎样得到板卡的Slot, Bus,Device,Function??

最新喜欢:

zhgangzhgang
lansing
驱动牛犊
驱动牛犊
  • 注册日期2003-04-23
  • 最后登录2005-09-01
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望3点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-04-08 09:06
可以在softIce中输入命令pci将显示所有的设备信息,如果不是pci总线不要用!
答的好请给分,谢谢!
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
板凳#
发布于:2004-04-08 12:26
DriverWorks不太清楚,没有用过,不过用DDK的话可以使用:

IoGetDeviceProperty()

其中DeviceProperty参数设成DevicePropertyAddress。
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
zephy
驱动牛犊
驱动牛犊
  • 注册日期2003-10-11
  • 最后登录2005-05-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-04-08 16:15
谢谢两位朋友!!
softice的命令我回头试试。但是我的目的是在应用程序中显示即箱中的多块pci板卡信息,所以需要在应用程序中的这些资源。
DDK不懂,太难。现在只想在DS中实现这个功能。windriver很方便,有现成的函数。DS也有这样的类,可是我没用起来,是不是这个类用的不对?还有没有别的办法?

zephy
驱动牛犊
驱动牛犊
  • 注册日期2003-10-11
  • 最后登录2005-05-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-04-09 00:07
知道的朋友指点一下呀!!
要不这分送不出去呀!!
dragon_hn
驱动中牛
驱动中牛
  • 注册日期2002-05-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分297分
  • 威望40点
  • 贡献值0点
  • 好评度32点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-04-13 10:58
知道的朋友指点一下呀!!
要不这分送不出去呀!!

怎么会送不出去,上面那么多朋友等着呢!
www.dragon-2008.com 欢迎交流
zephy
驱动牛犊
驱动牛犊
  • 注册日期2003-10-11
  • 最后登录2005-05-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-04-14 00:04
总不能进来一个就送一个吧!!

先得解决问题呀!!
cana_liu
驱动牛犊
驱动牛犊
  • 注册日期2003-01-24
  • 最后登录2004-05-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-04-14 15:50
HOWTO: Get Configuration and Location Information of PCI Device

SUMMARY
This article describes how you can get the configuration and location information (such as BusNumber, DeviceNumber, and Function Number) of a Peripheral Component Interconnect (PCI) device in a driver that is part of the target device\'s driver stack either as a function or filter driver.
MORE INFORMATION
On Windows NT 4.0, drivers get this information by scanning the bus and calling the HalGetBusData and HalGetBusDataByOffset APIs. On Windows 2000, the hardware buses are controlled by their respective bus drivers and not by HAL. Therefore, all of the Hal APIs that used to provide bus-related information are obsolete in Windows 2000.

On Windows 2000, a driver does not need to query the device to find resources. The driver gets the resources from the Plug and Play (PnP) manager in its IRP_MN_START_DEVICE request. Typically, a well-written driver would not require any of this information to function correctly. If for some reason the driver requires this information, the code sample to follow shows how to get the resources. The driver should be part of the device\'s driver stack because it requires the underlying physical device objects (PDO) of the device to send the PnP request.

The following code sample demonstrates how to get the configuration information: 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;

}


Because you can only send the PnP I/O Request Packets (IRPs) at PASSIVE_LEVEL, you cannot use the above function to get the configuration information at DISPATCH_LEVEL.

You can perform the following steps to access the configuration space at DISPATCH_LEVEL:
Send an IRP_MN_QUERY_INTERFACE at PASSIVE_LEVEL to get the direct-call interface structure (BUS_INTERFACE_STANDARD) from the PCI bus driver. Store this in a nonpaged pool memory (typically in DevcieExtension).
Call the SetBusData and GetBusData to access the configuration space at DISPATCH_LEVEL.
The PCI bus driver takes a reference count on the interface before it returns, so you must dereference the interface when it is no longer needed.
Use the following function to get the BUS_INTERFACE_STANDARD at PASSIVE_LEVEL: NTSTATUS
GetPCIBusInterfaceStandard(
    IN  PDEVICE_OBJECT DeviceObject,
    OUT PBUS_INTERFACE_STANDARD BusInterfaceStandard
    )
/*++

Routine Description:

    This routine gets the bus interface standard information from the PDO.

Arguments:

    DeviceObject - Device object to query for this information.

    BusInterface - Supplies a pointer to the retrieved information.

Return Value:

    NT status.

--*/
{
    KEVENT event;
    NTSTATUS status;
    PIRP irp;
    IO_STATUS_BLOCK ioStatusBlock;
    PIO_STACK_LOCATION irpStack;
    PDEVICE_OBJECT targetObject;

    Bus_KdPrint((\"GetPciBusInterfaceStandard entered.\\n\"));

    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 );
    irpStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
    irpStack->Parameters.QueryInterface.InterfaceType =
                        (LPGUID) &GUID_BUS_INTERFACE_STANDARD ;
    irpStack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
    irpStack->Parameters.QueryInterface.Version = 1;
    irpStack->Parameters.QueryInterface.Interface = (PINTERFACE)
BusInterfaceStandard;
    irpStack->Parameters.QueryInterface.InterfaceSpecificData = NULL;

    //
    // 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;

}


The following code shows how you can use the interface direct-call function to get the bus data.     bytes = busInterfaceStandard.GetBusData(<BR/>
                    busInterfaceStandard.Context,
                    PCI_WHICHSPACE_CONFIG,
                    Buffer
                    Offset,
                    Length);


When you no longer need the interface, use the following code to dereference the interface with the code to follow. Do not call any interface routines after you dereference the interface.     (busInterfaceStandard.InterfaceDereference)(
                (PVOID)busInterfaceStandard.Context);


Use the IoGetDeviceProperty function on the PDO of the target device to get the Bus, Function, and Device numbers as follows:     ULONG   propertyAddress, length;
    USHORT  FunctionNumber; DeviceNumber;
    
    //
    // Get the BusNumber. Please read the warning to follow.
    //

    IoGetDeviceProperty(PhysicalDeviceObject,
                        DevicePropertyBusNumber,
                        sizeof(ULONG),
                        (PVOID)&BusNumber,
                        &length);

    //
    // Get the DevicePropertyAddress
    //
    IoGetDeviceProperty(PhysicalDeviceObject,
                     DevicePropertyAddress,
                     sizeof(ULONG),
                     (PVOID)&propertyAddress,
                     &length);
    //
    // For PCI, the DevicePropertyAddress has device number
    // in the high word and the function number in the low word.
    //
    FunctionNumber = (USHORT)((propertyAddress) & 0x0000FFFF);
    DeviceNumber = (USHORT)(((propertyAddress) >> 16) & 0x0000FFFF);



这是microsoft提供的代码,总该能够解决你的问题吧,哈哈,给我分吧,
zephy
驱动牛犊
驱动牛犊
  • 注册日期2003-10-11
  • 最后登录2005-05-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-04-15 23:33
谢谢这位朋友,能从茫茫E文中翻出这些东西,回头试一下。

结帖的时候少不了你的!!
cana_liu
驱动牛犊
驱动牛犊
  • 注册日期2003-01-24
  • 最后登录2004-05-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-04-16 16:20
和和,我试过了,一个工控机上插了8块卡,都可以识别了,分到是次要的,叫个朋友嘛,和和,
cana_2003@hotmail.com,
msn or email都可以。和和
zhgang
驱动牛犊
驱动牛犊
  • 注册日期2002-12-19
  • 最后登录2004-04-19
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-04-17 15:44
用SDK的API库函数也能识别,函数名:PlxPciDeviceFind(pDevice,
&DeviceNum)

#define FIND_AMOUNT_MATCHED              80001
DeviceNum = FIND_AMOUNT_MATCHED
时,函数返回时DeviceNum为插槽上的板卡数,再
    for (i=0; i<DeviceNum; i++)
    {
        pDevice->BusNumber  = (U32)-1;
        pDevice->SlotNumber = (U32)-1;
        pDevice->VendorId   = (U32)-1;
        pDevice->DeviceId   = (U32)-1;
        pDevice->SerialNumber = \"\";

        PlxPciDeviceFind(
            pDevice,
            &i
            );
    }
可以逐个获得各板卡的信息。
zephy
驱动牛犊
驱动牛犊
  • 注册日期2003-10-11
  • 最后登录2005-05-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-04-30 17:00
最近忙着画板子,没顾的上网看看,谢谢各位朋友!!

过两天开始调试软件,希望能解决这个问题!

五一快乐!
游客

返回顶部