]> xenbits.xensource.com Git - legacy/linux-2.6.18-xen.git/commitdiff
Backport: PCI: support PCIe ARI capability
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 13 Mar 2009 07:40:54 +0000 (07:40 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 13 Mar 2009 07:40:54 +0000 (07:40 +0000)
    commit 58c3a727cb73b75a9104d295f096cca12959a5a5
    Author: Yu Zhao <yu.zhao@intel.com>
    Date:   Tue Oct 14 14:02:53 2008 +0800

    PCI: support PCIe ARI capability

    This patch adds support for PCI Express Alternative Routing-ID
    Interpretation (ARI) capability.

    The ARI capability extends the Function Number field of the PCI
    Express
    Endpoint by reusing the Device Number which is otherwise hardwired
    to 0.
    With ARI, an Endpoint can have up to 256 functions.

Signed-off-by: Yu Zhao <yu.zhao@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Yu Zhao <yu.zhao@intel.com>
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/probe.c
include/linux/pci.h
include/linux/pci_regs.h

index 9f79dd6d51ab7b8b0fbe18ab77f20fd0630e81ee..3cd615dd7fc629738f06ad47ac49ae0c4a8f8f19 100644 (file)
@@ -629,6 +629,38 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable)
        return 0;
 }
 
+/**
+ * pci_enable_ari - enable ARI forwarding if hardware support it
+ * @dev: the PCI device
+ */
+void pci_enable_ari(struct pci_dev *dev)
+{
+       int pos;
+       u32 cap;
+       u16 ctrl;
+
+       if (!dev->is_pcie)
+               return;
+
+       if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
+           dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
+               return;
+
+       pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+       if (!pos)
+               return;
+
+       pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap);
+       if (!(cap & PCI_EXP_DEVCAP2_ARI))
+               return;
+
+       pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
+       ctrl |= PCI_EXP_DEVCTL2_ARI;
+       pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+
+       dev->ari_enabled = 1;
+}
+
 int
 pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
 {
index a86b8d17a16c1c6f5fa00310b0057f7099243a7f..22165f6eb2652973cf259199981e382e2eb072dc 100644 (file)
@@ -119,3 +119,14 @@ enum pci_bar_type {
 
 extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
                                struct resource *res, unsigned int reg);
+extern void pci_enable_ari(struct pci_dev *dev);
+/**
+ * pci_ari_enabled - query ARI forwarding status
+ * @dev: the PCI device
+ *
+ * Returns 1 if ARI forwarding is enabled, or 0 if not enabled;
+ */
+static inline int pci_ari_enabled(struct pci_dev *dev)
+{
+       return dev->ari_enabled;
+}
index 078bbbcd145816e53de8b5b3c4fd38ae6a4ac513..68d5ddd5f8625886a6375f191e38a95382dd61e6 100644 (file)
@@ -885,6 +885,9 @@ void __devinit pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
        /* Fix up broken headers */
        pci_fixup_device(pci_fixup_header, dev);
 
+       /* Alternative Routing-ID Forwarding */
+       pci_enable_ari(dev);
+
        /*
         * Add the device to our list of discovered devices
         * and the bus list for fixup functions, etc.
index 0690c306927d2c251c2462e7312cbff99073f142..07c45bf31e9d40a6b422a4b3c80ae79184d758fd 100644 (file)
@@ -172,6 +172,7 @@ struct pci_dev {
        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 */
+       unsigned int    ari_enabled:1;  /* ARI forwarding */
 };
 
 #define pci_dev_g(n) list_entry(n, struct pci_dev, global_list)
index 6407ff5de0472d6bc4f4ba5e648dd4733bc12324..d388b33f1dbb79c4afb34333147755dce576c664 100644 (file)
 #define  PCI_EXP_RTCTL_CRSSVE  0x10    /* CRS Software Visibility Enable */
 #define PCI_EXP_RTCAP          30      /* Root Capabilities */
 #define PCI_EXP_RTSTA          32      /* Root Status */
+#define PCI_EXP_DEVCAP2                36      /* Device Capabilities 2 */
+#define  PCI_EXP_DEVCAP2_ARI   0x20    /* Alternative Routing-ID */
+#define PCI_EXP_DEVCTL2                40      /* Device Control 2 */
+#define  PCI_EXP_DEVCTL2_ARI   0x20    /* Alternative Routing-ID */
 
 /* Extended Capabilities (PCI-X 2.0 and Express) */
 #define PCI_EXT_CAP_ID(header)         (header & 0x0000ffff)
 #define PCI_EXT_CAP_ID_VC      2
 #define PCI_EXT_CAP_ID_DSN     3
 #define PCI_EXT_CAP_ID_PWR     4
+#define PCI_EXT_CAP_ID_ARI     14
 
 /* Advanced Error Reporting */
 #define PCI_ERR_UNCOR_STATUS   4       /* Uncorrectable Error Status */
 #define PCI_PWR_CAP            12      /* Capability */
 #define  PCI_PWR_CAP_BUDGET(x) ((x) & 1)       /* Included in system budget */
 
+/* Alternative Routing-ID Interpretation */
+#define PCI_ARI_CAP            0x04    /* ARI Capability Register */
+#define  PCI_ARI_CAP_MFVC      0x0001  /* MFVC Function Groups Capability */
+#define  PCI_ARI_CAP_ACS       0x0002  /* ACS Function Groups Capability */
+#define  PCI_ARI_CAP_NFN(x)    (((x) >> 8) & 0xff) /* Next Function Number */
+#define PCI_ARI_CTRL           0x06    /* ARI Control Register */
+#define  PCI_ARI_CTRL_MFVC     0x0001  /* MFVC Function Groups Enable */
+#define  PCI_ARI_CTRL_ACS      0x0002  /* ACS Function Groups Enable */
+#define  PCI_ARI_CTRL_FG(x)    (((x) >> 4) & 7) /* Function Group */
+
 #endif /* LINUX_PCI_REGS_H */