PCI device(二)

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;       /* PCI-E capability offset */
        u8              pcie_type:4;    /* PCI-E device/port type */
        u8              pcie_mpss:3;    /* PCI-E Max Payload Size Supported */
        u8              rom_base_reg;   /* which config register controls the ROM */
        u8              pin;            /* which interrupt pin this device uses */

        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. */
        int             pm_cap;         /* PM capability offset in the
                                           configuration space */
        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    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 */

        /* These fields are used by common fixups */
        unsigned int    transparent:1;  /* Transparent 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    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    is_pcie:1;      /* Obsolete. Will be removed.
                                           Use pci_is_pcie() instead */
        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 */

        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;
        struct kset *msi_kset;
#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
};

static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
{
#ifdef CONFIG_PCI_IOV
        if (dev->is_virtfn)
                dev = dev->physfn;
#endif

        return dev;
}

 

======================================================

include/linux/ioport.h

/*
 * Resources are tree-like, allowing
 * nesting etc..
 */
struct resource {
        resource_size_t start;
        resource_size_t end;
        const char *name;
        unsigned long flags;
        struct resource *parent, *sibling, *child;
};
=========

#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))

=========

746 static inline int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val)
747 {
748         return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val);
749 }

===================================================================================

PCI Configuration Address Space

Configuration space is defined geographically. The location of a peripheral device is determined by its physical location within an interconnected tree of PCI bus bridges. A device is located by its bus number and device (slot) number. Each peripheral device contains a set of well-defined configuration registers in its PCI configuration space. The registers are used not only to identify devices but also to supply device configuration information to the configuration framework. For example, base address registers in the device configuration space must be mapped before a device can respond to data access.

The method for generating configuration cycles is host dependent. In x86 machines, special I/O ports are used. On other platforms, the PCI configuration space can be memory-mapped to certain address locations corresponding to the PCI host bridge in the host address domain. When a device configuration register is accessed by the processor, the request is routed to the PCI host bridge. The bridge then translates the access into proper configuration cycles on the bus.
PCI Configuration Base Address Registers

The PCI configuration space consists ofup to six 32-bit base address registers for each device. These registers provide both size and data type information. System firmware assigns base addresses in the PCI address domain to these registers.

Each addressable region can be either memory or I/O space. The value contained in bit 0 of the base address register identifies the type. A value of 0 in bit 0 indicates a memory space and a value of 1 indicates an I/O space. The following figure shows two base address registers: one for memory and the other for I/O types.
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值