diff options
Diffstat (limited to 'drivers')
41 files changed, 417 insertions, 293 deletions
diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index e3d4b059fcd1..e347e7acd8ed 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -22,6 +22,7 @@ #include <linux/scatterlist.h> #include <linux/of.h> #include <linux/gfp.h> +#include <linux/pci.h> #include <scsi/scsi.h> #include <scsi/scsi_host.h> @@ -30,7 +31,6 @@ #include <asm/macio.h> #include <asm/io.h> #include <asm/dbdma.h> -#include <asm/pci-bridge.h> #include <asm/machdep.h> #include <asm/pmac_feature.h> #include <asm/mediabay.h> diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index 05755441250c..fdced547ad59 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -10,7 +10,6 @@ #include <linux/delay.h> #include <linux/vmalloc.h> #include <asm/uninorth.h> -#include <asm/pci-bridge.h> #include <asm/prom.h> #include <asm/pmac_feature.h> #include "agp.h" diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c index 7f1a3604b19f..b332b4d3b0e2 100644 --- a/drivers/gpu/drm/bochs/bochs_drv.c +++ b/drivers/gpu/drm/bochs/bochs_drv.c @@ -182,8 +182,8 @@ static const struct pci_device_id bochs_pci_tbl[] = { { .vendor = 0x1234, .device = 0x1111, - .subvendor = 0x1af4, - .subdevice = 0x1100, + .subvendor = PCI_SUBVENDOR_ID_REDHAT_QUMRANET, + .subdevice = PCI_SUBDEVICE_ID_QEMU, .driver_data = BOCHS_QEMU_STDVGA, }, { diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c index b1619e29a564..7bc394ec9fb3 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.c +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c @@ -33,8 +33,9 @@ static struct drm_driver driver; /* only bind to the cirrus chip in qemu */ static const struct pci_device_id pciidlist[] = { - { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, 0x1af4, 0x1100, 0, - 0, 0 }, + { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, + PCI_SUBVENDOR_ID_REDHAT_QUMRANET, PCI_SUBDEVICE_ID_QEMU, + 0, 0, 0 }, { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, PCI_VENDOR_ID_XEN, 0x0001, 0, 0, 0 }, {0,} diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index a9b01bcf7d0a..432480ff9d22 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -34,7 +34,6 @@ #include <asm/machdep.h> #include <asm/pmac_feature.h> #include <asm/prom.h> -#include <asm/pci-bridge.h> #endif /* CONFIG_PPC_PMAC */ /* from radeon_legacy_encoder.c */ diff --git a/drivers/ide/pdc202xx_new.c b/drivers/ide/pdc202xx_new.c index 9ad014a7afc7..b33646be699c 100644 --- a/drivers/ide/pdc202xx_new.c +++ b/drivers/ide/pdc202xx_new.c @@ -28,7 +28,6 @@ #ifdef CONFIG_PPC_PMAC #include <asm/prom.h> -#include <asm/pci-bridge.h> #endif #define DRV_NAME "pdc202xx_new" diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c index 96a345248224..7f0434f7e486 100644 --- a/drivers/ide/pmac.c +++ b/drivers/ide/pmac.c @@ -40,7 +40,6 @@ #include <asm/io.h> #include <asm/dbdma.h> #include <asm/ide.h> -#include <asm/pci-bridge.h> #include <asm/machdep.h> #include <asm/pmac_feature.h> #include <asm/sections.h> diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 4f12c6f01fe7..b6819f0fc608 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -31,7 +31,6 @@ #include <asm/macio.h> #include <asm/pmac_feature.h> #include <asm/prom.h> -#include <asm/pci-bridge.h> #undef DEBUG diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index 4c1903f781fc..a21403238a4a 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c @@ -19,7 +19,6 @@ #include <linux/delay.h> #include <asm/opal.h> #include <asm/msi_bitmap.h> -#include <asm/pci-bridge.h> /* for struct pci_controller */ #include <asm/pnv-pci.h> #include <asm/io.h> diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c index e23a642357e7..2437227712dc 100644 --- a/drivers/net/ethernet/sun/sungem.c +++ b/drivers/net/ethernet/sun/sungem.c @@ -51,7 +51,6 @@ #endif #ifdef CONFIG_PPC_PMAC -#include <asm/pci-bridge.h> #include <asm/prom.h> #include <asm/machdep.h> #include <asm/pmac_feature.h> diff --git a/drivers/net/ethernet/toshiba/spider_net.c b/drivers/net/ethernet/toshiba/spider_net.c index 3c54a2cae5df..67610270d171 100644 --- a/drivers/net/ethernet/toshiba/spider_net.c +++ b/drivers/net/ethernet/toshiba/spider_net.c @@ -48,7 +48,6 @@ #include <linux/wait.h> #include <linux/workqueue.h> #include <linux/bitops.h> -#include <asm/pci-bridge.h> #include <net/checksum.h> #include "spider_net.h" diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c index b1449f71601c..13f4fed38048 100644 --- a/drivers/of/of_pci.c +++ b/drivers/of/of_pci.c @@ -5,7 +5,6 @@ #include <linux/of_device.h> #include <linux/of_pci.h> #include <linux/slab.h> -#include <asm-generic/pci-bridge.h> static inline int __of_pci_pci_compare(struct device_node *node, unsigned int data) diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 8c05b5ceeaec..01b9d0a00abc 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -174,38 +174,6 @@ struct pci_ops *pci_bus_set_ops(struct pci_bus *bus, struct pci_ops *ops) } EXPORT_SYMBOL(pci_bus_set_ops); -/** - * pci_read_vpd - Read one entry from Vital Product Data - * @dev: pci device struct - * @pos: offset in vpd space - * @count: number of bytes to read - * @buf: pointer to where to store result - * - */ -ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf) -{ - if (!dev->vpd || !dev->vpd->ops) - return -ENODEV; - return dev->vpd->ops->read(dev, pos, count, buf); -} -EXPORT_SYMBOL(pci_read_vpd); - -/** - * pci_write_vpd - Write entry to Vital Product Data - * @dev: pci device struct - * @pos: offset in vpd space - * @count: number of bytes to write - * @buf: buffer containing write data - * - */ -ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf) -{ - if (!dev->vpd || !dev->vpd->ops) - return -ENODEV; - return dev->vpd->ops->write(dev, pos, count, buf); -} -EXPORT_SYMBOL(pci_write_vpd); - /* * The following routines are to prevent the user from accessing PCI config * space when it's unsafe to do so. Some devices require this during BIST and @@ -277,15 +245,91 @@ PCI_USER_WRITE_CONFIG(dword, u32) /* VPD access through PCI 2.2+ VPD capability */ -#define PCI_VPD_PCI22_SIZE (PCI_VPD_ADDR_MASK + 1) +/** + * pci_read_vpd - Read one entry from Vital Product Data + * @dev: pci device struct + * @pos: offset in vpd space + * @count: number of bytes to read + * @buf: pointer to where to store result + */ +ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf) +{ + if (!dev->vpd || !dev->vpd->ops) + return -ENODEV; + return dev->vpd->ops->read(dev, pos, count, buf); +} +EXPORT_SYMBOL(pci_read_vpd); -struct pci_vpd_pci22 { - struct pci_vpd base; - struct mutex lock; - u16 flag; - bool busy; - u8 cap; -}; +/** + * pci_write_vpd - Write entry to Vital Product Data + * @dev: pci device struct + * @pos: offset in vpd space + * @count: number of bytes to write + * @buf: buffer containing write data + */ +ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf) +{ + if (!dev->vpd || !dev->vpd->ops) + return -ENODEV; + return dev->vpd->ops->write(dev, pos, count, buf); +} +EXPORT_SYMBOL(pci_write_vpd); + +#define PCI_VPD_MAX_SIZE (PCI_VPD_ADDR_MASK + 1) + +/** + * pci_vpd_size - determine actual size of Vital Product Data + * @dev: pci device struct + * @old_size: current assumed size, also maximum allowed size + */ +static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size) +{ + size_t off = 0; + unsigned char header[1+2]; /* 1 byte tag, 2 bytes length */ + + while (off < old_size && + pci_read_vpd(dev, off, 1, header) == 1) { + unsigned char tag; + + if (header[0] & PCI_VPD_LRDT) { + /* Large Resource Data Type Tag */ + tag = pci_vpd_lrdt_tag(header); + /* Only read length from known tag items */ + if ((tag == PCI_VPD_LTIN_ID_STRING) || + (tag == PCI_VPD_LTIN_RO_DATA) || + (tag == PCI_VPD_LTIN_RW_DATA)) { + if (pci_read_vpd(dev, off+1, 2, + &header[1]) != 2) { + dev_warn(&dev->dev, + "invalid large VPD tag %02x size at offset %zu", + tag, off + 1); + return 0; + } + off += PCI_VPD_LRDT_TAG_SIZE + + pci_vpd_lrdt_size(header); + } + } else { + /* Short Resource Data Type Tag */ + off += PCI_VPD_SRDT_TAG_SIZE + + pci_vpd_srdt_size(header); + tag = pci_vpd_srdt_tag(header); + } + + if (tag == PCI_VPD_STIN_END) /* End tag descriptor */ + return off; + + if ((tag != PCI_VPD_LTIN_ID_STRING) && + (tag != PCI_VPD_LTIN_RO_DATA) && + (tag != PCI_VPD_LTIN_RW_DATA)) { + dev_warn(&dev->dev, + "invalid %s VPD tag %02x at offset %zu", + (header[0] & PCI_VPD_LRDT) ? "large" : "short", + tag, off); + return 0; + } + } + return 0; +} /* * Wait for last operation to complete. @@ -295,55 +339,71 @@ struct pci_vpd_pci22 { * * Returns 0 on success, negative values indicate error. */ -static int pci_vpd_pci22_wait(struct pci_dev *dev) +static int pci_vpd_wait(struct pci_dev *dev) { - struct pci_vpd_pci22 *vpd = - container_of(dev->vpd, struct pci_vpd_pci22, base); - unsigned long timeout = jiffies + HZ/20 + 2; + struct pci_vpd *vpd = dev->vpd; + unsigned long timeout = jiffies + msecs_to_jiffies(50); + unsigned long max_sleep = 16; u16 status; int ret; if (!vpd->busy) return 0; - for (;;) { + while (time_before(jiffies, timeout)) { ret = pci_user_read_config_word(dev, vpd->cap + PCI_VPD_ADDR, &status); if (ret < 0) return ret; if ((status & PCI_VPD_ADDR_F) == vpd->flag) { - vpd->busy = false; + vpd->busy = 0; return 0; } - if (time_after(jiffies, timeout)) { - dev_printk(KERN_DEBUG, &dev->dev, "vpd r/w failed. This is likely a firmware bug on this device. Contact the card vendor for a firmware update\n"); - return -ETIMEDOUT; - } if (fatal_signal_pending(current)) return -EINTR; - if (!cond_resched()) - udelay(10); + + usleep_range(10, max_sleep); + if (max_sleep < 1024) + max_sleep *= 2; } + + dev_warn(&dev->dev, "VPD access failed. This is likely a firmware bug on this device. Contact the card vendor for a firmware update\n"); + return -ETIMEDOUT; } -static ssize_t pci_vpd_pci22_read(struct pci_dev *dev, loff_t pos, size_t count, - void *arg) +static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count, + void *arg) { - struct pci_vpd_pci22 *vpd = - container_of(dev->vpd, struct pci_vpd_pci22, base); + struct pci_vpd *vpd = dev->vpd; int ret; loff_t end = pos + count; u8 *buf = arg; - if (pos < 0 || pos > vpd->base.len || end > vpd->base.len) + if (pos < 0) return -EINVAL; + if (!vpd->valid) { + vpd->valid = 1; + vpd->len = pci_vpd_size(dev, vpd->len); + } + + if (vpd->len == 0) + return -EIO; + + if (pos > vpd->len) + return 0; + + if (end > vpd->len) { + end = vpd->len; + count = end - pos; + } + if (mutex_lock_killable(&vpd->lock)) return -EINTR; - ret = pci_vpd_pci22_wait(dev); + ret = pci_vpd_wait(dev); if (ret < 0) goto out; @@ -355,9 +415,9 @@ static ssize_t pci_vpd_pci22_read(struct pci_dev *dev, loff_t pos, size_t count, pos & ~3); if (ret < 0) break; - vpd->busy = true; + vpd->busy = 1; vpd->flag = PCI_VPD_ADDR_F; - ret = pci_vpd_pci22_wait(dev); + ret = pci_vpd_wait(dev); if (ret < 0) break; @@ -380,22 +440,32 @@ out: return ret ? ret : count; } -static ssize_t pci_vpd_pci22_write(struct pci_dev *dev, loff_t pos, size_t count, - const void *arg) +static ssize_t pci_vpd_write(struct pci_dev *dev, loff_t pos, size_t count, + const void *arg) { - struct pci_vpd_pci22 *vpd = - container_of(dev->vpd, struct pci_vpd_pci22, base); + struct pci_vpd *vpd = dev->vpd; const u8 *buf = arg; loff_t end = pos + count; int ret = 0; - if (pos < 0 || (pos & 3) || (count & 3) || end > vpd->base.len) + if (pos < 0 || (pos & 3) || (count & 3)) + return -EINVAL; + + if (!vpd->valid) { + vpd->valid = 1; + vpd->len = pci_vpd_size(dev, vpd->len); + } + + if (vpd->len == 0) + return -EIO; + + if (end > vpd->len) return -EINVAL; if (mutex_lock_killable(&vpd->lock)) return -EINTR; - ret = pci_vpd_pci22_wait(dev); + ret = pci_vpd_wait(dev); if (ret < 0) goto out; @@ -415,9 +485,9 @@ static ssize_t pci_vpd_pci22_write(struct pci_dev *dev, loff_t pos, size_t count if (ret < 0) break; - vpd->busy = true; + vpd->busy = 1; vpd->flag = 0; - ret = pci_vpd_pci22_wait(dev); + ret = pci_vpd_wait(dev); if (ret < 0) break; @@ -428,15 +498,9 @@ out: return ret ? ret : count; } -static void pci_vpd_pci22_release(struct pci_dev *dev) -{ - kfree(container_of(dev->vpd, struct pci_vpd_pci22, base)); -} - -static const struct pci_vpd_ops pci_vpd_pci22_ops = { - .read = pci_vpd_pci22_read, - .write = pci_vpd_pci22_write, - .release = pci_vpd_pci22_release, +static const struct pci_vpd_ops pci_vpd_ops = { + .read = pci_vpd_read, + .write = pci_vpd_write, }; static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count, @@ -472,12 +536,11 @@ static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count, static const struct pci_vpd_ops pci_vpd_f0_ops = { .read = pci_vpd_f0_read, .write = pci_vpd_f0_write, - .release = pci_vpd_pci22_release, }; -int pci_vpd_pci22_init(struct pci_dev *dev) +int pci_vpd_init(struct pci_dev *dev) { - struct pci_vpd_pci22 *vpd; + struct pci_vpd *vpd; u8 cap; cap = pci_find_capability(dev, PCI_CAP_ID_VPD); @@ -488,18 +551,24 @@ int pci_vpd_pci22_init(struct pci_dev *dev) if (!vpd) return -ENOMEM; - vpd->base.len = PCI_VPD_PCI22_SIZE; + vpd->len = PCI_VPD_MAX_SIZE; if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) - vpd->base.ops = &pci_vpd_f0_ops; + vpd->ops = &pci_vpd_f0_ops; else - vpd->base.ops = &pci_vpd_pci22_ops; + vpd->ops = &pci_vpd_ops; mutex_init(&vpd->lock); vpd->cap = cap; - vpd->busy = false; - dev->vpd = &vpd->base; + vpd->busy = 0; + vpd->valid = 0; + dev->vpd = vpd; return 0; } +void pci_vpd_release(struct pci_dev *dev) +{ + kfree(dev->vpd); +} + /** * pci_cfg_access_lock - Lock PCI config reads/writes * @dev: pci device struct diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 89b3befc7155..f2187d491475 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -291,7 +291,12 @@ void pci_bus_add_device(struct pci_dev *dev) dev->match_driver = true; retval = device_attach(&dev->dev); - WARN_ON(retval < 0); + if (retval < 0) { + dev_warn(&dev->dev, "device attach failed (%d)\n", retval); + pci_proc_detach_device(dev); + pci_remove_sysfs_dev_files(dev); + return; + } dev->is_added = 1; } diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index fe600964fa50..bd3f7d0ef943 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -202,6 +202,23 @@ static int pcie_phy_write(void __iomem *dbi_base, int addr, int data) return 0; } +static void imx6_pcie_reset_phy(struct pcie_port *pp) +{ + u32 tmp; + + pcie_phy_read(pp->dbi_base, PHY_RX_OVRD_IN_LO, &tmp); + tmp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN | + PHY_RX_OVRD_IN_LO_RX_PLL_EN); + pcie_phy_write(pp->dbi_base, PHY_RX_OVRD_IN_LO, tmp); + + usleep_range(2000, 3000); + + pcie_phy_read(pp->dbi_base, PHY_RX_OVRD_IN_LO, &tmp); + tmp &= ~(PHY_RX_OVRD_IN_LO_RX_DATA_EN | + PHY_RX_OVRD_IN_LO_RX_PLL_EN); + pcie_phy_write(pp->dbi_base, PHY_RX_OVRD_IN_LO, tmp); +} + /* Added for PCI abort handling */ static int imx6q_pcie_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) @@ -332,16 +349,30 @@ static int imx6_pcie_wait_for_link(struct pcie_port *pp) { unsigned int retries; + /* + * Test if the PHY reports that the link is up and also that the LTSSM + * training finished. There are three possible states of the link when + * this code is called: + * 1) The link is DOWN (unlikely) + * The link didn't come up yet for some reason. This usually means + * we have a real problem somewhere, if it happens with a peripheral + * connected. This state calls for inspection of the DEBUG registers. + * 2) The link is UP, but still in LTSSM training + * Wait for the training to finish, which should take a very short + * time. If the training does not finish, we have a problem and we + * need to inspect the DEBUG registers. If the training does finish, + * the link is up and operating correctly. + * 3) The link is UP and no longer in LTSSM training + * The link is up and operating correctly. + */ for (retries = 0; retries < 200; retries++) { - if (dw_pcie_link_up(pp)) + u32 reg = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1); + if ((reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP) && + !(reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING)) return 0; - usleep_range(100, 1000); + usleep_range(1000, 2000); } - dev_err(pp->dev, "phy link never came up\n"); - dev_dbg(pp->dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n", - readl(pp->dbi_base + PCIE_PHY_DEBUG_R0), - readl(pp->dbi_base + PCIE_PHY_DEBUG_R1)); return -EINVAL; } @@ -390,8 +421,10 @@ static int imx6_pcie_establish_link(struct pcie_port *pp) IMX6Q_GPR12_PCIE_CTL_2, 1 << 10); ret = imx6_pcie_wait_for_link(pp); - if (ret) - return ret; + if (ret) { + dev_info(pp->dev, "Link never came up\n"); + goto err_reset_phy; + } /* Allow Gen2 mode after the link is up. */ tmp = readl(pp->dbi_base + PCIE_RC_LCR); @@ -410,19 +443,28 @@ static int imx6_pcie_establish_link(struct pcie_port *pp) ret = imx6_pcie_wait_for_speed_change(pp); if (ret) { dev_err(pp->dev, "Failed to bring link up!\n"); - return ret; + goto err_reset_phy; } /* Make sure link training is finished as well! */ ret = imx6_pcie_wait_for_link(pp); if (ret) { dev_err(pp->dev, "Failed to bring link up!\n"); - return ret; + goto err_reset_phy; } tmp = readl(pp->dbi_base + PCIE_RC_LCSR); dev_dbg(pp->dev, "Link up, Gen=%i\n", (tmp >> 16) & 0xf); + return 0; + +err_reset_phy: + dev_dbg(pp->dev, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n", + readl(pp->dbi_base + PCIE_PHY_DEBUG_R0), + readl(pp->dbi_base + PCIE_PHY_DEBUG_R1)); + imx6_pcie_reset_phy(pp); + + return ret; } static void imx6_pcie_host_init(struct pcie_port *pp) @@ -441,81 +483,10 @@ static void imx6_pcie_host_init(struct pcie_port *pp) dw_pcie_msi_init(pp); } -static void imx6_pcie_reset_phy(struct pcie_port *pp) -{ - u32 tmp; - - pcie_phy_read(pp->dbi_base, PHY_RX_OVRD_IN_LO, &tmp); - tmp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN | - PHY_RX_OVRD_IN_LO_RX_PLL_EN); - pcie_phy_write(pp->dbi_base, PHY_RX_OVRD_IN_LO, tmp); - - usleep_range(2000, 3000); - - pcie_phy_read(pp->dbi_base, PHY_RX_OVRD_IN_LO, &tmp); - tmp &= ~(PHY_RX_OVRD_IN_LO_RX_DATA_EN | - PHY_RX_OVRD_IN_LO_RX_PLL_EN); - pcie_phy_write(pp->dbi_base, PHY_RX_OVRD_IN_LO, tmp); -} - static int imx6_pcie_link_up(struct pcie_port *pp) { - u32 rc, debug_r0, rx_valid; - int count = 5; - - /* - * Test if the PHY reports that the link is up and also that the LTSSM - * training finished. There are three possible states of the link when - * this code is called: - * 1) The link is DOWN (unlikely) - * The link didn't come up yet for some reason. This usually means - * we have a real problem somewhere. Reset the PHY and exit. This - * state calls for inspection of the DEBUG registers. - * 2) The link is UP, but still in LTSSM training - * Wait for the training to finish, which should take a very short - * time. If the training does not finish, we have a problem and we - * need to inspect the DEBUG registers. If the training does finish, - * the link is up and operating correctly. - * 3) The link is UP and no longer in LTSSM training - * The link is up and operating correctly. - */ - while (1) { - rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1); - if (!(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP)) - break; - if (!(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING)) - return 1; - if (!count--) - break; - dev_dbg(pp->dev, "Link is up, but still in training\n"); - /* - * Wait a little bit, then re-check if the link finished - * the training. - */ - usleep_range(1000, 2000); - } - /* - * From L0, initiate MAC entry to gen2 if EP/RC supports gen2. - * Wait 2ms (LTSSM timeout is 24ms, PHY lock is ~5us in gen2). - * If (MAC/LTSSM.state == Recovery.RcvrLock) - * && (PHY/rx_valid==0) then pulse PHY/rx_reset. Transition - * to gen2 is stuck - */ - pcie_phy_read(pp->dbi_base, PCIE_PHY_RX_ASIC_OUT, &rx_valid); - debug_r0 = readl(pp->dbi_base + PCIE_PHY_DEBUG_R0); - - if (rx_valid & PCIE_PHY_RX_ASIC_OUT_VALID) - return 0; - - if ((debug_r0 & 0x3f) != 0x0d) - return 0; - - dev_err(pp->dev, "transition to gen2 is stuck, reset PHY!\n"); - dev_dbg(pp->dev, "debug_r0=%08x debug_r1=%08x\n", debug_r0, rc); - - imx6_pcie_reset_phy(pp); - - return 0; + return readl(pp->dbi_base + PCIE_PHY_DEBUG_R1) & + PCIE_PHY_DEBUG_R1_XMLH_LINK_UP; } static struct pcie_host_ops imx6_pcie_host_ops = { diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c index 3923bed93c7e..c40d8b2ce330 100644 --- a/drivers/pci/host/pci-layerscape.c +++ b/drivers/pci/host/pci-layerscape.c @@ -203,6 +203,7 @@ static const struct of_device_id ls_pcie_of_match[] = { { .compatible = "fsl,ls1021a-pcie", .data = &ls1021_drvdata }, { .compatible = "fsl,ls1043a-pcie", .data = &ls1043_drvdata }, { .compatible = "fsl,ls2080a-pcie", .data = &ls2080_drvdata }, + { .compatible = "fsl,ls2085a-pcie", .data = &ls2080_drvdata }, { }, }; MODULE_DEVICE_TABLE(of, ls_pcie_of_match); diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 21716827847a..f85f10d22049 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -517,6 +517,11 @@ int dw_pcie_host_init(struct pcie_port *pp) if (pp->ops->host_init) pp->ops->host_init(pp); + /* + * If the platform provides ->rd_other_conf, it means the platform + * uses its own address translation component rather than ATU, so + * we should not program the ATU here. + */ if (!pp->ops->rd_other_conf) dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, PCIE_ATU_TYPE_MEM, pp->mem_base, @@ -551,13 +556,11 @@ int dw_pcie_host_init(struct pcie_port *pp) pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); #endif - if (!pci_has_flag(PCI_PROBE_ONLY)) { - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); - list_for_each_entry(child, &bus->children, node) - pcie_bus_configure_settings(child); - } + list_for_each_entry(child, &bus->children, node) + pcie_bus_configure_settings(child); pci_bus_add_devices(bus); return 0; diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 4edb5181f4e2..35092188039b 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c @@ -390,9 +390,7 @@ static int rcar_pcie_enable(struct rcar_pcie *pcie) rcar_pcie_setup(&res, pcie); - /* Do not reassign resources if probe only */ - if (!pci_has_flag(PCI_PROBE_ONLY)) - pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS); + pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS); if (IS_ENABLED(CONFIG_PCI_MSI)) bus = pci_scan_root_bus_msi(pcie->dev, pcie->root_bus_nr, @@ -408,13 +406,11 @@ static int rcar_pcie_enable(struct rcar_pcie *pcie) pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); - if (!pci_has_flag(PCI_PROBE_ONLY)) { - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); - list_for_each_entry(child, &bus->children, node) - pcie_bus_configure_settings(child); - } + list_for_each_entry(child, &bus->children, node) + pcie_bus_configure_settings(child); pci_bus_add_devices(bus); diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 31f31d460fc9..fe4bd0aa91a6 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -387,10 +387,6 @@ static int sriov_init(struct pci_dev *dev, int pos) struct resource *res; struct pci_dev *pdev; - if (pci_pcie_type(dev) != PCI_EXP_TYPE_RC_END && - pci_pcie_type(dev) != PCI_EXP_TYPE_ENDPOINT) - return -ENODEV; - pci_read_config_word(dev, pos + PCI_SRIOV_CTRL, &ctrl); if (ctrl & PCI_SRIOV_CTRL_VFE) { pci_write_config_word(dev, pos + PCI_SRIOV_CTRL, 0); diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c index 0ae74d96ed85..51357377efbc 100644 --- a/drivers/pci/pci-label.c +++ b/drivers/pci/pci-label.c @@ -16,7 +16,7 @@ * the instance number and string from the type 41 record and exports * it to sysfs. * - * Please see http://linux.dell.com/wiki/index.php/Oss/libnetdevname for more + * Please see http://linux.dell.com/files/biosdevname/ for more * information. */ diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 95d9e7bd933b..ed39c093aa15 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -769,10 +769,12 @@ static ssize_t read_vpd_attr(struct file *filp, struct kobject *kobj, { struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj)); - if (off > bin_attr->size) - count = 0; - else if (count > bin_attr->size - off) - count = bin_attr->size - off; + if (bin_attr->size > 0) { + if (off > bin_attr->size) + count = 0; + else if (count > bin_attr->size - off) + count = bin_attr->size - off; + } return pci_read_vpd(dev, off, count, buf); } @@ -783,10 +785,12 @@ static ssize_t write_vpd_attr(struct file *filp, struct kobject *kobj, { struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj)); - if (off > bin_attr->size) - count = 0; - else if (count > bin_attr->size - off) - count = bin_attr->size - off; + if (bin_attr->size > 0) { + if (off > bin_attr->size) + count = 0; + else if (count > bin_attr->size - off) + count = bin_attr->size - off; + } return pci_write_vpd(dev, off, count, buf); } @@ -1319,7 +1323,7 @@ static int pci_create_capabilities_sysfs(struct pci_dev *dev) return -ENOMEM; sysfs_bin_attr_init(attr); - attr->size = dev->vpd->len; + attr->size = 0; attr->attr.name = "vpd"; attr->attr.mode = S_IRUSR | S_IWUSR; attr->read = read_vpd_attr; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 602eb4223510..eaf4ffc0c273 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -25,7 +25,6 @@ #include <linux/device.h> #include <linux/pm_runtime.h> #include <linux/pci_hotplug.h> -#include <asm-generic/pci-bridge.h> #include <asm/setup.h> #include <linux/aer.h> #include "pci.h" @@ -3386,18 +3385,6 @@ bool pci_check_and_unmask_intx(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(pci_check_and_unmask_intx); -int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size) -{ - return dma_set_max_seg_size(&dev->dev, size); -} -EXPORT_SYMBOL(pci_set_dma_max_seg_size); - -int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask) -{ - return dma_set_seg_boundary(&dev->dev, mask); -} -EXPORT_SYMBOL(pci_set_dma_seg_boundary); - /** * pci_wait_for_pending_transaction - waits for pending transaction * @dev: the PCI device to operate on @@ -3414,6 +3401,29 @@ int pci_wait_for_pending_transaction(struct pci_dev *dev) } EXPORT_SYMBOL(pci_wait_for_pending_transaction); +/* + * We should only need to wait 100ms after FLR, but some devices take longer. + * Wait for up to 1000ms for config space to return something other than -1. + * Intel IGD requires this when an LCD panel is attached. We read the 2nd + * dword because VFs don't implement the 1st dword. + */ +static void pci_flr_wait(struct pci_dev *dev) +{ + int i = 0; + u32 id; + + do { + msleep(100); + pci_read_config_dword(dev, PCI_COMMAND, &id); + } while (i++ < 10 && id == ~0); + + if (id == ~0) + dev_warn(&dev->dev, "Failed to return from FLR\n"); + else if (i > 1) + dev_info(&dev->dev, "Required additional %dms to return from FLR\n", + (i - 1) * 100); +} + static int pcie_flr(struct pci_dev *dev, int probe) { u32 cap; @@ -3429,7 +3439,7 @@ static int pcie_flr(struct pci_dev *dev, int probe) dev_err(&dev->dev, "timed out waiting for pending transaction; performing function level reset anyway\n"); pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR); - msleep(100); + pci_flr_wait(dev); return 0; } @@ -3459,7 +3469,7 @@ static int pci_af_flr(struct pci_dev *dev, int probe) dev_err(&dev->dev, "timed out waiting for pending transaction; performing AF function level reset anyway\n"); pci_write_config_byte(dev, pos + PCI_AF_CTRL, PCI_AF_CTRL_FLR); - msleep(100); + pci_flr_wait(dev); return 0; } diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 9a1660f592ef..d0fb93481573 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -97,21 +97,21 @@ static inline bool pci_has_subordinate(struct pci_dev *pci_dev) struct pci_vpd_ops { ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf); ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf); - void (*release)(struct pci_dev *dev); }; struct pci_vpd { - unsigned int len; const struct pci_vpd_ops *ops; struct bin_attribute *attr; /* descriptor for sysfs VPD entry */ + struct mutex lock; + unsigned int len; + u16 flag; + u8 cap; + u8 busy:1; + u8 valid:1; }; -int pci_vpd_pci22_init(struct pci_dev *dev); -static inline void pci_vpd_release(struct pci_dev *dev) -{ - if (dev->vpd) - dev->vpd->ops->release(dev); -} +int pci_vpd_init(struct pci_dev *dev); +void pci_vpd_release(struct pci_dev *dev); /* PCI /proc functions */ #ifdef CONFIG_PROC_FS diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 20db790465dd..db553dc22c8e 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c @@ -25,6 +25,7 @@ #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/stddef.h> +#include <linux/device.h> #include "aerdrv.h" /* Override the existing corrected and uncorrected error masks */ @@ -124,16 +125,13 @@ static struct pci_ops *__find_pci_bus_ops(struct pci_bus *bus) static struct pci_bus_ops *pci_bus_ops_pop(void) { unsigned long flags; - struct pci_bus_ops *bus_ops = NULL; + struct pci_bus_ops *bus_ops; spin_lock_irqsave(&inject_lock, flags); - if (list_empty(&pci_bus_ops_list)) - bus_ops = NULL; - else { - struct list_head *lh = pci_bus_ops_list.next; - list_del(lh); - bus_ops = list_entry(lh, struct pci_bus_ops, list); - } + bus_ops = list_first_entry_or_null(&pci_bus_ops_list, + struct pci_bus_ops, list); + if (bus_ops) + list_del(&bus_ops->list); spin_unlock_irqrestore(&inject_lock, flags); return bus_ops; } @@ -181,14 +179,16 @@ static u32 *find_pci_config_dword(struct aer_error *err, int where, return target; } -static int pci_read_aer(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 *val) +static int aer_inj_read_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) { u32 *sim; struct aer_error *err; unsigned long flags; struct pci_ops *ops; + struct pci_ops *my_ops; int domain; + int rv; spin_lock_irqsave(&inject_lock, flags); if (size != sizeof(u32)) @@ -208,19 +208,32 @@ static int pci_read_aer(struct pci_bus *bus, unsigned int devfn, int where, } out: ops = __find_pci_bus_ops(bus); + /* + * pci_lock must already be held, so we can directly + * manipulate bus->ops. Many config access functions, + * including pci_generic_config_read() require the original + * bus->ops be installed to function, so temporarily put them + * back. + */ + my_ops = bus->ops; + bus->ops = ops; + rv = ops->read(bus, devfn, where, size, val); + bus->ops = my_ops; spin_unlock_irqrestore(&inject_lock, flags); - return ops->read(bus, devfn, where, size, val); + return rv; } -static int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 val) +static int aer_inj_write_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) { u32 *sim; struct aer_error *err; unsigned long flags; int rw1cs; struct pci_ops *ops; + struct pci_ops *my_ops; int domain; + int rv; spin_lock_irqsave(&inject_lock, flags); if (size != sizeof(u32)) @@ -243,13 +256,24 @@ static int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, } out: ops = __find_pci_bus_ops(bus); + /* + * pci_lock must already be held, so we can directly + * manipulate bus->ops. Many config access functions, + * including pci_generic_config_write() require the original + * bus->ops be installed to function, so temporarily put them + * back. + */ + my_ops = bus->ops; + bus->ops = ops; + rv = ops->write(bus, devfn, where, size, val); + bus->ops = my_ops; spin_unlock_irqrestore(&inject_lock, flags); - return ops->write(bus, devfn, where, size, val); + return rv; } -static struct pci_ops pci_ops_aer = { - .read = pci_read_aer, - .write = pci_write_aer, +static struct pci_ops aer_inj_pci_ops = { + .read = aer_inj_read_config, + .write = aer_inj_write_config, }; static void pci_bus_ops_init(struct pci_bus_ops *bus_ops, @@ -270,9 +294,9 @@ static int pci_bus_set_aer_ops(struct pci_bus *bus) bus_ops = kmalloc(sizeof(*bus_ops), GFP_KERNEL); if (!bus_ops) return -ENOMEM; - ops = pci_bus_set_ops(bus, &pci_ops_aer); + ops = pci_bus_set_ops(bus, &aer_inj_pci_ops); spin_lock_irqsave(&inject_lock, flags); - if (ops == &pci_ops_aer) + if (ops == &aer_inj_pci_ops) goto out; pci_bus_ops_init(bus_ops, bus, ops); list_add(&bus_ops->list, &pci_bus_ops_list); @@ -334,13 +358,15 @@ static int aer_inject(struct aer_error_inj *einj) return -ENODEV; rpdev = pcie_find_root_port(dev); if (!rpdev) { + dev_err(&dev->dev, "aer_inject: Root port not found\n"); ret = -ENODEV; goto out_put; } pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); if (!pos_cap_err) { - ret = -EPERM; + dev_err(&dev->dev, "aer_inject: Device doesn't support AER\n"); + ret = -EPROTONOSUPPORT; goto out_put; } pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); @@ -350,7 +376,9 @@ static int aer_inject(struct aer_error_inj *einj) rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); if (!rp_pos_cap_err) { - ret = -EPERM; + dev_err(&rpdev->dev, + "aer_inject: Root port doesn't support AER\n"); + ret = -EPROTONOSUPPORT; goto out_put; } @@ -397,14 +425,16 @@ static int aer_inject(struct aer_error_inj *einj) if (!aer_mask_override && einj->cor_status && !(einj->cor_status & ~cor_mask)) { ret = -EINVAL; - printk(KERN_WARNING "The correctable error(s) is masked by device\n"); + dev_warn(&dev->dev, + "aer_inject: The correctable error(s) is masked by device\n"); spin_unlock_irqrestore(&inject_lock, flags); goto out_put; } if (!aer_mask_override && einj->uncor_status && !(einj->uncor_status & ~uncor_mask)) { ret = -EINVAL; - printk(KERN_WARNING "The uncorrectable error(s) is masked by device\n"); + dev_warn(&dev->dev, + "aer_inject: The uncorrectable error(s) is masked by device\n"); spin_unlock_irqrestore(&inject_lock, flags); goto out_put; } @@ -457,13 +487,19 @@ static int aer_inject(struct aer_error_inj *einj) if (find_aer_device(rpdev, &edev)) { if (!get_service_data(edev)) { - printk(KERN_WARNING "AER service is not initialized\n"); - ret = -EINVAL; + dev_warn(&edev->device, + "aer_inject: AER service is not initialized\n"); + ret = -EPROTONOSUPPORT; goto out_put; } + dev_info(&edev->device, + "aer_inject: Injecting errors %08x/%08x into device %s\n", + einj->cor_status, einj->uncor_status, pci_name(dev)); aer_irq(-1, edev); - } else - ret = -EINVAL; + } else { + dev_err(&rpdev->dev, "aer_inject: AER device not found\n"); + ret = -ENODEV; + } out_put: kfree(err_alloc); kfree(rperr_alloc); diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c index 63fc63911295..1ae4c73e7a3c 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c @@ -396,7 +396,7 @@ static int pcie_pme_suspend(struct pcie_device *srv) { struct pcie_pme_service_data *data = get_service_data(srv); struct pci_dev *port = srv->port; - bool wakeup; + bool wakeup, wake_irq_enabled = false; int ret; if (device_may_wakeup(&port->dev)) { @@ -409,11 +409,12 @@ static int pcie_pme_suspend(struct pcie_device *srv) spin_lock_irq(&data->lock); if (wakeup) { ret = enable_irq_wake(srv->irq); - data->suspend_level = PME_SUSPEND_WAKEUP; + if (ret == 0) { + data->suspend_level = PME_SUSPEND_WAKEUP; + wake_irq_enabled = true; + } } - if (!wakeup || ret) { - struct pci_dev *port = srv->port; - + if (!wake_irq_enabled) { pcie_pme_interrupt_enable(port, false); pcie_clear_root_pme_status(port); data->suspend_level = PME_SUSPEND_NOIRQ; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6d7ab9bb0d5a..3f1d00952355 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -15,7 +15,6 @@ #include <linux/pci-aspm.h> #include <linux/aer.h> #include <linux/acpi.h> -#include <asm-generic/pci-bridge.h> #include "pci.h" #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ @@ -1608,7 +1607,7 @@ static void pci_init_capabilities(struct pci_dev *dev) pci_pm_init(dev); /* Vital Product Data */ - pci_vpd_pci22_init(dev); + pci_vpd_init(dev); /* Alternative Routing-ID Forwarding */ pci_configure_ari(dev); @@ -1803,6 +1802,13 @@ static int only_one_child(struct pci_bus *bus) return 0; if (pci_pcie_type(parent) == PCI_EXP_TYPE_ROOT_PORT) return 1; + + /* + * PCIe downstream ports are bridges that normally lead to only a + * device 0, but if PCI_SCAN_ALL_PCIE_DEVS is set, scan all + * possible devices, not just device 0. See PCIe spec r3.0, + * sec 7.3.1. + */ if (parent->has_secondary_link && !pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS)) return 1; diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 0575a1e026b4..8e678027b900 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -438,7 +438,7 @@ static void quirk_amd_nl_class(struct pci_dev *pdev) u32 class = pdev->class; /* Use "USB Device (not host controller)" class */ - pdev->class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe; + pdev->class = PCI_CLASS_SERIAL_USB_DEVICE; dev_info(&pdev->dev, "PCI class overridden (%#08x -> %#08x) so dwc3 driver can claim this instead of xhci\n", class, pdev->class); } @@ -2135,6 +2135,35 @@ static void quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching); /* + * If a device follows the VPD format spec, the PCI core will not read or + * write past the VPD End Tag. But some vendors do not follow the VPD + * format spec, so we can't tell how much data is safe to access. Devices + * may behave unpredictably if we access too much. Blacklist these devices + * so we don't touch VPD at all. + */ +static void quirk_blacklist_vpd(struct pci_dev *dev) +{ + if (dev->vpd) { + dev->vpd->len = 0; + dev_warn(&dev->dev, FW_BUG "VPD access disabled\n"); + } +} + +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x0060, quirk_blacklist_vpd); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x007c, quirk_blacklist_vpd); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x0413, quirk_blacklist_vpd); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x0078, quirk_blacklist_vpd); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x0079, quirk_blacklist_vpd); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x0073, quirk_blacklist_vpd); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x0071, quirk_blacklist_vpd); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x005b, quirk_blacklist_vpd); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x002f, quirk_blacklist_vpd); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x005d, quirk_blacklist_vpd); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x005f, quirk_blacklist_vpd); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, PCI_ANY_ID, + quirk_blacklist_vpd); + +/* * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the * VPD end tag will hang the device. This problem was initially * observed when a vpd entry was created in sysfs @@ -3832,6 +3861,19 @@ static int pci_quirk_amd_sb_acs(struct pci_dev *dev, u16 acs_flags) #endif } +static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags) +{ + /* + * Cavium devices matching this quirk do not perform peer-to-peer + * with other functions, allowing masking out these bits as if they + * were unimplemented in the ACS capability. + */ + acs_flags &= ~(PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR | + PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT); + + return acs_flags ? 0 : 1; +} + /* * Many Intel PCH root ports do provide ACS-like features to disable peer * transactions and validate bus numbers in requests, but do not provide an @@ -3984,6 +4026,8 @@ static const struct pci_dev_acs_enabled { { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, { 0x19a2, 0x710, pci_quirk_mf_endpoint_acs }, /* Emulex BE3-R */ { 0x10df, 0x720, pci_quirk_mf_endpoint_acs }, /* Emulex Skyhawk-R */ + /* Cavium ThunderX */ + { PCI_VENDOR_ID_CAVIUM, PCI_ANY_ID, pci_quirk_cavium_acs }, { 0 } }; diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 7796d0a5befa..55641a39a3e9 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -25,7 +25,6 @@ #include <linux/ioport.h> #include <linux/cache.h> #include <linux/slab.h> -#include <asm-generic/pci-bridge.h> #include "pci.h" unsigned int pci_flags; diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index 141226631429..a6682c508c4c 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c @@ -18,11 +18,11 @@ #include <linux/spinlock.h> #include <linux/interrupt.h> #include <linux/module.h> +#include <linux/pci.h> #include <asm/dbdma.h> #include <asm/io.h> #include <asm/pgtable.h> #include <asm/prom.h> -#include <asm/pci-bridge.h> #include <asm/macio.h> #include <scsi/scsi.h> diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c index 555367f00228..1753e42826dd 100644 --- a/drivers/scsi/mesh.c +++ b/drivers/scsi/mesh.c @@ -29,6 +29,7 @@ #include <linux/interrupt.h> #include <linux/reboot.h> #include <linux/spinlock.h> +#include <linux/pci.h> #include <asm/dbdma.h> #include <asm/io.h> #include <asm/pgtable.h> @@ -38,7 +39,6 @@ #include <asm/processor.h> #include <asm/machdep.h> #include <asm/pmac_feature.h> -#include <asm/pci-bridge.h> #include <asm/macio.h> #include <scsi/scsi.h> diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 9eb1cff28bd4..c3640f8a8fb3 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -28,7 +28,6 @@ #ifdef CONFIG_PPC_PMAC #include <asm/machdep.h> #include <asm/pmac_feature.h> -#include <asm/pci-bridge.h> #include <asm/prom.h> #endif diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index cd8764150861..39d70b4a8958 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -3397,7 +3397,7 @@ err_pcidev: static const struct pci_device_id pci_id[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x2096), - .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, + .class = PCI_CLASS_SERIAL_USB_DEVICE, .class_mask = 0xffffffff, }, {}, diff --git a/drivers/usb/gadget/udc/goku_udc.c b/drivers/usb/gadget/udc/goku_udc.c index 1fdfec14a3ba..d2205d9e0c8b 100644 --- a/drivers/usb/gadget/udc/goku_udc.c +++ b/drivers/usb/gadget/udc/goku_udc.c @@ -1846,7 +1846,7 @@ err: /*-------------------------------------------------------------------------*/ static const struct pci_device_id pci_ids[] = { { - .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), + .class = PCI_CLASS_SERIAL_USB_DEVICE, .class_mask = ~0, .vendor = 0x102f, /* Toshiba */ .device = 0x0107, /* this UDC */ diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index 6706aef907f4..c894b94b234b 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -3735,7 +3735,7 @@ static void net2280_shutdown(struct pci_dev *pdev) /*-------------------------------------------------------------------------*/ static const struct pci_device_id pci_ids[] = { { - .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), + .class = PCI_CLASS_SERIAL_USB_DEVICE, .class_mask = ~0, .vendor = PCI_VENDOR_ID_PLX_LEGACY, .device = 0x2280, @@ -3743,7 +3743,7 @@ static const struct pci_device_id pci_ids[] = { { .subdevice = PCI_ANY_ID, .driver_data = PLX_LEGACY | PLX_2280, }, { - .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), + .class = PCI_CLASS_SERIAL_USB_DEVICE, .class_mask = ~0, .vendor = PCI_VENDOR_ID_PLX_LEGACY, .device = 0x2282, @@ -3752,7 +3752,7 @@ static const struct pci_device_id pci_ids[] = { { .driver_data = PLX_LEGACY, }, { - .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), + .class = PCI_CLASS_SERIAL_USB_DEVICE, .class_mask = ~0, .vendor = PCI_VENDOR_ID_PLX, .device = 0x3380, @@ -3761,7 +3761,7 @@ static const struct pci_device_id pci_ids[] = { { .driver_data = PLX_SUPERSPEED, }, { - .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), + .class = PCI_CLASS_SERIAL_USB_DEVICE, .class_mask = ~0, .vendor = PCI_VENDOR_ID_PLX, .device = 0x3382, diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index 7a04157ff579..9571ef54b86b 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c @@ -3234,22 +3234,22 @@ static const struct pci_device_id pch_udc_pcidev_id[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QUARK_X1000_UDC), - .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, + .class = PCI_CLASS_SERIAL_USB_DEVICE, .class_mask = 0xffffffff, }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EG20T_UDC), - .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, + .class = PCI_CLASS_SERIAL_USB_DEVICE, .class_mask = 0xffffffff, }, { PCI_DEVICE(PCI_VENDOR_ID_ROHM, PCI_DEVICE_ID_ML7213_IOH_UDC), - .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, + .class = PCI_CLASS_SERIAL_USB_DEVICE, .class_mask = 0xffffffff, }, { PCI_DEVICE(PCI_VENDOR_ID_ROHM, PCI_DEVICE_ID_ML7831_IOH_UDC), - .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, + .class = PCI_CLASS_SERIAL_USB_DEVICE, .class_mask = 0xffffffff, }, { 0 }, diff --git a/drivers/video/fbdev/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c index c42ce2fdfd44..0a4626886b00 100644 --- a/drivers/video/fbdev/aty/aty128fb.c +++ b/drivers/video/fbdev/aty/aty128fb.c @@ -68,7 +68,6 @@ #include <asm/machdep.h> #include <asm/pmac_feature.h> #include <asm/prom.h> -#include <asm/pci-bridge.h> #include "../macmodes.h" #endif diff --git a/drivers/video/fbdev/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c index ce0b1d05a388..218339a4edaa 100644 --- a/drivers/video/fbdev/aty/radeon_base.c +++ b/drivers/video/fbdev/aty/radeon_base.c @@ -76,7 +76,6 @@ #ifdef CONFIG_PPC -#include <asm/pci-bridge.h> #include "../macmodes.h" #ifdef CONFIG_BOOTX_TEXT diff --git a/drivers/video/fbdev/imsttfb.c b/drivers/video/fbdev/imsttfb.c index 9b167f7ef6c6..4363c64d74e8 100644 --- a/drivers/video/fbdev/imsttfb.c +++ b/drivers/video/fbdev/imsttfb.c @@ -33,7 +33,6 @@ #if defined(CONFIG_PPC) #include <linux/nvram.h> #include <asm/prom.h> -#include <asm/pci-bridge.h> #include "macmodes.h" #endif diff --git a/drivers/video/fbdev/matrox/matroxfb_base.h b/drivers/video/fbdev/matrox/matroxfb_base.h index 09b02cd1eb0e..7a90ea2c4613 100644 --- a/drivers/video/fbdev/matrox/matroxfb_base.h +++ b/drivers/video/fbdev/matrox/matroxfb_base.h @@ -47,7 +47,6 @@ #if defined(CONFIG_PPC_PMAC) #include <asm/prom.h> -#include <asm/pci-bridge.h> #include "../macmodes.h" #endif diff --git a/drivers/video/fbdev/offb.c b/drivers/video/fbdev/offb.c index 43a0a52fc527..fb60a8f0cc94 100644 --- a/drivers/video/fbdev/offb.c +++ b/drivers/video/fbdev/offb.c @@ -28,10 +28,6 @@ #include <linux/pci.h> #include <asm/io.h> -#ifdef CONFIG_PPC64 -#include <asm/pci-bridge.h> -#endif - #ifdef CONFIG_PPC32 #include <asm/bootx.h> #endif diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index 36205c27c4d0..127dfe4e8694 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c @@ -467,7 +467,7 @@ static const struct dev_pm_ops virtio_pci_pm_ops = { /* Qumranet donated their vendor ID for devices 0x1000 thru 0x10FF. */ static const struct pci_device_id virtio_pci_id_table[] = { - { PCI_DEVICE(0x1af4, PCI_ANY_ID) }, + { PCI_DEVICE(PCI_VENDOR_ID_REDHAT_QUMRANET, PCI_ANY_ID) }, { 0 } }; |