第21章PCI设备驱动之PCI总线与配置空间

本章重点

    PCI 总线在一般的小型手持设备中不太可能用到,但在工控和通信设备及其 PC 中却引领着潮流。在 Linux 系统中,PCI 设备驱动和 USB 设备驱动有共性,其驱动都由总线相关部分自身设备类型驱动两部分组成。

1、 PCI 总线及其配置空间, PCI 总线在 Linux 内核中的数据结构。PCI 设备驱动的 PCI 相关部分围绕着 pci_driver 结构体的成员函数展开,

2、 pci_driver 结构体及其成员函数的含义,分析PCI设备驱动的框架结构。

21.1 PCI总线与配置空间

21.1.1 PCI总线的 Linux 描述

    PCI 是 CPU 和外围设备通信的高速传输总线。PCI 规范能够实现 32 位并行数据传输,工作频率为 33MHz 或 66MHz,最大吞吐率达 266MB/s。


    PCI 总线体系结构是一种层次式的体系结构,在层次式体系结构中,PCI 桥设备占据着重要的地位,它将父总线与子总线连接在一起。树的顶端是系统的 CPU,它通过一个较为特殊的 PCI 桥设备 — Host/PCI 桥设备与根 PCI 总线连接起来。

    作为一种特殊的 PCI 设备,PCI 桥包括以下几种。

    Host/PCI 桥:用于连接 CPU 与 PCI 根总线,第 1 个根总线的编号为 0。在 PC 中,内存控制器通常被集成到 Host/PCI 桥设备芯片中,因此,Host/PCI 桥通常也被称为“北桥芯片组(North Bridge Chipset)”。

    PCI/ISA 桥:用于连接旧的 ISA 总线。通常,PCI 中的类似 i8359A 中断控制器这样的设备也会被集成到 PCI/ISA 桥设备中,PCI/ISA 桥通常也被称为“南桥芯片组(SouthBridge Chipset)”。

    PCI-to-PCI 桥:用于连接 PCI 主总线(primary bus)与次总线(secondary bus)。PCI 桥所处的 PCI 总线称为“主总线”(即次总线的父总线),桥设备所连接的 PCI 总线称为“次总线”(即主总线的子总线)。

    在 Linux 系统中,PCI 总线用 pci_bus 来描述,这个结构体记录了本 PCI 总线的信息以及本PCI 总线的父总线、子总线、桥设备信息,这个结构体的定义如代码清单 21.1 所示。

代码清单 21.1 pci_bus 结构体

include/linux/pci.h

 struct pci_bus {
         struct list_head node; /* 链表元素 node */
         struct pci_bus *parent; /*指向该 PCI 总线的父总线,即 PCI 桥所在的总线 */
         struct list_head children; /* 描述了这条 PCI 总线的子总线链表的表头 */
         struct list_head devices; /* 描述了这条 PCI 总线的逻辑设备链表的表头 */
         struct pci_dev *self; /* 指向引出这条 PCI 总线的桥设备的 pci_dev 结构 */
         struct resource *resource[PCI_BUS_NUM_RESOURCES];
         /* 指向应路由到这条 PCI 总线的地址空间资源 */

         struct pci_ops *ops; /* 这条 PCI 总线所使用的配置空间访问函数 */
         void *sysdata; /* 指向系统特定的扩展数据 */
         struct proc_dir_entry *procdir;/*该 PCI 总线在/proc/bus/pci 中对应的目录项*/

         unsigned char number; /* 这条 PCI 总线的总线编号 */
         unsigned char primary; /* 桥设备的主总线 */
         unsigned char secondary; /* PCI 总线的桥设备的次总线号 */

         unsigned char subordinate;/*PCI 总线的下属 PCI 总线的总线编号最大值*/

        char name[48];

         unsigned short bridge_ctl;
         pci_bus_flags_t bus_flags;
         struct device *bridge;
         struct class_device class_dev;
         struct bin_attribute *legacy_io;
         struct bin_attribute *legacy_mem;
         unsigned int is_added:1;
 };

    假定一个如图 21.1 所示的 PCI 总线系统,根总线 0 上有一个 PCI 桥,它引出子总线 Bus 1,Bus 1 上又有一个 PCI 桥引出 Bus 2。


    在上图中,Bus 0 总线的 pci_bus 结构体中的 number、primary、secondary 都应该为 0,因为它是通过 Host/PCI 桥引出的根总线;Bus 1 总线的 pci_bus 结构体中的 number 和 secondary 都为 1,但是它的 primary 应该为 0;Bus 2 总线的 pci_bus 结构体中的 number 和 secondary 都应该为 2,而其 primary 则应该等于 1。这 3 条总线的 subordinate 值都应该等于 2。

    系统中当前存在的所有根总线都通过其 pci_bus 结构体中的 node 成员链接成一条全局的根总线链表,其表头由 list 类型的全局变量 pci_root_buses 来描述。而根总线下面的所有下级总线通过其 pci_bus 结构体中的 node 成员链接到其父总线的 children 链表中。这样,通过这两种 PCI总线链表,Linux 内核就将所有的 pci_bus 结构体以一种倒置树的方式组织起来。

    假定对于如图 21.2所示的多根 PCI 总线体系结构,它所对应的总线链表结构将如图 21.3 所示。



21.1.2 PCI 设备的 Linux 描述

    在 Linux 系统中,所有种类的 PCI 设备用 pci_dev 结构体来描述,由于一个 PCI 接口卡上可能包含多个功能模块,每个功能被当作一个独立的逻辑设备,因此,每一个 PCI 功能,即PCI 逻辑设备都惟一地对应一个 pci_dev 设备描述符,该结构体的定义如代码清单 21.2 所示。

代码清单 21.2 pci_dev 结构体

include/linux/pci.h

/*
 * The pci_dev structure is used to describe PCI devices.
 */
struct pci_dev {
        struct list_head bus_list;      /* node in per-bus list */
        struct pci_bus  *bus;           /* bus this device is on */
        struct pci_bus  *subordinate;   /* bus this device bridges to */


        void            *sysdata;       /* hook for sys-specific extension */
        struct proc_dir_entry *procent; /* device entry in /proc/bus/pci */
        struct pci_slot *slot;          /* Physical slot this device is in */


        unsigned int    devfn;          /* encoded device & function index */
        unsigned short  vendor;
        unsigned short  device;
        unsigned short  subsystem_vendor;
        unsigned short  subsystem_device;
        unsigned int    class;          /* 3 bytes: (base,sub,prog-if) */
        u8              revision;       /* PCI revision, low byte of class word */
        u8              hdr_type;       /* PCI header type (`multi' flag masked out) */
        u8              pcie_cap;       /* PCIe capability offset */
        u8              msi_cap;        /* MSI capability offset */
        u8              msix_cap;       /* MSI-X capability offset */
        u8              pcie_mpss:3;    /* PCIe Max Payload Size Supported */
        u8              rom_base_reg;   /* which config register controls the ROM */
        u8              pin;            /* which interrupt pin this device uses */
        u16             pcie_flags_reg; /* cached PCIe Capabilities Register */
        u8              dma_alias_devfn;/* devfn of DMA alias, if any */


        struct pci_driver *driver;      /* which driver has allocated this device */
        u64             dma_mask;       /* Mask of the bits of bus address this
                                           device implements.  Normally this is
                                           0xffffffff.  You only need to change
                                           this if your device has broken DMA
                                           or supports 64-bit transfers.  */


        struct device_dma_parameters dma_parms;


        pci_power_t     current_state;  /* Current operating state. In ACPI-speak,
                                           this is D0-D3, D0 being fully functional,
                                           and D3 being off. */
        u8              pm_cap;         /* PM capability offset */
        unsigned int    pme_support:5;  /* Bitmask of states from which PME#
                                           can be generated */
        unsigned int    pme_interrupt:1;
        unsigned int    pme_poll:1;     /* Poll device's PME status bit */
        unsigned int    d1_support:1;   /* Low power state D1 is supported */
        unsigned int    d2_support:1;   /* Low power state D2 is supported */
        unsigned int    no_d1d2:1;      /* D1 and D2 are forbidden */
        unsigned int    no_d3cold:1;    /* D3cold is forbidden */
        unsigned int    d3cold_allowed:1;       /* D3cold is allowed by user */
        unsigned int    mmio_always_on:1;       /* disallow turning off io/mem
                                                   decoding during bar sizing */
        unsigned int    wakeup_prepared:1;
        unsigned int    runtime_d3cold:1;       /* whether go through runtime
                                                   D3cold, not set for devices
                                                   powered on/off by the
                                                   corresponding bridge */
        unsigned int    ignore_hotplug:1;       /* Ignore hotplug events */
        unsigned int    d3_delay;       /* D3->D0 transition time in ms */
        unsigned int    d3cold_delay;   /* D3cold->D0 transition time in ms */


#ifdef CONFIG_PCIEASPM
        struct pcie_link_state  *link_state;    /* ASPM link state */
#endif


        pci_channel_state_t error_state;        /* current connectivity state */
        struct  device  dev;            /* Generic device interface */


        int             cfg_size;       /* Size of configuration space */


        /*
         * Instead of touching interrupt line and base address registers
         * directly, use the values stored here. They might be different!
         */
        unsigned int    irq;
        struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */


        bool match_driver;              /* Skip attaching driver */
        /* These fields are used by common fixups */
        unsigned int    transparent:1;  /* Subtractive decode PCI bridge */
        unsigned int    multifunction:1;/* Part of multi-function device */
        /* keep track of device state */
        unsigned int    is_added:1;
        unsigned int    is_busmaster:1; /* device is busmaster */
        unsigned int    no_msi:1;       /* device may not use msi */
        unsigned int    no_64bit_msi:1; /* device may only use 32-bit MSIs */
        unsigned int    block_cfg_access:1;     /* config space access is blocked */
        unsigned int    broken_parity_status:1; /* Device generates false positive parity */
        unsigned int    irq_reroute_variant:2;  /* device needs IRQ rerouting variant */
        unsigned int    msi_enabled:1;
        unsigned int    msix_enabled:1;
        unsigned int    ari_enabled:1;  /* ARI forwarding */
        unsigned int    is_managed:1;
        unsigned int    needs_freset:1; /* Dev requires fundamental reset */
        unsigned int    state_saved:1;
        unsigned int    is_physfn:1;
        unsigned int    is_virtfn:1;
        unsigned int    reset_fn:1;
        unsigned int    is_hotplug_bridge:1;
        unsigned int    __aer_firmware_first_valid:1;
        unsigned int    __aer_firmware_first:1;
        unsigned int    broken_intx_masking:1;
        unsigned int    io_window_1k:1; /* Intel P2P bridge 1K I/O windows */
        unsigned int    irq_managed:1;
        unsigned int    has_secondary_link:1;
        unsigned int    non_compliant_bars:1;   /* broken BARs; ignore them */
        pci_dev_flags_t dev_flags;
        atomic_t        enable_cnt;     /* pci_enable_device has been called */


        u32             saved_config_space[16]; /* config space saved at suspend time */
        struct hlist_head saved_cap_space;
        struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
        int rom_attr_enabled;           /* has display of the rom attribute been enabled? */
        struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
        struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
#ifdef CONFIG_PCI_MSI
        struct list_head msi_list;
        const struct attribute_group **msi_irq_groups;
#endif
        struct pci_vpd *vpd;
#ifdef CONFIG_PCI_ATS
        union {
                struct pci_sriov *sriov;        /* SR-IOV capability related */
                struct pci_dev *physfn; /* the PF this VF is associated with */
        };
        struct pci_ats  *ats;   /* Address Translation Service */
#endif
        phys_addr_t rom; /* Physical address of ROM if it's not from the BAR */
        size_t romlen; /* Length of ROM if it's not from the BAR */
        char *driver_override; /* Driver name to force a match */
};

21.1.3 PCI 配置空间访问

     PCI 有 3 种地址空间:PCI I/O 空间、PCI 内存地址空间和 PCI 配置空间。CPU 可以访问所有的地址空间,其中 PCI I/O 空间和 PCI 内存地址空间由设备驱动程序使用。PCI 支持自动配置设备,PCI 驱动程序不需要实现复杂的检测逻辑。启动时,BIOS 或内核自身会遍历 PCI 总线并分配资源,如中断优先级和 I/O 基址。设备驱动程序通过 PCI 配置空间来找到资源分配情况。

    PCI 规范定义3 种类型的 PCI 配置空间头部,其中 type 0 用于标准的 PCI 设备,type 1 用于 PCI 桥,type 2 用于 PCI CardBus 桥。如图 2.17 所示,不管是哪一种类型的配置空间头部,前 16 个字节的格式都相同。


include/linux/pci_regs.h 文件中定义 PCI 配置空间头部,如代码清单 21.3 所示。

代码清单 21.3 PCI 配置空间头部寄存器定义

#define PCI_VENDOR_ID           0x00    /* 16 bits */

#define PCI_DEVICE_ID           0x02    /* 16 bits */

/* PCI 命令寄存器 */

#define PCI_COMMAND             0x04    /* 16 bits */
#define  PCI_COMMAND_IO         0x1     /* Enable response in I/O space */
#define  PCI_COMMAND_MEMORY     0x2     /* Enable response in Memory space */
#define  PCI_COMMAND_MASTER     0x4     /* Enable bus mastering */
#define  PCI_COMMAND_SPECIAL    0x8     /* Enable response to special cycles */
#define  PCI_COMMAND_INVALIDATE 0x10    /* Use memory write and invalidate */
#define  PCI_COMMAND_VGA_PALETTE 0x20   /* Enable palette snooping */
#define  PCI_COMMAND_PARITY     0x40    /* Enable parity checking */
#define  PCI_COMMAND_WAIT       0x80    /* Enable address/data stepping */
#define  PCI_COMMAND_SERR       0x100   /* Enable SERR */
#define  PCI_COMMAND_FAST_BACK  0x200   /* Enable back-to-back writes */
#define  PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */

/* PCI 状态寄存器 */

#define PCI_STATUS              0x06    /* 16 bits */
#define  PCI_STATUS_INTERRUPT   0x08    /* Interrupt status */
#define  PCI_STATUS_CAP_LIST    0x10    /* Support Capability List */
#define  PCI_STATUS_66MHZ       0x20    /* Support 66 MHz PCI 2.1 bus */
#define  PCI_STATUS_UDF         0x40    /* Support User Definable Features [obsolete] */
#define  PCI_STATUS_FAST_BACK   0x80    /* Accept fast-back to back */
#define  PCI_STATUS_PARITY      0x100   /* Detected parity error */
#define  PCI_STATUS_DEVSEL_MASK 0x600   /* DEVSEL timing */
#define  PCI_STATUS_DEVSEL_FAST         0x000
#define  PCI_STATUS_DEVSEL_MEDIUM       0x200
#define  PCI_STATUS_DEVSEL_SLOW         0x400
#define  PCI_STATUS_SIG_TARGET_ABORT    0x800 /* Set on target abort */
#define  PCI_STATUS_REC_TARGET_ABORT    0x1000 /* Master ack of " */
#define  PCI_STATUS_REC_MASTER_ABORT    0x2000 /* Set on master abort */
#define  PCI_STATUS_SIG_SYSTEM_ERROR    0x4000 /* Set when we drive SERR */
#define  PCI_STATUS_DETECTED_PARITY     0x8000 /* Set on parity error */

/* 类代码寄存器和修订版本寄存器 */

#define PCI_CLASS_REVISION      0x08    /* High 24 bits are class, low 8 revision */
#define PCI_REVISION_ID         0x08    /* Revision ID */
#define PCI_CLASS_PROG          0x09    /* Reg. Level Programming Interface */
#define PCI_CLASS_DEVICE        0x0a    /* Device class */

#define PCI_CACHE_LINE_SIZE     0x0c    /* 8 bits */
#define PCI_LATENCY_TIMER       0x0d    /* 8 bits */

/* PCI 头类型 */

#define PCI_HEADER_TYPE         0x0e    /* 8 bits */
#define  PCI_HEADER_TYPE_NORMAL         0
#define  PCI_HEADER_TYPE_BRIDGE         1

#define  PCI_HEADER_TYPE_CARDBUS        2

/* 表示配置空间头部中的 Built-In Self-Test 寄存器在配置空间中的字节地址索引 */

#define PCI_BIST                0x0f    /* 8 bits */
#define  PCI_BIST_CODE_MASK     0x0f    /* Return result */
#define  PCI_BIST_START         0x40    /* 1 to start BIST, 2 secs or less */
#define  PCI_BIST_CAPABLE       0x80    /* 1 if BIST capable */

        紧接着前 16 个字节的寄存器为基地址寄存器 0~基地址寄存器 5,其中,PCI_BASE_ADDRESS_2~5 仅对标准 PCI 设备的 0 类型配置空间头部有意义,PCI_BASE_ADDRESS_0~1 适用于0 类型和 1 类型配置空间头部。

    基地址寄存器中的 bit[0]的值决定这个基地址寄存器所指定的地址范围是在 I/O 空间还是在内存映射空间内进行译码。当基地址寄存器所指定的地址范围位于内存映射空间中时,其 bit[2∶1]表示内存地址的类型,bit[3]表示内存范围是否为可预取(Prefetchable)的内存。1 类型配置空间头部适用于 PCI-PCI 桥设备,其基地址寄存器 0 与基地址寄存器 1 可以用来指定桥设备本身可能要用到的地址范围,而后 40 个字节(0x18~0x39)则被用来配置桥设备的主、次编号以及地址过滤窗口等信息。

    pci_bus 结构体中的 pci_ops 类型成员指针 ops 指向该 PCI 总线所使用的配置空间访问操作的具体实现,pci_ops 结构体的定义如代码清单 21.4 所示。

代码清单 21.4 pci_ops 结构体

include/linux/pci.h

struct pci_ops {
        int (*add_bus)(struct pci_bus *bus);
        void (*remove_bus)(struct pci_bus *bus);

        void __iomem *(*map_bus)(struct pci_bus *bus, unsigned int devfn, int where);

        /* 读配置空间 */

        int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val);

        /* 写配置空间 */

        int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
};

        read()和 write()成员函数中的 size 表示访问的是字节、2 字节还是 4 字节,对于 write(),val 是要写入的值;对于 read(),val 是要返回的读取到的值的指针。通过 bus 参数的成员以及devfn 可定位相应 PCI 总线上相应 PCI 逻辑设备的配置空间。在 Linux 设备驱动中,可用如下一组函数来访问配置空间:

include/linux/pci.h

inline  int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val);
inline int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val);
inline int pci_read_config_dword(const struct pci_dev *dev, int where, u32 *val);
inline int pci_write_config_byte(const struct pci_dev *dev, int where, u8 val);
inline int pci_write_config_word(const struct pci_dev *dev, int where, u16 val);
inline int pci_write_config_dword(const struct pci_dev *dev, int where, u32 val);

上述函数只是对如下函数进行调用:

int pci_bu _read_config _ byte (struct pci _ bus *bus, unsigned int devfn, int where, u8 *val);
/* 读字节 */
int pci_bus_read_config_word (struct pci _ bus *bus, unsigned int devfn, int where, u16
*val); /* 读字 */
int pci_bus_read_config_dword (struct pci _ bus *bus, unsigned int devfn, int where, u32
*val); /* 读双字 */
int pci_bus_write_config_byte (struct pci _ bus *bus, unsigned int devfn, int where, u8
val); /* 写字节 */
int pci_bus_write_config_word (struct pci _ bus *bus, unsigned int devfn, int where, u16
val); /* 写字 */
int pci_bus_write_config_dword (struct pci _ bus *bus, unsigned int devfn, int where, u32
val); /* 写双字 */

         PCI 总线、设备与驱动在/proc 和/sysfs 文件系统中的描述。首先,通过查看/proc/bus/pci 中的文件,可以获得系统连接的 PCI 设备的基本信息描述。

Ubuntu Linux 上的/proc/bus/pci 目录下的树型结构如下:

/proc/bus/pci

├── 00
│   ├── 00.0
│   ├── 01.0
│   ├── 03.0
│   ├── 05.0
│   ├── 05.1
│   ├── 05.2
│   ├── 05.4
│   ├── 11.0
│   ├── 11.4
│   ├── 14.0
│   ├── 16.0
│   ├── 16.1
│   ├── 1a.0
│   ├── 1c.0
│   ├── 1c.4
│   ├── 1c.5
│   ├── 1c.7
│   ├── 1d.0
│   ├── 1f.0
│   ├── 1f.2
│   └── 1f.3
├── 04
│   └── 00.0
├── 05
│   └── 00.0
├── 06
│   └── 00.0
├── 07
│   └── 00.0
├── devices
└── ff
    ├── 0b.0
    ├── 0b.1
    ├── 0b.2
    ├── 0c.0
    ├── 0c.1
    ├── 0c.2
    ├── 0c.3
    ├── 0c.4
    ├── 0c.5
    ├── 0c.6
    ├── 0c.7
    ├── 0d.0
    ├── 0d.1
    ├── 0d.2
    ├── 0d.3
    ├── 0f.0
    ├── 0f.1
    ├── 0f.2
    ├── 0f.3
    ├── 0f.4
    ├── 0f.5
    ├── 0f.6
    ├── 10.0
    ├── 10.1
    ├── 10.5
    ├── 10.6
    ├── 10.7
    ├── 12.0
    ├── 12.1
    ├── 12.4
    ├── 12.5
    ├── 13.0
    ├── 13.1
    ├── 13.2
    ├── 13.3
    ├── 13.6
    ├── 13.7
    ├── 14.0
    ├── 14.1
    ├── 14.2
    ├── 14.3
    ├── 14.4
    ├── 14.5
    ├── 14.6
    ├── 14.7
    ├── 16.0
    ├── 16.1
    ├── 16.2
    ├── 16.3
    ├── 16.6
    ├── 16.7
    ├── 17.0
    ├── 17.1
    ├── 17.2
    ├── 17.3
    ├── 17.4
    ├── 17.5
    ├── 17.6
    ├── 17.7
    ├── 1e.0
    ├── 1e.1
    ├── 1e.2
    ├── 1e.3
    ├── 1e.4
    ├── 1f.0
    └── 1f.2

6 directories, 92 files

        sysfs 文件系统/sys/bus/pci 目录中也给出了系统中总线上挂接的设备及驱动信息,该目录下的树型结构如下:

/sys/bus/pci

├── devices
│   ├── 0000:00:00.0 -> ../../../devices/pci0000:00/0000:00:00.0
│   ├── 0000:00:01.0 -> ../../../devices/pci0000:00/0000:00:01.0
│   ├── 0000:00:03.0 -> ../../../devices/pci0000:00/0000:00:03.0
│   ├── 0000:00:05.0 -> ../../../devices/pci0000:00/0000:00:05.0
│   ├── 0000:00:05.1 -> ../../../devices/pci0000:00/0000:00:05.1
│   ├── 0000:00:05.2 -> ../../../devices/pci0000:00/0000:00:05.2
│   ├── 0000:00:05.4 -> ../../../devices/pci0000:00/0000:00:05.4
│   ├── 0000:00:11.0 -> ../../../devices/pci0000:00/0000:00:11.0
│   ├── 0000:00:11.4 -> ../../../devices/pci0000:00/0000:00:11.4
│   ├── 0000:00:14.0 -> ../../../devices/pci0000:00/0000:00:14.0
│   ├── 0000:00:16.0 -> ../../../devices/pci0000:00/0000:00:16.0
│   ├── 0000:00:16.1 -> ../../../devices/pci0000:00/0000:00:16.1
│   ├── 0000:00:1a.0 -> ../../../devices/pci0000:00/0000:00:1a.0
│   ├── 0000:00:1c.0 -> ../../../devices/pci0000:00/0000:00:1c.0
│   ├── 0000:00:1c.4 -> ../../../devices/pci0000:00/0000:00:1c.4
│   ├── 0000:00:1c.5 -> ../../../devices/pci0000:00/0000:00:1c.5
│   ├── 0000:00:1c.7 -> ../../../devices/pci0000:00/0000:00:1c.7
│   ├── 0000:00:1d.0 -> ../../../devices/pci0000:00/0000:00:1d.0
│   ├── 0000:00:1f.0 -> ../../../devices/pci0000:00/0000:00:1f.0
│   ├── 0000:00:1f.2 -> ../../../devices/pci0000:00/0000:00:1f.2
│   ├── 0000:00:1f.3 -> ../../../devices/pci0000:00/0000:00:1f.3
│   ├── 0000:04:00.0 -> ../../../devices/pci0000:00/0000:00:1c.4/0000:04:00.0
│   ├── 0000:05:00.0 -> ../../../devices/pci0000:00/0000:00:1c.5/0000:05:00.0
│   ├── 0000:06:00.0 -> ../../../devices/pci0000:00/0000:00:1c.7/0000:06:00.0
│   ├── 0000:07:00.0 -> ../../../devices/pci0000:00/0000:00:1c.7/0000:06:00.0/0000:07:00.0
│   ├── 0000:ff:0b.0 -> ../../../devices/pci0000:ff/0000:ff:0b.0
│   ├── 0000:ff:0b.1 -> ../../../devices/pci0000:ff/0000:ff:0b.1
│   ├── 0000:ff:0b.2 -> ../../../devices/pci0000:ff/0000:ff:0b.2
│   ├── 0000:ff:0c.0 -> ../../../devices/pci0000:ff/0000:ff:0c.0
│   ├── 0000:ff:0c.1 -> ../../../devices/pci0000:ff/0000:ff:0c.1
│   ├── 0000:ff:0c.2 -> ../../../devices/pci0000:ff/0000:ff:0c.2
│   ├── 0000:ff:0c.3 -> ../../../devices/pci0000:ff/0000:ff:0c.3
│   ├── 0000:ff:0c.4 -> ../../../devices/pci0000:ff/0000:ff:0c.4
│   ├── 0000:ff:0c.5 -> ../../../devices/pci0000:ff/0000:ff:0c.5
│   ├── 0000:ff:0c.6 -> ../../../devices/pci0000:ff/0000:ff:0c.6
│   ├── 0000:ff:0c.7 -> ../../../devices/pci0000:ff/0000:ff:0c.7
│   ├── 0000:ff:0d.0 -> ../../../devices/pci0000:ff/0000:ff:0d.0
│   ├── 0000:ff:0d.1 -> ../../../devices/pci0000:ff/0000:ff:0d.1
│   ├── 0000:ff:0d.2 -> ../../../devices/pci0000:ff/0000:ff:0d.2
│   ├── 0000:ff:0d.3 -> ../../../devices/pci0000:ff/0000:ff:0d.3
│   ├── 0000:ff:0f.0 -> ../../../devices/pci0000:ff/0000:ff:0f.0
│   ├── 0000:ff:0f.1 -> ../../../devices/pci0000:ff/0000:ff:0f.1
│   ├── 0000:ff:0f.2 -> ../../../devices/pci0000:ff/0000:ff:0f.2
│   ├── 0000:ff:0f.3 -> ../../../devices/pci0000:ff/0000:ff:0f.3
│   ├── 0000:ff:0f.4 -> ../../../devices/pci0000:ff/0000:ff:0f.4
│   ├── 0000:ff:0f.5 -> ../../../devices/pci0000:ff/0000:ff:0f.5
│   ├── 0000:ff:0f.6 -> ../../../devices/pci0000:ff/0000:ff:0f.6
│   ├── 0000:ff:10.0 -> ../../../devices/pci0000:ff/0000:ff:10.0
│   ├── 0000:ff:10.1 -> ../../../devices/pci0000:ff/0000:ff:10.1
│   ├── 0000:ff:10.5 -> ../../../devices/pci0000:ff/0000:ff:10.5
│   ├── 0000:ff:10.6 -> ../../../devices/pci0000:ff/0000:ff:10.6
│   ├── 0000:ff:10.7 -> ../../../devices/pci0000:ff/0000:ff:10.7
│   ├── 0000:ff:12.0 -> ../../../devices/pci0000:ff/0000:ff:12.0
│   ├── 0000:ff:12.1 -> ../../../devices/pci0000:ff/0000:ff:12.1
│   ├── 0000:ff:12.4 -> ../../../devices/pci0000:ff/0000:ff:12.4
│   ├── 0000:ff:12.5 -> ../../../devices/pci0000:ff/0000:ff:12.5
│   ├── 0000:ff:13.0 -> ../../../devices/pci0000:ff/0000:ff:13.0
│   ├── 0000:ff:13.1 -> ../../../devices/pci0000:ff/0000:ff:13.1
│   ├── 0000:ff:13.2 -> ../../../devices/pci0000:ff/0000:ff:13.2
│   ├── 0000:ff:13.3 -> ../../../devices/pci0000:ff/0000:ff:13.3
│   ├── 0000:ff:13.6 -> ../../../devices/pci0000:ff/0000:ff:13.6
│   ├── 0000:ff:13.7 -> ../../../devices/pci0000:ff/0000:ff:13.7
│   ├── 0000:ff:14.0 -> ../../../devices/pci0000:ff/0000:ff:14.0
│   ├── 0000:ff:14.1 -> ../../../devices/pci0000:ff/0000:ff:14.1
│   ├── 0000:ff:14.2 -> ../../../devices/pci0000:ff/0000:ff:14.2
│   ├── 0000:ff:14.3 -> ../../../devices/pci0000:ff/0000:ff:14.3
│   ├── 0000:ff:14.4 -> ../../../devices/pci0000:ff/0000:ff:14.4
│   ├── 0000:ff:14.5 -> ../../../devices/pci0000:ff/0000:ff:14.5
│   ├── 0000:ff:14.6 -> ../../../devices/pci0000:ff/0000:ff:14.6
│   ├── 0000:ff:14.7 -> ../../../devices/pci0000:ff/0000:ff:14.7
│   ├── 0000:ff:16.0 -> ../../../devices/pci0000:ff/0000:ff:16.0
│   ├── 0000:ff:16.1 -> ../../../devices/pci0000:ff/0000:ff:16.1
│   ├── 0000:ff:16.2 -> ../../../devices/pci0000:ff/0000:ff:16.2
│   ├── 0000:ff:16.3 -> ../../../devices/pci0000:ff/0000:ff:16.3
│   ├── 0000:ff:16.6 -> ../../../devices/pci0000:ff/0000:ff:16.6
│   ├── 0000:ff:16.7 -> ../../../devices/pci0000:ff/0000:ff:16.7
│   ├── 0000:ff:17.0 -> ../../../devices/pci0000:ff/0000:ff:17.0
│   ├── 0000:ff:17.1 -> ../../../devices/pci0000:ff/0000:ff:17.1
│   ├── 0000:ff:17.2 -> ../../../devices/pci0000:ff/0000:ff:17.2
│   ├── 0000:ff:17.3 -> ../../../devices/pci0000:ff/0000:ff:17.3
│   ├── 0000:ff:17.4 -> ../../../devices/pci0000:ff/0000:ff:17.4
│   ├── 0000:ff:17.5 -> ../../../devices/pci0000:ff/0000:ff:17.5
│   ├── 0000:ff:17.6 -> ../../../devices/pci0000:ff/0000:ff:17.6
│   ├── 0000:ff:17.7 -> ../../../devices/pci0000:ff/0000:ff:17.7
│   ├── 0000:ff:1e.0 -> ../../../devices/pci0000:ff/0000:ff:1e.0
│   ├── 0000:ff:1e.1 -> ../../../devices/pci0000:ff/0000:ff:1e.1
│   ├── 0000:ff:1e.2 -> ../../../devices/pci0000:ff/0000:ff:1e.2
│   ├── 0000:ff:1e.3 -> ../../../devices/pci0000:ff/0000:ff:1e.3
│   ├── 0000:ff:1e.4 -> ../../../devices/pci0000:ff/0000:ff:1e.4
│   ├── 0000:ff:1f.0 -> ../../../devices/pci0000:ff/0000:ff:1f.0
│   └── 0000:ff:1f.2 -> ../../../devices/pci0000:ff/0000:ff:1f.2
├── drivers
│   ├── agpgart-intel
│   │   ├── bind
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── agpgart-via
│   │   ├── bind
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── ahci
│   │   ├── 0000:00:11.4 -> ../../../../devices/pci0000:00/0000:00:11.4
│   │   ├── 0000:00:1f.2 -> ../../../../devices/pci0000:00/0000:00:1f.2
│   │   ├── bind
│   │   ├── module -> ../../../../module/ahci
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── asiliantfb
│   │   ├── bind
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── ast
│   │   ├── 0000:07:00.0 -> ../../../../devices/pci0000:00/0000:00:1c.7/0000:06:00.0/0000:07:00.0
│   │   ├── bind
│   │   ├── module -> ../../../../module/drm
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── ata_generic
│   │   ├── bind
│   │   ├── module -> ../../../../module/ata_generic
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── ata_piix
│   │   ├── bind
│   │   ├── module -> ../../../../module/ata_piix
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── dwc2-pci
│   │   ├── bind
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── ehci-pci
│   │   ├── 0000:00:1a.0 -> ../../../../devices/pci0000:00/0000:00:1a.0
│   │   ├── 0000:00:1d.0 -> ../../../../devices/pci0000:00/0000:00:1d.0
│   │   ├── bind
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── hswep_uncore
│   │   ├── 0000:ff:0b.1 -> ../../../../devices/pci0000:ff/0000:ff:0b.1
│   │   ├── 0000:ff:0b.2 -> ../../../../devices/pci0000:ff/0000:ff:0b.2
│   │   ├── 0000:ff:10.1 -> ../../../../devices/pci0000:ff/0000:ff:10.1
│   │   ├── 0000:ff:12.1 -> ../../../../devices/pci0000:ff/0000:ff:12.1
│   │   ├── 0000:ff:12.5 -> ../../../../devices/pci0000:ff/0000:ff:12.5
│   │   ├── 0000:ff:14.0 -> ../../../../devices/pci0000:ff/0000:ff:14.0
│   │   ├── 0000:ff:14.1 -> ../../../../devices/pci0000:ff/0000:ff:14.1
│   │   ├── 0000:ff:17.0 -> ../../../../devices/pci0000:ff/0000:ff:17.0
│   │   ├── 0000:ff:17.1 -> ../../../../devices/pci0000:ff/0000:ff:17.1
│   │   ├── 0000:ff:1e.3 -> ../../../../devices/pci0000:ff/0000:ff:1e.3
│   │   ├── bind
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── igb
│   │   ├── 0000:04:00.0 -> ../../../../devices/pci0000:00/0000:00:1c.4/0000:04:00.0
│   │   ├── 0000:05:00.0 -> ../../../../devices/pci0000:00/0000:00:1c.5/0000:05:00.0
│   │   ├── bind
│   │   ├── module -> ../../../../module/igb
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── imsttfb
│   │   ├── bind
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── intel_mid_gpio
│   │   ├── bind
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── iosf_mbi_pci
│   │   ├── bind
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── lpc_ich
│   │   ├── 0000:00:1f.0 -> ../../../../devices/pci0000:00/0000:00:1f.0
│   │   ├── bind
│   │   ├── module -> ../../../../module/lpc_ich
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── mei_me
│   │   ├── bind
│   │   ├── module -> ../../../../module/mei_me
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── ohci-pci
│   │   ├── bind
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── parport_pc
│   │   ├── bind
│   │   ├── module -> ../../../../module/parport_pc
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── pata_sis
│   │   ├── bind
│   │   ├── module -> ../../../../module/pata_sis
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── pcieport
│   │   ├── 0000:00:01.0 -> ../../../../devices/pci0000:00/0000:00:01.0
│   │   ├── 0000:00:03.0 -> ../../../../devices/pci0000:00/0000:00:03.0
│   │   ├── 0000:00:1c.0 -> ../../../../devices/pci0000:00/0000:00:1c.0
│   │   ├── 0000:00:1c.4 -> ../../../../devices/pci0000:00/0000:00:1c.4
│   │   ├── 0000:00:1c.5 -> ../../../../devices/pci0000:00/0000:00:1c.5
│   │   ├── 0000:00:1c.7 -> ../../../../devices/pci0000:00/0000:00:1c.7
│   │   ├── bind
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── sbridge_edac
│   │   ├── 0000:ff:12.0 -> ../../../../devices/pci0000:ff/0000:ff:12.0
│   │   ├── bind
│   │   ├── module -> ../../../../module/sb_edac
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── serial
│   │   ├── bind
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── shpchp
│   │   ├── bind
│   │   ├── module -> ../../../../module/shpchp
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── uhci_hcd
│   │   ├── bind
│   │   ├── module -> ../../../../module/uhci_hcd
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── virtio-pci
│   │   ├── bind
│   │   ├── module -> ../../../../module/virtio_pci
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   ├── xen-platform-pci
│   │   ├── bind
│   │   ├── new_id
│   │   ├── remove_id
│   │   ├── uevent
│   │   └── unbind
│   └── xhci_hcd
│       ├── 0000:00:14.0 -> ../../../../devices/pci0000:00/0000:00:14.0
│       ├── bind
│       ├── new_id
│       ├── remove_id
│       ├── uevent
│       └── unbind
├── drivers_autoprobe
├── drivers_probe
├── rescan
├── resource_alignment
├── slots
│   ├── 0
│   │   ├── adapter
│   │   ├── address
│   │   ├── cur_bus_speed
│   │   ├── max_bus_speed
│   │   ├── module -> ../../../../module/pciehp
│   │   └── power
│   ├── 2
│   │   ├── address
│   │   ├── cur_bus_speed
│   │   └── max_bus_speed
│   └── 3
│       ├── address
│       ├── cur_bus_speed
│       └── max_bus_speed
└── uevent

164 directories, 151 files

        此外,pciutils(PCI 工具)中的 lspci 工具会分析/proc/bus/pci 中的文件,从而可被用户用于查看系统中 PCI 设备的描述信息。例如在Ubuntu上运行lspci的结果为:

00:00.0 Host bridge: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 DMI2 (rev 02)
00:01.0 PCI bridge: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 PCI Express Root Port 1 (rev 02)
00:03.0 PCI bridge: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 PCI Express Root Port 3 (rev 02)
00:05.0 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Address Map, VTd_Misc, System Management (rev 02)
00:05.1 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Hot Plug (rev 02)
00:05.2 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 RAS, Control Status and Global Errors (rev 02)
00:05.4 PIC: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 I/O APIC (rev 02)
00:11.0 Unassigned class [ff00]: Intel Corporation C610/X99 series chipset SPSR (rev 05)
00:11.4 SATA controller: Intel Corporation C610/X99 series chipset sSATA Controller [AHCI mode] (rev 05)
00:14.0 USB controller: Intel Corporation C610/X99 series chipset USB xHCI Host Controller (rev 05)
00:16.0 Communication controller: Intel Corporation C610/X99 series chipset MEI Controller #1 (rev 05)
00:16.1 Communication controller: Intel Corporation C610/X99 series chipset MEI Controller #2 (rev 05)
00:1a.0 USB controller: Intel Corporation C610/X99 series chipset USB Enhanced Host Controller #2 (rev 05)
00:1c.0 PCI bridge: Intel Corporation C610/X99 series chipset PCI Express Root Port #1 (rev d5)
00:1c.4 PCI bridge: Intel Corporation C610/X99 series chipset PCI Express Root Port #5 (rev d5)
00:1c.5 PCI bridge: Intel Corporation C610/X99 series chipset PCI Express Root Port #6 (rev d5)
00:1c.7 PCI bridge: Intel Corporation C610/X99 series chipset PCI Express Root Port #8 (rev d5)
00:1d.0 USB controller: Intel Corporation C610/X99 series chipset USB Enhanced Host Controller #1 (rev 05)
00:1f.0 ISA bridge: Intel Corporation C610/X99 series chipset LPC Controller (rev 05)
00:1f.2 SATA controller: Intel Corporation C610/X99 series chipset 6-Port SATA Controller [AHCI mode] (rev 05)
00:1f.3 SMBus: Intel Corporation C610/X99 series chipset SMBus Controller (rev 05)
04:00.0 Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev 03)
05:00.0 Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev 03)
06:00.0 PCI bridge: ASPEED Technology, Inc. AST1150 PCI-to-PCI Bridge (rev 03)
07:00.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics Family (rev 30)
ff:0b.0 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 R3 QPI Link 0 & 1 Monitoring (rev 02)
ff:0b.1 Performance counters: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 R3 QPI Link 0 & 1 Monitoring (rev 02)
ff:0b.2 Performance counters: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 R3 QPI Link 0 & 1 Monitoring (rev 02)
ff:0c.0 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Unicast Registers (rev 02)
ff:0c.1 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Unicast Registers (rev 02)
ff:0c.2 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Unicast Registers (rev 02)
ff:0c.3 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Unicast Registers (rev 02)
ff:0c.4 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Unicast Registers (rev 02)
ff:0c.5 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Unicast Registers (rev 02)
ff:0c.6 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Unicast Registers (rev 02)
ff:0c.7 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Unicast Registers (rev 02)
ff:0d.0 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Unicast Registers (rev 02)
ff:0d.1 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Unicast Registers (rev 02)
ff:0d.2 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Unicast Registers (rev 02)
ff:0d.3 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Unicast Registers (rev 02)
ff:0f.0 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Buffered Ring Agent (rev 02)
ff:0f.1 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Buffered Ring Agent (rev 02)
ff:0f.2 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Buffered Ring Agent (rev 02)
ff:0f.3 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Buffered Ring Agent (rev 02)
ff:0f.4 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 System Address Decoder & Broadcast Registers (rev 02)
ff:0f.5 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 System Address Decoder & Broadcast Registers (rev 02)
ff:0f.6 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 System Address Decoder & Broadcast Registers (rev 02)
ff:10.0 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 PCIe Ring Interface (rev 02)
ff:10.1 Performance counters: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 PCIe Ring Interface (rev 02)
ff:10.5 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Scratchpad & Semaphore Registers (rev 02)
ff:10.6 Performance counters: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Scratchpad & Semaphore Registers (rev 02)
ff:10.7 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Scratchpad & Semaphore Registers (rev 02)
ff:12.0 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Home Agent 0 (rev 02)
ff:12.1 Performance counters: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Home Agent 0 (rev 02)
ff:12.4 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Home Agent 1 (rev 02)
ff:12.5 Performance counters: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Home Agent 1 (rev 02)
ff:13.0 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Integrated Memory Controller 0 Target Address, Thermal & RAS Registers (rev 02)
ff:13.1 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Integrated Memory Controller 0 Target Address, Thermal & RAS Registers (rev 02)
ff:13.2 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Integrated Memory Controller 0 Channel Target Address Decoder (rev 02)
ff:13.3 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Integrated Memory Controller 0 Channel Target Address Decoder (rev 02)
ff:13.6 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 DDRIO Channel 0/1 Broadcast (rev 02)
ff:13.7 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 DDRIO Global Broadcast (rev 02)
ff:14.0 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Integrated Memory Controller 0 Channel 0 Thermal Control (rev 02)
ff:14.1 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Integrated Memory Controller 0 Channel 1 Thermal Control (rev 02)
ff:14.2 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Integrated Memory Controller 0 Channel 0 ERROR Registers (rev 02)
ff:14.3 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Integrated Memory Controller 0 Channel 1 ERROR Registers (rev 02)
ff:14.4 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 DDRIO (VMSE) 0 & 1 (rev 02)
ff:14.5 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 DDRIO (VMSE) 0 & 1 (rev 02)
ff:14.6 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 DDRIO (VMSE) 0 & 1 (rev 02)
ff:14.7 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 DDRIO (VMSE) 0 & 1 (rev 02)
ff:16.0 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Integrated Memory Controller 1 Target Address, Thermal & RAS Registers (rev 02)
ff:16.1 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Integrated Memory Controller 1 Target Address, Thermal & RAS Registers (rev 02)
ff:16.2 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Integrated Memory Controller 1 Channel Target Address Decoder (rev 02)
ff:16.3 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Integrated Memory Controller 1 Channel Target Address Decoder (rev 02)
ff:16.6 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 DDRIO Channel 2/3 Broadcast (rev 02)
ff:16.7 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 DDRIO Global Broadcast (rev 02)
ff:17.0 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Integrated Memory Controller 1 Channel 0 Thermal Control (rev 02)
ff:17.1 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Integrated Memory Controller 1 Channel 1 Thermal Control (rev 02)
ff:17.2 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Integrated Memory Controller 1 Channel 0 ERROR Registers (rev 02)
ff:17.3 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Integrated Memory Controller 1 Channel 1 ERROR Registers (rev 02)
ff:17.4 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 DDRIO (VMSE) 2 & 3 (rev 02)
ff:17.5 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 DDRIO (VMSE) 2 & 3 (rev 02)
ff:17.6 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 DDRIO (VMSE) 2 & 3 (rev 02)
ff:17.7 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 DDRIO (VMSE) 2 & 3 (rev 02)
ff:1e.0 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Power Control Unit (rev 02)
ff:1e.1 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Power Control Unit (rev 02)
ff:1e.2 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Power Control Unit (rev 02)
ff:1e.3 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Power Control Unit (rev 02)
ff:1e.4 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 Power Control Unit (rev 02)
ff:1f.0 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 VCU (rev 02)
ff:1f.2 System peripheral: Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 VCU (rev 02)

21.1.4 PCI DMA相关的 API

内核中定义一组专门针对 PCI 设备的 DMA 操作接口,主要包括如下。

1、设置 DMA 缓冲区掩码。

int pci_set_dma_mask(struct pci_dev *dev, u64 mask);

2、一致性 DMA 缓冲区分配/释放。

void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_handle);

void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle);

3、流式 DMA 缓冲区映射/去映射。

dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t size, int direction);
int pci_map_sg(struct pci_dev *pdev,struct scatterlist *sgl,int num_entries, int direction);
void pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size, int direction);
void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, int direction);

分析:

以 pci_开头的 API 用于 PCI 设备驱动。

21.1.5 PCI 设备驱动其他常用 API

除了 DMA API 外,在 PCI 设备驱动中其他常用的函数(或宏)如下所示。

1、获取 I/O 或内存资源。

#define pci _ resource _ start(dev,bar) ((dev)!resource[(bar)].start)
#define pci _ resource _ end(dev,bar) ((dev)!resource[(bar)].end)
#define pci _ resource _ flags(dev,bar) ((dev)!resource[(bar)].flags)
#define pci _ resource _ len(dev,bar) \
((pci _ resource _ start((dev),(bar)) == 0 &&  \
pci _ resource _ end((dev),(bar)) == \
pci _ resource _ start((dev),(bar))) ? 0 : \
\
(pci _ resource _ end((dev),(bar)) - \

pci _ resource _ start((dev),(bar)) + 1))

2、申请/释放 I/O 或内存资源。

int pci_request_regions(struct pci_dev *pdev, const char *res _ name);

void pci_release_regions(struct pci_dev *pdev);

3、获取/设置驱动私有数据。

void *pci_get_drvdata (struct pci_dev *pdev);

void pci_set_drvdata (struct pci_dev *pdev, void *data);

4、使能/禁止 PCI 设备。

int pci_enable_device(struct pci_dev *dev);

void pci_disable_device(struct pci_dev *dev);

5、设置为总线主 DMA。

void pci_set_master(struct pci _ dev *dev);

6、寻找指定总线指定槽位的 PCI 设备。

struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);

7、设置 PCI 能量管理状态

int pci_set_power_state(struct pci_dev *dev, pci_power_t state);

8、在设备的能力表中找出指定的能力。

int pci_find_capability (struct pci_dev *dev, int cap);

9、启用设备内存写无效事务。

int pci_set_mwi(struct pci_dev *dev);

10、禁用设备内存写无效事务。

void pci_clear_mwi(struct pci_dev *dev);


猜你喜欢

转载自blog.csdn.net/xiezhi123456/article/details/80769028
PCI