liubing3052
驱动牛犊
驱动牛犊
  • 注册日期2007-08-28
  • 最后登录2008-03-25
  • 粉丝0
  • 关注0
  • 积分100分
  • 威望11点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
阅读:2598回复:6

关于硬件资源列表的问题,请各位不吝指教

楼主#
更多 发布于:2007-10-31 18:54
ddk的文档中指示在使用NdisReadSlotInformation( )函数之后会返回一个CM_PARTIAL_RESOURCE_DESCRIPTOR结构体,结构体中的TYPE变量指示u联合体中哪一个资源(如interrupt,memory或i/0 space)有效,但是我的pci卡同时要用到上面的三个资源,那么:
1,按上所述,资源列表岂非只有一个资源?
2,就算所有的pci资源都在列表中,岂非只能读取一个?
不知道这里面有什么窍门,请各位高手为小弟解惑。
下面一贴使我在网上看到的,望君指摘。
liubing3052
驱动牛犊
驱动牛犊
  • 注册日期2007-08-28
  • 最后登录2008-03-25
  • 粉丝0
  • 关注0
  • 积分100分
  • 威望11点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-10-31 18:57
Following are the steps necessary to accomplish this task:

1.    Find the PCI device with HalGetBusData:

Scan all the buses and slots to find the location of your PCI device. In the buffer returned by HalGetBusData, look for a match to your device's PCI VendorId and DeviceId.

If your device driver requires additional information from the PCI configuration space, use HalGetBusData or HalGetBusDataByOffset. Fields in the PCI configuration space can be set with HalSetBusData or HalSetBusDataByOffset.

IMPORTANT: Do not set the base address registers (BARs) or the interrupt information in the PCI configuration space. Also, do not expect the BARs original settings to be those that will be used for your device. Since PCI is dynamically configurable, the operating system reserves the right to move the BARs as it sees fit.

Find the PCI device with 3 FOR loops: one for the bus, one for the device number, and one for the function number. Note that the structure PCI_SLOT_NUMBER contains the device number and function number information.
2.    Claim the device resources with HalAssignSlotResources:

Once the PCI device is located, pass the bus and slot information to HalAssignSlotResources. This API ensures that there are no conflicts with the resources specified in the configuration space. When the call to HalAssignSlotResources is made, the HAL might move the device's memory or port ranges, so do not use the values directly from the configuration space. Instead, use the values returned in the resource list and translate them as indicated in steps 4 and 5 below. The HAL will not move resources for a device spontaneously, it moves resources only as a result of the HalAssignSlotResources call.

Sometimes the call to HalAssignSlotResources causes problems when the HAL moves the PCI device resources on top of another PCI device that has not yet been claimed. You can usually prevent this by adding the PCILOCK option to the Boot.ini file. For information on the PCILOCK option, please see the following article in the Microsoft Knowledge Base:

148501 (http://support.microsoft.com/kb/148501/EN-US/) Preventing PCI Resource Conflicts on Intel-Based Computers

If adding the PCILOCK option does not work, the PCI device resources should be claimed with IoReportResourceUsage.

Using IoReportResourceUsage instead of HalAssignSlotResources:

Occasionally, PCI devices cease functioning when the Base Address Registers are reprogrammed or the PCI devices only work with specific resource assignments. On these PCI devices, HalAssignSlotResources frequently fails. In these cases, use IoReportResourceUsage instead of HalAssignSlotResources.

To use IoReportResourceUsage, get the current device settings by reading the PCI device's configuration space through HalGetBusData/HalGetBusDataByOffset. Build a resource list based on the information in the PCI configuration space and claim the resources using IoReportResourceUsage. It is important to make sure that the resource list InterfaceType is correctly set to PCIBus. Also, PCI interrupts are always considered level sensitive and shared, so make sure the proper flags are set in the resource list.

The interrupt value returned from the configuration space might look out of range when the driver is running on a checked build. This is because the checked HAL will exclusive-or (XOR) the true interrupt value with 0x2B. Use the value returned by HalGetBusData/HalGetBusDataByOffset unmodified because the HAL will know how to interpret this value. Use this returned value in the resource list for IoReportResourceUsage as well as for the BusInterruptLevel and BusInterruptVector parameters for the HalGetInterruptVector call.
3.    Parse the resource list for the device resources:

HalAssignSlotResources will claim the PCI device resources and return the claimed resources in a CM_RESOURCE_LIST structure. The driver will have to parse this resource list to get the interrupt, memory range, and I/O range information. Note that a single PCI device can have multiple memory and I/O ranges. If necessary, save this information in the driver's device extension for later translation. Do not use the raw resource information to access the I/O or memory spaces.

At this point, if the driver were to examine the PCI configuration space, the BARs should be the same as those returned in the CM_RESOURCE_LIST structure. However, use the information returned in the resource list.

If the PCI resources were claimed with IoReportResourceUsage, parse the resource list the driver built and store the information in an appropriate driver location.
4.    For each memory range claimed, call HalTranslateBusAddress and MmMapIoSpace:

HalTranslateBusAddress translates a bus-specific address into the corresponding system-logical address. After the call to this API, check the fourth parameter. On entry to the API, zero indicates memory space. On exit from the API, if the value is still zero, as is the normal case for memory translation, the driver must also call MmMapIoSpace.

Save the translated memory range information in a driver-accessible area like the device extension. Use the translated range to access the memory space.
5.    For each I/O range claimed, call HalTranslateBusAddress, and if needed, MmMapIoSpace:

Mapping is similar to that for memory space. However, on entry to HalTranslateBusAddress, the fourth parameter is one, which indicates I/O space. On exit, the API may have changed this parameter to zero, in which case the driver must also call MmMapIoSpace.

Save the translated I/O range information in a driver-accessible area like the device extension. Use the translated range to access the I/O space.

On some RISC-based systems, there is no I/O space: I/O space is mapped to memory space. In this situation, the fourth parameter will change to indicate that the I/O space has been mapped to memory space. On an x86- based system, translating an I/O space will use HalTranslateBusAddress, but not MmMapIoSpace. On some RISC-based systems, both HalTranslateBusAddress and MmMapIoSpace might be called. It is important to check the fourth parameter of HalTranslateBusAddress after the call to this API.

This is a common problem when porting from x86-based machines to RISC platforms. Driver writers sometimes assume that if they are translating I/O ranges, they will never need to call MmMapIoSpace. This is an incorrect assumption.
6.    If the device supports interrupts, call HalGetInterruptVector and IoConnectInterrupt:

Once IoConnectInterrupt has been called, the driver's interrupt service routine (ISR) might be called if the PCI device is interrupting. For this reason, it is best to connect the interrupt after translating all the device registers. If the previous translation has not occurred or the information is not available to the ISR (if, for example, the translated memory and I/O ranges are not saved in the device extension), the ISR will not be able to check the PCI device registers and clear the interrupt. If the interrupt is not cleared, the system will hang.
liubing3052
驱动牛犊
驱动牛犊
  • 注册日期2007-08-28
  • 最后登录2008-03-25
  • 粉丝0
  • 关注0
  • 积分100分
  • 威望11点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-10-31 18:58
typedef struct _CM_RESOURCE_LIST {
  ULONG  Count;
  CM_FULL_RESOURCE_DESCRIPTOR  List[1];
} CM_RESOURCE_LIST, *PCM_RESOURCE_LIST;
liubing3052
驱动牛犊
驱动牛犊
  • 注册日期2007-08-28
  • 最后登录2008-03-25
  • 粉丝0
  • 关注0
  • 积分100分
  • 威望11点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-10-31 18:59
typedef struct _CM_FULL_RESOURCE_DESCRIPTOR {
  INTERFACE_TYPE  InterfaceType;
  ULONG  BusNumber;
  CM_PARTIAL_RESOURCE_LIST  PartialResourceList;
} CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR;
liubing3052
驱动牛犊
驱动牛犊
  • 注册日期2007-08-28
  • 最后登录2008-03-25
  • 粉丝0
  • 关注0
  • 积分100分
  • 威望11点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-10-31 19:00
typedef struct _CM_PARTIAL_RESOURCE_LIST {
  USHORT  Version;
  USHORT  Revision;
  ULONG  Count;
  CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1];
} CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;
liubing3052
驱动牛犊
驱动牛犊
  • 注册日期2007-08-28
  • 最后登录2008-03-25
  • 粉丝0
  • 关注0
  • 积分100分
  • 威望11点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-10-31 19:10
CM_PARTIAL_RESOURCE_DESCRIPTOR

The CM_PARTIAL_RESOURCE_DESCRIPTOR structure specifies one or more system hardware resources, of a single type, assigned to a device. This structure is used to create an array within a CM_PARTIAL_RESOURCE_LIST structure.
 
typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR {
     UCHAR Type;
    UCHAR ShareDisposition;
    USHORT Flags;
    union {
        struct {
            PHYSICAL_ADDRESS Start;
            ULONG Length;
        } Generic;
        struct {
            PHYSICAL_ADDRESS Start;
            ULONG Length;
        } Port;
        struct {
            ULONG Level;
            ULONG Vector;
            KAFFINITY Affinity;
        } Interrupt;
        // This member exists only on Windows Vista and later
        struct {
            union {
               struct {
                   USHORT DataPayload;
                   USHORT MessageCount;
                   ULONG  Vector;
                   ULONG_PTR MessageTargetAddress;
               } Raw;
               struct {
                   ULONG Level;
                   ULONG Vector;
                   KAFFINITY Affinity;
               } Translated;        
            };
        } MessageInterrupt;
        struct {
            PHYSICAL_ADDRESS Start;
            ULONG Length;
        } Memory;
        struct {
            ULONG Channel;
            ULONG Port;
            ULONG Reserved1;
        } Dma;
        struct {
            ULONG Data[3];
        } DevicePrivate;
        struct {
            ULONG Start;
            ULONG Length;
            ULONG Reserved;
        } BusNumber;
        struct {
            ULONG DataSize;
            ULONG Reserved1;
            ULONG Reserved2;
        } DeviceSpecificData;
        // The following structures provide support for memory-mapped
        // IO resources greater than MAXULONG
        struct {
            PHYSICAL_ADDRESS Start;
            ULONG Length40;
        } Memory40;
        struct {
            PHYSICAL_ADDRESS Start;
            ULONG Length48;
        } Memory48;
        struct {
            PHYSICAL_ADDRESS Start;
            ULONG Length64;
        } Memory64;
    } u;
} CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;

Members
Type
    Identifies the resource type. The constant value specified for Type indicates which structure within the u union is valid, as indicated in the following table. (These flags are used within both CM_PARTIAL_RESOURCE_DESCRIPTOR and IO_RESOURCE_DESCRIPTOR structures, except where noted.)
    Type  Value                                                                                u Member Substructure
    CmResourceTypePort                                                                u.Port
    CmResourceTypeInterrupt                                                        u.Interrupt or u.MessageInterrupt. If
                                                                                            theCM_RESOURCE_INTERRUPT_MESSAGE
                                                                                            flag of Flags is set, use u.MessageInterrupt,
                                                                                            otherwise use u.Interrupt.
     CmResourceTypeMemory                                                      u.Memory
      CmResourceTypeDma                                                         u.Dma
       CmResourceTypeDevicePrivate                                           u.DevicePrivate
      CmResourceTypeBusNumber                                                  u.BusNumber
    CmResourceTypeDeviceSpecific                                          u.DeviceSpecificData (Not used                    
                                                                                                     within IO_RESOURCE_DESCRIPTOR.)
    CmResourceTypePcCardConfig                                                 u.DevicePrivate
    CmResourceTypeMfCardConfig                                                  u.DevicePrivate
    CmResourceTypeConfigData                                                   Reserved for system use.
    CmResourceTypeNonArbitrated                                           Not used.
     CmResourceTypeMemoryLarge                          One of u.Memory40, u.Memory48, or u.Memory64.
                                                                                       The CM_RESOURCE_MEMORY_LARGE_XXX
                                                                                       flags set in the Flags member determines which
                                                                                       structure is used.


  
  
  
  
  
liubing3052
驱动牛犊
驱动牛犊
  • 注册日期2007-08-28
  • 最后登录2008-03-25
  • 粉丝0
  • 关注0
  • 积分100分
  • 威望11点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-10-31 19:20
我还想问的是CmResourceTypePort类型的资源既可以映射到i/o寻址空间又可以映射到存储寻址空间(这个在CM_PARTIAL_RESOURCE_DESCRIPTOR的flag变量里指明),那么CmResourceTypeMemory 又是什么样的资源呢?
游客

返回顶部