summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 12:05:36 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 12:05:36 -0700
commitfdb2f9c2ebd4f07d7b11a3bc86d8c669eb841697 (patch)
treed85824518fc13a8c84b7399019fc11ad77aaa120
parent81f56e5375e84689b891e0e6c5a02ec12a1f18d9 (diff)
parent78c8f84302ce007aedcfa11912fd4aacf22727ab (diff)
Merge tag 'for-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas: "Host bridge hotplug - Protect acpi_pci_drivers and acpi_pci_roots (Taku Izumi) - Clear host bridge resource info to avoid issue when releasing (Yinghai Lu) - Notify acpi_pci_drivers when hot-plugging host bridges (Jiang Liu) - Use standard list ops for acpi_pci_drivers (Jiang Liu) Device hotplug - Use pci_get_domain_bus_and_slot() to close hotplug races (Jiang Liu) - Remove fakephp driver (Bjorn Helgaas) - Fix VGA ref count in hotplug remove path (Yinghai Lu) - Allow acpiphp to handle PCIe ports without native hotplug (Jiang Liu) - Implement resume regardless of pciehp_force param (Oliver Neukum) - Make pci_fixup_irqs() work after init (Thierry Reding) Miscellaneous - Add pci_pcie_type(dev) and remove pci_dev.pcie_type (Yijing Wang) - Factor out PCI Express Capability accessors (Jiang Liu) - Add pcibios_window_alignment() so powerpc EEH can use generic resource assignment (Gavin Shan) - Make pci_error_handlers const (Stephen Hemminger) - Cleanup drivers/pci/remove.c (Bjorn Helgaas) - Improve Vendor-Specific Extended Capability support (Bjorn Helgaas) - Use standard list ops for bus->devices (Bjorn Helgaas) - Avoid kmalloc in pci_get_subsys() and pci_get_class() (Feng Tang) - Reassign invalid bus number ranges (Intel DP43BF workaround) (Yinghai Lu)" * tag 'for-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (102 commits) PCI: acpiphp: Handle PCIe ports without native hotplug capability PCI/ACPI: Use acpi_driver_data() rather than searching acpi_pci_roots PCI/ACPI: Protect acpi_pci_roots list with mutex PCI/ACPI: Use acpi_pci_root info rather than looking it up again PCI/ACPI: Pass acpi_pci_root to acpi_pci_drivers' add/remove interface PCI/ACPI: Protect acpi_pci_drivers list with mutex PCI/ACPI: Notify acpi_pci_drivers when hot-plugging PCI root bridges PCI/ACPI: Use normal list for struct acpi_pci_driver PCI/ACPI: Use DEVICE_ACPI_HANDLE rather than searching acpi_pci_roots PCI: Fix default vga ref_count ia64/PCI: Clear host bridge aperture struct resource x86/PCI: Clear host bridge aperture struct resource PCI: Stop all children first, before removing all children Revert "PCI: Use hotplug-safe pci_get_domain_bus_and_slot()" PCI: Provide a default pcibios_update_irq() PCI: Discard __init annotations for pci_fixup_irqs() and related functions PCI: Use correct type when freeing bus resource list PCI: Check P2P bridge for invalid secondary/subordinate range PCI: Convert "new_id"/"remove_id" into generic pci_bus driver attributes xen-pcifront: Use hotplug-safe pci_get_domain_bus_and_slot() ...
-rw-r--r--Documentation/feature-removal-schedule.txt32
-rw-r--r--arch/alpha/kernel/pci.c6
-rw-r--r--arch/arm/kernel/bios32.c9
-rw-r--r--arch/arm/mach-tegra/pcie.c12
-rw-r--r--arch/frv/mb93090-mb00/pci-vdk.c4
-rw-r--r--arch/ia64/pci/pci.c11
-rw-r--r--arch/ia64/sn/kernel/io_common.c4
-rw-r--r--arch/m68k/kernel/pcibios.c5
-rw-r--r--arch/mips/pci/pci-octeon.c15
-rw-r--r--arch/mips/pci/pci.c6
-rw-r--r--arch/powerpc/include/asm/machdep.h3
-rw-r--r--arch/powerpc/kernel/pci-common.c20
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c41
-rw-r--r--arch/sh/drivers/pci/pci.c5
-rw-r--r--arch/sparc/kernel/leon_pci.c9
-rw-r--r--arch/sparc/kernel/pci.c4
-rw-r--r--arch/tile/kernel/pci.c34
-rw-r--r--arch/tile/kernel/pci_gx.c8
-rw-r--r--arch/unicore32/kernel/pci.c8
-rw-r--r--arch/x86/pci/acpi.c3
-rw-r--r--arch/x86/pci/visws.c5
-rw-r--r--arch/xtensa/kernel/pci.c8
-rw-r--r--drivers/acpi/pci_root.c101
-rw-r--r--drivers/acpi/pci_slot.c44
-rw-r--r--drivers/block/nvme.c2
-rw-r--r--drivers/char/agp/sgi-agp.c5
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c10
-rw-r--r--drivers/gpu/vga/vgaarb.c29
-rw-r--r--drivers/infiniband/hw/mthca/mthca_reset.c8
-rw-r--r--drivers/infiniband/hw/qib/qib.h2
-rw-r--r--drivers/infiniband/hw/qib/qib_pcie.c40
-rw-r--r--drivers/iommu/intel-iommu.c6
-rw-r--r--drivers/media/dvb/ngene/ngene-cards.c2
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_main.c4
-rw-r--r--drivers/net/ethernet/atheros/atl1e/atl1e_main.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c20
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c52
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/t3_hw.c22
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c12
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.c6
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c2
-rw-r--r--drivers/net/ethernet/intel/e100.c2
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_main.c2
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c29
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c14
-rw-r--r--drivers/net/ethernet/intel/igbvf/netdev.c2
-rw-r--r--drivers/net/ethernet/intel/ixgb/ixgb_main.c2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c4
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/reset.c8
-rw-r--r--drivers/net/ethernet/myricom/myri10ge/myri10ge.c31
-rw-r--r--drivers/net/ethernet/neterion/s2io.c2
-rw-r--r--drivers/net/ethernet/neterion/vxge/vxge-config.c4
-rw-r--r--drivers/net/ethernet/neterion/vxge/vxge-main.c2
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c2
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c4
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c2
-rw-r--r--drivers/net/ethernet/qlogic/qlge/qlge_main.c2
-rw-r--r--drivers/net/ethernet/realtek/r8169.c44
-rw-r--r--drivers/net/ethernet/sun/niu.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c21
-rw-r--r--drivers/net/wireless/iwlegacy/common.h4
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c7
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c8
-rw-r--r--drivers/parisc/dino.c10
-rw-r--r--drivers/parisc/lba_pci.c7
-rw-r--r--drivers/pci/Kconfig1
-rw-r--r--drivers/pci/access.c202
-rw-r--r--drivers/pci/bus.c6
-rw-r--r--drivers/pci/hotplug/Kconfig24
-rw-r--r--drivers/pci/hotplug/Makefile3
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c99
-rw-r--r--drivers/pci/hotplug/cpcihp_generic.c8
-rw-r--r--drivers/pci/hotplug/cpqphp_ctrl.c21
-rw-r--r--drivers/pci/hotplug/fakephp.c164
-rw-r--r--drivers/pci/hotplug/pciehp_acpi.c6
-rw-r--r--drivers/pci/hotplug/pciehp_core.c28
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c12
-rw-r--r--drivers/pci/hotplug/pcihp_slot.c20
-rw-r--r--drivers/pci/iov.c6
-rw-r--r--drivers/pci/pci-driver.c57
-rw-r--r--drivers/pci/pci.c358
-rw-r--r--drivers/pci/pcie/aer/aer_inject.c2
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c26
-rw-r--r--drivers/pci/pcie/aer/aerdrv_acpi.c2
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c67
-rw-r--r--drivers/pci/pcie/aspm.c119
-rw-r--r--drivers/pci/pcie/pme.c29
-rw-r--r--drivers/pci/pcie/portdrv_bus.c2
-rw-r--r--drivers/pci/pcie/portdrv_core.c34
-rw-r--r--drivers/pci/pcie/portdrv_pci.c27
-rw-r--r--drivers/pci/probe.c39
-rw-r--r--drivers/pci/proc.c19
-rw-r--r--drivers/pci/quirks.c31
-rw-r--r--drivers/pci/remove.c156
-rw-r--r--drivers/pci/rom.c59
-rw-r--r--drivers/pci/search.c63
-rw-r--r--drivers/pci/setup-bus.c81
-rw-r--r--drivers/pci/setup-irq.c9
-rw-r--r--drivers/pci/xen-pcifront.c10
-rw-r--r--drivers/pcmcia/cardbus.c15
-rw-r--r--drivers/rapidio/devices/tsi721.c18
-rw-r--r--drivers/scsi/ipr.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c8
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_nx.c4
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c2
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c2
-rw-r--r--drivers/staging/et131x/et131x.c19
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_pci.c8
-rw-r--r--drivers/tty/serial/8250/8250_pci.c2
-rw-r--r--drivers/tty/serial/jsm/jsm_driver.c2
-rw-r--r--drivers/xen/xen-pciback/pci_stub.c2
-rw-r--r--include/linux/acpi.h6
-rw-r--r--include/linux/pci-acpi.h17
-rw-r--r--include/linux/pci.h55
-rw-r--r--include/linux/pci_regs.h7
-rw-r--r--include/linux/pcieport_if.h2
123 files changed, 1078 insertions, 1750 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index f4d8c7105fcd..bc55d38081dc 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -253,38 +253,6 @@ Who: Dave Jones <davej@redhat.com>, Matthew Garrett <mjg@redhat.com>
-----------------------------
-What: fakephp and associated sysfs files in /sys/bus/pci/slots/
-When: 2011
-Why: In 2.6.27, the semantics of /sys/bus/pci/slots was redefined to
- represent a machine's physical PCI slots. The change in semantics
- had userspace implications, as the hotplug core no longer allowed
- drivers to create multiple sysfs files per physical slot (required
- for multi-function devices, e.g.). fakephp was seen as a developer's
- tool only, and its interface changed. Too late, we learned that
- there were some users of the fakephp interface.
-
- In 2.6.30, the original fakephp interface was restored. At the same
- time, the PCI core gained the ability that fakephp provided, namely
- function-level hot-remove and hot-add.
-
- Since the PCI core now provides the same functionality, exposed in:
-
- /sys/bus/pci/rescan
- /sys/bus/pci/devices/.../remove
- /sys/bus/pci/devices/.../rescan
-
- there is no functional reason to maintain fakephp as well.
-
- We will keep the existing module so that 'modprobe fakephp' will
- present the old /sys/bus/pci/slots/... interface for compatibility,
- but users are urged to migrate their applications to the API above.
-
- After a reasonable transition period, we will remove the legacy
- fakephp interface.
-Who: Alex Chiang <achiang@hp.com>
-
----------------------------
-
What: CONFIG_RFKILL_INPUT
When: 2.6.33
Why: Should be implemented in userspace, policy daemon.
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index 9816d5a4d176..ef757147cbf9 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -256,12 +256,6 @@ pcibios_fixup_bus(struct pci_bus *bus)
}
}
-void __init
-pcibios_update_irq(struct pci_dev *dev, int irq)
-{
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
int
pcibios_enable_device(struct pci_dev *dev, int mask)
{
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 2b2f25e7fef5..9cf16b83bbb5 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -270,15 +270,6 @@ static void __devinit pci_fixup_it8152(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8152, pci_fixup_it8152);
-
-
-void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
-{
- if (debug_pci)
- printk("PCI: Assigning IRQ %02d to %s\n", irq, pci_name(dev));
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
/*
* If the bus contains any of these devices, then we must not turn on
* parity checking of any kind. Currently this is CyberPro 20x0 only.
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index d3ad5150d660..c25a2a4f2e3d 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -367,17 +367,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_fixup_class);
/* Tegra PCIE requires relaxed ordering */
static void __devinit tegra_pcie_relax_enable(struct pci_dev *dev)
{
- u16 val16;
- int pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
-
- if (pos <= 0) {
- dev_err(&dev->dev, "skipping relaxed ordering fixup\n");
- return;
- }
-
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &val16);
- val16 |= PCI_EXP_DEVCTL_RELAX_EN;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, val16);
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);
}
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c
index d04ed14bbf0c..71e9bcf58105 100644
--- a/arch/frv/mb93090-mb00/pci-vdk.c
+++ b/arch/frv/mb93090-mb00/pci-vdk.c
@@ -330,10 +330,8 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
pci_read_bridge_bases(bus);
if (bus->number == 0) {
- struct list_head *ln;
struct pci_dev *dev;
- for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
- dev = pci_dev_b(ln);
+ list_for_each_entry(dev, &bus->devices, bus_list) {
if (dev->devfn == 0) {
dev->resource[0].start = 0;
dev->resource[0].end = 0;
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 81acc7a57f3e..5faa66c5c2a8 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -295,7 +295,6 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
window->resource.flags = flags;
window->resource.start = addr.minimum + offset;
window->resource.end = window->resource.start + addr.address_length - 1;
- window->resource.child = NULL;
window->offset = offset;
if (insert_resource(root, &window->resource)) {
@@ -357,7 +356,7 @@ pci_acpi_scan_root(struct acpi_pci_root *root)
&windows);
if (windows) {
controller->window =
- kmalloc_node(sizeof(*controller->window) * windows,
+ kzalloc_node(sizeof(*controller->window) * windows,
GFP_KERNEL, controller->node);
if (!controller->window)
goto out2;
@@ -461,14 +460,6 @@ void pcibios_set_master (struct pci_dev *dev)
/* No special bus mastering setup handling */
}
-void __devinit
-pcibios_update_irq (struct pci_dev *dev, int irq)
-{
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-
- /* ??? FIXME -- record old value for shutdown. */
-}
-
int
pcibios_enable_device (struct pci_dev *dev, int mask)
{
diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c
index fbb5f2f87eed..8630875e74b5 100644
--- a/arch/ia64/sn/kernel/io_common.c
+++ b/arch/ia64/sn/kernel/io_common.c
@@ -229,7 +229,6 @@ void sn_pci_fixup_slot(struct pci_dev *dev, struct pcidev_info *pcidev_info,
{
int segment = pci_domain_nr(dev->bus);
struct pcibus_bussoft *bs;
- struct pci_bus *host_pci_bus;
struct pci_dev *host_pci_dev;
unsigned int bus_no, devfn;
@@ -245,8 +244,7 @@ void sn_pci_fixup_slot(struct pci_dev *dev, struct pcidev_info *pcidev_info,
bus_no = (pcidev_info->pdi_slot_host_handle >> 32) & 0xff;
devfn = pcidev_info->pdi_slot_host_handle & 0xffffffff;
- host_pci_bus = pci_find_bus(segment, bus_no);
- host_pci_dev = pci_get_slot(host_pci_bus, devfn);
+ host_pci_dev = pci_get_domain_bus_and_slot(segment, bus_no, devfn);
pcidev_info->host_pci_dev = host_pci_dev;
pcidev_info->pdi_linux_pcidev = dev;
diff --git a/arch/m68k/kernel/pcibios.c b/arch/m68k/kernel/pcibios.c
index b2988aa1840b..73fa0b56a06c 100644
--- a/arch/m68k/kernel/pcibios.c
+++ b/arch/m68k/kernel/pcibios.c
@@ -87,11 +87,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
return 0;
}
-void pcibios_update_irq(struct pci_dev *dev, int irq)
-{
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
void __devinit pcibios_fixup_bus(struct pci_bus *bus)
{
struct pci_dev *dev;
diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c
index 52a1ba70b3b6..c5dfb2c87d44 100644
--- a/arch/mips/pci/pci-octeon.c
+++ b/arch/mips/pci/pci-octeon.c
@@ -117,16 +117,11 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
}
/* Enable the PCIe normal error reporting */
- pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (pos) {
- /* Update Device Control */
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config);
- config |= PCI_EXP_DEVCTL_CERE; /* Correctable Error Reporting */
- config |= PCI_EXP_DEVCTL_NFERE; /* Non-Fatal Error Reporting */
- config |= PCI_EXP_DEVCTL_FERE; /* Fatal Error Reporting */
- config |= PCI_EXP_DEVCTL_URRE; /* Unsupported Request */
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config);
- }
+ config = PCI_EXP_DEVCTL_CERE; /* Correctable Error Reporting */
+ config |= PCI_EXP_DEVCTL_NFERE; /* Non-Fatal Error Reporting */
+ config |= PCI_EXP_DEVCTL_FERE; /* Fatal Error Reporting */
+ config |= PCI_EXP_DEVCTL_URRE; /* Unsupported Request */
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL, config);
/* Find the Advanced Error Reporting capability */
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index 690356808f8a..04e35bcde07c 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -313,12 +313,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
}
}
-void __init
-pcibios_update_irq(struct pci_dev *dev, int irq)
-{
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
#ifdef CONFIG_HOTPLUG
EXPORT_SYMBOL(PCIBIOS_MIN_IO);
EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 42ce570812c1..f7706d722b39 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -214,6 +214,9 @@ struct machdep_calls {
/* Called after scan and before resource survey */
void (*pcibios_fixup_phb)(struct pci_controller *hose);
+ /* Called during PCI resource reassignment */
+ resource_size_t (*pcibios_window_alignment)(struct pci_bus *, unsigned long type);
+
/* Called to shutdown machine specific hardware not already controlled
* by other drivers.
*/
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 2aa04f29e1de..43fea543d686 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -99,6 +99,26 @@ void pcibios_free_controller(struct pci_controller *phb)
kfree(phb);
}
+/*
+ * The function is used to return the minimal alignment
+ * for memory or I/O windows of the associated P2P bridge.
+ * By default, 4KiB alignment for I/O windows and 1MiB for
+ * memory windows.
+ */
+resource_size_t pcibios_window_alignment(struct pci_bus *bus,
+ unsigned long type)
+{
+ if (ppc_md.pcibios_window_alignment)
+ return ppc_md.pcibios_window_alignment(bus, type);
+
+ /*
+ * PCI core will figure out the default
+ * alignment: 4KiB for I/O and 1MiB for
+ * memory window.
+ */
+ return 1;
+}
+
static resource_size_t pcibios_io_size(const struct pci_controller *hose)
{
#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 9cda6a1ad0cf..0e7eccc0f88d 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -855,7 +855,7 @@ static void __devinit pnv_ioda_setup_PEs(struct pci_bus *bus)
if (pe == NULL)
continue;
/* Leaving the PCIe domain ... single PE# */
- if (dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
+ if (pci_pcie_type(dev) == PCI_EXP_TYPE_PCI_BRIDGE)
pnv_ioda_setup_bus_PE(dev, pe);
else if (dev->subordinate)
pnv_ioda_setup_PEs(dev->subordinate);
@@ -1139,6 +1139,44 @@ static void __devinit pnv_pci_ioda_fixup_phb(struct pci_controller *hose)
}
}
+/*
+ * Returns the alignment for I/O or memory windows for P2P
+ * bridges. That actually depends on how PEs are segmented.
+ * For now, we return I/O or M32 segment size for PE sensitive
+ * P2P bridges. Otherwise, the default values (4KiB for I/O,
+ * 1MiB for memory) will be returned.
+ *
+ * The current PCI bus might be put into one PE, which was
+ * create against the parent PCI bridge. For that case, we
+ * needn't enlarge the alignment so that we can save some
+ * resources.
+ */
+static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus,
+ unsigned long type)
+{
+ struct pci_dev *bridge;
+ struct pci_controller *hose = pci_bus_to_host(bus);
+ struct pnv_phb *phb = hose->private_data;
+ int num_pci_bridges = 0;
+
+ bridge = bus->self;
+ while (bridge) {
+ if (pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE) {
+ num_pci_bridges++;
+ if (num_pci_bridges >= 2)
+ return 1;
+ }
+
+ bridge = bridge->bus->self;
+ }
+
+ /* We need support prefetchable memory window later */
+ if (type & IORESOURCE_MEM)
+ return phb->ioda.m32_segsize;
+
+ return phb->ioda.io_segsize;
+}
+
/* Prevent enabling devices for which we couldn't properly
* assign a PE
*/
@@ -1306,6 +1344,7 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np)
*/
ppc_md.pcibios_fixup_phb = pnv_pci_ioda_fixup_phb;
ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook;
+ ppc_md.pcibios_window_alignment = pnv_pci_window_alignment;
pci_add_flags(PCI_PROBE_ONLY | PCI_REASSIGN_ALL_RSRC);
/* Reset IODA tables to a clean state */
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 40db2d0aef3f..a7e078f2e2e4 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -192,11 +192,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
return pci_enable_resources(dev, mask);
}
-void __init pcibios_update_irq(struct pci_dev *dev, int irq)
-{
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
static void __init
pcibios_bus_report_status_early(struct pci_channel *hose,
int top_bus, int current_bus,
diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c
index 21dcda75a520..fc0521161568 100644
--- a/arch/sparc/kernel/leon_pci.c
+++ b/arch/sparc/kernel/leon_pci.c
@@ -102,15 +102,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
return pci_enable_resources(dev, mask);
}
-void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
-{
-#ifdef CONFIG_PCI_DEBUG
- printk(KERN_DEBUG "LEONPCI: Assigning IRQ %02d to %s\n", irq,
- pci_name(dev));
-#endif
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
/* in/out routines taken from pcic.c
*
* This probably belongs here rather than ioport.c because
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index 065b88c4f868..acc8c838ff72 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -622,10 +622,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *pbus)
{
}
-void pcibios_update_irq(struct pci_dev *pdev, int irq)
-{
-}
-
resource_size_t pcibios_align_resource(void *data, const struct resource *res,
resource_size_t size, resource_size_t align)
{
diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c
index 33c10864d2f7..759822687e8f 100644
--- a/arch/tile/kernel/pci.c
+++ b/arch/tile/kernel/pci.c
@@ -246,16 +246,13 @@ static void __devinit fixup_read_and_payload_sizes(void)
/* Scan for the smallest maximum payload size. */
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- int pcie_caps_offset;
u32 devcap;
int max_payload;
- pcie_caps_offset = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (pcie_caps_offset == 0)
+ if (!pci_is_pcie(dev))
continue;
- pci_read_config_dword(dev, pcie_caps_offset + PCI_EXP_DEVCAP,
- &devcap);
+ pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &devcap);
max_payload = devcap & PCI_EXP_DEVCAP_PAYLOAD;
if (max_payload < smallest_max_payload)
smallest_max_payload = max_payload;
@@ -263,21 +260,10 @@ static void __devinit fixup_read_and_payload_sizes(void)
/* Now, set the max_payload_size for all devices to that value. */
new_values = (max_read_size << 12) | (smallest_max_payload << 5);
- while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- int pcie_caps_offset;
- u16 devctl;
-
- pcie_caps_offset = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (pcie_caps_offset == 0)
- continue;
-
- pci_read_config_word(dev, pcie_caps_offset + PCI_EXP_DEVCTL,
- &devctl);
- devctl &= ~(PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ);
- devctl |= new_values;
- pci_write_config_word(dev, pcie_caps_offset + PCI_EXP_DEVCTL,
- devctl);
- }
+ while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
+ pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ,
+ new_values);
}
@@ -404,14 +390,6 @@ void pcibios_set_master(struct pci_dev *dev)
}
/*
- * This is called from the generic Linux layer.
- */
-void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
-{
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
-/*
* Enable memory and/or address decoding, as appropriate, for the
* device described by the 'dev' struct.
*
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c
index 0e213e35ffc3..2ba6d052f85d 100644
--- a/arch/tile/kernel/pci_gx.c
+++ b/arch/tile/kernel/pci_gx.c
@@ -1034,14 +1034,6 @@ char __devinit *pcibios_setup(char *str)
}
/*
- * This is called from the generic Linux layer.
- */
-void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
-{
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
-/*
* Enable memory address decoding, as appropriate, for the
* device described by the 'dev' struct. The I/O decoding
* is disabled, though the TILE-Gx supports I/O addressing.
diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c
index 46cb6c9de6c9..b0056f68d321 100644
--- a/arch/unicore32/kernel/pci.c
+++ b/arch/unicore32/kernel/pci.c
@@ -154,14 +154,6 @@ void __init puv3_pci_adjust_zones(unsigned long *zone_size,
zhole_size[0] = 0;
}
-void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
-{
- if (debug_pci)
- printk(KERN_DEBUG "PCI: Assigning IRQ %02d to %s\n",
- irq, pci_name(dev));
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
/*
* If the bus contains any of these devices, then we must not turn on
* parity checking of any kind.
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 505acdd6d600..192397c98606 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -305,7 +305,6 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
res->flags = flags;
res->start = start;
res->end = end;
- res->child = NULL;
if (!pci_use_crs) {
dev_printk(KERN_DEBUG, &info->bridge->dev,
@@ -434,7 +433,7 @@ probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device,
size = sizeof(*info->res) * info->res_num;
info->res_num = 0;
- info->res = kmalloc(size, GFP_KERNEL);
+ info->res = kzalloc(size, GFP_KERNEL);
if (!info->res)
return;
diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c
index 6f2f8eeed171..3e6d2a6db866 100644
--- a/arch/x86/pci/visws.c
+++ b/arch/x86/pci/visws.c
@@ -62,11 +62,6 @@ out:
return irq;
}
-void __init pcibios_update_irq(struct pci_dev *dev, int irq)
-{
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
int __init pci_visws_init(void)
{
pcibios_enable_irq = &pci_visws_enable_irq;
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c
index 69759e9cb3ea..54354de38a70 100644
--- a/arch/xtensa/kernel/pci.c
+++ b/arch/xtensa/kernel/pci.c
@@ -210,14 +210,6 @@ void pcibios_set_master(struct pci_dev *dev)
/* No special bus mastering setup handling */
}
-/* the next one is stolen from the alpha port... */
-
-void __init
-pcibios_update_irq(struct pci_dev *dev, int irq)
-{
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
int pcibios_enable_device(struct pci_dev *dev, int mask)
{
u16 cmd, old_cmd;
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 72a2c98bc429..bce469c0b48a 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -27,7 +27,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
-#include <linux/spinlock.h>
+#include <linux/mutex.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/pci.h>
@@ -71,9 +71,11 @@ static struct acpi_driver acpi_pci_root_driver = {
},
};
+/* Lock to protect both acpi_pci_roots and acpi_pci_drivers lists */
+static DEFINE_MUTEX(acpi_pci_root_lock);
static LIST_HEAD(acpi_pci_roots);
+static LIST_HEAD(acpi_pci_drivers);
-static struct acpi_pci_driver *sub_driver;
static DEFINE_MUTEX(osc_lock);
int acpi_pci_register_driver(struct acpi_pci_driver *driver)
@@ -81,55 +83,46 @@ int acpi_pci_register_driver(struct acpi_pci_driver *driver)
int n = 0;
struct acpi_pci_root *root;
- struct acpi_pci_driver **pptr = &sub_driver;
- while (*pptr)
- pptr = &(*pptr)->next;
- *pptr = driver;
-
- if (!driver->add)
- return 0;
-
- list_for_each_entry(root, &acpi_pci_roots, node) {
- driver->add(root->device->handle);
- n++;
- }
+ mutex_lock(&acpi_pci_root_lock);
+ list_add_tail(&driver->node, &acpi_pci_drivers);
+ if (driver->add)
+ list_for_each_entry(root, &acpi_pci_roots, node) {
+ driver->add(root);
+ n++;
+ }
+ mutex_unlock(&acpi_pci_root_lock);
return n;
}
-
EXPORT_SYMBOL(acpi_pci_register_driver);
void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
{
struct acpi_pci_root *root;
- struct acpi_pci_driver **pptr = &sub_driver;
- while (*pptr) {
- if (*pptr == driver)
- break;
- pptr = &(*pptr)->next;
- }
- BUG_ON(!*pptr);
- *pptr = (*pptr)->next;
-
- if (!driver->remove)
- return;
-
- list_for_each_entry(root, &acpi_pci_roots, node)
- driver->remove(root->device->handle);
+ mutex_lock(&acpi_pci_root_lock);
+ list_del(&driver->node);
+ if (driver->remove)
+ list_for_each_entry(root, &acpi_pci_roots, node)
+ driver->remove(root);
+ mutex_unlock(&acpi_pci_root_lock);
}
-
EXPORT_SYMBOL(acpi_pci_unregister_driver);
acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
{
struct acpi_pci_root *root;
+ acpi_handle handle = NULL;
+ mutex_lock(&acpi_pci_root_lock);
list_for_each_entry(root, &acpi_pci_roots, node)
if ((root->segment == (u16) seg) &&
- (root->secondary.start == (u16) bus))
- return root->device->handle;
- return NULL;
+ (root->secondary.start == (u16) bus)) {
+ handle = root->device->handle;
+ break;
+ }
+ mutex_unlock(&acpi_pci_root_lock);
+ return handle;
}
EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
@@ -277,12 +270,15 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags)
struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle)
{
struct acpi_pci_root *root;
+ struct acpi_device *device;
- list_for_each_entry(root, &acpi_pci_roots, node) {
- if (root->device->handle == handle)
- return root;
- }
- return NULL;
+ if (acpi_bus_get_device(handle, &device) ||
+ acpi_match_device_ids(device, root_device_ids))
+ return NULL;
+
+ root = acpi_driver_data(device);
+
+ return root;
}
EXPORT_SYMBOL_GPL(acpi_pci_find_root);
@@ -518,8 +514,9 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
* TBD: Need PCI interface for enumeration/configuration of roots.
*/
- /* TBD: Locking */
+ mutex_lock(&acpi_pci_root_lock);
list_add_tail(&root->node, &acpi_pci_roots);
+ mutex_unlock(&acpi_pci_root_lock);
printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n",
acpi_device_name(device), acpi_device_bid(device),
@@ -538,7 +535,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
"Bus %04x:%02x not present in PCI namespace\n",
root->segment, (unsigned int)root->secondary.start);
result = -ENODEV;
- goto end;
+ goto out_del_root;
}
/*
@@ -548,7 +545,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
*/
result = acpi_pci_bind_root(device);
if (result)
- goto end;
+ goto out_del_root;
/*
* PCI Routing Table
@@ -633,9 +630,11 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
return 0;
+out_del_root:
+ mutex_lock(&acpi_pci_root_lock);
+ list_del(&root->node);
+ mutex_unlock(&acpi_pci_root_lock);
end:
- if (!list_empty(&root->node))
- list_del(&root->node);
kfree(root);
return result;
}
@@ -643,18 +642,34 @@ end:
static int acpi_pci_root_start(struct acpi_device *device)
{
struct acpi_pci_root *root = acpi_driver_data(device);
+ struct acpi_pci_driver *driver;
+
+ mutex_lock(&acpi_pci_root_lock);
+ list_for_each_entry(driver, &acpi_pci_drivers, node)
+ if (driver->add)
+ driver->add(root);
+ mutex_unlock(&acpi_pci_root_lock);
pci_bus_add_devices(root->bus);
+
return 0;
}
static int acpi_pci_root_remove(struct acpi_device *device, int type)
{
struct acpi_pci_root *root = acpi_driver_data(device);
+ struct acpi_pci_driver *driver;
+
+ mutex_lock(&acpi_pci_root_lock);
+ list_for_each_entry(driver, &acpi_pci_drivers, node)
+ if (driver->remove)
+ driver->remove(root);
device_set_run_wake(root->bus->bridge, false);
pci_acpi_remove_bus_pm_notifier(device);
+ list_del(&root->node);
+ mutex_unlock(&acpi_pci_root_lock);
kfree(root);
return 0;
}
diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c
index e50e31a518af..d22585f21aeb 100644
--- a/drivers/acpi/pci_slot.c
+++ b/drivers/acpi/pci_slot.c
@@ -67,8 +67,8 @@ struct acpi_pci_slot {
struct list_head list; /* node in the list of slots */
};
-static int acpi_pci_slot_add(acpi_handle handle);
-static void acpi_pci_slot_remove(acpi_handle handle);
+static int acpi_pci_slot_add(struct acpi_pci_root *root);
+static void acpi_pci_slot_remove(struct acpi_pci_root *root);
static LIST_HEAD(slot_list);
static DEFINE_MUTEX(slot_list_lock);
@@ -233,45 +233,20 @@ out:
/*
* walk_root_bridge - generic root bridge walker
- * @handle: points to an acpi_pci_root
+ * @root: poiner of an acpi_pci_root
* @user_function: user callback for slot objects
*
* Call user_function for all objects underneath this root bridge.
* Walk p2p bridges underneath us and call user_function on those too.
*/
static int
-walk_root_bridge(acpi_handle handle, acpi_walk_callback user_function)
+walk_root_bridge(struct acpi_pci_root *root, acpi_walk_callback user_function)
{
- int seg, bus;
- unsigned long long tmp;
acpi_status status;
- acpi_handle dummy_handle;
- struct pci_bus *pci_bus;
+ acpi_handle handle = root->device->handle;
+ struct pci_bus *pci_bus = root->bus;
struct callback_args context;
- /* If the bridge doesn't have _STA, we assume it is always there */
- status = acpi_get_handle(handle, "_STA", &dummy_handle);
- if (ACPI_SUCCESS(status)) {
- status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp);
- if (ACPI_FAILURE(status)) {
- info("%s: _STA evaluation failure\n", __func__);
- return 0;
- }
- if ((tmp & ACPI_STA_DEVICE_FUNCTIONING) == 0)
- /* don't register this object */
- return 0;
- }
-
- status = acpi_evaluate_integer(handle, "_SEG", NULL, &tmp);
- seg = ACPI_SUCCESS(status) ? tmp : 0;
-
- status = acpi_evaluate_integer(handle, "_BBN", NULL, &tmp);
- bus = ACPI_SUCCESS(status) ? tmp : 0;
-
- pci_bus = pci_find_bus(seg, bus);
- if (!pci_bus)
- return 0;
-
context.pci_bus = pci_bus;
context.user_function = user_function;
context.root_handle = handle;
@@ -295,11 +270,11 @@ walk_root_bridge(acpi_handle handle, acpi_walk_callback user_function)
* @handle: points to an acpi_pci_root
*/
static int
-acpi_pci_slot_add(acpi_handle handle)
+acpi_pci_slot_add(struct acpi_pci_root *root)
{
acpi_status status;
- status = walk_root_bridge(handle, register_slot);
+ status = walk_root_bridge(root, register_slot);
if (ACPI_FAILURE(status))
err("%s: register_slot failure - %d\n", __func__, status);
@@ -311,10 +286,11 @@ acpi_pci_slot_add(acpi_handle handle)
* @handle: points to an acpi_pci_root
*/
static void
-acpi_pci_slot_remove(acpi_handle handle)
+acpi_pci_slot_remove(struct acpi_pci_root *root)
{
struct acpi_pci_slot *slot, *tmp;
struct pci_bus *pbus;
+ acpi_handle handle = root->device->handle;
mutex_lock(&slot_list_lock);
list_for_each_entry_safe(slot, tmp, &slot_list, list) {
diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c
index ad16c68c8645..931769e133e5 100644
--- a/drivers/block/nvme.c
+++ b/drivers/block/nvme.c
@@ -1726,7 +1726,7 @@ static void __devexit nvme_remove(struct pci_dev *pdev)
#define nvme_suspend NULL
#define nvme_resume NULL
-static struct pci_error_handlers nvme_err_handler = {
+static const struct pci_error_handlers nvme_err_handler = {
.error_detected = nvme_error_detected,
.mmio_enabled = nvme_dump_registers,
.link_reset = nvme_link_reset,
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
index 192000377737..3a5af2f9b015 100644
--- a/drivers/char/agp/sgi-agp.c
+++ b/drivers/char/agp/sgi-agp.c
@@ -289,12 +289,11 @@ static int __devinit agp_sgi_init(void)
j = 0;
list_for_each_entry(info, &tioca_list, ca_list) {
- struct list_head *tmp;
if (list_empty(info->ca_devices))
continue;
- list_for_each(tmp, info->ca_devices) {
+ list_for_each_entry(pdev, info->ca_devices, bus_list) {
u8 cap_ptr;
- pdev = pci_dev_b(tmp);
+
if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8))
continue;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index e93b80a6d4e9..ed3340adeb6f 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -77,13 +77,9 @@ void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw,
void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
{
u16 ctl, v;
- int cap, err;
+ int err;
- cap = pci_pcie_cap(rdev->pdev);
- if (!cap)
- return;
-
- err = pci_read_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, &ctl);
+ err = pcie_capability_read_word(rdev->pdev, PCI_EXP_DEVCTL, &ctl);
if (err)
return;
@@ -95,7 +91,7 @@ void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
if ((v == 0) || (v == 6) || (v == 7)) {
ctl &= ~PCI_EXP_DEVCTL_READRQ;
ctl |= (2 << 12);
- pci_write_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, ctl);
+ pcie_capability_write_word(rdev->pdev, PCI_EXP_DEVCTL, ctl);
}
}
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
index 3df8fc0ec01a..e893f6e1937d 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -141,7 +141,11 @@ EXPORT_SYMBOL_GPL(vga_default_device);
void vga_set_default_device(struct pci_dev *pdev)
{
- vga_default = pdev;
+ if (vga_default == pdev)
+ return;
+
+ pci_dev_put(vga_default);
+ vga_default = pci_dev_get(pdev);
}
#endif
@@ -577,7 +581,7 @@ static bool vga_arbiter_add_pci_device(struct pci_dev *pdev)
#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE
if (vga_default == NULL &&
((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK))
- vga_default = pci_dev_get(pdev);
+ vga_set_default_device(pdev);
#endif
vga_arbiter_check_bridge_sharing(vgadev);
@@ -613,10 +617,8 @@ static bool vga_arbiter_del_pci_device(struct pci_dev *pdev)
}
#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE
- if (vga_default == pdev) {
- pci_dev_put(vga_default);
- vga_default = NULL;
- }
+ if (vga_default == pdev)
+ vga_set_default_device(NULL);
#endif
if (vgadev->decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM))
@@ -1066,7 +1068,6 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
}
} else if (strncmp(curr_pos, "target ", 7) == 0) {
- struct pci_bus *pbus;
unsigned int domain, bus, devfn;
struct vga_device *vgadev;
@@ -1085,19 +1086,11 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
pr_debug("vgaarb: %s ==> %x:%x:%x.%x\n", curr_pos,
domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
- pbus = pci_find_bus(domain, bus);
- pr_debug("vgaarb: pbus %p\n", pbus);
- if (pbus == NULL) {
- pr_err("vgaarb: invalid PCI domain and/or bus address %x:%x\n",
- domain, bus);
- ret_val = -ENODEV;
- goto done;
- }
- pdev = pci_get_slot(pbus, devfn);
+ pdev = pci_get_domain_bus_and_slot(domain, bus, devfn);
pr_debug("vgaarb: pdev %p\n", pdev);
if (!pdev) {
- pr_err("vgaarb: invalid PCI address %x:%x\n",
- bus, devfn);
+ pr_err("vgaarb: invalid PCI address %x:%x:%x\n",
+ domain, bus, devfn);
ret_val = -ENODEV;
goto done;
}
diff --git a/drivers/infiniband/hw/mthca/mthca_reset.c b/drivers/infiniband/hw/mthca/mthca_reset.c
index 4fa3534ec233..74c6a9426047 100644
--- a/drivers/infiniband/hw/mthca/mthca_reset.c
+++ b/drivers/infiniband/hw/mthca/mthca_reset.c
@@ -241,16 +241,16 @@ good:
if (hca_pcie_cap) {
devctl = hca_header[(hca_pcie_cap + PCI_EXP_DEVCTL) / 4];
- if (pci_write_config_word(mdev->pdev, hca_pcie_cap + PCI_EXP_DEVCTL,
- devctl)) {
+ if (pcie_capability_write_word(mdev->pdev, PCI_EXP_DEVCTL,
+ devctl)) {
err = -ENODEV;
mthca_err(mdev, "Couldn't restore HCA PCI Express "
"Device Control register, aborting.\n");
goto out;
}
linkctl = hca_header[(hca_pcie_cap + PCI_EXP_LNKCTL) / 4];
- if (pci_write_config_word(mdev->pdev, hca_pcie_cap + PCI_EXP_LNKCTL,
- linkctl)) {
+ if (pcie_capability_write_word(mdev->pdev, PCI_EXP_LNKCTL,
+ linkctl)) {
err = -ENODEV;
mthca_err(mdev, "Couldn't restore HCA PCI Express "
"Link control register, aborting.\n");
diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qib.h
index 7b1b86690024..4d11575c2010 100644
--- a/drivers/infiniband/hw/qib/qib.h
+++ b/drivers/infiniband/hw/qib/qib.h
@@ -87,7 +87,7 @@ struct qlogic_ib_stats {
};
extern struct qlogic_ib_stats qib_stats;
-extern struct pci_error_handlers qib_pci_err_handler;
+extern const struct pci_error_handlers qib_pci_err_handler;
extern struct pci_driver qib_driver;
#define QIB_CHIP_SWVERSION QIB_CHIP_VERS_MAJ
diff --git a/drivers/infiniband/hw/qib/qib_pcie.c b/drivers/infiniband/hw/qib/qib_pcie.c
index 062c301ebf53..c574ec7c85e6 100644
--- a/drivers/infiniband/hw/qib/qib_pcie.c
+++ b/drivers/infiniband/hw/qib/qib_pcie.c
@@ -273,10 +273,9 @@ int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent,
struct qib_msix_entry *entry)
{
u16 linkstat, speed;
- int pos = 0, pose, ret = 1;
+ int pos = 0, ret = 1;
- pose = pci_pcie_cap(dd->pcidev);
- if (!pose) {
+ if (!pci_is_pcie(dd->pcidev)) {
qib_dev_err(dd, "Can't find PCI Express capability!\n");
/* set up something... */
dd->lbus_width = 1;
@@ -298,7 +297,7 @@ int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent,
if (!pos)
qib_enable_intx(dd->pcidev);
- pci_read_config_word(dd->pcidev, pose + PCI_EXP_LNKSTA, &linkstat);
+ pcie_capability_read_word(dd->pcidev, PCI_EXP_LNKSTA, &linkstat);
/*
* speed is bits 0-3, linkwidth is bits 4-8
* no defines for them in headers
@@ -516,7 +515,6 @@ static int qib_tune_pcie_coalesce(struct qib_devdata *dd)
{
int r;
struct pci_dev *parent;
- int ppos;
u16 devid;
u32 mask, bits, val;
@@ -529,8 +527,7 @@ static int qib_tune_pcie_coalesce(struct qib_devdata *dd)
qib_devinfo(dd->pcidev, "Parent not root\n");
return 1;
}
- ppos = pci_pcie_cap(parent);
- if (!ppos)
+ if (!pci_is_pcie(parent))
return 1;
if (parent->vendor != 0x8086)
return 1;
@@ -587,7 +584,6 @@ static int qib_tune_pcie_caps(struct qib_devdata *dd)
{
int ret = 1; /* Assume the worst */
struct pci_dev *parent;
- int ppos, epos;
u16 pcaps, pctl, ecaps, ectl;
int rc_sup, ep_sup;
int rc_cur, ep_cur;
@@ -598,19 +594,15 @@ static int qib_tune_pcie_caps(struct qib_devdata *dd)
qib_devinfo(dd->pcidev, "Parent not root\n");
goto bail;
}
- ppos = pci_pcie_cap(parent);
- if (ppos) {
- pci_read_config_word(parent, ppos + PCI_EXP_DEVCAP, &pcaps);
- pci_read_config_word(parent, ppos + PCI_EXP_DEVCTL, &pctl);
- } else
+
+ if (!pci_is_pcie(parent) || !pci_is_pcie(dd->pcidev))
goto bail;
+ pcie_capability_read_word(parent, PCI_EXP_DEVCAP, &pcaps);
+ pcie_capability_read_word(parent, PCI_EXP_DEVCTL, &pctl);
/* Find out supported and configured values for endpoint (us) */
- epos = pci_pcie_cap(dd->pcidev);
- if (epos) {
- pci_read_config_word(dd->pcidev, epos + PCI_EXP_DEVCAP, &ecaps);
- pci_read_config_word(dd->pcidev, epos + PCI_EXP_DEVCTL, &ectl);
- } else
- goto bail;
+ pcie_capability_read_word(dd->pcidev, PCI_EXP_DEVCAP, &ecaps);
+ pcie_capability_read_word(dd->pcidev, PCI_EXP_DEVCTL, &ectl);
+
ret = 0;
/* Find max payload supported by root, endpoint */
rc_sup = fld2val(pcaps, PCI_EXP_DEVCAP_PAYLOAD);
@@ -629,14 +621,14 @@ static int qib_tune_pcie_caps(struct qib_devdata *dd)
rc_cur = rc_sup;
pctl = (pctl & ~PCI_EXP_DEVCTL_PAYLOAD) |
val2fld(rc_cur, PCI_EXP_DEVCTL_PAYLOAD);
- pci_write_config_word(parent, ppos + PCI_EXP_DEVCTL, pctl);
+ pcie_capability_write_word(parent, PCI_EXP_DEVCTL, pctl);
}
/* If less than (allowed, supported), bump endpoint payload */
if (rc_sup > ep_cur) {
ep_cur = rc_sup;
ectl = (ectl & ~PCI_EXP_DEVCTL_PAYLOAD) |
val2fld(ep_cur, PCI_EXP_DEVCTL_PAYLOAD);
- pci_write_config_word(dd->pcidev, epos + PCI_EXP_DEVCTL, ectl);
+ pcie_capability_write_word(dd->pcidev, PCI_EXP_DEVCTL, ectl);
}
/*
@@ -654,13 +646,13 @@ static int qib_tune_pcie_caps(struct qib_devdata *dd)
rc_cur = rc_sup;
pctl = (pctl & ~PCI_EXP_DEVCTL_READRQ) |
val2fld(rc_cur, PCI_EXP_DEVCTL_READRQ);
- pci_write_config_word(parent, ppos + PCI_EXP_DEVCTL, pctl);
+ pcie_capability_write_word(parent, PCI_EXP_DEVCTL, pctl);
}
if (rc_sup > ep_cur) {
ep_cur = rc_sup;
ectl = (ectl & ~PCI_EXP_DEVCTL_READRQ) |
val2fld(ep_cur, PCI_EXP_DEVCTL_READRQ);
- pci_write_config_word(dd->pcidev, epos + PCI_EXP_DEVCTL, ectl);
+ pcie_capability_write_word(dd->pcidev, PCI_EXP_DEVCTL, ectl);
}
bail:
return ret;
@@ -753,7 +745,7 @@ qib_pci_resume(struct pci_dev *pdev)
qib_init(dd, 1); /* same as re-init after reset */
}
-struct pci_error_handlers qib_pci_err_handler = {
+const struct pci_error_handlers qib_pci_err_handler = {
.error_detected = qib_pci_error_detected,
.mmio_enabled = qib_pci_mmio_enabled,
.link_reset = qib_pci_link_reset,
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 2297ec193eb4..db820d7dd0bc 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2351,7 +2351,7 @@ static int iommu_should_identity_map(struct pci_dev *pdev, int startup)
return 0;
if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
return 0;
- } else if (pdev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
+ } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
return 0;
/*
@@ -3546,10 +3546,10 @@ found:
struct pci_dev *bridge = bus->self;
if (!bridge || !pci_is_pcie(bridge) ||
- bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
+ pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
return 0;
- if (bridge->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
+ if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT) {
for (i = 0; i < atsru->devices_cnt; i++)
if (atsru->devices[i] == bridge)
return 1;
diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c
index 72ee8de02260..0a497be97af8 100644
--- a/drivers/media/dvb/ngene/ngene-cards.c
+++ b/drivers/media/dvb/ngene/ngene-cards.c
@@ -524,7 +524,7 @@ static void ngene_resume(struct pci_dev *dev)
printk(KERN_INFO DEVICE_NAME ": resume\n");
}
-static struct pci_error_handlers ngene_errors = {
+static const struct pci_error_handlers ngene_errors = {
.error_detected = ngene_error_detected,
.link_reset = ngene_link_reset,
.slot_reset = ngene_slot_reset,
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 1bf5bbfe778e..55a2e3795055 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -149,7 +149,7 @@ static void atl1c_reset_pcie(struct atl1c_hw *hw, u32 flag)
data &= ~(PCI_ERR_UNC_DLP | PCI_ERR_UNC_FCP);
pci_write_config_dword(pdev, pos + PCI_ERR_UNCOR_SEVER, data);
/* clear error status */
- pci_write_config_word(pdev, pci_pcie_cap(pdev) + PCI_EXP_DEVSTA,
+ pcie_capability_write_word(pdev, PCI_EXP_DEVSTA,
PCI_EXP_DEVSTA_NFED |
PCI_EXP_DEVSTA_FED |
PCI_EXP_DEVSTA_CED |
@@ -2685,7 +2685,7 @@ static void atl1c_io_resume(struct pci_dev *pdev)
netif_device_attach(netdev);
}
-static struct pci_error_handlers atl1c_err_handler = {
+static const struct pci_error_handlers atl1c_err_handler = {
.error_detected = atl1c_io_error_detected,
.slot_reset = atl1c_io_slot_reset,
.resume = atl1c_io_resume,
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
index a98acc8a956f..e213da29e73d 100644
--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
@@ -2489,7 +2489,7 @@ static void atl1e_io_resume(struct pci_dev *pdev)
netif_device_attach(netdev);
}
-static struct pci_error_handlers atl1e_err_handler = {
+static const struct pci_error_handlers atl1e_err_handler = {
.error_detected = atl1e_io_error_detected,
.slot_reset = atl1e_io_slot_reset,
.resume = atl1e_io_resume,
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index e48312f2305d..d4310700c7a7 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -8742,7 +8742,7 @@ static void bnx2_io_resume(struct pci_dev *pdev)
rtnl_unlock();
}
-static struct pci_error_handlers bnx2_err_handler = {
+static const struct pci_error_handlers bnx2_err_handler = {
.error_detected = bnx2_io_error_detected,
.slot_reset = bnx2_io_slot_reset,
.resume = bnx2_io_resume,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 0875ecfe3372..e11485ca037d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -1162,14 +1162,9 @@ static int bnx2x_send_final_clnup(struct bnx2x *bp, u8 clnup_func,
static u8 bnx2x_is_pcie_pending(struct pci_dev *dev)
{
- int pos;
u16 status;
- pos = pci_pcie_cap(dev);
- if (!pos)
- return false;
-
- pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &status);
+ pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status);
return status & PCI_EXP_DEVSTA_TRPND;
}
@@ -6135,8 +6130,7 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
u16 devctl;
int r_order, w_order;
- pci_read_config_word(bp->pdev,
- pci_pcie_cap(bp->pdev) + PCI_EXP_DEVCTL, &devctl);
+ pcie_capability_read_word(bp->pdev, PCI_EXP_DEVCTL, &devctl);
DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
if (bp->mrrs == -1)
@@ -9380,7 +9374,7 @@ static int __devinit bnx2x_prev_mark_path(struct bnx2x *bp)
static int __devinit bnx2x_do_flr(struct bnx2x *bp)
{
- int i, pos;
+ int i;
u16 status;
struct pci_dev *dev = bp->pdev;
@@ -9397,16 +9391,12 @@ static int __devinit bnx2x_do_flr(struct bnx2x *bp)
return -EINVAL;
}
- pos = pci_pcie_cap(dev);
- if (!pos)
- return -ENOTTY;
-
/* Wait for Transaction Pending bit clean */
for (i = 0; i < 4; i++) {
if (i)
msleep((1 << (i - 1)) * 100);
- pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &status);
+ pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status);
if (!(status & PCI_EXP_DEVSTA_TRPND))
goto clear;
}
@@ -12167,7 +12157,7 @@ static void bnx2x_io_resume(struct pci_dev *pdev)
rtnl_unlock();
}
-static struct pci_error_handlers bnx2x_err_handler = {
+static const struct pci_error_handlers bnx2x_err_handler = {
.error_detected = bnx2x_io_error_detected,
.slot_reset = bnx2x_io_slot_reset,
.resume = bnx2x_io_resume,
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index bf906c51d82a..388d32213937 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -3653,17 +3653,9 @@ static int tg3_power_down_prepare(struct tg3 *tp)
tg3_enable_register_access(tp);
/* Restore the CLKREQ setting. */
- if (tg3_flag(tp, CLKREQ_BUG)) {
- u16 lnkctl;
-
- pci_read_config_word(tp->pdev,
- pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL,
- &lnkctl);
- lnkctl |= PCI_EXP_LNKCTL_CLKREQ_EN;
- pci_write_config_word(tp->pdev,
- pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL,
- lnkctl);
- }
+ if (tg3_flag(tp, CLKREQ_BUG))
+ pcie_capability_set_word(tp->pdev, PCI_EXP_LNKCTL,
+ PCI_EXP_LNKCTL_CLKREQ_EN);
misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL);
tw32(TG3PCI_MISC_HOST_CTRL,
@@ -4434,20 +4426,13 @@ relink:
/* Prevent send BD corruption. */
if (tg3_flag(tp, CLKREQ_BUG)) {
- u16 oldlnkctl, newlnkctl;
-
- pci_read_config_word(tp->pdev,
- pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL,
- &oldlnkctl);
if (tp->link_config.active_speed == SPEED_100 ||
tp->link_config.active_speed == SPEED_10)
- newlnkctl = oldlnkctl & ~PCI_EXP_LNKCTL_CLKREQ_EN;
+ pcie_capability_clear_word(tp->pdev, PCI_EXP_LNKCTL,
+ PCI_EXP_LNKCTL_CLKREQ_EN);
else
- newlnkctl = oldlnkctl | PCI_EXP_LNKCTL_CLKREQ_EN;
- if (newlnkctl != oldlnkctl)
- pci_write_config_word(tp->pdev,
- pci_pcie_cap(tp->pdev) +
- PCI_EXP_LNKCTL, newlnkctl);
+ pcie_capability_set_word(tp->pdev, PCI_EXP_LNKCTL,
+ PCI_EXP_LNKCTL_CLKREQ_EN);
}
if (current_link_up != netif_carrier_ok(tp->dev)) {
@@ -8054,7 +8039,7 @@ static int tg3_chip_reset(struct tg3 *tp)
udelay(120);
- if (tg3_flag(tp, PCI_EXPRESS) && pci_pcie_cap(tp->pdev)) {
+ if (tg3_flag(tp, PCI_EXPRESS) && pci_is_pcie(tp->pdev)) {
u16 val16;
if (tp->pci_chip_rev_id == CHIPREV_ID_5750_A0) {
@@ -8071,24 +8056,17 @@ static int tg3_chip_reset(struct tg3 *tp)
}
/* Clear the "no snoop" and "relaxed ordering" bits. */
- pci_read_config_word(tp->pdev,
- pci_pcie_cap(tp->pdev) + PCI_EXP_DEVCTL,
- &val16);
- val16 &= ~(PCI_EXP_DEVCTL_RELAX_EN |
- PCI_EXP_DEVCTL_NOSNOOP_EN);
+ val16 = PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN;
/*
* Older PCIe devices only support the 128 byte
* MPS setting. Enforce the restriction.
*/
if (!tg3_flag(tp, CPMU_PRESENT))
- val16 &= ~PCI_EXP_DEVCTL_PAYLOAD;
- pci_write_config_word(tp->pdev,
- pci_pcie_cap(tp->pdev) + PCI_EXP_DEVCTL,
- val16);
+ val16 |= PCI_EXP_DEVCTL_PAYLOAD;
+ pcie_capability_clear_word(tp->pdev, PCI_EXP_DEVCTL, val16);
/* Clear error status */
- pci_write_config_word(tp->pdev,
- pci_pcie_cap(tp->pdev) + PCI_EXP_DEVSTA,
+ pcie_capability_write_word(tp->pdev, PCI_EXP_DEVSTA,
PCI_EXP_DEVSTA_CED |
PCI_EXP_DEVSTA_NFED |
PCI_EXP_DEVSTA_FED |
@@ -14565,9 +14543,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tg3_flag_set(tp, PCI_EXPRESS);
- pci_read_config_word(tp->pdev,
- pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL,
- &lnkctl);
+ pcie_capability_read_word(tp->pdev, PCI_EXP_LNKCTL, &lnkctl);
if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
ASIC_REV_5906) {
@@ -16397,7 +16373,7 @@ done:
rtnl_unlock();
}
-static struct pci_error_handlers tg3_err_handler = {
+static const struct pci_error_handlers tg3_err_handler = {
.error_detected = tg3_io_error_detected,
.slot_reset = tg3_io_slot_reset,
.resume = tg3_io_resume
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
index 6505070abcfa..875bbb999aa2 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
@@ -3036,7 +3036,7 @@ static void t3_io_resume(struct pci_dev *pdev)
t3_resume_ports(adapter);
}
-static struct pci_error_handlers t3_err_handler = {
+static const struct pci_error_handlers t3_err_handler = {
.error_detected = t3_io_error_detected,
.slot_reset = t3_io_slot_reset,
.resume = t3_io_resume,
diff --git a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
index bff8a3cdd3df..aef45d3113ba 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
@@ -3289,22 +3289,18 @@ static void config_pcie(struct adapter *adap)
unsigned int log2_width, pldsize;
unsigned int fst_trn_rx, fst_trn_tx, acklat, rpllmt;
- pci_read_config_word(adap->pdev,
- adap->pdev->pcie_cap + PCI_EXP_DEVCTL,
- &val);
+ pcie_capability_read_word(adap->pdev, PCI_EXP_DEVCTL, &val);
pldsize = (val & PCI_EXP_DEVCTL_PAYLOAD) >> 5;
pci_read_config_word(adap->pdev, 0x2, &devid);
if (devid == 0x37) {
- pci_write_config_word(adap->pdev,
- adap->pdev->pcie_cap + PCI_EXP_DEVCTL,
- val & ~PCI_EXP_DEVCTL_READRQ &
- ~PCI_EXP_DEVCTL_PAYLOAD);
+ pcie_capability_write_word(adap->pdev, PCI_EXP_DEVCTL,
+ val & ~PCI_EXP_DEVCTL_READRQ &
+ ~PCI_EXP_DEVCTL_PAYLOAD);
pldsize = 0;
}
- pci_read_config_word(adap->pdev, adap->pdev->pcie_cap + PCI_EXP_LNKCTL,
- &val);
+ pcie_capability_read_word(adap->pdev, PCI_EXP_LNKCTL, &val);
fst_trn_tx = G_NUMFSTTRNSEQ(t3_read_reg(adap, A_PCIE_PEX_CTRL0));
fst_trn_rx = adap->params.rev == 0 ? fst_trn_tx :
@@ -3425,15 +3421,13 @@ out_err:
static void get_pci_mode(struct adapter *adapter, struct pci_params *p)
{
static unsigned short speed_map[] = { 33, 66, 100, 133 };
- u32 pci_mode, pcie_cap;
+ u32 pci_mode;
- pcie_cap = pci_pcie_cap(adapter->pdev);
- if (pcie_cap) {
+ if (pci_is_pcie(adapter->pdev)) {
u16 val;
p->variant = PCI_VARIANT_PCIE;
- pci_read_config_word(adapter->pdev, pcie_cap + PCI_EXP_LNKSTA,
- &val);
+ pcie_capability_read_word(adapter->pdev, PCI_EXP_LNKSTA, &val);
p->width = (val >> 4) & 0x3f;
return;
}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 5ed49af23d6a..933985420acb 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -3453,7 +3453,7 @@ static void eeh_resume(struct pci_dev *pdev)
rtnl_unlock();
}
-static struct pci_error_handlers cxgb4_eeh = {
+static const struct pci_error_handlers cxgb4_eeh = {
.error_detected = eeh_err_detected,
.slot_reset = eeh_slot_reset,
.resume = eeh_resume,
@@ -3694,15 +3694,7 @@ static void __devinit print_port_info(const struct net_device *dev)
static void __devinit enable_pcie_relaxed_ordering(struct pci_dev *dev)
{
- u16 v;
- int pos;
-
- pos = pci_pcie_cap(dev);
- if (pos > 0) {
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &v);
- v |= PCI_EXP_DEVCTL_RELAX_EN;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, v);
- }
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);
}
/*
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index fa947dfa4c30..af1601323173 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -2741,11 +2741,9 @@ static void __devinit get_pci_mode(struct adapter *adapter,
struct pci_params *p)
{
u16 val;
- u32 pcie_cap = pci_pcie_cap(adapter->pdev);
- if (pcie_cap) {
- pci_read_config_word(adapter->pdev, pcie_cap + PCI_EXP_LNKSTA,
- &val);
+ if (pci_is_pcie(adapter->pdev)) {
+ pcie_capability_read_word(adapter->pdev, PCI_EXP_LNKSTA, &val);
p->speed = val & PCI_EXP_LNKSTA_CLS;
p->width = (val & PCI_EXP_LNKSTA_NLW) >> 4;
}
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 78b8aa8069f0..95d10472f236 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -4106,7 +4106,7 @@ err:
dev_err(&adapter->pdev->dev, "EEH resume failed\n");
}
-static struct pci_error_handlers be_eeh_handlers = {
+static const struct pci_error_handlers be_eeh_handlers = {
.error_detected = be_eeh_err_detected,
.slot_reset = be_eeh_reset,
.resume = be_eeh_resume,
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
index 535f94fac4a1..29ce9bd27f94 100644
--- a/drivers/net/ethernet/intel/e100.c
+++ b/drivers/net/ethernet/intel/e100.c
@@ -3157,7 +3157,7 @@ static void e100_io_resume(struct pci_dev *pdev)
}
}
-static struct pci_error_handlers e100_err_handler = {
+static const struct pci_error_handlers e100_err_handler = {
.error_detected = e100_io_error_detected,
.slot_reset = e100_io_slot_reset,
.resume = e100_io_resume,
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index bde337ee1a34..f3f9aeb7d1e1 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -192,7 +192,7 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
static void e1000_io_resume(struct pci_dev *pdev);
-static struct pci_error_handlers e1000_err_handler = {
+static const struct pci_error_handlers e1000_err_handler = {
.error_detected = e1000_io_error_detected,
.slot_reset = e1000_io_slot_reset,
.resume = e1000_io_resume,
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index d01a099475a1..3f0223ac4c7c 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -5584,16 +5584,15 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
*/
if (adapter->flags & FLAG_IS_QUAD_PORT) {
struct pci_dev *us_dev = pdev->bus->self;
- int pos = pci_pcie_cap(us_dev);
u16 devctl;
- pci_read_config_word(us_dev, pos + PCI_EXP_DEVCTL, &devctl);
- pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL,
- (devctl & ~PCI_EXP_DEVCTL_CERE));
+ pcie_capability_read_word(us_dev, PCI_EXP_DEVCTL, &devctl);
+ pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL,
+ (devctl & ~PCI_EXP_DEVCTL_CERE));
e1000_power_off(pdev, sleep, wake);
- pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, devctl);
+ pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, devctl);
} else {
e1000_power_off(pdev, sleep, wake);
}
@@ -5607,25 +5606,15 @@ static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
#else
static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
{
- int pos;
- u16 reg16;
-
/*
* Both device and parent should have the same ASPM setting.
* Disable ASPM in downstream component first and then upstream.
*/
- pos = pci_pcie_cap(pdev);
- pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
- reg16 &= ~state;
- pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
-
- if (!pdev->bus->self)
- return;
+ pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, state);
- pos = pci_pcie_cap(pdev->bus->self);
- pci_read_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, &reg16);
- reg16 &= ~state;
- pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16);
+ if (pdev->bus->self)
+ pcie_capability_clear_word(pdev->bus->self, PCI_EXP_LNKCTL,
+ state);
}
#endif
static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
@@ -6486,7 +6475,7 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
}
/* PCI Error Recovery (ERS) */
-static struct pci_error_handlers e1000_err_handler = {
+static const struct pci_error_handlers e1000_err_handler = {
.error_detected = e1000_io_error_detected,
.slot_reset = e1000_io_slot_reset,
.resume = e1000_io_resume,
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 48cc4fb1a307..f88c822e57a6 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -217,7 +217,7 @@ static pci_ers_result_t igb_io_error_detected(struct pci_dev *,
static pci_ers_result_t igb_io_slot_reset(struct pci_dev *);
static void igb_io_resume(struct pci_dev *);
-static struct pci_error_handlers igb_err_handler = {
+static const struct pci_error_handlers igb_err_handler = {
.error_detected = igb_io_error_detected,
.slot_reset = igb_io_slot_reset,
.resume = igb_io_resume,
@@ -6538,28 +6538,20 @@ static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
{
struct igb_adapter *adapter = hw->back;
- u16 cap_offset;
- cap_offset = adapter->pdev->pcie_cap;
- if (!cap_offset)
+ if (pcie_capability_read_word(adapter->pdev, reg, value))
return -E1000_ERR_CONFIG;
- pci_read_config_word(adapter->pdev, cap_offset + reg, value);
-
return 0;
}
s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
{
struct igb_adapter *adapter = hw->back;
- u16 cap_offset;
- cap_offset = adapter->pdev->pcie_cap;
- if (!cap_offset)
+ if (pcie_capability_write_word(adapter->pdev, reg, *value))
return -E1000_ERR_CONFIG;
- pci_write_config_word(adapter->pdev, cap_offset + reg, *value);
-
return 0;
}
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c
index 0696abfe9944..0ac11f527a84 100644
--- a/drivers/net/ethernet/intel/igbvf/netdev.c
+++ b/drivers/net/ethernet/intel/igbvf/netdev.c
@@ -2833,7 +2833,7 @@ static void __devexit igbvf_remove(struct pci_dev *pdev)
}
/* PCI Error Recovery (ERS) */
-static struct pci_error_handlers igbvf_err_handler = {
+static const struct pci_error_handlers igbvf_err_handler = {
.error_detected = igbvf_io_error_detected,
.slot_reset = igbvf_io_slot_reset,
.resume = igbvf_io_resume,
diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c
index d05fc95befc5..d99a2d51b948 100644
--- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c
+++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c
@@ -115,7 +115,7 @@ static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev,
static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev);
static void ixgb_io_resume (struct pci_dev *pdev);
-static struct pci_error_handlers ixgb_err_handler = {
+static const struct pci_error_handlers ixgb_err_handler = {
.error_detected = ixgb_io_error_detected,
.slot_reset = ixgb_io_slot_reset,
.resume = ixgb_io_resume,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 4326f74f7137..ee61819d6088 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7527,7 +7527,7 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
goto skip_bad_vf_detection;
bdev = pdev->bus->self;
- while (bdev && (bdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT))
+ while (bdev && (pci_pcie_type(bdev) != PCI_EXP_TYPE_ROOT_PORT))
bdev = bdev->bus->self;
if (!bdev)
@@ -7677,7 +7677,7 @@ static void ixgbe_io_resume(struct pci_dev *pdev)
netif_device_attach(netdev);
}
-static struct pci_error_handlers ixgbe_err_handler = {
+static const struct pci_error_handlers ixgbe_err_handler = {
.error_detected = ixgbe_io_error_detected,
.slot_reset = ixgbe_io_slot_reset,
.resume = ixgbe_io_resume,
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 60ef64587412..6647383c4ddc 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -3256,7 +3256,7 @@ static void ixgbevf_io_resume(struct pci_dev *pdev)
}
/* PCI Error Recovery (ERS) */
-static struct pci_error_handlers ixgbevf_err_handler = {
+static const struct pci_error_handlers ixgbevf_err_handler = {
.error_detected = ixgbevf_io_error_detected,
.slot_reset = ixgbevf_io_slot_reset,
.resume = ixgbevf_io_resume,
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 2f816c6aed72..dd6ea942625c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -2300,7 +2300,7 @@ static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev)
return ret ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
}
-static struct pci_error_handlers mlx4_err_handler = {
+static const struct pci_error_handlers mlx4_err_handler = {
.error_detected = mlx4_pci_err_detected,
.slot_reset = mlx4_pci_slot_reset,
};
diff --git a/drivers/net/ethernet/mellanox/mlx4/reset.c b/drivers/net/ethernet/mellanox/mlx4/reset.c
index 11e7c1cb99bf..dd1b5093d8b1 100644
--- a/drivers/net/ethernet/mellanox/mlx4/reset.c
+++ b/drivers/net/ethernet/mellanox/mlx4/reset.c
@@ -141,16 +141,16 @@ int mlx4_reset(struct mlx4_dev *dev)
/* Now restore the PCI headers */
if (pcie_cap) {
devctl = hca_header[(pcie_cap + PCI_EXP_DEVCTL) / 4];
- if (pci_write_config_word(dev->pdev, pcie_cap + PCI_EXP_DEVCTL,
- devctl)) {
+ if (pcie_capability_write_word(dev->pdev, PCI_EXP_DEVCTL,
+ devctl)) {
err = -ENODEV;
mlx4_err(dev, "Couldn't restore HCA PCI Express "
"Device Control register, aborting.\n");
goto out;
}
linkctl = hca_header[(pcie_cap + PCI_EXP_LNKCTL) / 4];
- if (pci_write_config_word(dev->pdev, pcie_cap + PCI_EXP_LNKCTL,
- linkctl)) {
+ if (pcie_capability_write_word(dev->pdev, PCI_EXP_LNKCTL,
+ linkctl)) {
err = -ENODEV;
mlx4_err(dev, "Couldn't restore HCA PCI Express "
"Link control register, aborting.\n");
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index fa85cf1353fd..83516e3369c9 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -1078,22 +1078,16 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
#ifdef CONFIG_MYRI10GE_DCA
static int myri10ge_toggle_relaxed(struct pci_dev *pdev, int on)
{
- int ret, cap, err;
+ int ret;
u16 ctl;
- cap = pci_pcie_cap(pdev);
- if (!cap)
- return 0;
-
- err = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl);
- if (err)
- return 0;
+ pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &ctl);
ret = (ctl & PCI_EXP_DEVCTL_RELAX_EN) >> 4;
if (ret != on) {
ctl &= ~PCI_EXP_DEVCTL_RELAX_EN;
ctl |= (on << 4);
- pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl);
+ pcie_capability_write_word(pdev, PCI_EXP_DEVCTL, ctl);
}
return ret;
}
@@ -3192,18 +3186,13 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
struct device *dev = &mgp->pdev->dev;
int cap;
unsigned err_cap;
- u16 val;
- u8 ext_type;
int ret;
if (!myri10ge_ecrc_enable || !bridge)
return;
/* check that the bridge is a root port */
- cap = pci_pcie_cap(bridge);
- pci_read_config_word(bridge, cap + PCI_CAP_FLAGS, &val);
- ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4;
- if (ext_type != PCI_EXP_TYPE_ROOT_PORT) {
+ if (pci_pcie_type(bridge) != PCI_EXP_TYPE_ROOT_PORT) {
if (myri10ge_ecrc_enable > 1) {
struct pci_dev *prev_bridge, *old_bridge = bridge;
@@ -3218,11 +3207,8 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
" to force ECRC\n");
return;
}
- cap = pci_pcie_cap(bridge);
- pci_read_config_word(bridge,
- cap + PCI_CAP_FLAGS, &val);
- ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4;
- } while (ext_type != PCI_EXP_TYPE_ROOT_PORT);
+ } while (pci_pcie_type(bridge) !=
+ PCI_EXP_TYPE_ROOT_PORT);
dev_info(dev,
"Forcing ECRC on non-root port %s"
@@ -3335,11 +3321,10 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
int overridden = 0;
if (myri10ge_force_firmware == 0) {
- int link_width, exp_cap;
+ int link_width;
u16 lnk;
- exp_cap = pci_pcie_cap(mgp->pdev);
- pci_read_config_word(mgp->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk);
+ pcie_capability_read_word(mgp->pdev, PCI_EXP_LNKSTA, &lnk);
link_width = (lnk >> 4) & 0x3f;
/* Check to see if Link is less than 8 or if the
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
index d958c2299372..de50547c187d 100644
--- a/drivers/net/ethernet/neterion/s2io.c
+++ b/drivers/net/ethernet/neterion/s2io.c
@@ -484,7 +484,7 @@ static DEFINE_PCI_DEVICE_TABLE(s2io_tbl) = {
MODULE_DEVICE_TABLE(pci, s2io_tbl);
-static struct pci_error_handlers s2io_err_handler = {
+static const struct pci_error_handlers s2io_err_handler = {
.error_detected = s2io_io_error_detected,
.slot_reset = s2io_io_slot_reset,
.resume = s2io_io_resume,
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-config.c b/drivers/net/ethernet/neterion/vxge/vxge-config.c
index 32d06824fe3e..c2e420a84d22 100644
--- a/drivers/net/ethernet/neterion/vxge/vxge-config.c
+++ b/drivers/net/ethernet/neterion/vxge/vxge-config.c
@@ -757,7 +757,7 @@ __vxge_hw_verify_pci_e_info(struct __vxge_hw_device *hldev)
u16 lnk;
/* Get the negotiated link width and speed from PCI config space */
- pci_read_config_word(dev, dev->pcie_cap + PCI_EXP_LNKSTA, &lnk);
+ pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnk);
if ((lnk & PCI_EXP_LNKSTA_CLS) != 1)
return VXGE_HW_ERR_INVALID_PCI_INFO;
@@ -1982,7 +1982,7 @@ u16 vxge_hw_device_link_width_get(struct __vxge_hw_device *hldev)
struct pci_dev *dev = hldev->pdev;
u16 lnk;
- pci_read_config_word(dev, dev->pcie_cap + PCI_EXP_LNKSTA, &lnk);
+ pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnk);
return (lnk & VXGE_HW_PCI_EXP_LNKCAP_LNK_WIDTH) >> 4;
}
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c
index de2190443510..cfa71a30dc8d 100644
--- a/drivers/net/ethernet/neterion/vxge/vxge-main.c
+++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c
@@ -4799,7 +4799,7 @@ static void __devexit vxge_remove(struct pci_dev *pdev)
__LINE__);
}
-static struct pci_error_handlers vxge_err_handler = {
+static const struct pci_error_handlers vxge_err_handler = {
.error_detected = vxge_io_error_detected,
.slot_reset = vxge_io_slot_reset,
.resume = vxge_io_resume,
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index feb85d56c750..b2a94d02a521 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -2795,7 +2795,7 @@ static const struct dev_pm_ops pch_gbe_pm_ops = {
};
#endif
-static struct pci_error_handlers pch_gbe_err_handler = {
+static const struct pci_error_handlers pch_gbe_err_handler = {
.error_detected = pch_gbe_io_error_detected,
.slot_reset = pch_gbe_io_slot_reset,
.resume = pch_gbe_io_resume
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
index a77c558d8f40..df450616ab37 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
@@ -1386,7 +1386,7 @@ static void netxen_mask_aer_correctable(struct netxen_adapter *adapter)
adapter->ahw.board_type != NETXEN_BRDTYPE_P3_10G_TP)
return;
- if (root->pcie_type != PCI_EXP_TYPE_ROOT_PORT)
+ if (pci_pcie_type(root) != PCI_EXP_TYPE_ROOT_PORT)
return;
aer_pos = pci_find_ext_capability(root, PCI_EXT_CAP_ID_ERR);
@@ -3340,7 +3340,7 @@ netxen_free_vlan_ip_list(struct netxen_adapter *adapter)
{ }
#endif
-static struct pci_error_handlers netxen_err_handler = {
+static const struct pci_error_handlers netxen_err_handler = {
.error_detected = netxen_io_error_detected,
.slot_reset = netxen_io_slot_reset,
.resume = netxen_io_resume,
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 212c12193275..473ce134ca63 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -4522,7 +4522,7 @@ static void
qlcnic_restore_indev_addr(struct net_device *dev, unsigned long event)
{ }
#endif
-static struct pci_error_handlers qlcnic_err_handler = {
+static const struct pci_error_handlers qlcnic_err_handler = {
.error_detected = qlcnic_io_error_detected,
.slot_reset = qlcnic_io_slot_reset,
.resume = qlcnic_io_resume,
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
index b53a3b60b648..b262d6156816 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
@@ -4847,7 +4847,7 @@ static void qlge_io_resume(struct pci_dev *pdev)
netif_device_attach(ndev);
}
-static struct pci_error_handlers qlge_err_handler = {
+static const struct pci_error_handlers qlge_err_handler = {
.error_detected = qlge_io_error_detected,
.slot_reset = qlge_io_slot_reset,
.resume = qlge_io_resume,
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index b47d5b35024e..a7cc56007b33 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -833,15 +833,8 @@ static void rtl_unlock_work(struct rtl8169_private *tp)
static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
{
- int cap = pci_pcie_cap(pdev);
-
- if (cap) {
- u16 ctl;
-
- pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl);
- ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force;
- pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl);
- }
+ pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_READRQ, force);
}
struct rtl_cond {
@@ -4739,28 +4732,14 @@ static void rtl_ephy_init(struct rtl8169_private *tp, const struct ephy_info *e,
static void rtl_disable_clock_request(struct pci_dev *pdev)
{
- int cap = pci_pcie_cap(pdev);
-
- if (cap) {
- u16 ctl;
-
- pci_read_config_word(pdev, cap + PCI_EXP_LNKCTL, &ctl);
- ctl &= ~PCI_EXP_LNKCTL_CLKREQ_EN;
- pci_write_config_word(pdev, cap + PCI_EXP_LNKCTL, ctl);
- }
+ pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL,
+ PCI_EXP_LNKCTL_CLKREQ_EN);
}
static void rtl_enable_clock_request(struct pci_dev *pdev)
{
- int cap = pci_pcie_cap(pdev);
-
- if (cap) {
- u16 ctl;
-
- pci_read_config_word(pdev, cap + PCI_EXP_LNKCTL, &ctl);
- ctl |= PCI_EXP_LNKCTL_CLKREQ_EN;
- pci_write_config_word(pdev, cap + PCI_EXP_LNKCTL, ctl);
- }
+ pcie_capability_set_word(pdev, PCI_EXP_LNKCTL,
+ PCI_EXP_LNKCTL_CLKREQ_EN);
}
#define R8168_CPCMD_QUIRK_MASK (\
@@ -5405,14 +5384,9 @@ static void rtl_hw_start_8101(struct net_device *dev)
tp->event_slow &= ~RxFIFOOver;
if (tp->mac_version == RTL_GIGA_MAC_VER_13 ||
- tp->mac_version == RTL_GIGA_MAC_VER_16) {
- int cap = pci_pcie_cap(pdev);
-
- if (cap) {
- pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL,
- PCI_EXP_DEVCTL_NOSNOOP_EN);
- }
- }
+ tp->mac_version == RTL_GIGA_MAC_VER_16)
+ pcie_capability_set_word(pdev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_NOSNOOP_EN);
RTL_W8(Cfg9346, Cfg9346_Unlock);
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index c2a0fe393267..3208dca66758 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -9762,9 +9762,8 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev,
union niu_parent_id parent_id;
struct net_device *dev;
struct niu *np;
- int err, pos;
+ int err;
u64 dma_mask;
- u16 val16;
niu_driver_version();
@@ -9787,8 +9786,7 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev,
goto err_out_disable_pdev;
}
- pos = pci_pcie_cap(pdev);
- if (pos <= 0) {
+ if (!pci_is_pcie(pdev)) {
dev_err(&pdev->dev, "Cannot find PCI Express capability, aborting\n");
goto err_out_free_res;
}
@@ -9813,14 +9811,11 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev,
goto err_out_free_dev;
}
- pci_read_config_word(pdev, pos + PCI_EXP_DEVCTL, &val16);
- val16 &= ~PCI_EXP_DEVCTL_NOSNOOP_EN;
- val16 |= (PCI_EXP_DEVCTL_CERE |
- PCI_EXP_DEVCTL_NFERE |
- PCI_EXP_DEVCTL_FERE |
- PCI_EXP_DEVCTL_URRE |
- PCI_EXP_DEVCTL_RELAX_EN);
- pci_write_config_word(pdev, pos + PCI_EXP_DEVCTL, val16);
+ pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_NOSNOOP_EN,
+ PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE |
+ PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE |
+ PCI_EXP_DEVCTL_RELAX_EN);
dma_mask = DMA_BIT_MASK(44);
err = pci_set_dma_mask(pdev, dma_mask);
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index a978984d78a5..ef11dc639461 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -113,41 +113,32 @@ static void ath_pci_aspm_init(struct ath_common *common)
struct ath_hw *ah = sc->sc_ah;
struct pci_dev *pdev = to_pci_dev(sc->dev);
struct pci_dev *parent;
- int pos;
- u8 aspm;
+ u16 aspm;
if (!ah->is_pciexpress)
return;
- pos = pci_pcie_cap(pdev);
- if (!pos)
- return;
-
parent = pdev->bus->self;
if (!parent)
return;
if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
/* Bluetooth coexistance requires disabling ASPM. */
- pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &aspm);
- aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
- pci_write_config_byte(pdev, pos + PCI_EXP_LNKCTL, aspm);
+ pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL,
+ PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
/*
* Both upstream and downstream PCIe components should
* have the same ASPM settings.
*/
- pos = pci_pcie_cap(parent);
- pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm);
- aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
- pci_write_config_byte(parent, pos + PCI_EXP_LNKCTL, aspm);
+ pcie_capability_clear_word(parent, PCI_EXP_LNKCTL,
+ PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
ath_info(common, "Disabling ASPM since BTCOEX is enabled\n");
return;
}
- pos = pci_pcie_cap(parent);
- pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm);
+ pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &aspm);
if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) {
ah->aspm_enabled = true;
/* Initialize PCIe PM and SERDES registers. */
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index 5f5017767b99..724682669060 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -1832,10 +1832,8 @@ int il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd);
static inline u16
il_pcie_link_ctl(struct il_priv *il)
{
- int pos;
u16 pci_lnk_ctl;
- pos = pci_pcie_cap(il->pci_dev);
- pci_read_config_word(il->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
+ pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &pci_lnk_ctl);
return pci_lnk_ctl;
}
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index dbeebef562d5..063ecaff5b56 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -675,13 +675,10 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans)
static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
- int pos;
u16 pci_lnk_ctl;
- struct pci_dev *pci_dev = trans_pcie->pci_dev;
-
- pos = pci_pcie_cap(pci_dev);
- pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
+ pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_LNKCTL,
+ &pci_lnk_ctl);
return pci_lnk_ctl;
}
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 80f75d3ba84a..5983631a1b1a 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -372,13 +372,11 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev,
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
u8 tmp;
- int pos;
- u8 linkctrl_reg;
+ u16 linkctrl_reg;
/*Link Control Register */
- pos = pci_pcie_cap(pdev);
- pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &linkctrl_reg);
- pcipriv->ndis_adapter.linkctrl_reg = linkctrl_reg;
+ pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &linkctrl_reg);
+ pcipriv->ndis_adapter.linkctrl_reg = (u8)linkctrl_reg;
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Link Control Register =%x\n",
pcipriv->ndis_adapter.linkctrl_reg);
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index ffddc4f64268..fb6a1fe21b93 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -477,14 +477,12 @@ dino_card_setup(struct pci_bus *bus, void __iomem *base_addr)
if (ccio_allocate_resource(dino_dev->hba.dev, res, _8MB,
F_EXTEND(0xf0000000UL) | _8MB,
F_EXTEND(0xffffffffUL) &~ _8MB, _8MB) < 0) {
- struct list_head *ln, *tmp_ln;
+ struct pci_dev *dev, *tmp;
printk(KERN_ERR "Dino: cannot attach bus %s\n",
dev_name(bus->bridge));
/* kill the bus, we can't do anything with it */
- list_for_each_safe(ln, tmp_ln, &bus->devices) {
- struct pci_dev *dev = pci_dev_b(ln);
-
+ list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
list_del(&dev->bus_list);
}
@@ -549,7 +547,6 @@ dino_card_fixup(struct pci_dev *dev)
static void __init
dino_fixup_bus(struct pci_bus *bus)
{
- struct list_head *ln;
struct pci_dev *dev;
struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge));
@@ -596,8 +593,7 @@ dino_fixup_bus(struct pci_bus *bus)
}
- list_for_each(ln, &bus->devices) {
- dev = pci_dev_b(ln);
+ list_for_each_entry(dev, &bus->devices, bus_list) {
if (is_card_dino(&dino_dev->hba.dev->id))
dino_card_fixup(dev);
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 4f9cf2456f4e..fdd63a6a62d6 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -629,7 +629,7 @@ truncate_pat_collision(struct resource *root, struct resource *new)
static void
lba_fixup_bus(struct pci_bus *bus)
{
- struct list_head *ln;
+ struct pci_dev *dev;
#ifdef FBB_SUPPORT
u16 status;
#endif
@@ -710,9 +710,8 @@ lba_fixup_bus(struct pci_bus *bus)
}
- list_for_each(ln, &bus->devices) {
+ list_for_each_entry(dev, &bus->devices, bus_list) {
int i;
- struct pci_dev *dev = pci_dev_b(ln);
DBG("lba_fixup_bus() %s\n", pci_name(dev));
@@ -770,7 +769,7 @@ lba_fixup_bus(struct pci_bus *bus)
}
/* Lastly enable FBB/PERR/SERR on all devices too */
- list_for_each(ln, &bus->devices) {
+ list_for_each_entry(dev, &bus->devices, bus_list) {
(void) pci_read_config_word(dev, PCI_COMMAND, &status);
status |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR | fbb_enable;
(void) pci_write_config_word(dev, PCI_COMMAND, status);
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 848bfb84c04c..6d51aa68ec7a 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -3,7 +3,6 @@
#
config ARCH_SUPPORTS_MSI
bool
- default n
config PCI_MSI
bool "Message Signaled Interrupts (MSI and MSI-X)"
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index ba91a7e17519..3af0478c057b 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -469,3 +469,205 @@ void pci_cfg_access_unlock(struct pci_dev *dev)
raw_spin_unlock_irqrestore(&pci_lock, flags);
}
EXPORT_SYMBOL_GPL(pci_cfg_access_unlock);
+
+static inline int pcie_cap_version(const struct pci_dev *dev)
+{
+ return dev->pcie_flags_reg & PCI_EXP_FLAGS_VERS;
+}
+
+static inline bool pcie_cap_has_devctl(const struct pci_dev *dev)
+{
+ return true;
+}
+
+static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev)
+{
+ int type = pci_pcie_type(dev);
+
+ return pcie_cap_version(dev) > 1 ||
+ type == PCI_EXP_TYPE_ROOT_PORT ||
+ type == PCI_EXP_TYPE_ENDPOINT ||
+ type == PCI_EXP_TYPE_LEG_END;
+}
+
+static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev)
+{
+ int type = pci_pcie_type(dev);
+
+ return pcie_cap_version(dev) > 1 ||
+ type == PCI_EXP_TYPE_ROOT_PORT ||
+ (type == PCI_EXP_TYPE_DOWNSTREAM &&
+ dev->pcie_flags_reg & PCI_EXP_FLAGS_SLOT);
+}
+
+static inline bool pcie_cap_has_rtctl(const struct pci_dev *dev)
+{
+ int type = pci_pcie_type(dev);
+
+ return pcie_cap_version(dev) > 1 ||
+ type == PCI_EXP_TYPE_ROOT_PORT ||
+ type == PCI_EXP_TYPE_RC_EC;
+}
+
+static bool pcie_capability_reg_implemented(struct pci_dev *dev, int pos)
+{
+ if (!pci_is_pcie(dev))
+ return false;
+
+ switch (pos) {
+ case PCI_EXP_FLAGS_TYPE:
+ return true;
+ case PCI_EXP_DEVCAP:
+ case PCI_EXP_DEVCTL:
+ case PCI_EXP_DEVSTA:
+ return pcie_cap_has_devctl(dev);
+ case PCI_EXP_LNKCAP:
+ case PCI_EXP_LNKCTL:
+ case PCI_EXP_LNKSTA:
+ return pcie_cap_has_lnkctl(dev);
+ case PCI_EXP_SLTCAP:
+ case PCI_EXP_SLTCTL:
+ case PCI_EXP_SLTSTA:
+ return pcie_cap_has_sltctl(dev);
+ case PCI_EXP_RTCTL:
+ case PCI_EXP_RTCAP:
+ case PCI_EXP_RTSTA:
+ return pcie_cap_has_rtctl(dev);
+ case PCI_EXP_DEVCAP2:
+ case PCI_EXP_DEVCTL2:
+ case PCI_EXP_LNKCAP2:
+ case PCI_EXP_LNKCTL2:
+ case PCI_EXP_LNKSTA2:
+ return pcie_cap_version(dev) > 1;
+ default:
+ return false;
+ }
+}
+
+/*
+ * Note that these accessor functions are only for the "PCI Express
+ * Capability" (see PCIe spec r3.0, sec 7.8). They do not apply to the
+ * other "PCI Express Extended Capabilities" (AER, VC, ACS, MFVC, etc.)
+ */
+int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val)
+{
+ int ret;
+
+ *val = 0;
+ if (pos & 1)
+ return -EINVAL;
+
+ if (pcie_capability_reg_implemented(dev, pos)) {
+ ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val);
+ /*
+ * Reset *val to 0 if pci_read_config_word() fails, it may
+ * have been written as 0xFFFF if hardware error happens
+ * during pci_read_config_word().
+ */
+ if (ret)
+ *val = 0;
+ return ret;
+ }
+
+ /*
+ * For Functions that do not implement the Slot Capabilities,
+ * Slot Status, and Slot Control registers, these spaces must
+ * be hardwired to 0b, with the exception of the Presence Detect
+ * State bit in the Slot Status register of Downstream Ports,
+ * which must be hardwired to 1b. (PCIe Base Spec 3.0, sec 7.8)
+ */
+ if (pci_is_pcie(dev) && pos == PCI_EXP_SLTSTA &&
+ pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) {
+ *val = PCI_EXP_SLTSTA_PDS;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(pcie_capability_read_word);
+
+int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val)
+{
+ int ret;
+
+ *val = 0;
+ if (pos & 3)
+ return -EINVAL;
+
+ if (pcie_capability_reg_implemented(dev, pos)) {
+ ret = pci_read_config_dword(dev, pci_pcie_cap(dev) + pos, val);
+ /*
+ * Reset *val to 0 if pci_read_config_dword() fails, it may
+ * have been written as 0xFFFFFFFF if hardware error happens
+ * during pci_read_config_dword().
+ */
+ if (ret)
+ *val = 0;
+ return ret;
+ }
+
+ if (pci_is_pcie(dev) && pos == PCI_EXP_SLTCTL &&
+ pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) {
+ *val = PCI_EXP_SLTSTA_PDS;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(pcie_capability_read_dword);
+
+int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val)
+{
+ if (pos & 1)
+ return -EINVAL;
+
+ if (!pcie_capability_reg_implemented(dev, pos))
+ return 0;
+
+ return pci_write_config_word(dev, pci_pcie_cap(dev) + pos, val);
+}
+EXPORT_SYMBOL(pcie_capability_write_word);
+
+int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val)
+{
+ if (pos & 3)
+ return -EINVAL;
+
+ if (!pcie_capability_reg_implemented(dev, pos))
+ return 0;
+
+ return pci_write_config_dword(dev, pci_pcie_cap(dev) + pos, val);
+}
+EXPORT_SYMBOL(pcie_capability_write_dword);
+
+int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos,
+ u16 clear, u16 set)
+{
+ int ret;
+ u16 val;
+
+ ret = pcie_capability_read_word(dev, pos, &val);
+ if (!ret) {
+ val &= ~clear;
+ val |= set;
+ ret = pcie_capability_write_word(dev, pos, val);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(pcie_capability_clear_and_set_word);
+
+int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos,
+ u32 clear, u32 set)
+{
+ int ret;
+ u32 val;
+
+ ret = pcie_capability_read_dword(dev, pos, &val);
+ if (!ret) {
+ val &= ~clear;
+ val |= set;
+ ret = pcie_capability_write_dword(dev, pos, val);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(pcie_capability_clear_and_set_dword);
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 4b0970b46e0b..6241fd05bd41 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -87,11 +87,15 @@ EXPORT_SYMBOL_GPL(pci_bus_resource_n);
void pci_bus_remove_resources(struct pci_bus *bus)
{
int i;
+ struct pci_bus_resource *bus_res, *tmp;
for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++)
bus->resource[i] = NULL;
- pci_free_resource_list(&bus->resources);
+ list_for_each_entry_safe(bus_res, tmp, &bus->resources, list) {
+ list_del(&bus_res->list);
+ kfree(bus_res);
+ }
}
/**
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
index 66f29bc00be4..b0e46dede1a9 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -17,28 +17,6 @@ menuconfig HOTPLUG_PCI
if HOTPLUG_PCI
-config HOTPLUG_PCI_FAKE
- tristate "Fake PCI Hotplug driver"
- help
- Say Y here if you want to use the fake PCI hotplug driver. It can
- be used to simulate PCI hotplug events if even if your system is
- not PCI hotplug capable.
-
- This driver will "emulate" removing PCI devices from the system.
- If the "power" file is written to with "0" then the specified PCI
- device will be completely removed from the kernel.
-
- WARNING, this does NOT turn off the power to the PCI device.
- This is a "logical" removal, not a physical or electrical
- removal.
-
- Use this module at your own risk. You have been warned!
-
- To compile this driver as a module, choose M here: the
- module will be called fakephp.
-
- When in doubt, say N.
-
config HOTPLUG_PCI_COMPAQ
tristate "Compaq PCI Hotplug driver"
depends on X86 && PCI_BIOS
@@ -143,7 +121,7 @@ config HOTPLUG_PCI_SHPC
config HOTPLUG_PCI_RPA
tristate "RPA PCI Hotplug driver"
- depends on PPC_PSERIES && EEH && !HOTPLUG_PCI_FAKE
+ depends on PPC_PSERIES && EEH
help
Say Y here if you have a RPA system that supports PCI Hotplug.
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index 6cd9f3c9887d..c459cd4e39c2 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -23,9 +23,6 @@ obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o
obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o
-# Link this last so it doesn't claim devices that have a real hotplug driver
-obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o
-
pci_hotplug-objs := pci_hotplug_core.o pcihp_slot.o
ifdef CONFIG_HOTPLUG_PCI_CPCI
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index ad6fd6695495..3d6d4fd1e3c5 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -115,6 +115,35 @@ static const struct acpi_dock_ops acpiphp_dock_ops = {
.handler = handle_hotplug_event_func,
};
+/* Check whether the PCI device is managed by native PCIe hotplug driver */
+static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev)
+{
+ u32 reg32;
+ acpi_handle tmp;
+ struct acpi_pci_root *root;
+
+ /* Check whether the PCIe port supports native PCIe hotplug */
+ if (pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &reg32))
+ return false;
+ if (!(reg32 & PCI_EXP_SLTCAP_HPC))
+ return false;
+
+ /*
+ * Check whether native PCIe hotplug has been enabled for
+ * this PCIe hierarchy.
+ */
+ tmp = acpi_find_root_bridge_handle(pdev);
+ if (!tmp)
+ return false;
+ root = acpi_pci_find_root(tmp);
+ if (!root)
+ return false;
+ if (!(root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL))
+ return false;
+
+ return true;
+}
+
/* callback routine to register each ACPI PCI slot object */
static acpi_status
register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
@@ -142,16 +171,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
function = adr & 0xffff;
pdev = pbus->self;
- if (pdev && pci_is_pcie(pdev)) {
- tmp = acpi_find_root_bridge_handle(pdev);
- if (tmp) {
- struct acpi_pci_root *root = acpi_pci_find_root(tmp);
-
- if (root && (root->osc_control_set &
- OSC_PCI_EXPRESS_NATIVE_HP_CONTROL))
- return AE_OK;
- }
- }
+ if (pdev && device_is_managed_by_native_pciehp(pdev))
+ return AE_OK;
newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL);
if (!newfunc)
@@ -382,10 +403,10 @@ static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge)
/* allocate and initialize host bridge data structure */
-static void add_host_bridge(acpi_handle *handle)
+static void add_host_bridge(struct acpi_pci_root *root)
{
struct acpiphp_bridge *bridge;
- struct acpi_pci_root *root = acpi_pci_find_root(handle);
+ acpi_handle handle = root->device->handle;
bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
if (bridge == NULL)
@@ -468,11 +489,12 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
/* find hot-pluggable slots, and then find P2P bridge */
-static int add_bridge(acpi_handle handle)
+static int add_bridge(struct acpi_pci_root *root)
{
acpi_status status;
unsigned long long tmp;
acpi_handle dummy_handle;
+ acpi_handle handle = root->device->handle;
/* if the bridge doesn't have _STA, we assume it is always there */
status = acpi_get_handle(handle, "_STA", &dummy_handle);
@@ -490,7 +512,7 @@ static int add_bridge(acpi_handle handle)
/* check if this bridge has ejectable slots */
if (detect_ejectable_slots(handle) > 0) {
dbg("found PCI host-bus bridge with hot-pluggable slots\n");
- add_host_bridge(handle);
+ add_host_bridge(root);
}
/* search P2P bridges under this host bridge */
@@ -588,9 +610,10 @@ cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
return AE_OK;
}
-static void remove_bridge(acpi_handle handle)
+static void remove_bridge(struct acpi_pci_root *root)
{
struct acpiphp_bridge *bridge;
+ acpi_handle handle = root->device->handle;
/* cleanup p2p bridges under this host bridge
in a depth-first manner */
@@ -869,17 +892,6 @@ static int __ref enable_device(struct acpiphp_slot *slot)
return retval;
}
-static void disable_bridges(struct pci_bus *bus)
-{
- struct pci_dev *dev;
- list_for_each_entry(dev, &bus->devices, bus_list) {
- if (dev->subordinate) {
- disable_bridges(dev->subordinate);
- pci_disable_device(dev);
- }
- }
-}
-
/* return first device in slot, acquiring a reference on it */
static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot)
{
@@ -931,12 +943,7 @@ static int disable_device(struct acpiphp_slot *slot)
* here.
*/
while ((pdev = dev_in_slot(slot))) {
- pci_stop_bus_device(pdev);
- if (pdev->subordinate) {
- disable_bridges(pdev->subordinate);
- pci_disable_device(pdev);
- }
- __pci_remove_bus_device(pdev);
+ pci_stop_and_remove_bus_device(pdev);
pci_dev_put(pdev);
}
@@ -1477,34 +1484,6 @@ int __init acpiphp_get_num_slots(void)
}
-#if 0
-/**
- * acpiphp_for_each_slot - call function for each slot
- * @fn: callback function
- * @data: context to be passed to callback function
- */
-static int acpiphp_for_each_slot(acpiphp_callback fn, void *data)
-{
- struct list_head *node;
- struct acpiphp_bridge *bridge;
- struct acpiphp_slot *slot;
- int retval = 0;
-
- list_for_each (node, &bridge_list) {
- bridge = (struct acpiphp_bridge *)node;
- for (slot = bridge->slots; slot; slot = slot->next) {
- retval = fn(slot, data);
- if (!retval)
- goto err_exit;
- }
- }
-
- err_exit:
- return retval;
-}
-#endif
-
-
/**
* acpiphp_enable_slot - power on slot
* @slot: ACPI PHP slot
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c
index 81af764c629b..a6a71c41cdf8 100644
--- a/drivers/pci/hotplug/cpcihp_generic.c
+++ b/drivers/pci/hotplug/cpcihp_generic.c
@@ -154,12 +154,8 @@ static int __init cpcihp_generic_init(void)
if(!r)
return -EBUSY;
- bus = pci_find_bus(0, bridge_busnr);
- if (!bus) {
- err("Invalid bus number %d", bridge_busnr);
- return -EINVAL;
- }
- dev = pci_get_slot(bus, PCI_DEVFN(bridge_slot, 0));
+ dev = pci_get_domain_bus_and_slot(0, bridge_busnr,
+ PCI_DEVFN(bridge_slot, 0));
if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
err("Invalid bridge device %s", bridge);
pci_dev_put(dev);
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
index e43908d9b5df..36112fe212d3 100644
--- a/drivers/pci/hotplug/cpqphp_ctrl.c
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -2890,27 +2890,8 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
func->mem_head = mem_node;
} else
return -ENOMEM;
- } else if ((temp_register & 0x0BL) == 0x04) {
- /* Map memory */
- base = temp_register & 0xFFFFFFF0;
- base = ~base + 1;
-
- dbg("CND: length = 0x%x\n", base);
- mem_node = get_resource(&(resources->mem_head), base);
-
- /* allocate the resource to the board */
- if (mem_node) {
- base = mem_node->base;
-
- mem_node->next = func->mem_head;
- func->mem_head = mem_node;
- } else
- return -ENOMEM;
- } else if ((temp_register & 0x0BL) == 0x06) {
- /* Those bits are reserved, we can't handle this */
- return 1;
} else {
- /* Requesting space below 1M */
+ /* Reserved bits or requesting space below 1M */
return NOT_ENOUGH_RESOURCES;
}
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
deleted file mode 100644
index a019c9a712be..000000000000
--- a/drivers/pci/hotplug/fakephp.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/* Works like the fakephp driver used to, except a little better.
- *
- * - It's possible to remove devices with subordinate busses.
- * - New PCI devices that appear via any method, not just a fakephp triggered
- * rescan, will be noticed.
- * - Devices that are removed via any method, not just a fakephp triggered
- * removal, will also be noticed.
- *
- * Uses nothing from the pci-hotplug subsystem.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/kobject.h>
-#include <linux/sysfs.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include "../pci.h"
-
-struct legacy_slot {
- struct kobject kobj;
- struct pci_dev *dev;
- struct list_head list;
-};
-
-static LIST_HEAD(legacy_list);
-
-static ssize_t legacy_show(struct kobject *kobj, struct attribute *attr,
- char *buf)
-{
- struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
- strcpy(buf, "1\n");
- return 2;
-}
-
-static void remove_callback(void *data)
-{
- pci_stop_and_remove_bus_device((struct pci_dev *)data);
-}
-
-static ssize_t legacy_store(struct kobject *kobj, struct attribute *attr,
- const char *buf, size_t len)
-{
- struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
- unsigned long val;
-
- if (strict_strtoul(buf, 0, &val) < 0)
- return -EINVAL;
-
- if (val)
- pci_rescan_bus(slot->dev->bus);
- else
- sysfs_schedule_callback(&slot->dev->dev.kobj, remove_callback,
- slot->dev, THIS_MODULE);
- return len;
-}
-
-static struct attribute *legacy_attrs[] = {
- &(struct attribute){ .name = "power", .mode = 0644 },
- NULL,
-};
-
-static void legacy_release(struct kobject *kobj)
-{
- struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
-
- pci_dev_put(slot->dev);
- kfree(slot);
-}
-
-static struct kobj_type legacy_ktype = {
- .sysfs_ops = &(const struct sysfs_ops){
- .store = legacy_store, .show = legacy_show
- },
- .release = &legacy_release,
- .default_attrs = legacy_attrs,
-};
-
-static int legacy_add_slot(struct pci_dev *pdev)
-{
- struct legacy_slot *slot = kzalloc(sizeof(*slot), GFP_KERNEL);
-
- if (!slot)
- return -ENOMEM;
-
- if (kobject_init_and_add(&slot->kobj, &legacy_ktype,
- &pci_slots_kset->kobj, "%s",
- dev_name(&pdev->dev))) {
- dev_warn(&pdev->dev, "Failed to created legacy fake slot\n");
- return -EINVAL;
- }
- slot->dev = pci_dev_get(pdev);
-
- list_add(&slot->list, &legacy_list);
-
- return 0;
-}
-
-static int legacy_notify(struct notifier_block *nb,
- unsigned long action, void *data)
-{
- struct pci_dev *pdev = to_pci_dev(data);
-
- if (action == BUS_NOTIFY_ADD_DEVICE) {
- legacy_add_slot(pdev);
- } else if (action == BUS_NOTIFY_DEL_DEVICE) {
- struct legacy_slot *slot;
-
- list_for_each_entry(slot, &legacy_list, list)
- if (slot->dev == pdev)
- goto found;
-
- dev_warn(&pdev->dev, "Missing legacy fake slot?");
- return -ENODEV;
-found:
- kobject_del(&slot->kobj);
- list_del(&slot->list);
- kobject_put(&slot->kobj);
- }
-
- return 0;
-}
-
-static struct notifier_block legacy_notifier = {
- .notifier_call = legacy_notify
-};
-
-static int __init init_legacy(void)
-{
- struct pci_dev *pdev = NULL;
-
- /* Add existing devices */
- for_each_pci_dev(pdev)
- legacy_add_slot(pdev);
-
- /* Be alerted of any new ones */
- bus_register_notifier(&pci_bus_type, &legacy_notifier);
- return 0;
-}
-module_init(init_legacy);
-
-static void __exit remove_legacy(void)
-{
- struct legacy_slot *slot, *tmp;
-
- bus_unregister_notifier(&pci_bus_type, &legacy_notifier);
-
- list_for_each_entry_safe(slot, tmp, &legacy_list, list) {
- list_del(&slot->list);
- kobject_del(&slot->kobj);
- kobject_put(&slot->kobj);
- }
-}
-module_exit(remove_legacy);
-
-
-MODULE_AUTHOR("Trent Piepho <xyzzy@speakeasy.org>");
-MODULE_DESCRIPTION("Legacy version of the fakephp interface");
-MODULE_LICENSE("GPL");
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c
index 376d70d17176..24d709b7388c 100644
--- a/drivers/pci/hotplug/pciehp_acpi.c
+++ b/drivers/pci/hotplug/pciehp_acpi.c
@@ -81,16 +81,12 @@ static struct list_head __initdata dummy_slots = LIST_HEAD_INIT(dummy_slots);
/* Dummy driver for dumplicate name detection */
static int __init dummy_probe(struct pcie_device *dev)
{
- int pos;
u32 slot_cap;
acpi_handle handle;
struct dummy_slot *slot, *tmp;
struct pci_dev *pdev = dev->port;
- pos = pci_pcie_cap(pdev);
- if (!pos)
- return -ENODEV;
- pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap);
+ pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap);
slot = kzalloc(sizeof(*slot), GFP_KERNEL);
if (!slot)
return -ENOMEM;
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 365c6b96c642..916bf4f53aba 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -300,24 +300,24 @@ static int pciehp_suspend (struct pcie_device *dev)
static int pciehp_resume (struct pcie_device *dev)
{
+ struct controller *ctrl;
+ struct slot *slot;
+ u8 status;
+
dev_info(&dev->device, "%s ENTRY\n", __func__);
- if (pciehp_force) {
- struct controller *ctrl = get_service_data(dev);
- struct slot *slot;
- u8 status;
+ ctrl = get_service_data(dev);
- /* reinitialize the chipset's event detection logic */
- pcie_enable_notification(ctrl);
+ /* reinitialize the chipset's event detection logic */
+ pcie_enable_notification(ctrl);
- slot = ctrl->slot;
+ slot = ctrl->slot;
- /* Check if slot is occupied */
- pciehp_get_adapter_status(slot, &status);
- if (status)
- pciehp_enable_slot(slot);
- else
- pciehp_disable_slot(slot);
- }
+ /* Check if slot is occupied */
+ pciehp_get_adapter_status(slot, &status);
+ if (status)
+ pciehp_enable_slot(slot);
+ else
+ pciehp_disable_slot(slot);
return 0;
}
#endif /* PM */
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 302451e8289d..13b2eaf7ba43 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -44,25 +44,25 @@
static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value)
{
struct pci_dev *dev = ctrl->pcie->port;
- return pci_read_config_word(dev, pci_pcie_cap(dev) + reg, value);
+ return pcie_capability_read_word(dev, reg, value);
}
static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value)
{
struct pci_dev *dev = ctrl->pcie->port;
- return pci_read_config_dword(dev, pci_pcie_cap(dev) + reg, value);
+ return pcie_capability_read_dword(dev, reg, value);
}
static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value)
{
struct pci_dev *dev = ctrl->pcie->port;
- return pci_write_config_word(dev, pci_pcie_cap(dev) + reg, value);
+ return pcie_capability_write_word(dev, reg, value);
}
static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
{
struct pci_dev *dev = ctrl->pcie->port;
- return pci_write_config_dword(dev, pci_pcie_cap(dev) + reg, value);
+ return pcie_capability_write_dword(dev, reg, value);
}
/* Power Control Command */
@@ -855,10 +855,6 @@ struct controller *pcie_init(struct pcie_device *dev)
goto abort;
}
ctrl->pcie = dev;
- if (!pci_pcie_cap(pdev)) {
- ctrl_err(ctrl, "Cannot find PCI Express capability\n");
- goto abort_ctrl;
- }
if (pciehp_readl(ctrl, PCI_EXP_SLTCAP, &slot_cap)) {
ctrl_err(ctrl, "Cannot read SLOTCAP register\n");
goto abort_ctrl;
diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c
index 8c05a18c9770..fec2d5b75440 100644
--- a/drivers/pci/hotplug/pcihp_slot.c
+++ b/drivers/pci/hotplug/pcihp_slot.c
@@ -96,17 +96,11 @@ static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp)
static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
{
int pos;
- u16 reg16;
u32 reg32;
if (!hpp)
return;
- /* Find PCI Express capability */
- pos = pci_pcie_cap(dev);
- if (!pos)
- return;
-
if (hpp->revision > 1) {
dev_warn(&dev->dev, "PCIe settings rev %d not supported\n",
hpp->revision);
@@ -114,17 +108,13 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
}
/* Initialize Device Control Register */
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
- reg16 = (reg16 & hpp->pci_exp_devctl_and) | hpp->pci_exp_devctl_or;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
+ pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
+ ~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or);
/* Initialize Link Control Register */
- if (dev->subordinate) {
- pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &reg16);
- reg16 = (reg16 & hpp->pci_exp_lnkctl_and)
- | hpp->pci_exp_lnkctl_or;
- pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, reg16);
- }
+ if (dev->subordinate)
+ pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
+ ~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or);
/* Find Advanced Error Reporting Enhanced Capability */
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 74bbaf82638d..aeccc911abb8 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -433,8 +433,8 @@ static int sriov_init(struct pci_dev *dev, int pos)
struct resource *res;
struct pci_dev *pdev;
- if (dev->pcie_type != PCI_EXP_TYPE_RC_END &&
- dev->pcie_type != PCI_EXP_TYPE_ENDPOINT)
+ 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);
@@ -503,7 +503,7 @@ found:
iov->self = dev;
pci_read_config_dword(dev, pos + PCI_SRIOV_CAP, &iov->cap);
pci_read_config_byte(dev, pos + PCI_SRIOV_FUNC_LINK, &iov->link);
- if (dev->pcie_type == PCI_EXP_TYPE_RC_END)
+ if (pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END)
iov->link = PCI_DEVFN(PCI_SLOT(dev->devfn), iov->link);
if (pdev)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index d6fd6b6d9d4b..9e1d2959e226 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -139,7 +139,6 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count)
return retval;
return count;
}
-static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
/**
* store_remove_id - remove a PCI device ID from this driver
@@ -185,38 +184,16 @@ store_remove_id(struct device_driver *driver, const char *buf, size_t count)
return retval;
return count;
}
-static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id);
-static int
-pci_create_newid_files(struct pci_driver *drv)
-{
- int error = 0;
+static struct driver_attribute pci_drv_attrs[] = {
+ __ATTR(new_id, S_IWUSR, NULL, store_new_id),
+ __ATTR(remove_id, S_IWUSR, NULL, store_remove_id),
+ __ATTR_NULL,
+};
- if (drv->probe != NULL) {
- error = driver_create_file(&drv->driver, &driver_attr_new_id);
- if (error == 0) {
- error = driver_create_file(&drv->driver,
- &driver_attr_remove_id);
- if (error)
- driver_remove_file(&drv->driver,
- &driver_attr_new_id);
- }
- }
- return error;
-}
-
-static void pci_remove_newid_files(struct pci_driver *drv)
-{
- driver_remove_file(&drv->driver, &driver_attr_remove_id);
- driver_remove_file(&drv->driver, &driver_attr_new_id);
-}
-#else /* !CONFIG_HOTPLUG */
-static inline int pci_create_newid_files(struct pci_driver *drv)
-{
- return 0;
-}
-static inline void pci_remove_newid_files(struct pci_driver *drv) {}
-#endif
+#else
+#define pci_drv_attrs NULL
+#endif /* CONFIG_HOTPLUG */
/**
* pci_match_id - See if a pci device matches a given pci_id table
@@ -1162,8 +1139,6 @@ const struct dev_pm_ops pci_dev_pm_ops = {
int __pci_register_driver(struct pci_driver *drv, struct module *owner,
const char *mod_name)
{
- int error;
-
/* initialize common driver fields */
drv->driver.name = drv->name;
drv->driver.bus = &pci_bus_type;
@@ -1174,19 +1149,7 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner,
INIT_LIST_HEAD(&drv->dynids.list);
/* register with core */
- error = driver_register(&drv->driver);
- if (error)
- goto out;
-
- error = pci_create_newid_files(drv);
- if (error)
- goto out_newid;
-out:
- return error;
-
-out_newid:
- driver_unregister(&drv->driver);
- goto out;
+ return driver_register(&drv->driver);
}
/**
@@ -1202,7 +1165,6 @@ out_newid:
void
pci_unregister_driver(struct pci_driver *drv)
{
- pci_remove_newid_files(drv);
driver_unregister(&drv->driver);
pci_free_dynids(drv);
}
@@ -1302,6 +1264,7 @@ struct bus_type pci_bus_type = {
.shutdown = pci_device_shutdown,
.dev_attrs = pci_dev_attrs,
.bus_attrs = pci_bus_attrs,
+ .drv_attrs = pci_drv_attrs,
.pm = PCI_PM_OPS_PTR,
};
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index ab4bf5a4c2f1..54858838f098 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -254,52 +254,17 @@ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
}
/**
- * pci_pcie_cap2 - query for devices' PCI_CAP_ID_EXP v2 capability structure
- * @dev: PCI device to check
- *
- * Like pci_pcie_cap() but also checks that the PCIe capability version is
- * >= 2. Note that v1 capability structures could be sparse in that not
- * all register fields were required. v2 requires the entire structure to
- * be present size wise, while still allowing for non-implemented registers
- * to exist but they must be hardwired to 0.
- *
- * Due to the differences in the versions of capability structures, one
- * must be careful not to try and access non-existant registers that may
- * exist in early versions - v1 - of Express devices.
- *
- * Returns the offset of the PCIe capability structure as long as the
- * capability version is >= 2; otherwise 0 is returned.
- */
-static int pci_pcie_cap2(struct pci_dev *dev)
-{
- u16 flags;
- int pos;
-
- pos = pci_pcie_cap(dev);
- if (pos) {
- pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags);
- if ((flags & PCI_EXP_FLAGS_VERS) < 2)
- pos = 0;
- }
-
- return pos;
-}
-
-/**
- * pci_find_ext_capability - Find an extended capability
+ * pci_find_next_ext_capability - Find an extended capability
* @dev: PCI device to query
+ * @start: address at which to start looking (0 to start at beginning of list)
* @cap: capability code
*
- * Returns the address of the requested extended capability structure
+ * Returns the address of the next matching extended capability structure
* within the device's PCI configuration space or 0 if the device does
- * not support it. Possible values for @cap:
- *
- * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting
- * %PCI_EXT_CAP_ID_VC Virtual Channel
- * %PCI_EXT_CAP_ID_DSN Device Serial Number
- * %PCI_EXT_CAP_ID_PWR Power Budgeting
+ * not support it. Some capabilities can occur several times, e.g., the
+ * vendor-specific capability, and this provides a way to find them all.
*/
-int pci_find_ext_capability(struct pci_dev *dev, int cap)
+int pci_find_next_ext_capability(struct pci_dev *dev, int start, int cap)
{
u32 header;
int ttl;
@@ -311,6 +276,9 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
if (dev->cfg_size <= PCI_CFG_SPACE_SIZE)
return 0;
+ if (start)
+ pos = start;
+
if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
return 0;
@@ -322,7 +290,7 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
return 0;
while (ttl-- > 0) {
- if (PCI_EXT_CAP_ID(header) == cap)
+ if (PCI_EXT_CAP_ID(header) == cap && pos != start)
return pos;
pos = PCI_EXT_CAP_NEXT(header);
@@ -335,6 +303,26 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
return 0;
}
+EXPORT_SYMBOL_GPL(pci_find_next_ext_capability);
+
+/**
+ * pci_find_ext_capability - Find an extended capability
+ * @dev: PCI device to query
+ * @cap: capability code
+ *
+ * Returns the address of the requested extended capability structure
+ * within the device's PCI configuration space or 0 if the device does
+ * not support it. Possible values for @cap:
+ *
+ * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting
+ * %PCI_EXT_CAP_ID_VC Virtual Channel
+ * %PCI_EXT_CAP_ID_DSN Device Serial Number
+ * %PCI_EXT_CAP_ID_PWR Power Budgeting
+ */
+int pci_find_ext_capability(struct pci_dev *dev, int cap)
+{
+ return pci_find_next_ext_capability(dev, 0, cap);
+}
EXPORT_SYMBOL_GPL(pci_find_ext_capability);
static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap)
@@ -854,21 +842,6 @@ EXPORT_SYMBOL(pci_choose_state);
#define PCI_EXP_SAVE_REGS 7
-#define pcie_cap_has_devctl(type, flags) 1
-#define pcie_cap_has_lnkctl(type, flags) \
- ((flags & PCI_EXP_FLAGS_VERS) > 1 || \
- (type == PCI_EXP_TYPE_ROOT_PORT || \
- type == PCI_EXP_TYPE_ENDPOINT || \
- type == PCI_EXP_TYPE_LEG_END))
-#define pcie_cap_has_sltctl(type, flags) \
- ((flags & PCI_EXP_FLAGS_VERS) > 1 || \
- ((type == PCI_EXP_TYPE_ROOT_PORT) || \
- (type == PCI_EXP_TYPE_DOWNSTREAM && \
- (flags & PCI_EXP_FLAGS_SLOT))))
-#define pcie_cap_has_rtctl(type, flags) \
- ((flags & PCI_EXP_FLAGS_VERS) > 1 || \
- (type == PCI_EXP_TYPE_ROOT_PORT || \
- type == PCI_EXP_TYPE_RC_EC))
static struct pci_cap_saved_state *pci_find_saved_cap(
struct pci_dev *pci_dev, char cap)
@@ -885,13 +858,11 @@ static struct pci_cap_saved_state *pci_find_saved_cap(
static int pci_save_pcie_state(struct pci_dev *dev)
{
- int pos, i = 0;
+ int i = 0;
struct pci_cap_saved_state *save_state;
u16 *cap;
- u16 flags;
- pos = pci_pcie_cap(dev);
- if (!pos)
+ if (!pci_is_pcie(dev))
return 0;
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
@@ -899,60 +870,37 @@ static int pci_save_pcie_state(struct pci_dev *dev)
dev_err(&dev->dev, "buffer not found in %s\n", __func__);
return -ENOMEM;
}
- cap = (u16 *)&save_state->cap.data[0];
-
- pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags);
- if (pcie_cap_has_devctl(dev->pcie_type, flags))
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &cap[i++]);
- if (pcie_cap_has_lnkctl(dev->pcie_type, flags))
- pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]);
- if (pcie_cap_has_sltctl(dev->pcie_type, flags))
- pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]);
- if (pcie_cap_has_rtctl(dev->pcie_type, flags))
- pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]);
-
- pos = pci_pcie_cap2(dev);
- if (!pos)
- return 0;
+ cap = (u16 *)&save_state->cap.data[0];
+ pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &cap[i++]);
+ pcie_capability_read_word(dev, PCI_EXP_LNKCTL, &cap[i++]);
+ pcie_capability_read_word(dev, PCI_EXP_SLTCTL, &cap[i++]);
+ pcie_capability_read_word(dev, PCI_EXP_RTCTL, &cap[i++]);
+ pcie_capability_read_word(dev, PCI_EXP_DEVCTL2, &cap[i++]);
+ pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &cap[i++]);
+ pcie_capability_read_word(dev, PCI_EXP_SLTCTL2, &cap[i++]);
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]);
- pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]);
- pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]);
return 0;
}
static void pci_restore_pcie_state(struct pci_dev *dev)
{
- int i = 0, pos;
+ int i = 0;
struct pci_cap_saved_state *save_state;
u16 *cap;
- u16 flags;
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
- pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (!save_state || pos <= 0)
- return;
- cap = (u16 *)&save_state->cap.data[0];
-
- pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags);
-
- if (pcie_cap_has_devctl(dev->pcie_type, flags))
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, cap[i++]);
- if (pcie_cap_has_lnkctl(dev->pcie_type, flags))
- pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]);
- if (pcie_cap_has_sltctl(dev->pcie_type, flags))
- pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]);
- if (pcie_cap_has_rtctl(dev->pcie_type, flags))
- pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]);
-
- pos = pci_pcie_cap2(dev);
- if (!pos)
+ if (!save_state)
return;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]);
- pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]);
- pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]);
+ cap = (u16 *)&save_state->cap.data[0];
+ pcie_capability_write_word(dev, PCI_EXP_DEVCTL, cap[i++]);
+ pcie_capability_write_word(dev, PCI_EXP_LNKCTL, cap[i++]);
+ pcie_capability_write_word(dev, PCI_EXP_SLTCTL, cap[i++]);
+ pcie_capability_write_word(dev, PCI_EXP_RTCTL, cap[i++]);
+ pcie_capability_write_word(dev, PCI_EXP_DEVCTL2, cap[i++]);
+ pcie_capability_write_word(dev, PCI_EXP_LNKCTL2, cap[i++]);
+ pcie_capability_write_word(dev, PCI_EXP_SLTCTL2, cap[i++]);
}
@@ -1543,7 +1491,7 @@ void pci_pme_wakeup_bus(struct pci_bus *bus)
/**
* pci_wakeup - Wake up a PCI device
- * @dev: Device to handle.
+ * @pci_dev: Device to handle.
* @ign: ignored parameter
*/
static int pci_wakeup(struct pci_dev *pci_dev, void *ign)
@@ -2067,35 +2015,24 @@ void pci_free_cap_save_buffers(struct pci_dev *dev)
*/
void pci_enable_ari(struct pci_dev *dev)
{
- int pos;
u32 cap;
- u16 ctrl;
struct pci_dev *bridge;
if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn)
return;
- pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI);
- if (!pos)
+ if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI))
return;
bridge = dev->bus->self;
if (!bridge)
return;
- /* ARI is a PCIe cap v2 feature */
- pos = pci_pcie_cap2(bridge);
- if (!pos)
- return;
-
- pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap);
+ pcie_capability_read_dword(bridge, PCI_EXP_DEVCAP2, &cap);
if (!(cap & PCI_EXP_DEVCAP2_ARI))
return;
- pci_read_config_word(bridge, pos + PCI_EXP_DEVCTL2, &ctrl);
- ctrl |= PCI_EXP_DEVCTL2_ARI;
- pci_write_config_word(bridge, pos + PCI_EXP_DEVCTL2, ctrl);
-
+ pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_ARI);
bridge->ari_enabled = 1;
}
@@ -2110,20 +2047,14 @@ void pci_enable_ari(struct pci_dev *dev)
*/
void pci_enable_ido(struct pci_dev *dev, unsigned long type)
{
- int pos;
- u16 ctrl;
+ u16 ctrl = 0;
- /* ID-based Ordering is a PCIe cap v2 feature */
- pos = pci_pcie_cap2(dev);
- if (!pos)
- return;
-
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
if (type & PCI_EXP_IDO_REQUEST)
ctrl |= PCI_EXP_IDO_REQ_EN;
if (type & PCI_EXP_IDO_COMPLETION)
ctrl |= PCI_EXP_IDO_CMP_EN;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+ if (ctrl)
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL2, ctrl);
}
EXPORT_SYMBOL(pci_enable_ido);
@@ -2134,20 +2065,14 @@ EXPORT_SYMBOL(pci_enable_ido);
*/
void pci_disable_ido(struct pci_dev *dev, unsigned long type)
{
- int pos;
- u16 ctrl;
+ u16 ctrl = 0;
- /* ID-based Ordering is a PCIe cap v2 feature */
- pos = pci_pcie_cap2(dev);
- if (!pos)
- return;
-
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
if (type & PCI_EXP_IDO_REQUEST)
- ctrl &= ~PCI_EXP_IDO_REQ_EN;
+ ctrl |= PCI_EXP_IDO_REQ_EN;
if (type & PCI_EXP_IDO_COMPLETION)
- ctrl &= ~PCI_EXP_IDO_CMP_EN;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+ ctrl |= PCI_EXP_IDO_CMP_EN;
+ if (ctrl)
+ pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2, ctrl);
}
EXPORT_SYMBOL(pci_disable_ido);
@@ -2172,17 +2097,11 @@ EXPORT_SYMBOL(pci_disable_ido);
*/
int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type)
{
- int pos;
u32 cap;
u16 ctrl;
int ret;
- /* OBFF is a PCIe cap v2 feature */
- pos = pci_pcie_cap2(dev);
- if (!pos)
- return -ENOTSUPP;
-
- pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap);
+ pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap);
if (!(cap & PCI_EXP_OBFF_MASK))
return -ENOTSUPP; /* no OBFF support at all */
@@ -2193,7 +2112,7 @@ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type)
return ret;
}
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
+ pcie_capability_read_word(dev, PCI_EXP_DEVCTL2, &ctrl);
if (cap & PCI_EXP_OBFF_WAKE)
ctrl |= PCI_EXP_OBFF_WAKE_EN;
else {
@@ -2211,7 +2130,7 @@ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type)
return -ENOTSUPP;
}
}
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+ pcie_capability_write_word(dev, PCI_EXP_DEVCTL2, ctrl);
return 0;
}
@@ -2225,17 +2144,7 @@ EXPORT_SYMBOL(pci_enable_obff);
*/
void pci_disable_obff(struct pci_dev *dev)
{
- int pos;
- u16 ctrl;
-
- /* OBFF is a PCIe cap v2 feature */
- pos = pci_pcie_cap2(dev);
- if (!pos)
- return;
-
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
- ctrl &= ~PCI_EXP_OBFF_WAKE_EN;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+ pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2, PCI_EXP_OBFF_WAKE_EN);
}
EXPORT_SYMBOL(pci_disable_obff);
@@ -2248,15 +2157,9 @@ EXPORT_SYMBOL(pci_disable_obff);
*/
static bool pci_ltr_supported(struct pci_dev *dev)
{
- int pos;
u32 cap;
- /* LTR is a PCIe cap v2 feature */
- pos = pci_pcie_cap2(dev);
- if (!pos)
- return false;
-
- pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap);
+ pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap);
return cap & PCI_EXP_DEVCAP2_LTR;
}
@@ -2273,22 +2176,15 @@ static bool pci_ltr_supported(struct pci_dev *dev)
*/
int pci_enable_ltr(struct pci_dev *dev)
{
- int pos;
- u16 ctrl;
int ret;
- if (!pci_ltr_supported(dev))
- return -ENOTSUPP;
-
- /* LTR is a PCIe cap v2 feature */
- pos = pci_pcie_cap2(dev);
- if (!pos)
- return -ENOTSUPP;
-
/* Only primary function can enable/disable LTR */
if (PCI_FUNC(dev->devfn) != 0)
return -EINVAL;
+ if (!pci_ltr_supported(dev))
+ return -ENOTSUPP;
+
/* Enable upstream ports first */
if (dev->bus->self) {
ret = pci_enable_ltr(dev->bus->self);
@@ -2296,11 +2192,7 @@ int pci_enable_ltr(struct pci_dev *dev)
return ret;
}
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
- ctrl |= PCI_EXP_LTR_EN;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
-
- return 0;
+ return pcie_capability_set_word(dev, PCI_EXP_DEVCTL2, PCI_EXP_LTR_EN);
}
EXPORT_SYMBOL(pci_enable_ltr);
@@ -2310,24 +2202,14 @@ EXPORT_SYMBOL(pci_enable_ltr);
*/
void pci_disable_ltr(struct pci_dev *dev)
{
- int pos;
- u16 ctrl;
-
- if (!pci_ltr_supported(dev))
- return;
-
- /* LTR is a PCIe cap v2 feature */
- pos = pci_pcie_cap2(dev);
- if (!pos)
- return;
-
/* Only primary function can enable/disable LTR */
if (PCI_FUNC(dev->devfn) != 0)
return;
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
- ctrl &= ~PCI_EXP_LTR_EN;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+ if (!pci_ltr_supported(dev))
+ return;
+
+ pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2, PCI_EXP_LTR_EN);
}
EXPORT_SYMBOL(pci_disable_ltr);
@@ -2410,9 +2292,6 @@ void pci_enable_acs(struct pci_dev *dev)
if (!pci_acs_enable)
return;
- if (!pci_is_pcie(dev))
- return;
-
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
if (!pos)
return;
@@ -2460,8 +2339,8 @@ bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags)
acs_flags &= (PCI_ACS_RR | PCI_ACS_CR |
PCI_ACS_EC | PCI_ACS_DT);
- if (pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM ||
- pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_DOWNSTREAM ||
+ pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT ||
pdev->multifunction) {
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ACS);
if (!pos)
@@ -3177,15 +3056,10 @@ EXPORT_SYMBOL(pci_set_dma_seg_boundary);
static int pcie_flr(struct pci_dev *dev, int probe)
{
int i;
- int pos;
u32 cap;
- u16 status, control;
-
- pos = pci_pcie_cap(dev);
- if (!pos)
- return -ENOTTY;
+ u16 status;
- pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP, &cap);
+ pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap);
if (!(cap & PCI_EXP_DEVCAP_FLR))
return -ENOTTY;
@@ -3197,7 +3071,7 @@ static int pcie_flr(struct pci_dev *dev, int probe)
if (i)
msleep((1 << (i - 1)) * 100);
- pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &status);
+ pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status);
if (!(status & PCI_EXP_DEVSTA_TRPND))
goto clear;
}
@@ -3206,9 +3080,7 @@ static int pcie_flr(struct pci_dev *dev, int probe)
"proceeding with reset anyway\n");
clear:
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &control);
- control |= PCI_EXP_DEVCTL_BCR_FLR;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, control);
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
msleep(100);
@@ -3576,18 +3448,11 @@ EXPORT_SYMBOL(pcix_set_mmrbc);
*/
int pcie_get_readrq(struct pci_dev *dev)
{
- int ret, cap;
u16 ctl;
- cap = pci_pcie_cap(dev);
- if (!cap)
- return -EINVAL;
-
- ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
- if (!ret)
- ret = 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+ pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl);
- return ret;
+ return 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12);
}
EXPORT_SYMBOL(pcie_get_readrq);
@@ -3601,19 +3466,11 @@ EXPORT_SYMBOL(pcie_get_readrq);
*/
int pcie_set_readrq(struct pci_dev *dev, int rq)
{
- int cap, err = -EINVAL;
- u16 ctl, v;
+ u16 v;
if (rq < 128 || rq > 4096 || !is_power_of_2(rq))
- goto out;
-
- cap = pci_pcie_cap(dev);
- if (!cap)
- goto out;
+ return -EINVAL;
- err = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
- if (err)
- goto out;
/*
* If using the "performance" PCIe config, we clamp the
* read rq size to the max packet size to prevent the
@@ -3631,14 +3488,8 @@ int pcie_set_readrq(struct pci_dev *dev, int rq)
v = (ffs(rq) - 8) << 12;
- if ((ctl & PCI_EXP_DEVCTL_READRQ) != v) {
- ctl &= ~PCI_EXP_DEVCTL_READRQ;
- ctl |= v;
- err = pci_write_config_word(dev, cap + PCI_EXP_DEVCTL, ctl);
- }
-
-out:
- return err;
+ return pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_READRQ, v);
}
EXPORT_SYMBOL(pcie_set_readrq);
@@ -3651,18 +3502,11 @@ EXPORT_SYMBOL(pcie_set_readrq);
*/
int pcie_get_mps(struct pci_dev *dev)
{
- int ret, cap;
u16 ctl;
- cap = pci_pcie_cap(dev);
- if (!cap)
- return -EINVAL;
-
- ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
- if (!ret)
- ret = 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
+ pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl);
- return ret;
+ return 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
}
/**
@@ -3675,32 +3519,18 @@ int pcie_get_mps(struct pci_dev *dev)
*/
int pcie_set_mps(struct pci_dev *dev, int mps)
{
- int cap, err = -EINVAL;
- u16 ctl, v;
+ u16 v;
if (mps < 128 || mps > 4096 || !is_power_of_2(mps))
- goto out;
+ return -EINVAL;
v = ffs(mps) - 8;
if (v > dev->pcie_mpss)
- goto out;
+ return -EINVAL;
v <<= 5;
- cap = pci_pcie_cap(dev);
- if (!cap)
- goto out;
-
- err = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
- if (err)
- goto out;
-
- if ((ctl & PCI_EXP_DEVCTL_PAYLOAD) != v) {
- ctl &= ~PCI_EXP_DEVCTL_PAYLOAD;
- ctl |= v;
- err = pci_write_config_word(dev, cap + PCI_EXP_DEVCTL, ctl);
- }
-out:
- return err;
+ return pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_PAYLOAD, v);
}
/**
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index 52229863e9fe..4e24cb8a94ae 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -288,7 +288,7 @@ static struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
while (1) {
if (!pci_is_pcie(dev))
break;
- if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
+ if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
return dev;
if (!dev->bus->self)
break;
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 58ad7917553c..030cf12d5468 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -48,7 +48,7 @@ static pci_ers_result_t aer_error_detected(struct pci_dev *dev,
static void aer_error_resume(struct pci_dev *dev);
static pci_ers_result_t aer_root_reset(struct pci_dev *dev);
-static struct pci_error_handlers aer_error_handlers = {
+static const struct pci_error_handlers aer_error_handlers = {
.error_detected = aer_error_detected,
.resume = aer_error_resume,
};
@@ -81,10 +81,11 @@ bool pci_aer_available(void)
static int set_device_error_reporting(struct pci_dev *dev, void *data)
{
bool enable = *((bool *)data);
+ int type = pci_pcie_type(dev);
- if ((dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) ||
- (dev->pcie_type == PCI_EXP_TYPE_UPSTREAM) ||
- (dev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)) {
+ if ((type == PCI_EXP_TYPE_ROOT_PORT) ||
+ (type == PCI_EXP_TYPE_UPSTREAM) ||
+ (type == PCI_EXP_TYPE_DOWNSTREAM)) {
if (enable)
pci_enable_pcie_error_reporting(dev);
else
@@ -121,19 +122,17 @@ static void set_downstream_devices_error_reporting(struct pci_dev *dev,
static void aer_enable_rootport(struct aer_rpc *rpc)
{
struct pci_dev *pdev = rpc->rpd->port;
- int pos, aer_pos;
+ int aer_pos;
u16 reg16;
u32 reg32;
- pos = pci_pcie_cap(pdev);
/* Clear PCIe Capability's Device Status */
- pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, &reg16);
- pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16);
+ pcie_capability_read_word(pdev, PCI_EXP_DEVSTA, &reg16);
+ pcie_capability_write_word(pdev, PCI_EXP_DEVSTA, reg16);
/* Disable system error generation in response to error messages */
- pci_read_config_word(pdev, pos + PCI_EXP_RTCTL, &reg16);
- reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK);
- pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16);
+ pcie_capability_clear_word(pdev, PCI_EXP_RTCTL,
+ SYSTEM_ERROR_INTR_ON_MESG_MASK);
aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
/* Clear error status */
@@ -395,9 +394,8 @@ static void aer_error_resume(struct pci_dev *dev)
u16 reg16;
/* Clean up Root device status */
- pos = pci_pcie_cap(dev);
- pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &reg16);
- pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16);
+ pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &reg16);
+ pcie_capability_write_word(dev, PCI_EXP_DEVSTA, reg16);
/* Clean AER Root Error Status */
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c
index 124f20ff11b2..5194a7d41730 100644
--- a/drivers/pci/pcie/aer/aerdrv_acpi.c
+++ b/drivers/pci/pcie/aer/aerdrv_acpi.c
@@ -60,7 +60,7 @@ static int aer_hest_parse(struct acpi_hest_header *hest_hdr, void *data)
p = (struct acpi_hest_aer_common *)(hest_hdr + 1);
if (p->flags & ACPI_HEST_GLOBAL) {
if ((pci_is_pcie(info->pci_dev) &&
- info->pci_dev->pcie_type == pcie_type) || bridge)
+ pci_pcie_type(info->pci_dev) == pcie_type) || bridge)
ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
} else
if (hest_match_pci(p, info->pci_dev))
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 0ca053538146..06bad96af415 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -32,53 +32,28 @@ static bool nosourceid;
module_param(forceload, bool, 0);
module_param(nosourceid, bool, 0);
+#define PCI_EXP_AER_FLAGS (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \
+ PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
+
int pci_enable_pcie_error_reporting(struct pci_dev *dev)
{
- u16 reg16 = 0;
- int pos;
-
if (pcie_aer_get_firmware_first(dev))
return -EIO;
- pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
- if (!pos)
+ if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR))
return -EIO;
- pos = pci_pcie_cap(dev);
- if (!pos)
- return -EIO;
-
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
- reg16 |= (PCI_EXP_DEVCTL_CERE |
- PCI_EXP_DEVCTL_NFERE |
- PCI_EXP_DEVCTL_FERE |
- PCI_EXP_DEVCTL_URRE);
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
-
- return 0;
+ return pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS);
}
EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting);
int pci_disable_pcie_error_reporting(struct pci_dev *dev)
{
- u16 reg16 = 0;
- int pos;
-
if (pcie_aer_get_firmware_first(dev))
return -EIO;
- pos = pci_pcie_cap(dev);
- if (!pos)
- return -EIO;
-
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
- reg16 &= ~(PCI_EXP_DEVCTL_CERE |
- PCI_EXP_DEVCTL_NFERE |
- PCI_EXP_DEVCTL_FERE |
- PCI_EXP_DEVCTL_URRE);
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
-
- return 0;
+ return pcie_capability_clear_word(dev, PCI_EXP_DEVCTL,
+ PCI_EXP_AER_FLAGS);
}
EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting);
@@ -151,18 +126,12 @@ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info)
*/
if (atomic_read(&dev->enable_cnt) == 0)
return false;
- pos = pci_pcie_cap(dev);
- if (!pos)
- return false;
/* Check if AER is enabled */
- pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
- if (!(reg16 & (
- PCI_EXP_DEVCTL_CERE |
- PCI_EXP_DEVCTL_NFERE |
- PCI_EXP_DEVCTL_FERE |
- PCI_EXP_DEVCTL_URRE)))
+ pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &reg16);
+ if (!(reg16 & PCI_EXP_AER_FLAGS))
return false;
+
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (!pos)
return false;
@@ -240,7 +209,7 @@ static bool find_source_device(struct pci_dev *parent,
static int report_error_detected(struct pci_dev *dev, void *data)
{
pci_ers_result_t vote;
- struct pci_error_handlers *err_handler;
+ const struct pci_error_handlers *err_handler;
struct aer_broadcast_data *result_data;
result_data = (struct aer_broadcast_data *) data;
@@ -274,7 +243,7 @@ static int report_error_detected(struct pci_dev *dev, void *data)
static int report_mmio_enabled(struct pci_dev *dev, void *data)
{
pci_ers_result_t vote;
- struct pci_error_handlers *err_handler;
+ const struct pci_error_handlers *err_handler;
struct aer_broadcast_data *result_data;
result_data = (struct aer_broadcast_data *) data;
@@ -292,7 +261,7 @@ static int report_mmio_enabled(struct pci_dev *dev, void *data)
static int report_slot_reset(struct pci_dev *dev, void *data)
{
pci_ers_result_t vote;
- struct pci_error_handlers *err_handler;
+ const struct pci_error_handlers *err_handler;
struct aer_broadcast_data *result_data;
result_data = (struct aer_broadcast_data *) data;
@@ -309,7 +278,7 @@ static int report_slot_reset(struct pci_dev *dev, void *data)
static int report_resume(struct pci_dev *dev, void *data)
{
- struct pci_error_handlers *err_handler;
+ const struct pci_error_handlers *err_handler;
dev->error_state = pci_channel_io_normal;
@@ -465,7 +434,7 @@ static pci_ers_result_t reset_link(struct pci_dev *dev)
if (driver && driver->reset_link) {
status = driver->reset_link(udev);
- } else if (udev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) {
+ } else if (pci_pcie_type(udev) == PCI_EXP_TYPE_DOWNSTREAM) {
status = default_downstream_reset_link(udev);
} else {
dev_printk(KERN_DEBUG, &dev->dev,
@@ -540,14 +509,12 @@ static void do_recovery(struct pci_dev *dev, int severity)
"resume",
report_resume);
- dev_printk(KERN_DEBUG, &dev->dev,
- "AER driver successfully recovered\n");
+ dev_info(&dev->dev, "AER: Device recovery successful\n");
return;
failed:
/* TODO: Should kernel panic here? */
- dev_printk(KERN_DEBUG, &dev->dev,
- "AER driver didn't recover\n");
+ dev_info(&dev->dev, "AER: Device recovery failed\n");
}
/**
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index b500840a143b..213753b283a6 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -125,21 +125,16 @@ static int policy_to_clkpm_state(struct pcie_link_state *link)
static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable)
{
- int pos;
- u16 reg16;
struct pci_dev *child;
struct pci_bus *linkbus = link->pdev->subordinate;
list_for_each_entry(child, &linkbus->devices, bus_list) {
- pos = pci_pcie_cap(child);
- if (!pos)
- return;
- pci_read_config_word(child, pos + PCI_EXP_LNKCTL, &reg16);
if (enable)
- reg16 |= PCI_EXP_LNKCTL_CLKREQ_EN;
+ pcie_capability_set_word(child, PCI_EXP_LNKCTL,
+ PCI_EXP_LNKCTL_CLKREQ_EN);
else
- reg16 &= ~PCI_EXP_LNKCTL_CLKREQ_EN;
- pci_write_config_word(child, pos + PCI_EXP_LNKCTL, reg16);
+ pcie_capability_clear_word(child, PCI_EXP_LNKCTL,
+ PCI_EXP_LNKCTL_CLKREQ_EN);
}
link->clkpm_enabled = !!enable;
}
@@ -157,7 +152,7 @@ static void pcie_set_clkpm(struct pcie_link_state *link, int enable)
static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
{
- int pos, capable = 1, enabled = 1;
+ int capable = 1, enabled = 1;
u32 reg32;
u16 reg16;
struct pci_dev *child;
@@ -165,16 +160,13 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
/* All functions should have the same cap and state, take the worst */
list_for_each_entry(child, &linkbus->devices, bus_list) {
- pos = pci_pcie_cap(child);
- if (!pos)
- return;
- pci_read_config_dword(child, pos + PCI_EXP_LNKCAP, &reg32);
+ pcie_capability_read_dword(child, PCI_EXP_LNKCAP, &reg32);
if (!(reg32 & PCI_EXP_LNKCAP_CLKPM)) {
capable = 0;
enabled = 0;
break;
}
- pci_read_config_word(child, pos + PCI_EXP_LNKCTL, &reg16);
+ pcie_capability_read_word(child, PCI_EXP_LNKCTL, &reg16);
if (!(reg16 & PCI_EXP_LNKCTL_CLKREQ_EN))
enabled = 0;
}
@@ -190,7 +182,7 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
*/
static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
{
- int ppos, cpos, same_clock = 1;
+ int same_clock = 1;
u16 reg16, parent_reg, child_reg[8];
unsigned long start_jiffies;
struct pci_dev *child, *parent = link->pdev;
@@ -203,46 +195,43 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
BUG_ON(!pci_is_pcie(child));
/* Check downstream component if bit Slot Clock Configuration is 1 */
- cpos = pci_pcie_cap(child);
- pci_read_config_word(child, cpos + PCI_EXP_LNKSTA, &reg16);
+ pcie_capability_read_word(child, PCI_EXP_LNKSTA, &reg16);
if (!(reg16 & PCI_EXP_LNKSTA_SLC))
same_clock = 0;
/* Check upstream component if bit Slot Clock Configuration is 1 */
- ppos = pci_pcie_cap(parent);
- pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, &reg16);
+ pcie_capability_read_word(parent, PCI_EXP_LNKSTA, &reg16);
if (!(reg16 & PCI_EXP_LNKSTA_SLC))
same_clock = 0;
/* Configure downstream component, all functions */
list_for_each_entry(child, &linkbus->devices, bus_list) {
- cpos = pci_pcie_cap(child);
- pci_read_config_word(child, cpos + PCI_EXP_LNKCTL, &reg16);
+ pcie_capability_read_word(child, PCI_EXP_LNKCTL, &reg16);
child_reg[PCI_FUNC(child->devfn)] = reg16;
if (same_clock)
reg16 |= PCI_EXP_LNKCTL_CCC;
else
reg16 &= ~PCI_EXP_LNKCTL_CCC;
- pci_write_config_word(child, cpos + PCI_EXP_LNKCTL, reg16);
+ pcie_capability_write_word(child, PCI_EXP_LNKCTL, reg16);
}
/* Configure upstream component */
- pci_read_config_word(parent, ppos + PCI_EXP_LNKCTL, &reg16);
+ pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &reg16);
parent_reg = reg16;
if (same_clock)
reg16 |= PCI_EXP_LNKCTL_CCC;
else
reg16 &= ~PCI_EXP_LNKCTL_CCC;
- pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, reg16);
+ pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16);
/* Retrain link */
reg16 |= PCI_EXP_LNKCTL_RL;
- pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, reg16);
+ pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16);
/* Wait for link training end. Break out after waiting for timeout */
start_jiffies = jiffies;
for (;;) {
- pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, &reg16);
+ pcie_capability_read_word(parent, PCI_EXP_LNKSTA, &reg16);
if (!(reg16 & PCI_EXP_LNKSTA_LT))
break;
if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT))
@@ -255,12 +244,10 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
/* Training failed. Restore common clock configurations */
dev_printk(KERN_ERR, &parent->dev,
"ASPM: Could not configure common clock\n");
- list_for_each_entry(child, &linkbus->devices, bus_list) {
- cpos = pci_pcie_cap(child);
- pci_write_config_word(child, cpos + PCI_EXP_LNKCTL,
- child_reg[PCI_FUNC(child->devfn)]);
- }
- pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, parent_reg);
+ list_for_each_entry(child, &linkbus->devices, bus_list)
+ pcie_capability_write_word(child, PCI_EXP_LNKCTL,
+ child_reg[PCI_FUNC(child->devfn)]);
+ pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_reg);
}
/* Convert L0s latency encoding to ns */
@@ -305,16 +292,14 @@ struct aspm_register_info {
static void pcie_get_aspm_reg(struct pci_dev *pdev,
struct aspm_register_info *info)
{
- int pos;
u16 reg16;
u32 reg32;
- pos = pci_pcie_cap(pdev);
- pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &reg32);
+ pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &reg32);
info->support = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10;
info->latency_encoding_l0s = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12;
info->latency_encoding_l1 = (reg32 & PCI_EXP_LNKCAP_L1EL) >> 15;
- pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
+ pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &reg16);
info->enabled = reg16 & PCI_EXP_LNKCTL_ASPMC;
}
@@ -412,7 +397,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
* do ASPM for now.
*/
list_for_each_entry(child, &linkbus->devices, bus_list) {
- if (child->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) {
+ if (pci_pcie_type(child) == PCI_EXP_TYPE_PCI_BRIDGE) {
link->aspm_disable = ASPM_STATE_ALL;
break;
}
@@ -420,17 +405,15 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
/* Get and check endpoint acceptable latencies */
list_for_each_entry(child, &linkbus->devices, bus_list) {
- int pos;
u32 reg32, encoding;
struct aspm_latency *acceptable =
&link->acceptable[PCI_FUNC(child->devfn)];
- if (child->pcie_type != PCI_EXP_TYPE_ENDPOINT &&
- child->pcie_type != PCI_EXP_TYPE_LEG_END)
+ if (pci_pcie_type(child) != PCI_EXP_TYPE_ENDPOINT &&
+ pci_pcie_type(child) != PCI_EXP_TYPE_LEG_END)
continue;
- pos = pci_pcie_cap(child);
- pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, &reg32);
+ pcie_capability_read_dword(child, PCI_EXP_DEVCAP, &reg32);
/* Calculate endpoint L0s acceptable latency */
encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
acceptable->l0s = calc_l0s_acceptable(encoding);
@@ -444,13 +427,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val)
{
- u16 reg16;
- int pos = pci_pcie_cap(pdev);
-
- pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
- reg16 &= ~0x3;
- reg16 |= val;
- pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
+ pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL, 0x3, val);
}
static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state)
@@ -505,7 +482,6 @@ static void free_link_state(struct pcie_link_state *link)
static int pcie_aspm_sanity_check(struct pci_dev *pdev)
{
struct pci_dev *child;
- int pos;
u32 reg32;
/*
@@ -513,8 +489,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
* very strange. Disable ASPM for the whole slot
*/
list_for_each_entry(child, &pdev->subordinate->devices, bus_list) {
- pos = pci_pcie_cap(child);
- if (!pos)
+ if (!pci_is_pcie(child))
return -EINVAL;
/*
@@ -530,7 +505,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
* Disable ASPM for pre-1.1 PCIe device, we follow MS to use
* RBER bit to determine if a function is 1.1 version device
*/
- pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, &reg32);
+ pcie_capability_read_dword(child, PCI_EXP_DEVCAP, &reg32);
if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) {
dev_printk(KERN_INFO, &child->dev, "disabling ASPM"
" on pre-1.1 PCIe device. You can enable it"
@@ -552,7 +527,7 @@ static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev)
INIT_LIST_HEAD(&link->children);
INIT_LIST_HEAD(&link->link);
link->pdev = pdev;
- if (pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) {
+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_DOWNSTREAM) {
struct pcie_link_state *parent;
parent = pdev->bus->parent->self->link_state;
if (!parent) {
@@ -585,12 +560,12 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
if (!pci_is_pcie(pdev) || pdev->link_state)
return;
- if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
- pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
+ if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT &&
+ pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM)
return;
/* VIA has a strange chipset, root port is under a bridge */
- if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT &&
+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT &&
pdev->bus->self)
return;
@@ -647,8 +622,8 @@ static void pcie_update_aspm_capable(struct pcie_link_state *root)
if (link->root != root)
continue;
list_for_each_entry(child, &linkbus->devices, bus_list) {
- if ((child->pcie_type != PCI_EXP_TYPE_ENDPOINT) &&
- (child->pcie_type != PCI_EXP_TYPE_LEG_END))
+ if ((pci_pcie_type(child) != PCI_EXP_TYPE_ENDPOINT) &&
+ (pci_pcie_type(child) != PCI_EXP_TYPE_LEG_END))
continue;
pcie_aspm_check_latency(child);
}
@@ -663,8 +638,8 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
if (!pci_is_pcie(pdev) || !parent || !parent->link_state)
return;
- if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
- (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
+ if ((pci_pcie_type(parent) != PCI_EXP_TYPE_ROOT_PORT) &&
+ (pci_pcie_type(parent) != PCI_EXP_TYPE_DOWNSTREAM))
return;
down_read(&pci_bus_sem);
@@ -704,8 +679,8 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev)
if (aspm_disabled || !pci_is_pcie(pdev) || !link)
return;
- if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
- (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
+ if ((pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT) &&
+ (pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM))
return;
/*
* Devices changed PM state, we should recheck if latency
@@ -729,8 +704,8 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
if (aspm_policy != POLICY_POWERSAVE)
return;
- if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
- (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
+ if ((pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT) &&
+ (pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM))
return;
down_read(&pci_bus_sem);
@@ -757,8 +732,8 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem,
if (!pci_is_pcie(pdev))
return;
- if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
- pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT ||
+ pci_pcie_type(pdev) == PCI_EXP_TYPE_DOWNSTREAM)
parent = pdev;
if (!parent || !parent->link_state)
return;
@@ -933,8 +908,8 @@ void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev)
struct pcie_link_state *link_state = pdev->link_state;
if (!pci_is_pcie(pdev) ||
- (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
- pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
+ (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT &&
+ pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
return;
if (link_state->aspm_support)
@@ -950,8 +925,8 @@ void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev)
struct pcie_link_state *link_state = pdev->link_state;
if (!pci_is_pcie(pdev) ||
- (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
- pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
+ (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT &&
+ pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
return;
if (link_state->aspm_support)
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c
index 001f1b78f39c..9ca0dc9ffd84 100644
--- a/drivers/pci/pcie/pme.c
+++ b/drivers/pci/pcie/pme.c
@@ -57,17 +57,12 @@ struct pcie_pme_service_data {
*/
void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable)
{
- int rtctl_pos;
- u16 rtctl;
-
- rtctl_pos = pci_pcie_cap(dev) + PCI_EXP_RTCTL;
-
- pci_read_config_word(dev, rtctl_pos, &rtctl);
if (enable)
- rtctl |= PCI_EXP_RTCTL_PMEIE;
+ pcie_capability_set_word(dev, PCI_EXP_RTCTL,
+ PCI_EXP_RTCTL_PMEIE);
else
- rtctl &= ~PCI_EXP_RTCTL_PMEIE;
- pci_write_config_word(dev, rtctl_pos, rtctl);
+ pcie_capability_clear_word(dev, PCI_EXP_RTCTL,
+ PCI_EXP_RTCTL_PMEIE);
}
/**
@@ -120,7 +115,7 @@ static bool pcie_pme_from_pci_bridge(struct pci_bus *bus, u8 devfn)
if (!dev)
return false;
- if (pci_is_pcie(dev) && dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) {
+ if (pci_is_pcie(dev) && pci_pcie_type(dev) == PCI_EXP_TYPE_PCI_BRIDGE) {
down_read(&pci_bus_sem);
if (pcie_pme_walk_bus(bus))
found = true;
@@ -226,18 +221,15 @@ static void pcie_pme_work_fn(struct work_struct *work)
struct pcie_pme_service_data *data =
container_of(work, struct pcie_pme_service_data, work);
struct pci_dev *port = data->srv->port;
- int rtsta_pos;
u32 rtsta;
- rtsta_pos = pci_pcie_cap(port) + PCI_EXP_RTSTA;
-
spin_lock_irq(&data->lock);
for (;;) {
if (data->noirq)
break;
- pci_read_config_dword(port, rtsta_pos, &rtsta);
+ pcie_capability_read_dword(port, PCI_EXP_RTSTA, &rtsta);
if (rtsta & PCI_EXP_RTSTA_PME) {
/*
* Clear PME status of the port. If there are other
@@ -276,17 +268,14 @@ static irqreturn_t pcie_pme_irq(int irq, void *context)
{
struct pci_dev *port;
struct pcie_pme_service_data *data;
- int rtsta_pos;
u32 rtsta;
unsigned long flags;
port = ((struct pcie_device *)context)->port;
data = get_service_data((struct pcie_device *)context);
- rtsta_pos = pci_pcie_cap(port) + PCI_EXP_RTSTA;
-
spin_lock_irqsave(&data->lock, flags);
- pci_read_config_dword(port, rtsta_pos, &rtsta);
+ pcie_capability_read_dword(port, PCI_EXP_RTSTA, &rtsta);
if (!(rtsta & PCI_EXP_RTSTA_PME)) {
spin_unlock_irqrestore(&data->lock, flags);
@@ -335,13 +324,13 @@ static void pcie_pme_mark_devices(struct pci_dev *port)
struct pci_dev *dev;
/* Check if this is a root port event collector. */
- if (port->pcie_type != PCI_EXP_TYPE_RC_EC || !bus)
+ if (pci_pcie_type(port) != PCI_EXP_TYPE_RC_EC || !bus)
return;
down_read(&pci_bus_sem);
list_for_each_entry(dev, &bus->devices, bus_list)
if (pci_is_pcie(dev)
- && dev->pcie_type == PCI_EXP_TYPE_RC_END)
+ && pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END)
pcie_pme_set_native(dev, NULL);
up_read(&pci_bus_sem);
}
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c
index 18bf90f748f6..67be55a7f260 100644
--- a/drivers/pci/pcie/portdrv_bus.c
+++ b/drivers/pci/pcie/portdrv_bus.c
@@ -38,7 +38,7 @@ static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
return 0;
if ((driver->port_type != PCIE_ANY_PORT) &&
- (driver->port_type != pciedev->port->pcie_type))
+ (driver->port_type != pci_pcie_type(pciedev->port)))
return 0;
return 1;
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 75915b30ad19..d03a7a39b2d8 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -200,10 +200,13 @@ static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask)
{
int i, irq = -1;
- /* We have to use INTx if MSI cannot be used for PCIe PME or pciehp. */
+ /*
+ * If MSI cannot be used for PCIe PME or hotplug, we have to use
+ * INTx or other interrupts, e.g. system shared interrupt.
+ */
if (((mask & PCIE_PORT_SERVICE_PME) && pcie_pme_no_msi()) ||
((mask & PCIE_PORT_SERVICE_HP) && pciehp_no_msi())) {
- if (dev->pin)
+ if (dev->irq)
irq = dev->irq;
goto no_msi;
}
@@ -212,8 +215,12 @@ static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask)
if (!pcie_port_enable_msix(dev, irqs, mask))
return 0;
- /* We're not going to use MSI-X, so try MSI and fall back to INTx */
- if (!pci_enable_msi(dev) || dev->pin)
+ /*
+ * We're not going to use MSI-X, so try MSI and fall back to INTx.
+ * If neither MSI/MSI-X nor INTx available, try other interrupt. On
+ * some platforms, root port doesn't support MSI/MSI-X/INTx in RC mode.
+ */
+ if (!pci_enable_msi(dev) || dev->irq)
irq = dev->irq;
no_msi:
@@ -246,8 +253,7 @@ static void cleanup_service_irqs(struct pci_dev *dev)
*/
static int get_port_device_capability(struct pci_dev *dev)
{
- int services = 0, pos;
- u16 reg16;
+ int services = 0;
u32 reg32;
int cap_mask = 0;
int err;
@@ -265,11 +271,9 @@ static int get_port_device_capability(struct pci_dev *dev)
return 0;
}
- pos = pci_pcie_cap(dev);
- pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &reg16);
/* Hot-Plug Capable */
- if ((cap_mask & PCIE_PORT_SERVICE_HP) && (reg16 & PCI_EXP_FLAGS_SLOT)) {
- pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, &reg32);
+ if (cap_mask & PCIE_PORT_SERVICE_HP) {
+ pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, &reg32);
if (reg32 & PCI_EXP_SLTCAP_HPC) {
services |= PCIE_PORT_SERVICE_HP;
/*
@@ -277,10 +281,8 @@ static int get_port_device_capability(struct pci_dev *dev)
* enabled by the BIOS and the hot-plug service driver
* is not loaded.
*/
- pos += PCI_EXP_SLTCTL;
- pci_read_config_word(dev, pos, &reg16);
- reg16 &= ~(PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
- pci_write_config_word(dev, pos, reg16);
+ pcie_capability_clear_word(dev, PCI_EXP_SLTCTL,
+ PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
}
}
/* AER capable */
@@ -298,7 +300,7 @@ static int get_port_device_capability(struct pci_dev *dev)
services |= PCIE_PORT_SERVICE_VC;
/* Root ports are capable of generating PME too */
if ((cap_mask & PCIE_PORT_SERVICE_PME)
- && dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
+ && pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) {
services |= PCIE_PORT_SERVICE_PME;
/*
* Disable PME interrupt on this port in case it's been enabled
@@ -336,7 +338,7 @@ static int pcie_device_init(struct pci_dev *pdev, int service, int irq)
device->release = release_pcie_device; /* callback to free pcie dev */
dev_set_name(device, "%s:pcie%02x",
pci_name(pdev),
- get_descriptor_id(pdev->pcie_type, service));
+ get_descriptor_id(pci_pcie_type(pdev), service));
device->parent = &pdev->dev;
device_enable_async_suspend(device);
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index e76b44777dbf..0761d90ca279 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -64,14 +64,7 @@ __setup("pcie_ports=", pcie_port_setup);
*/
void pcie_clear_root_pme_status(struct pci_dev *dev)
{
- int rtsta_pos;
- u32 rtsta;
-
- rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA;
-
- pci_read_config_dword(dev, rtsta_pos, &rtsta);
- rtsta |= PCI_EXP_RTSTA_PME;
- pci_write_config_dword(dev, rtsta_pos, rtsta);
+ pcie_capability_set_dword(dev, PCI_EXP_RTSTA, PCI_EXP_RTSTA_PME);
}
static int pcie_portdrv_restore_config(struct pci_dev *dev)
@@ -95,7 +88,7 @@ static int pcie_port_resume_noirq(struct device *dev)
* which breaks ACPI-based runtime wakeup on PCI Express, so clear those
* bits now just in case (shouldn't hurt).
*/
- if(pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT)
pcie_clear_root_pme_status(pdev);
return 0;
}
@@ -195,9 +188,9 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev,
int status;
if (!pci_is_pcie(dev) ||
- ((dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
- (dev->pcie_type != PCI_EXP_TYPE_UPSTREAM) &&
- (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)))
+ ((pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) &&
+ (pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM) &&
+ (pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM)))
return -ENODEV;
if (!dev->irq && dev->pin) {
@@ -385,11 +378,11 @@ static const struct pci_device_id port_pci_ids[] = { {
};
MODULE_DEVICE_TABLE(pci, port_pci_ids);
-static struct pci_error_handlers pcie_portdrv_err_handler = {
- .error_detected = pcie_portdrv_error_detected,
- .mmio_enabled = pcie_portdrv_mmio_enabled,
- .slot_reset = pcie_portdrv_slot_reset,
- .resume = pcie_portdrv_err_resume,
+static const struct pci_error_handlers pcie_portdrv_err_handler = {
+ .error_detected = pcie_portdrv_error_detected,
+ .mmio_enabled = pcie_portdrv_mmio_enabled,
+ .slot_reset = pcie_portdrv_slot_reset,
+ .resume = pcie_portdrv_err_resume,
};
static struct pci_driver pcie_portdriver = {
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 9f8a6b79a8ec..ec909afa90b6 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -606,10 +606,10 @@ static void pci_set_bus_speed(struct pci_bus *bus)
u32 linkcap;
u16 linksta;
- pci_read_config_dword(bridge, pos + PCI_EXP_LNKCAP, &linkcap);
+ pcie_capability_read_dword(bridge, PCI_EXP_LNKCAP, &linkcap);
bus->max_bus_speed = pcie_link_speed[linkcap & 0xf];
- pci_read_config_word(bridge, pos + PCI_EXP_LNKSTA, &linksta);
+ pcie_capability_read_word(bridge, PCI_EXP_LNKSTA, &linksta);
pcie_update_link_speed(bus, linksta);
}
}
@@ -729,8 +729,10 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
/* Check if setup is sensible at all */
if (!pass &&
- (primary != bus->number || secondary <= bus->number)) {
- dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n");
+ (primary != bus->number || secondary <= bus->number ||
+ secondary > subordinate)) {
+ dev_info(&dev->dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n",
+ secondary, subordinate);
broken = 1;
}
@@ -932,24 +934,16 @@ void set_pcie_port_type(struct pci_dev *pdev)
pdev->is_pcie = 1;
pdev->pcie_cap = pos;
pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
- pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
+ pdev->pcie_flags_reg = reg16;
pci_read_config_word(pdev, pos + PCI_EXP_DEVCAP, &reg16);
pdev->pcie_mpss = reg16 & PCI_EXP_DEVCAP_PAYLOAD;
}
void set_pcie_hotplug_bridge(struct pci_dev *pdev)
{
- int pos;
- u16 reg16;
u32 reg32;
- pos = pci_pcie_cap(pdev);
- if (!pos)
- return;
- pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
- if (!(reg16 & PCI_EXP_FLAGS_SLOT))
- return;
- pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &reg32);
+ pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &reg32);
if (reg32 & PCI_EXP_SLTCAP_HPC)
pdev->is_hotplug_bridge = 1;
}
@@ -1163,8 +1157,7 @@ int pci_cfg_space_size(struct pci_dev *dev)
if (class == PCI_CLASS_BRIDGE_HOST)
return pci_cfg_space_size_ext(dev);
- pos = pci_pcie_cap(dev);
- if (!pos) {
+ if (!pci_is_pcie(dev)) {
pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
if (!pos)
goto fail;
@@ -1386,9 +1379,9 @@ static int only_one_child(struct pci_bus *bus)
if (!parent || !pci_is_pcie(parent))
return 0;
- if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
+ if (pci_pcie_type(parent) == PCI_EXP_TYPE_ROOT_PORT)
return 1;
- if (parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM &&
+ if (pci_pcie_type(parent) == PCI_EXP_TYPE_DOWNSTREAM &&
!pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS))
return 1;
return 0;
@@ -1465,7 +1458,7 @@ static int pcie_find_smpss(struct pci_dev *dev, void *data)
*/
if (dev->is_hotplug_bridge && (!list_is_singular(&dev->bus->devices) ||
(dev->bus->self &&
- dev->bus->self->pcie_type != PCI_EXP_TYPE_ROOT_PORT)))
+ pci_pcie_type(dev->bus->self) != PCI_EXP_TYPE_ROOT_PORT)))
*smpss = 0;
if (*smpss > dev->pcie_mpss)
@@ -1481,7 +1474,8 @@ static void pcie_write_mps(struct pci_dev *dev, int mps)
if (pcie_bus_config == PCIE_BUS_PERFORMANCE) {
mps = 128 << dev->pcie_mpss;
- if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && dev->bus->self)
+ if (pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT &&
+ dev->bus->self)
/* For "Performance", the assumption is made that
* downstream communication will never be larger than
* the MRRS. So, the MPS only needs to be configured
@@ -1756,11 +1750,6 @@ int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max)
"busn_res: can not insert %pR under %s%pR (conflicts with %s %pR)\n",
res, pci_is_root_bus(b) ? "domain " : "",
parent_res, conflict->name, conflict);
- else
- dev_printk(KERN_DEBUG, &b->dev,
- "busn_res: %pR is inserted under %s%pR\n",
- res, pci_is_root_bus(b) ? "domain " : "",
- parent_res);
return conflict == NULL;
}
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 27911b55c2a5..eb907a8faf2a 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -434,25 +434,6 @@ int pci_proc_detach_device(struct pci_dev *dev)
return 0;
}
-#if 0
-int pci_proc_attach_bus(struct pci_bus* bus)
-{
- struct proc_dir_entry *de = bus->procdir;
-
- if (!proc_initialized)
- return -EACCES;
-
- if (!de) {
- char name[16];
- sprintf(name, "%02x", bus->number);
- de = bus->procdir = proc_mkdir(name, proc_bus_pci_dir);
- if (!de)
- return -ENOMEM;
- }
- return 0;
-}
-#endif /* 0 */
-
int pci_proc_detach_bus(struct pci_bus* bus)
{
struct proc_dir_entry *de = bus->procdir;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 51553179e967..7a451ff56ecc 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3081,17 +3081,36 @@ static int reset_intel_generic_dev(struct pci_dev *dev, int probe)
static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe)
{
- int pos;
+ int i;
+ u16 status;
- pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (!pos)
- return -ENOTTY;
+ /*
+ * http://www.intel.com/content/dam/doc/datasheet/82599-10-gbe-controller-datasheet.pdf
+ *
+ * The 82599 supports FLR on VFs, but FLR support is reported only
+ * in the PF DEVCAP (sec 9.3.10.4), not in the VF DEVCAP (sec 9.5).
+ * Therefore, we can't use pcie_flr(), which checks the VF DEVCAP.
+ */
if (probe)
return 0;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL,
- PCI_EXP_DEVCTL_BCR_FLR);
+ /* Wait for Transaction Pending bit clean */
+ for (i = 0; i < 4; i++) {
+ if (i)
+ msleep((1 << (i - 1)) * 100);
+
+ pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status);
+ if (!(status & PCI_EXP_DEVSTA_TRPND))
+ goto clear;
+ }
+
+ dev_err(&dev->dev, "transaction is not cleared; "
+ "proceeding with reset anyway\n");
+
+clear:
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
+
msleep(100);
return 0;
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 04a4861b4749..513972f3ed13 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -32,152 +32,82 @@ static void pci_stop_dev(struct pci_dev *dev)
static void pci_destroy_dev(struct pci_dev *dev)
{
- /* Remove the device from the device lists, and prevent any further
- * list accesses from this device */
down_write(&pci_bus_sem);
list_del(&dev->bus_list);
- dev->bus_list.next = dev->bus_list.prev = NULL;
up_write(&pci_bus_sem);
pci_free_resources(dev);
pci_dev_put(dev);
}
-/**
- * pci_remove_device_safe - remove an unused hotplug device
- * @dev: the device to remove
- *
- * Delete the device structure from the device lists and
- * notify userspace (/sbin/hotplug), but only if the device
- * in question is not being used by a driver.
- * Returns 0 on success.
- */
-#if 0
-int pci_remove_device_safe(struct pci_dev *dev)
-{
- if (pci_dev_driver(dev))
- return -EBUSY;
- pci_destroy_dev(dev);
- return 0;
-}
-#endif /* 0 */
-
-void pci_remove_bus(struct pci_bus *pci_bus)
+void pci_remove_bus(struct pci_bus *bus)
{
- pci_proc_detach_bus(pci_bus);
+ pci_proc_detach_bus(bus);
down_write(&pci_bus_sem);
- list_del(&pci_bus->node);
- pci_bus_release_busn_res(pci_bus);
+ list_del(&bus->node);
+ pci_bus_release_busn_res(bus);
up_write(&pci_bus_sem);
- if (!pci_bus->is_added)
+ if (!bus->is_added)
return;
- pci_remove_legacy_files(pci_bus);
- device_unregister(&pci_bus->dev);
+ pci_remove_legacy_files(bus);
+ device_unregister(&bus->dev);
}
EXPORT_SYMBOL(pci_remove_bus);
-static void __pci_remove_behind_bridge(struct pci_dev *dev);
-/**
- * pci_stop_and_remove_bus_device - remove a PCI device and any children
- * @dev: the device to remove
- *
- * Remove a PCI device from the device lists, informing the drivers
- * that the device has been removed. We also remove any subordinate
- * buses and children in a depth-first manner.
- *
- * For each device we remove, delete the device structure from the
- * device lists, remove the /proc entry, and notify userspace
- * (/sbin/hotplug).
- */
-void __pci_remove_bus_device(struct pci_dev *dev)
+static void pci_stop_bus_device(struct pci_dev *dev)
{
- if (dev->subordinate) {
- struct pci_bus *b = dev->subordinate;
+ struct pci_bus *bus = dev->subordinate;
+ struct pci_dev *child, *tmp;
- __pci_remove_behind_bridge(dev);
- pci_remove_bus(b);
- dev->subordinate = NULL;
+ /*
+ * Stopping an SR-IOV PF device removes all the associated VFs,
+ * which will update the bus->devices list and confuse the
+ * iterator. Therefore, iterate in reverse so we remove the VFs
+ * first, then the PF.
+ */
+ if (bus) {
+ list_for_each_entry_safe_reverse(child, tmp,
+ &bus->devices, bus_list)
+ pci_stop_bus_device(child);
}
- pci_destroy_dev(dev);
-}
-EXPORT_SYMBOL(__pci_remove_bus_device);
-
-void pci_stop_and_remove_bus_device(struct pci_dev *dev)
-{
- pci_stop_bus_device(dev);
- __pci_remove_bus_device(dev);
+ pci_stop_dev(dev);
}
-static void __pci_remove_behind_bridge(struct pci_dev *dev)
+static void pci_remove_bus_device(struct pci_dev *dev)
{
- struct list_head *l, *n;
+ struct pci_bus *bus = dev->subordinate;
+ struct pci_dev *child, *tmp;
- if (dev->subordinate)
- list_for_each_safe(l, n, &dev->subordinate->devices)
- __pci_remove_bus_device(pci_dev_b(l));
-}
+ if (bus) {
+ list_for_each_entry_safe(child, tmp,
+ &bus->devices, bus_list)
+ pci_remove_bus_device(child);
-static void pci_stop_behind_bridge(struct pci_dev *dev)
-{
- struct list_head *l, *n;
+ pci_remove_bus(bus);
+ dev->subordinate = NULL;
+ }
- if (dev->subordinate)
- list_for_each_safe(l, n, &dev->subordinate->devices)
- pci_stop_bus_device(pci_dev_b(l));
+ pci_destroy_dev(dev);
}
/**
- * pci_stop_and_remove_behind_bridge - stop and remove all devices behind
- * a PCI bridge
- * @dev: PCI bridge device
+ * pci_stop_and_remove_bus_device - remove a PCI device and any children
+ * @dev: the device to remove
*
- * Remove all devices on the bus, except for the parent bridge.
- * This also removes any child buses, and any devices they may
- * contain in a depth-first manner.
- */
-void pci_stop_and_remove_behind_bridge(struct pci_dev *dev)
-{
- pci_stop_behind_bridge(dev);
- __pci_remove_behind_bridge(dev);
-}
-
-static void pci_stop_bus_devices(struct pci_bus *bus)
-{
- struct list_head *l, *n;
-
- /*
- * VFs could be removed by pci_stop_and_remove_bus_device() in the
- * pci_stop_bus_devices() code path for PF.
- * aka, bus->devices get updated in the process.
- * but VFs are inserted after PFs when SRIOV is enabled for PF,
- * We can iterate the list backwards to get prev valid PF instead
- * of removed VF.
- */
- list_for_each_prev_safe(l, n, &bus->devices) {
- struct pci_dev *dev = pci_dev_b(l);
- pci_stop_bus_device(dev);
- }
-}
-
-/**
- * pci_stop_bus_device - stop a PCI device and any children
- * @dev: the device to stop
+ * Remove a PCI device from the device lists, informing the drivers
+ * that the device has been removed. We also remove any subordinate
+ * buses and children in a depth-first manner.
*
- * Stop a PCI device (detach the driver, remove from the global list
- * and so on). This also stop any subordinate buses and children in a
- * depth-first manner.
+ * For each device we remove, delete the device structure from the
+ * device lists, remove the /proc entry, and notify userspace
+ * (/sbin/hotplug).
*/
-void pci_stop_bus_device(struct pci_dev *dev)
+void pci_stop_and_remove_bus_device(struct pci_dev *dev)
{
- if (dev->subordinate)
- pci_stop_bus_devices(dev->subordinate);
-
- pci_stop_dev(dev);
+ pci_stop_bus_device(dev);
+ pci_remove_bus_device(dev);
}
-
EXPORT_SYMBOL(pci_stop_and_remove_bus_device);
-EXPORT_SYMBOL(pci_stop_and_remove_behind_bridge);
-EXPORT_SYMBOL_GPL(pci_stop_bus_device);
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index 48ebdb237f3f..0b3037ab8b93 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -167,44 +167,6 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
return rom;
}
-#if 0
-/**
- * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy
- * @pdev: pointer to pci device struct
- * @size: pointer to receive size of pci window over ROM
- *
- * Return: kernel virtual pointer to image of ROM
- *
- * Map a PCI ROM into kernel space. If ROM is boot video ROM,
- * the shadow BIOS copy will be returned instead of the
- * actual ROM.
- */
-void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size)
-{
- struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
- void __iomem *rom;
-
- rom = pci_map_rom(pdev, size);
- if (!rom)
- return NULL;
-
- if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW |
- IORESOURCE_ROM_BIOS_COPY))
- return rom;
-
- res->start = (unsigned long)kmalloc(*size, GFP_KERNEL);
- if (!res->start)
- return rom;
-
- res->end = res->start + *size;
- memcpy_fromio((void*)(unsigned long)res->start, rom, *size);
- pci_unmap_rom(pdev, rom);
- res->flags |= IORESOURCE_ROM_COPY;
-
- return (void __iomem *)(unsigned long)res->start;
-}
-#endif /* 0 */
-
/**
* pci_unmap_rom - unmap the ROM from kernel space
* @pdev: pointer to pci device struct
@@ -226,27 +188,6 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
pci_disable_rom(pdev);
}
-#if 0
-/**
- * pci_remove_rom - disable the ROM and remove its sysfs attribute
- * @pdev: pointer to pci device struct
- *
- * Remove the rom file in sysfs and disable ROM decoding.
- */
-void pci_remove_rom(struct pci_dev *pdev)
-{
- struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
-
- if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
- sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
- if (!(res->flags & (IORESOURCE_ROM_ENABLE |
- IORESOURCE_ROM_SHADOW |
- IORESOURCE_ROM_BIOS_COPY |
- IORESOURCE_ROM_COPY)))
- pci_disable_rom(pdev);
-}
-#endif /* 0 */
-
/**
* pci_cleanup_rom - free the ROM copy created by pci_map_rom_copy
* @pdev: pointer to pci device struct
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index 993d4a0a2469..bf969ba58e59 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -41,7 +41,7 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
continue;
}
/* PCI device should connect to a PCIe bridge */
- if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) {
+ if (pci_pcie_type(pdev) != PCI_EXP_TYPE_PCI_BRIDGE) {
/* Busted hardware? */
WARN_ON_ONCE(1);
return NULL;
@@ -130,16 +130,14 @@ pci_find_next_bus(const struct pci_bus *from)
* decrement the reference count by calling pci_dev_put().
* If no device is found, %NULL is returned.
*/
-struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn)
+struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn)
{
- struct list_head *tmp;
struct pci_dev *dev;
WARN_ON(in_interrupt());
down_read(&pci_bus_sem);
- list_for_each(tmp, &bus->devices) {
- dev = pci_dev_b(tmp);
+ list_for_each_entry(dev, &bus->devices, bus_list) {
if (dev->devfn == devfn)
goto out;
}
@@ -245,30 +243,14 @@ struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device,
unsigned int ss_vendor, unsigned int ss_device,
struct pci_dev *from)
{
- struct pci_dev *pdev;
- struct pci_device_id *id;
-
- /*
- * pci_find_subsys() can be called on the ide_setup() path,
- * super-early in boot. But the down_read() will enable local
- * interrupts, which can cause some machines to crash. So here we
- * detect and flag that situation and bail out early.
- */
- if (unlikely(no_pci_devices()))
- return NULL;
-
- id = kzalloc(sizeof(*id), GFP_KERNEL);
- if (!id)
- return NULL;
- id->vendor = vendor;
- id->device = device;
- id->subvendor = ss_vendor;
- id->subdevice = ss_device;
-
- pdev = pci_get_dev_by_id(id, from);
- kfree(id);
-
- return pdev;
+ struct pci_device_id id = {
+ .vendor = vendor,
+ .device = device,
+ .subvendor = ss_vendor,
+ .subdevice = ss_device,
+ };
+
+ return pci_get_dev_by_id(&id, from);
}
/**
@@ -307,19 +289,16 @@ pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from)
*/
struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
{
- struct pci_dev *dev;
- struct pci_device_id *id;
-
- id = kzalloc(sizeof(*id), GFP_KERNEL);
- if (!id)
- return NULL;
- id->vendor = id->device = id->subvendor = id->subdevice = PCI_ANY_ID;
- id->class_mask = PCI_ANY_ID;
- id->class = class;
-
- dev = pci_get_dev_by_id(id, from);
- kfree(id);
- return dev;
+ struct pci_device_id id = {
+ .vendor = PCI_ANY_ID,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .class_mask = PCI_ANY_ID,
+ .class = class,
+ };
+
+ return pci_get_dev_by_id(&id, from);
}
/**
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index fb506137aaee..1e808ca338f8 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -697,6 +697,38 @@ static resource_size_t calculate_memsize(resource_size_t size,
return size;
}
+resource_size_t __weak pcibios_window_alignment(struct pci_bus *bus,
+ unsigned long type)
+{
+ return 1;
+}
+
+#define PCI_P2P_DEFAULT_MEM_ALIGN 0x100000 /* 1MiB */
+#define PCI_P2P_DEFAULT_IO_ALIGN 0x1000 /* 4KiB */
+#define PCI_P2P_DEFAULT_IO_ALIGN_1K 0x400 /* 1KiB */
+
+static resource_size_t window_alignment(struct pci_bus *bus,
+ unsigned long type)
+{
+ resource_size_t align = 1, arch_align;
+
+ if (type & IORESOURCE_MEM)
+ align = PCI_P2P_DEFAULT_MEM_ALIGN;
+ else if (type & IORESOURCE_IO) {
+ /*
+ * Per spec, I/O windows are 4K-aligned, but some
+ * bridges have an extension to support 1K alignment.
+ */
+ if (bus->self->io_window_1k)
+ align = PCI_P2P_DEFAULT_IO_ALIGN_1K;
+ else
+ align = PCI_P2P_DEFAULT_IO_ALIGN;
+ }
+
+ arch_align = pcibios_window_alignment(bus, type);
+ return max(align, arch_align);
+}
+
/**
* pbus_size_io() - size the io window of a given bus
*
@@ -717,17 +749,12 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
unsigned long size = 0, size0 = 0, size1 = 0;
resource_size_t children_add_size = 0;
- resource_size_t min_align = 4096, align;
+ resource_size_t min_align, io_align, align;
if (!b_res)
return;
- /*
- * Per spec, I/O windows are 4K-aligned, but some bridges have an
- * extension to support 1K alignment.
- */
- if (bus->self->io_window_1k)
- min_align = 1024;
+ io_align = min_align = window_alignment(bus, IORESOURCE_IO);
list_for_each_entry(dev, &bus->devices, bus_list) {
int i;
@@ -754,8 +781,8 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
}
}
- if (min_align > 4096)
- min_align = 4096;
+ if (min_align > io_align)
+ min_align = io_align;
size0 = calculate_iosize(size, min_size, size1,
resource_size(b_res), min_align);
@@ -785,6 +812,28 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
}
}
+static inline resource_size_t calculate_mem_align(resource_size_t *aligns,
+ int max_order)
+{
+ resource_size_t align = 0;
+ resource_size_t min_align = 0;
+ int order;
+
+ for (order = 0; order <= max_order; order++) {
+ resource_size_t align1 = 1;
+
+ align1 <<= (order + 20);
+
+ if (!align)
+ min_align = align1;
+ else if (ALIGN(align + min_align, min_align) < align1)
+ min_align = align1 >> 1;
+ align += aligns[order];
+ }
+
+ return min_align;
+}
+
/**
* pbus_size_mem() - size the memory window of a given bus
*
@@ -864,19 +913,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
children_add_size += get_res_add_size(realloc_head, r);
}
}
- align = 0;
- min_align = 0;
- for (order = 0; order <= max_order; order++) {
- resource_size_t align1 = 1;
- align1 <<= (order + 20);
-
- if (!align)
- min_align = align1;
- else if (ALIGN(align + min_align, min_align) < align1)
- min_align = align1 >> 1;
- align += aligns[order];
- }
+ min_align = calculate_mem_align(aligns, max_order);
+ min_align = max(min_align, window_alignment(bus, b_res->flags & mask));
size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align);
if (children_add_size > add_size)
add_size = children_add_size;
diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
index eb219a1d16f7..9bd6864ec5d3 100644
--- a/drivers/pci/setup-irq.c
+++ b/drivers/pci/setup-irq.c
@@ -17,8 +17,13 @@
#include <linux/ioport.h>
#include <linux/cache.h>
+void __weak pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+ dev_dbg(&dev->dev, "assigning IRQ %02d\n", irq);
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
-static void __init
+static void
pdev_fixup_irq(struct pci_dev *dev,
u8 (*swizzle)(struct pci_dev *, u8 *),
int (*map_irq)(const struct pci_dev *, u8, u8))
@@ -54,7 +59,7 @@ pdev_fixup_irq(struct pci_dev *dev,
pcibios_update_irq(dev, irq);
}
-void __init
+void
pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *),
int (*map_irq)(const struct pci_dev *, u8, u8))
{
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index d6cc62cb4cf7..def8d0b5620c 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -982,7 +982,6 @@ static int pcifront_detach_devices(struct pcifront_device *pdev)
int err = 0;
int i, num_devs;
unsigned int domain, bus, slot, func;
- struct pci_bus *pci_bus;
struct pci_dev *pci_dev;
char str[64];
@@ -1032,13 +1031,8 @@ static int pcifront_detach_devices(struct pcifront_device *pdev)
goto out;
}
- pci_bus = pci_find_bus(domain, bus);
- if (!pci_bus) {
- dev_dbg(&pdev->xdev->dev, "Cannot get bus %04x:%02x\n",
- domain, bus);
- continue;
- }
- pci_dev = pci_get_slot(pci_bus, PCI_DEVFN(slot, func));
+ pci_dev = pci_get_domain_bus_and_slot(domain, bus,
+ PCI_DEVFN(slot, func));
if (!pci_dev) {
dev_dbg(&pdev->xdev->dev,
"Cannot get PCI device %04x:%02x:%02x.%d\n",
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index 24caeaf50529..9d3ac998fc1f 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -105,8 +105,17 @@ int __ref cb_alloc(struct pcmcia_socket *s)
*/
void cb_free(struct pcmcia_socket *s)
{
- struct pci_dev *bridge = s->cb_dev;
+ struct pci_dev *bridge, *dev, *tmp;
+ struct pci_bus *bus;
- if (bridge)
- pci_stop_and_remove_behind_bridge(bridge);
+ bridge = s->cb_dev;
+ if (!bridge)
+ return;
+
+ bus = bridge->subordinate;
+ if (!bus)
+ return;
+
+ list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list)
+ pci_stop_and_remove_bus_device(dev);
}
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index 5d44252b7342..d5e1625bbac2 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -2219,9 +2219,7 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct tsi721_device *priv;
- int cap;
int err;
- u32 regval;
priv = kzalloc(sizeof(struct tsi721_device), GFP_KERNEL);
if (priv == NULL) {
@@ -2330,20 +2328,16 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
dev_info(&pdev->dev, "Unable to set consistent DMA mask\n");
}
- cap = pci_pcie_cap(pdev);
- BUG_ON(cap == 0);
+ BUG_ON(!pci_is_pcie(pdev));
/* Clear "no snoop" and "relaxed ordering" bits, use default MRRS. */
- pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL, &regval);
- regval &= ~(PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN |
- PCI_EXP_DEVCTL_NOSNOOP_EN);
- regval |= 0x2 << MAX_READ_REQUEST_SZ_SHIFT;
- pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL, regval);
+ pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN |
+ PCI_EXP_DEVCTL_NOSNOOP_EN,
+ 0x2 << MAX_READ_REQUEST_SZ_SHIFT);
/* Adjust PCIe completion timeout. */
- pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL2, &regval);
- regval &= ~(0x0f);
- pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL2, regval | 0x2);
+ pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL2, 0xf, 0x2);
/*
* FIXUP: correct offsets of MSI-X tables in the MSI-X Capability Block
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 1059c99690e6..0a2c5a8ebb82 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -9228,7 +9228,7 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
};
MODULE_DEVICE_TABLE(pci, ipr_pci_table);
-static struct pci_error_handlers ipr_err_handler = {
+static const struct pci_error_handlers ipr_err_handler = {
.error_detected = ipr_pci_error_detected,
.slot_reset = ipr_pci_slot_reset,
};
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 29937b606c84..628a703abddb 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -10425,7 +10425,7 @@ static struct pci_device_id lpfc_id_table[] = {
MODULE_DEVICE_TABLE(pci, lpfc_id_table);
-static struct pci_error_handlers lpfc_err_handler = {
+static const struct pci_error_handlers lpfc_err_handler = {
.error_detected = lpfc_io_error_detected,
.slot_reset = lpfc_io_slot_reset,
.resume = lpfc_io_resume,
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index b1ebd6f8dab3..1ccae45c5270 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -8306,7 +8306,7 @@ _scsih_pci_mmio_enabled(struct pci_dev *pdev)
return PCI_ERS_RESULT_NEED_RESET;
}
-static struct pci_error_handlers _scsih_err_handler = {
+static const struct pci_error_handlers _scsih_err_handler = {
.error_detected = _scsih_pci_error_detected,
.mmio_enabled = _scsih_pci_mmio_enabled,
.slot_reset = _scsih_pci_slot_reset,
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 9ce3a8f8754f..7cfdf2bd8edb 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -1615,13 +1615,11 @@ qla82xx_get_fw_offs(struct qla_hw_data *ha)
char *
qla82xx_pci_info_str(struct scsi_qla_host *vha, char *str)
{
- int pcie_reg;
struct qla_hw_data *ha = vha->hw;
char lwstr[6];
uint16_t lnk;
- pcie_reg = pci_pcie_cap(ha->pdev);
- pci_read_config_word(ha->pdev, pcie_reg + PCI_EXP_LNKSTA, &lnk);
+ pcie_capability_read_word(ha->pdev, PCI_EXP_LNKSTA, &lnk);
ha->link_width = (lnk >> 4) & 0x3f;
strcpy(str, "PCIe (");
@@ -2497,7 +2495,6 @@ fw_load_failed:
int
qla82xx_start_firmware(scsi_qla_host_t *vha)
{
- int pcie_cap;
uint16_t lnk;
struct qla_hw_data *ha = vha->hw;
@@ -2528,8 +2525,7 @@ qla82xx_start_firmware(scsi_qla_host_t *vha)
}
/* Negotiated Link width */
- pcie_cap = pci_pcie_cap(ha->pdev);
- pci_read_config_word(ha->pdev, pcie_cap + PCI_EXP_LNKSTA, &lnk);
+ pcie_capability_read_word(ha->pdev, PCI_EXP_LNKSTA, &lnk);
ha->link_width = (lnk >> 4) & 0x3f;
/* Synchronize with Receive peg */
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index fb8cd3847d4b..d3052622e77a 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -4471,7 +4471,7 @@ qla2xxx_pci_resume(struct pci_dev *pdev)
ha->flags.eeh_busy = 0;
}
-static struct pci_error_handlers qla2xxx_err_handler = {
+static const struct pci_error_handlers qla2xxx_err_handler = {
.error_detected = qla2xxx_pci_error_detected,
.mmio_enabled = qla2xxx_pci_mmio_enabled,
.slot_reset = qla2xxx_pci_slot_reset,
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index 939d7261c37a..807bf76f1b6a 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -1566,7 +1566,6 @@ qla4_8xxx_set_qsnt_ready(struct scsi_qla_host *ha)
static int
qla4_8xxx_start_firmware(struct scsi_qla_host *ha, uint32_t image_start)
{
- int pcie_cap;
uint16_t lnk;
/* scrub dma mask expansion register */
@@ -1590,8 +1589,7 @@ qla4_8xxx_start_firmware(struct scsi_qla_host *ha, uint32_t image_start)
}
/* Negotiated Link width */
- pcie_cap = pci_pcie_cap(ha->pdev);
- pci_read_config_word(ha->pdev, pcie_cap + PCI_EXP_LNKSTA, &lnk);
+ pcie_capability_read_word(ha->pdev, PCI_EXP_LNKSTA, &lnk);
ha->link_width = (lnk >> 4) & 0x3f;
/* Synchronize with Receive peg */
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 487e3c8411c9..79243b76d17e 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -6148,7 +6148,7 @@ qla4xxx_pci_resume(struct pci_dev *pdev)
clear_bit(AF_EEH_BUSY, &ha->flags);
}
-static struct pci_error_handlers qla4xxx_err_handler = {
+static const struct pci_error_handlers qla4xxx_err_handler = {
.error_detected = qla4xxx_pci_error_detected,
.mmio_enabled = qla4xxx_pci_mmio_enabled,
.slot_reset = qla4xxx_pci_slot_reset,
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 36d1ed7817eb..e2b8e68b57e7 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -2117,7 +2117,7 @@ static struct pci_device_id sym2_id_table[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, sym2_id_table);
-static struct pci_error_handlers sym2_err_handler = {
+static const struct pci_error_handlers sym2_err_handler = {
.error_detected = sym2_io_error_detected,
.mmio_enabled = sym2_io_slot_dump,
.slot_reset = sym2_io_slot_reset,
diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c
index 029725c89e58..49553f88c7b3 100644
--- a/drivers/staging/et131x/et131x.c
+++ b/drivers/staging/et131x/et131x.c
@@ -3995,16 +3995,14 @@ static void et131x_hwaddr_init(struct et131x_adapter *adapter)
static int et131x_pci_init(struct et131x_adapter *adapter,
struct pci_dev *pdev)
{
- int cap = pci_pcie_cap(pdev);
u16 max_payload;
- u16 ctl;
int i, rc;
rc = et131x_init_eeprom(adapter);
if (rc < 0)
goto out;
- if (!cap) {
+ if (!pci_is_pcie(pdev)) {
dev_err(&pdev->dev, "Missing PCIe capabilities\n");
goto err_out;
}
@@ -4012,7 +4010,7 @@ static int et131x_pci_init(struct et131x_adapter *adapter,
/* Let's set up the PORT LOGIC Register. First we need to know what
* the max_payload_size is
*/
- if (pci_read_config_word(pdev, cap + PCI_EXP_DEVCAP, &max_payload)) {
+ if (pcie_capability_read_word(pdev, PCI_EXP_DEVCAP, &max_payload)) {
dev_err(&pdev->dev,
"Could not read PCI config space for Max Payload Size\n");
goto err_out;
@@ -4049,17 +4047,10 @@ static int et131x_pci_init(struct et131x_adapter *adapter,
}
/* Change the max read size to 2k */
- if (pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl)) {
+ if (pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_READRQ, 0x4 << 12)) {
dev_err(&pdev->dev,
- "Could not read PCI config space for Max read size\n");
- goto err_out;
- }
-
- ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | (0x04 << 12);
-
- if (pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl)) {
- dev_err(&pdev->dev,
- "Could not write PCI config space for Max read size\n");
+ "Couldn't change PCI config space for Max read size\n");
goto err_out;
}
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c
index ddadcc3e4e7c..5abbee37cdca 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c
@@ -31,12 +31,10 @@ static void rtl8192_parse_pci_configuration(struct pci_dev *pdev,
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
u8 tmp;
- int pos;
- u8 LinkCtrlReg;
+ u16 LinkCtrlReg;
- pos = pci_find_capability(priv->pdev, PCI_CAP_ID_EXP);
- pci_read_config_byte(priv->pdev, pos + PCI_EXP_LNKCTL, &LinkCtrlReg);
- priv->NdisAdapter.LinkCtrlReg = LinkCtrlReg;
+ pcie_capability_read_word(priv->pdev, PCI_EXP_LNKCTL, &LinkCtrlReg);
+ priv->NdisAdapter.LinkCtrlReg = (u8)LinkCtrlReg;
RT_TRACE(COMP_INIT, "Link Control Register =%x\n",
priv->NdisAdapter.LinkCtrlReg);
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index 28e7c7cce893..452278efef29 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -4236,7 +4236,7 @@ static void serial8250_io_resume(struct pci_dev *dev)
pciserial_resume_ports(priv);
}
-static struct pci_error_handlers serial8250_err_handler = {
+static const struct pci_error_handlers serial8250_err_handler = {
.error_detected = serial8250_io_error_detected,
.slot_reset = serial8250_io_slot_reset,
.resume = serial8250_io_resume,
diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c
index 7545fe1b9925..5ab3c3b595e4 100644
--- a/drivers/tty/serial/jsm/jsm_driver.c
+++ b/drivers/tty/serial/jsm/jsm_driver.c
@@ -54,7 +54,7 @@ static pci_ers_result_t jsm_io_error_detected(struct pci_dev *pdev,
static pci_ers_result_t jsm_io_slot_reset(struct pci_dev *pdev);
static void jsm_io_resume(struct pci_dev *pdev);
-static struct pci_error_handlers jsm_err_handler = {
+static const struct pci_error_handlers jsm_err_handler = {
.error_detected = jsm_io_error_detected,
.slot_reset = jsm_io_slot_reset,
.resume = jsm_io_resume,
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index 03342728bf23..92ff01dbeb10 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -871,7 +871,7 @@ end:
}
/*add xen_pcibk AER handling*/
-static struct pci_error_handlers xen_pcibk_error_handler = {
+static const struct pci_error_handlers xen_pcibk_error_handler = {
.error_detected = xen_pcibk_error_detected,
.mmio_enabled = xen_pcibk_mmio_enabled,
.slot_reset = xen_pcibk_slot_reset,
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 4f2a76224509..90be98981102 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -138,9 +138,9 @@ void acpi_penalize_isa_irq(int irq, int active);
void acpi_pci_irq_disable (struct pci_dev *dev);
struct acpi_pci_driver {
- struct acpi_pci_driver *next;
- int (*add)(acpi_handle handle);
- void (*remove)(acpi_handle handle);
+ struct list_head node;
+ int (*add)(struct acpi_pci_root *root);
+ void (*remove)(struct acpi_pci_root *root);
};
int acpi_pci_register_driver(struct acpi_pci_driver *driver);
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index 248fba2af98a..9a22b5efb384 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -22,19 +22,24 @@ extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle);
static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
{
struct pci_bus *pbus = pdev->bus;
+
/* Find a PCI root bus */
while (!pci_is_root_bus(pbus))
pbus = pbus->parent;
- return acpi_get_pci_rootbridge_handle(pci_domain_nr(pbus),
- pbus->number);
+
+ return DEVICE_ACPI_HANDLE(pbus->bridge);
}
static inline acpi_handle acpi_pci_get_bridge_handle(struct pci_bus *pbus)
{
- if (!pci_is_root_bus(pbus))
- return DEVICE_ACPI_HANDLE(&(pbus->self->dev));
- return acpi_get_pci_rootbridge_handle(pci_domain_nr(pbus),
- pbus->number);
+ struct device *dev;
+
+ if (pci_is_root_bus(pbus))
+ dev = pbus->bridge;
+ else
+ dev = &pbus->self->dev;
+
+ return DEVICE_ACPI_HANDLE(dev);
}
#endif
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 5faa8310eec9..be1de01de1c4 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -254,10 +254,10 @@ struct pci_dev {
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 */
+ u16 pcie_flags_reg; /* cached PCI-E Capabilities Register */
struct pci_driver *driver; /* which driver has allocated this device */
u64 dma_mask; /* Mask of the bits of bus address this
@@ -369,7 +369,6 @@ static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
extern struct pci_dev *alloc_pci_dev(void);
-#define pci_dev_b(n) list_entry(n, struct pci_dev, bus_list)
#define to_pci_dev(n) container_of(n, struct pci_dev, dev)
#define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL)
@@ -596,7 +595,7 @@ struct pci_driver {
int (*resume_early) (struct pci_dev *dev);
int (*resume) (struct pci_dev *dev); /* Device woken up */
void (*shutdown) (struct pci_dev *dev);
- struct pci_error_handlers *err_handler;
+ const struct pci_error_handlers *err_handler;
struct device_driver driver;
struct pci_dynids dynids;
};
@@ -734,9 +733,7 @@ u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp);
extern struct pci_dev *pci_dev_get(struct pci_dev *dev);
extern void pci_dev_put(struct pci_dev *dev);
extern void pci_remove_bus(struct pci_bus *b);
-extern void __pci_remove_bus_device(struct pci_dev *dev);
extern void pci_stop_and_remove_bus_device(struct pci_dev *dev);
-extern void pci_stop_bus_device(struct pci_dev *dev);
void pci_setup_cardbus(struct pci_bus *bus);
extern void pci_sort_breadthfirst(void);
#define dev_is_pci(d) ((d)->bus == &pci_bus_type)
@@ -755,6 +752,7 @@ enum pci_lost_interrupt_reason pci_lost_interrupt(struct pci_dev *dev);
int pci_find_capability(struct pci_dev *dev, int cap);
int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap);
int pci_find_ext_capability(struct pci_dev *dev, int cap);
+int pci_find_next_ext_capability(struct pci_dev *dev, int pos, int cap);
int pci_find_ht_capability(struct pci_dev *dev, int ht_cap);
int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap);
struct pci_bus *pci_find_next_bus(const struct pci_bus *from);
@@ -816,6 +814,39 @@ static inline int pci_write_config_dword(const struct pci_dev *dev, int where,
return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val);
}
+int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val);
+int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val);
+int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val);
+int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val);
+int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos,
+ u16 clear, u16 set);
+int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos,
+ u32 clear, u32 set);
+
+static inline int pcie_capability_set_word(struct pci_dev *dev, int pos,
+ u16 set)
+{
+ return pcie_capability_clear_and_set_word(dev, pos, 0, set);
+}
+
+static inline int pcie_capability_set_dword(struct pci_dev *dev, int pos,
+ u32 set)
+{
+ return pcie_capability_clear_and_set_dword(dev, pos, 0, set);
+}
+
+static inline int pcie_capability_clear_word(struct pci_dev *dev, int pos,
+ u16 clear)
+{
+ return pcie_capability_clear_and_set_word(dev, pos, clear, 0);
+}
+
+static inline int pcie_capability_clear_dword(struct pci_dev *dev, int pos,
+ u32 clear)
+{
+ return pcie_capability_clear_and_set_dword(dev, pos, clear, 0);
+}
+
/* user-space driven config access */
int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val);
int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val);
@@ -1013,7 +1044,6 @@ void pci_unregister_driver(struct pci_driver *dev);
module_driver(__pci_driver, pci_register_driver, \
pci_unregister_driver)
-void pci_stop_and_remove_behind_bridge(struct pci_dev *dev);
struct pci_driver *pci_dev_driver(const struct pci_dev *dev);
int pci_add_dynid(struct pci_driver *drv,
unsigned int vendor, unsigned int device,
@@ -1031,6 +1061,8 @@ int pci_cfg_space_size_ext(struct pci_dev *dev);
int pci_cfg_space_size(struct pci_dev *dev);
unsigned char pci_bus_max_busnr(struct pci_bus *bus);
void pci_setup_bridge(struct pci_bus *bus);
+resource_size_t pcibios_window_alignment(struct pci_bus *bus,
+ unsigned long type);
#define PCI_VGA_STATE_CHANGE_BRIDGE (1 << 0)
#define PCI_VGA_STATE_CHANGE_DECODES (1 << 1)
@@ -1472,7 +1504,7 @@ enum pci_fixup_pass {
/* Anonymous variables would be nice... */
#define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, class, \
class_shift, hook) \
- static const struct pci_fixup const __pci_fixup_##name __used \
+ static const struct pci_fixup __pci_fixup_##name __used \
__attribute__((__section__(#section), aligned((sizeof(void *))))) \
= { vendor, device, class, class_shift, hook };
@@ -1650,6 +1682,15 @@ static inline bool pci_is_pcie(struct pci_dev *dev)
return !!pci_pcie_cap(dev);
}
+/**
+ * pci_pcie_type - get the PCIe device/port type
+ * @dev: PCI device
+ */
+static inline int pci_pcie_type(const struct pci_dev *dev)
+{
+ return (dev->pcie_flags_reg & PCI_EXP_FLAGS_TYPE) >> 4;
+}
+
void pci_request_acs(void);
bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags);
bool pci_acs_path_enabled(struct pci_dev *start,
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index 7fb75b143755..20ae747ddf34 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -549,6 +549,7 @@
#define PCI_EXP_LNKCAP2_SLS_8_0GB 0x04 /* Current Link Speed 8.0GT/s */
#define PCI_EXP_LNKCAP2_CROSSLINK 0x100 /* Crosslink supported */
#define PCI_EXP_LNKCTL2 48 /* Link Control 2 */
+#define PCI_EXP_LNKSTA2 50 /* Link Status 2 */
#define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */
/* Extended Capabilities (PCI-X 2.0 and Express) */
@@ -677,6 +678,12 @@
#define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */
#define PCI_EXT_CAP_PWR_SIZEOF 16
+/* Vendor-Specific (VSEC, PCI_EXT_CAP_ID_VNDR) */
+#define PCI_VNDR_HEADER 4 /* Vendor-Specific Header */
+#define PCI_VNDR_HEADER_ID(x) ((x) & 0xffff)
+#define PCI_VNDR_HEADER_REV(x) (((x) >> 16) & 0xf)
+#define PCI_VNDR_HEADER_LEN(x) (((x) >> 20) & 0xfff)
+
/*
* Hypertransport sub capability types
*
diff --git a/include/linux/pcieport_if.h b/include/linux/pcieport_if.h
index 6775532b92a9..e6f91b1406d8 100644
--- a/include/linux/pcieport_if.h
+++ b/include/linux/pcieport_if.h
@@ -49,7 +49,7 @@ struct pcie_port_service_driver {
int (*resume) (struct pcie_device *dev);
/* Service Error Recovery Handler */
- struct pci_error_handlers *err_handler;
+ const struct pci_error_handlers *err_handler;
/* Link Reset Capability - AER service driver specific */
pci_ers_result_t (*reset_link) (struct pci_dev *dev);