From 9ada07b1100a9c7d3107c47673664194574b02a0 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 6 Mar 2014 21:11:22 +0100 Subject: [PATCH 01/21] PCI/portdrv: Use pci_enable_msix_exact() instead of pci_enable_msix() As result of deprecation of MSI-X/MSI enablement functions pci_enable_msix() and pci_enable_msi_block() all drivers using these two interfaces need to be updated to use the new pci_enable_msi_range() or pci_enable_msi_exact() and pci_enable_msix_range() or pci_enable_msix_exact() interfaces. Signed-off-by: Alexander Gordeev Signed-off-by: Bjorn Helgaas --- drivers/pci/pcie/portdrv_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 986f8eadfd393..0b1efb2760d13 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -99,7 +99,7 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) for (i = 0; i < nr_entries; i++) msix_entries[i].entry = i; - status = pci_enable_msix(dev, msix_entries, nr_entries); + status = pci_enable_msix_exact(dev, msix_entries, nr_entries); if (status) goto Exit; @@ -171,7 +171,7 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) pci_disable_msix(dev); /* Now allocate the MSI-X vectors for real */ - status = pci_enable_msix(dev, msix_entries, nvec); + status = pci_enable_msix_exact(dev, msix_entries, nvec); if (status) goto Exit; } From 1406276c1254d761da7c16b30aa32e3af2b3612a Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 14 Apr 2014 14:59:50 -0600 Subject: [PATCH 02/21] PCI/MSI: Simplify populate_msi_sysfs() Simplify populate_msi_sysfs() by - Swapping the order of the two allocations and storing the msi_dev_attr-derived pointer right after allocation, allowing the cleanup code to pick things up without extra effort. - Using kasprintf() instead of the kmalloc()/sprintf() pair. Signed-off-by: Jan Beulich Signed-off-by: Bjorn Helgaas Acked-by: Greg Kroah-Hartman --- drivers/pci/msi.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 955ab7990c5bd..04130c3f9cf6c 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -544,22 +544,18 @@ static int populate_msi_sysfs(struct pci_dev *pdev) if (!msi_attrs) return -ENOMEM; list_for_each_entry(entry, &pdev->msi_list, list) { - char *name = kmalloc(20, GFP_KERNEL); - if (!name) - goto error_attrs; - msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL); - if (!msi_dev_attr) { - kfree(name); + if (!msi_dev_attr) goto error_attrs; - } + msi_attrs[count] = &msi_dev_attr->attr; - sprintf(name, "%d", entry->irq); sysfs_attr_init(&msi_dev_attr->attr); - msi_dev_attr->attr.name = name; + msi_dev_attr->attr.name = kasprintf(GFP_KERNEL, "%d", + entry->irq); + if (!msi_dev_attr->attr.name) + goto error_attrs; msi_dev_attr->attr.mode = S_IRUGO; msi_dev_attr->show = msi_mode_show; - msi_attrs[count] = &msi_dev_attr->attr; ++count; } From 8e56aed0b0579b667489bcb1d94c223726f0eaa1 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Mon, 14 Apr 2014 16:04:55 -0600 Subject: [PATCH 03/21] PCI: hotplug: Remove unnecessary "dev->bus" test Every pci_dev is on a valid pci_bus, so we don't need to test whether dev->bus is NULL or not. The only exceptions are a few legacy cases like alpha_core_agp_setup(), parisc_agp_setup(), and megaraid's make_local_pdev(), where we allocate a pci_dev with a NULL bus pointer. These are dubious uses (especially the megaraid one), and I don't think it's possible to exercise this pci_configure_slot() path with any of them. Found by Coverity (CID 146446). Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/pcihp_slot.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c index 16f9203523179..e246a10a0d2c5 100644 --- a/drivers/pci/hotplug/pcihp_slot.c +++ b/drivers/pci/hotplug/pcihp_slot.c @@ -160,8 +160,7 @@ void pci_configure_slot(struct pci_dev *dev) (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) return; - if (dev->bus) - pcie_bus_configure_settings(dev->bus); + pcie_bus_configure_settings(dev->bus); memset(&hpp, 0, sizeof(hpp)); ret = pci_get_hp_params(dev, &hpp); From 17f830bb83ff64533f02cfd4b114d4a5957c2ee7 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Sat, 5 Apr 2014 15:05:07 -0600 Subject: [PATCH 04/21] PCI: pciehp: Use PCI_EXP_SLTCAP_PSN define Use PCI_EXP_SLTCAP_PSN to make it easier to find code that uses the Physical Slot Number field in the PCIe Slot Capabilities register. No functional change. Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/pciehp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 8a66866b8cf1a..8e9012dca450d 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -127,7 +127,7 @@ struct controller { #define HP_SUPR_RM(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_HPS) #define EMI(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_EIP) #define NO_CMD_CMPL(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_NCCS) -#define PSN(ctrl) ((ctrl)->slot_cap >> 19) +#define PSN(ctrl) (((ctrl)->slot_cap & PCI_EXP_SLTCAP_PSN) >> 19) int pciehp_sysfs_enable_slot(struct slot *slot); int pciehp_sysfs_disable_slot(struct slot *slot); From ff0c41b2df1577f3354f788af4f6bb5dbdfd26da Mon Sep 17 00:00:00 2001 From: Mike Qiu Date: Mon, 14 Apr 2014 16:12:35 -0600 Subject: [PATCH 05/21] powerpc/PCI: Fix NULL dereference in sys_pciconfig_iobase() list traversal 3bc955987fb3 ("powerpc/PCI: Use list_for_each_entry() for bus traversal") caused a NULL pointer dereference because the loop body set the iterator to NULL: Unable to handle kernel paging request for data at address 0x00000000 Faulting instruction address: 0xc000000000041d78 Oops: Kernel access of bad area, sig: 11 [#1] ... NIP [c000000000041d78] .sys_pciconfig_iobase+0x68/0x1f0 LR [c000000000041e0c] .sys_pciconfig_iobase+0xfc/0x1f0 Call Trace: [c0000003b4787db0] [c000000000041e0c] .sys_pciconfig_iobase+0xfc/0x1f0 (unreliable) [c0000003b4787e30] [c000000000009ed8] syscall_exit+0x0/0x98 Fix it by using a temporary variable for the iterator. [bhelgaas: changelog, drop tmp_bus initialization] Fixes: 3bc955987fb3 powerpc/PCI: Use list_for_each_entry() for bus traversal Signed-off-by: Mike Qiu Signed-off-by: Bjorn Helgaas --- arch/powerpc/kernel/pci_64.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 2a4779091a580..155013da27e05 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -208,7 +208,7 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus, unsigned long in_devfn) { struct pci_controller* hose; - struct pci_bus *bus = NULL; + struct pci_bus *tmp_bus, *bus = NULL; struct device_node *hose_node; /* Argh ! Please forgive me for that hack, but that's the @@ -229,10 +229,12 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus, * used on pre-domains setup. We return the first match */ - list_for_each_entry(bus, &pci_root_buses, node) { - if (in_bus >= bus->number && in_bus <= bus->busn_res.end) + list_for_each_entry(tmp_bus, &pci_root_buses, node) { + if (in_bus >= tmp_bus->number && + in_bus <= tmp_bus->busn_res.end) { + bus = tmp_bus; break; - bus = NULL; + } } if (bus == NULL || bus->dev.of_node == NULL) return -ENODEV; From 56a3d18279f00c7ccbcdc193ceaf1a2f88c51457 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sat, 5 Apr 2014 15:13:33 -0600 Subject: [PATCH 06/21] PCI: Remove unnecessary includes of None of these files are actually using any __init type directives and hence don't need to include . Most are just a left over from __devinit and __cpuinit removal, or simply due to code getting copied from one driver to the next. Signed-off-by: Paul Gortmaker Signed-off-by: Bjorn Helgaas --- drivers/pci/bus.c | 1 - drivers/pci/host-bridge.c | 1 - drivers/pci/hotplug/acpiphp_glue.c | 1 - drivers/pci/hotplug/cpqphp_nvram.c | 1 - drivers/pci/hotplug/s390_pci_hpc.c | 1 - drivers/pci/msi.c | 1 - drivers/pci/search.c | 1 - drivers/pci/setup-irq.c | 1 - drivers/pci/setup-res.c | 1 - 9 files changed, 9 deletions(-) diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index fb8aed307c282..ba2bf55a38df5 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "pci.h" diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c index 47aaf22d814e1..0e5f3c95af5bd 100644 --- a/drivers/pci/host-bridge.c +++ b/drivers/pci/host-bridge.c @@ -3,7 +3,6 @@ */ #include -#include #include #include diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index bccc27ee10308..0238a02b4cb36 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -41,7 +41,6 @@ #define pr_fmt(fmt) "acpiphp_glue: " fmt -#include #include #include diff --git a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c index 76ba8a1c774df..9600a392eaae8 100644 --- a/drivers/pci/hotplug/cpqphp_nvram.c +++ b/drivers/pci/hotplug/cpqphp_nvram.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include "cpqphp.h" #include "cpqphp_nvram.h" diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c index 8d2ce22151eb6..d1332d2f8730c 100644 --- a/drivers/pci/hotplug/s390_pci_hpc.c +++ b/drivers/pci/hotplug/s390_pci_hpc.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 955ab7990c5bd..aaf8d3243cd61 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 4a1b972efe7f2..8e495bda678f2 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -7,7 +7,6 @@ * Copyright (C) 2003 -- 2004 Greg Kroah-Hartman */ -#include #include #include #include diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c index 9bd6864ec5d3f..dbc4ffcf42dec 100644 --- a/drivers/pci/setup-irq.c +++ b/drivers/pci/setup-irq.c @@ -10,7 +10,6 @@ */ -#include #include #include #include diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 7eed671d55861..1e37c590a1833 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -16,7 +16,6 @@ * Resource sorting */ -#include #include #include #include From 1a30fd0dba778f7ef1a6254989060a141fca8e23 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Mon, 31 Mar 2014 12:21:38 -0600 Subject: [PATCH 07/21] PCI: Add Patsburg (X79) to Intel PCH root port ACS quirk Intel has updated Red Hat bz1037684 to note that X79 PCH root ports also provide isolation and the same ACS quirks apply. Some sources indicate additional device IDs for X79, but this patch includes only the ones specifically identified by Intel: https://bugzilla.redhat.com/show_bug.cgi?id=1037684#c11 Signed-off-by: Alex Williamson Signed-off-by: Bjorn Helgaas Acked-by: Don Dugger --- drivers/pci/quirks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e7292065a1b13..5e4ac635368fe 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3453,6 +3453,8 @@ static const u16 pci_quirk_intel_pch_acs_ids[] = { /* Wildcat PCH */ 0x9c90, 0x9c91, 0x9c92, 0x9c93, 0x9c94, 0x9c95, 0x9c96, 0x9c97, 0x9c98, 0x9c99, 0x9c9a, 0x9c9b, + /* Patsburg (X79) PCH */ + 0x1d10, 0x1d12, 0x1d14, 0x1d16, 0x1d18, 0x1d1a, 0x1d1c, 0x1d1e, }; static bool pci_quirk_intel_pch_acs_match(struct pci_dev *dev) From 7ee4910ab31c4b1fafb7e4f273cbe9340ac953aa Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 31 Mar 2014 15:19:29 +0200 Subject: [PATCH 08/21] PCI: Remove old serial device IDs These IDs are no longer referenced since kernel 3.1 so I suppose we can remove them from pci_ids.h. Signed-off-by: Jean Delvare Signed-off-by: Bjorn Helgaas Acked-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index d4de24b4d4c64..7fa31731c8548 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1631,8 +1631,6 @@ #define PCI_DEVICE_ID_ATT_VENUS_MODEM 0x480 #define PCI_VENDOR_ID_SPECIALIX 0x11cb -#define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000 -#define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000 #define PCI_SUBDEVICE_ID_SPECIALIX_SPEED4 0xa004 #define PCI_VENDOR_ID_ANALOG_DEVICES 0x11d4 @@ -2874,7 +2872,6 @@ #define PCI_DEVICE_ID_SCALEMP_VSMP_CTL 0x1010 #define PCI_VENDOR_ID_COMPUTONE 0x8e0e -#define PCI_DEVICE_ID_COMPUTONE_IP2EX 0x0291 #define PCI_DEVICE_ID_COMPUTONE_PG 0x0302 #define PCI_SUBVENDOR_ID_COMPUTONE 0x8e0e #define PCI_SUBDEVICE_ID_COMPUTONE_PG4 0x0001 From 476a357fd9045a4c91faa055fadabf550aedb8c5 Mon Sep 17 00:00:00 2001 From: Rajat Jain Date: Thu, 20 Feb 2014 17:42:31 -0800 Subject: [PATCH 09/21] PCI: pciehp: Acknowledge spurious "cmd completed" event In case of a spurious "cmd completed", pcie_write_cmd() does not clear it, but yet expects more "cmd completed" events to be generated. This does not happen because the previous (spurious) event has not been acknowledged. Fix that. Signed-off-by: Rajat Jain Signed-off-by: Rajat Jain Signed-off-by: Guenter Roeck Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/pciehp_hpc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index d7d058fa19a42..1463412cf7f8e 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -159,6 +159,8 @@ static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); if (slot_status & PCI_EXP_SLTSTA_CC) { + pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, + PCI_EXP_SLTSTA_CC); if (!ctrl->no_cmd_complete) { /* * After 1 sec and CMD_COMPLETED still not set, just From 374a91404314cef882b27b293dd34d89e2a3c0b6 Mon Sep 17 00:00:00 2001 From: Rajat Jain Date: Mon, 31 Mar 2014 16:51:23 -0700 Subject: [PATCH 10/21] PCI: Allow hotplug service drivers to operate in polling mode Today the PCIe port bus driver disables the Hot-plug service if the port device does not have the capability to generate interrupts. However, a user must be able to use the "pciehp_poll_mode" parameter to use the pciehp in polling method in such a case. Today it is not possible. This patch allows a hotplug service driver to decide whether or not it would like to continue in the absence of interrupts. Signed-off-by: Rajat Jain Signed-off-by: Rajat Jain Signed-off-by: Guenter Roeck Signed-off-by: Bjorn Helgaas --- drivers/pci/pcie/portdrv_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 986f8eadfd393..f6503add2f350 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -379,10 +379,13 @@ int pcie_port_device_register(struct pci_dev *dev) /* * Initialize service irqs. Don't use service devices that * require interrupts if there is no way to generate them. + * However, some drivers may have a polling mode (e.g. pciehp_poll_mode) + * that can be used in the absence of irqs. Allow them to determine + * if that is to be used. */ status = init_service_irqs(dev, irqs, capabilities); if (status) { - capabilities &= PCIE_PORT_SERVICE_VC; + capabilities &= PCIE_PORT_SERVICE_VC | PCIE_PORT_SERVICE_HP; if (!capabilities) goto error_disable; } From c1309040967e200d3ea6415ae54cf6a69d7ad996 Mon Sep 17 00:00:00 2001 From: Mark Rustad Date: Mon, 31 Mar 2014 14:58:39 -0700 Subject: [PATCH 11/21] PCI: Use designated initialization in PCI_VDEVICE By using designated initialization in PCI_VDEVICE, like other similar macros, many "missing initializer" warnings that appear when compiling with W=2 can be silenced. Tested-by: Phil Schmitt Tested-by: Aaron Brown Tested-by: Kavindya Deegala Signed-off-by: Mark Rustad Signed-off-by: Jeff Kirsher Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/linux/pci.h b/include/linux/pci.h index aab57b4abe7fc..a95aac7ad37fd 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -680,8 +680,8 @@ struct pci_driver { /** * PCI_VDEVICE - macro used to describe a specific pci device in short form - * @vendor: the vendor name - * @device: the 16 bit PCI Device ID + * @vend: the vendor name + * @dev: the 16 bit PCI Device ID * * This macro is used to create a struct pci_device_id that matches a * specific PCI device. The subvendor, and subdevice fields will be set @@ -689,9 +689,9 @@ struct pci_driver { * private data. */ -#define PCI_VDEVICE(vendor, device) \ - PCI_VENDOR_ID_##vendor, (device), \ - PCI_ANY_ID, PCI_ANY_ID, 0, 0 +#define PCI_VDEVICE(vend, dev) \ + .vendor = PCI_VENDOR_ID_##vend, .device = (dev), \ + .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, 0, 0 /* these external functions are only available when PCI support is enabled */ #ifdef CONFIG_PCI From 67ebd8140dc8923c65451fa0f6a8eee003c4dcd3 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Sat, 5 Apr 2014 15:14:22 -0600 Subject: [PATCH 12/21] PCI: Fix incorrect vgaarb conditional in WARN_ON() 3448a19da479 "vgaarb: use bridges to control VGA routing where possible" added the "flags & PCI_VGA_STATE_CHANGE_DECODES" condition to an existing WARN_ON(), but used bitwise AND (&) instead of logical AND (&&), so the condition is never true. Replace with logical AND. Found by Coverity (CID 142811). Fixes: 3448a19da479 "vgaarb: use bridges to control VGA routing where possible" Signed-off-by: Bjorn Helgaas Acked-by: Yinghai Lu Acked-by: David Airlie --- drivers/pci/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 7325d43bf030c..39012831867e6 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4125,7 +4125,7 @@ int pci_set_vga_state(struct pci_dev *dev, bool decode, u16 cmd; int rc; - WARN_ON((flags & PCI_VGA_STATE_CHANGE_DECODES) & (command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY))); + WARN_ON((flags & PCI_VGA_STATE_CHANGE_DECODES) && (command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY))); /* ARCH specific VGA enables */ rc = pci_set_vga_state_arch(dev, decode, command_bits, flags); From 761ce53330a4f02c58768631027d1c1dd0d538f7 Mon Sep 17 00:00:00 2001 From: Laurent Dufour Date: Thu, 10 Apr 2014 15:02:13 +0200 Subject: [PATCH 13/21] PCI: rphahp: Fix endianess issues Numerical values stored in the device tree are encoded in Big Endian and should be byte swapped when running in Little Endian. The RPA hotplug module should convert those values as well. Note that in rpaphp_get_drc_props(), the comparison between indexes[i+1] and *index is done using the BE values (whatever is the current endianess). This doesn't matter since we are checking for equality here. This way only the returned value is byte swapped. RPA also made RTAS calls which implies BE values to be used. According to the patch done in RTAS (http://patchwork.ozlabs.org/patch/336865), no additional conversion is required in RPA. Signed-off-by: Laurent Dufour Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/rpaphp_core.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 4796c15fba941..984d708552f6f 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -223,16 +223,16 @@ int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, type_tmp = (char *) &types[1]; /* Iterate through parent properties, looking for my-drc-index */ - for (i = 0; i < indexes[0]; i++) { + for (i = 0; i < be32_to_cpu(indexes[0]); i++) { if ((unsigned int) indexes[i + 1] == *my_index) { if (drc_name) *drc_name = name_tmp; if (drc_type) *drc_type = type_tmp; if (drc_index) - *drc_index = *my_index; + *drc_index = be32_to_cpu(*my_index); if (drc_power_domain) - *drc_power_domain = domains[i+1]; + *drc_power_domain = be32_to_cpu(domains[i+1]); return 0; } name_tmp += (strlen(name_tmp) + 1); @@ -321,16 +321,19 @@ int rpaphp_add_slot(struct device_node *dn) /* register PCI devices */ name = (char *) &names[1]; type = (char *) &types[1]; - for (i = 0; i < indexes[0]; i++) { + for (i = 0; i < be32_to_cpu(indexes[0]); i++) { + int index; - slot = alloc_slot_struct(dn, indexes[i + 1], name, power_domains[i + 1]); + index = be32_to_cpu(indexes[i + 1]); + slot = alloc_slot_struct(dn, index, name, + be32_to_cpu(power_domains[i + 1])); if (!slot) return -ENOMEM; slot->type = simple_strtoul(type, NULL, 10); dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n", - indexes[i + 1], name, type); + index, name, type); retval = rpaphp_enable_slot(slot); if (!retval) From a30d0108b09ae46d24594a2e699c4dad21bb4af4 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Mon, 14 Apr 2014 09:14:06 +0200 Subject: [PATCH 14/21] GenWQE: Use pci_enable_msi_exact() instead of pci_enable_msi_block() As result of deprecation of MSI-X/MSI enablement functions pci_enable_msix() and pci_enable_msi_block() all drivers using these two interfaces need to be updated to use the new pci_enable_msi_range() or pci_enable_msi_exact() and pci_enable_msix_range() or pci_enable_msix_exact() interfaces. Signed-off-by: Alexander Gordeev Signed-off-by: Bjorn Helgaas Acked-by: Frank Haverkamp Acked-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c index 6b1a6ef9f1a8c..294f667ccab62 100644 --- a/drivers/misc/genwqe/card_utils.c +++ b/drivers/misc/genwqe/card_utils.c @@ -628,7 +628,7 @@ int genwqe_set_interrupt_capability(struct genwqe_dev *cd, int count) int rc; struct pci_dev *pci_dev = cd->pci_dev; - rc = pci_enable_msi_block(pci_dev, count); + rc = pci_enable_msi_exact(pci_dev, count); if (rc == 0) cd->flags |= GENWQE_FLAG_MSI_ENABLED; return rc; From 473153aff4b978006f1c5fbc0e9032fd11061709 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 22 Apr 2014 17:27:57 +0100 Subject: [PATCH 15/21] PCI: Update my email address Signed-off-by: Ben Hutchings Signed-off-by: Bjorn Helgaas --- Documentation/ABI/testing/sysfs-bus-pci | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci index a3c5a66850361..ab8d76dfaa809 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci @@ -117,7 +117,7 @@ Description: What: /sys/bus/pci/devices/.../vpd Date: February 2008 -Contact: Ben Hutchings +Contact: Ben Hutchings Description: A file named vpd in a device directory will be a binary file containing the Vital Product Data for the From 7c82126a94e69bbbac586f0249e7ef11e681246c Mon Sep 17 00:00:00 2001 From: Thomas Jarosch Date: Mon, 7 Apr 2014 15:10:32 +0200 Subject: [PATCH 16/21] PCI: Add new ID for Intel GPU "spurious interrupt" quirk After a CPU upgrade while keeping the same mainboard, we faced "spurious interrupt" problems again. It turned out that the new CPU also featured a new GPU with a different PCI ID. Add this PCI ID to the quirk table. Probably all other Intel GPU PCI IDs are affected, too, but I don't want to add them without a test system. See f67fd55fa96f ("PCI: Add quirk for still enabled interrupts on Intel Sandy Bridge GPUs") for some history. [bhelgaas: add f67fd55fa96f reference, stable tag] Signed-off-by: Thomas Jarosch Signed-off-by: Bjorn Helgaas CC: stable@vger.kernel.org # v3.4+ --- drivers/pci/quirks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e7292065a1b13..0feb4a32a9417 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2954,6 +2954,7 @@ static void disable_igfx_irq(struct pci_dev *dev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0152, disable_igfx_irq); /* * PCI devices which are on Intel chips can skip the 10ms delay From 8895d3bcb8ba960b1b83f95d772b641352ea8e51 Mon Sep 17 00:00:00 2001 From: Bandan Das Date: Tue, 1 Apr 2014 21:32:59 -0400 Subject: [PATCH 17/21] PCI: Fail new_id for vendor/device values already built into driver While using the sysfs new_id interface, the user can unintentionally feed incorrect values if the driver static table has a matching entry. This is possible since only the device and vendor fields are mandatory and the rest are optional. As a result, store_new_id() will fill in default values that are then passed on to the driver and can have unintended consequences. As an example, consider the ixgbe driver and the 82599EB network card: echo "8086 10fb" > /sys/bus/pci/drivers/ixgbe/new_id This will pass a pci_device_id with driver_data = 0 to ixgbe_probe(), which uses that zero to index a table of card operations. The zeroth entry of the table does *not* correspond to the 82599 operations. This change returns an error if the user attempts to add a dynid for a vendor/device combination for which a static entry already exists. However, if the user intentionally wants a different set of values, she must provide all the 7 fields and that will be accepted. [bhelgaas: drop KVM text since the problem isn't KVM-specific] Signed-off-by: Bandan Das Signed-off-by: Bjorn Helgaas Reviewed-by: Alex Williamson --- drivers/pci/pci-driver.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index d911e0c1f3597..650ce8935fd79 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -107,7 +107,7 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) subdevice=PCI_ANY_ID, class=0, class_mask=0; unsigned long driver_data=0; int fields=0; - int retval; + int retval = 0; fields = sscanf(buf, "%x %x %x %x %x %x %lx", &vendor, &device, &subvendor, &subdevice, @@ -115,6 +115,26 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) if (fields < 2) return -EINVAL; + if (fields != 7) { + struct pci_dev *pdev = kzalloc(sizeof(*pdev), GFP_KERNEL); + if (!pdev) + return -ENOMEM; + + pdev->vendor = vendor; + pdev->device = device; + pdev->subsystem_vendor = subvendor; + pdev->subsystem_device = subdevice; + pdev->class = class; + + if (pci_match_id(pdrv->id_table, pdev)) + retval = -EEXIST; + + kfree(pdev); + + if (retval) + return retval; + } + /* Only accept driver_data values that match an existing id_table entry */ if (ids) { From 10874f5a00266343a06e95da680e8a5a383d9a80 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Mon, 14 Apr 2014 16:11:40 -0600 Subject: [PATCH 18/21] PCI: Remove unnecessary __ref annotations Some PCI functions used to be marked __devinit. When CONFIG_HOTPLUG was not set, these functions were discarded after boot. A few callers of these __devinit functions were marked __ref to indicate that they could safely call the __devinit functions even though the callers were not __devinit. But CONFIG_HOTPLUG and __devinit are now gone, and the need for the __ref annotations is also gone, so remove them. Relevant historical commits: 54b956b90360 Remove __dev* markings from init.h a8e4b9c101ae PCI: add generic pci_hp_add_bridge() 0ab2b57f8db8 PCI: fix section mismatch warning in pci_scan_child_bus 451124a7cc6c PCI: fix 4x section mismatch warnings Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug-pci.c | 2 +- drivers/pci/hotplug/acpiphp_glue.c | 2 +- drivers/pci/hotplug/cpci_hotplug_pci.c | 2 +- drivers/pci/hotplug/shpchp_pci.c | 2 +- drivers/pci/pci.h | 8 ++++---- drivers/pci/probe.c | 8 ++++---- drivers/pci/setup-bus.c | 25 ++++++++++++------------- 7 files changed, 24 insertions(+), 25 deletions(-) diff --git a/drivers/pci/hotplug-pci.c b/drivers/pci/hotplug-pci.c index 6258dc260d9f5..c68366cee6b72 100644 --- a/drivers/pci/hotplug-pci.c +++ b/drivers/pci/hotplug-pci.c @@ -4,7 +4,7 @@ #include #include "pci.h" -int __ref pci_hp_add_bridge(struct pci_dev *dev) +int pci_hp_add_bridge(struct pci_dev *dev) { struct pci_bus *parent = dev->bus; int pass, busnr, start = parent->busn_res.start; diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 0238a02b4cb36..bb945e33b1ecf 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -500,7 +500,7 @@ static int acpiphp_rescan_slot(struct acpiphp_slot *slot) * This function should be called per *physical slot*, * not per each slot object in ACPI namespace. */ -static void __ref enable_slot(struct acpiphp_slot *slot) +static void enable_slot(struct acpiphp_slot *slot) { struct pci_dev *dev; struct pci_bus *bus = slot->bus; diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 8c14648517681..b238a1a283722 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -250,7 +250,7 @@ int cpci_led_off(struct slot* slot) * Device configuration functions */ -int __ref cpci_configure_slot(struct slot *slot) +int cpci_configure_slot(struct slot *slot) { struct pci_dev *dev; struct pci_bus *parent; diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index 2bf69fe1926c6..18209ebc09796 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -34,7 +34,7 @@ #include "../pci.h" #include "shpchp.h" -int __ref shpchp_configure_device(struct slot *p_slot) +int shpchp_configure_device(struct slot *p_slot) { struct pci_dev *dev; struct controller *ctrl = p_slot->ctrl; diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 6bd082299e319..fe233a3099cf6 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -201,11 +201,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, struct resource *res, unsigned int reg); int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); void pci_configure_ari(struct pci_dev *dev); -void __ref __pci_bus_size_bridges(struct pci_bus *bus, +void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head); -void __ref __pci_bus_assign_resources(const struct pci_bus *bus, - struct list_head *realloc_head, - struct list_head *fail_head); +void __pci_bus_assign_resources(const struct pci_bus *bus, + struct list_head *realloc_head, + struct list_head *fail_head); /** * pci_ari_enabled - query ARI forwarding status diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index ef09f5f2fe6c0..fe89a982a3da8 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -719,7 +719,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, return child; } -struct pci_bus *__ref pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr) +struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr) { struct pci_bus *child; @@ -1369,7 +1369,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) WARN_ON(ret < 0); } -struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn) +struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn) { struct pci_dev *dev; @@ -1958,7 +1958,7 @@ EXPORT_SYMBOL(pci_scan_bus); * * Returns the max number of subordinate bus discovered. */ -unsigned int __ref pci_rescan_bus_bridge_resize(struct pci_dev *bridge) +unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge) { unsigned int max; struct pci_bus *bus = bridge->subordinate; @@ -1981,7 +1981,7 @@ unsigned int __ref pci_rescan_bus_bridge_resize(struct pci_dev *bridge) * * Returns the max number of subordinate bus discovered. */ -unsigned int __ref pci_rescan_bus(struct pci_bus *bus) +unsigned int pci_rescan_bus(struct pci_bus *bus) { unsigned int max; diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 138bdd6393be8..d219d44709b2f 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1113,8 +1113,7 @@ static void pci_bus_size_cardbus(struct pci_bus *bus, ; } -void __ref __pci_bus_size_bridges(struct pci_bus *bus, - struct list_head *realloc_head) +void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) { struct pci_dev *dev; unsigned long mask, prefmask; @@ -1178,15 +1177,15 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus, } } -void __ref pci_bus_size_bridges(struct pci_bus *bus) +void pci_bus_size_bridges(struct pci_bus *bus) { __pci_bus_size_bridges(bus, NULL); } EXPORT_SYMBOL(pci_bus_size_bridges); -void __ref __pci_bus_assign_resources(const struct pci_bus *bus, - struct list_head *realloc_head, - struct list_head *fail_head) +void __pci_bus_assign_resources(const struct pci_bus *bus, + struct list_head *realloc_head, + struct list_head *fail_head) { struct pci_bus *b; struct pci_dev *dev; @@ -1218,15 +1217,15 @@ void __ref __pci_bus_assign_resources(const struct pci_bus *bus, } } -void __ref pci_bus_assign_resources(const struct pci_bus *bus) +void pci_bus_assign_resources(const struct pci_bus *bus) { __pci_bus_assign_resources(bus, NULL, NULL); } EXPORT_SYMBOL(pci_bus_assign_resources); -static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge, - struct list_head *add_head, - struct list_head *fail_head) +static void __pci_bridge_assign_resources(const struct pci_dev *bridge, + struct list_head *add_head, + struct list_head *fail_head) { struct pci_bus *b; @@ -1304,9 +1303,9 @@ enum release_type { * try to release pci bridge resources that is from leaf bridge, * so we can allocate big new one later */ -static void __ref pci_bus_release_bridge_resources(struct pci_bus *bus, - unsigned long type, - enum release_type rel_type) +static void pci_bus_release_bridge_resources(struct pci_bus *bus, + unsigned long type, + enum release_type rel_type) { struct pci_dev *dev; bool is_leaf_bridge = true; From cad01f9191226f069a0932a01b738bacde784a62 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Sat, 5 Apr 2014 15:07:00 -0600 Subject: [PATCH 19/21] MAINTAINERS: Add arch/x86/kernel/quirks.c to PCI file patterns I'm not asserting any claim over arch/x86/kernel/quirks.c, and I don't plan to merge changes to it, but some of the quirks there are PCI-related, and I'd like to see changes to them. Signed-off-by: Bjorn Helgaas --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6dc67b1fdb507..8dbea21d973dc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6693,6 +6693,7 @@ F: Documentation/PCI/ F: drivers/pci/ F: include/linux/pci* F: arch/x86/pci/ +F: arch/x86/kernel/quirks.c PCI DRIVER FOR IMX6 M: Richard Zhu From efdd4070f38e962d69c11f23c5aa033121a8cf0f Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Sat, 5 Apr 2014 15:08:22 -0600 Subject: [PATCH 20/21] PCI: Remove dead code "pdev" can never be NULL here, so remove the test. Found by Coverity (CID 744313). Signed-off-by: Bjorn Helgaas --- drivers/pci/pci-driver.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 650ce8935fd79..ff236ed4f5cf4 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -1345,8 +1345,6 @@ static int pci_uevent(struct device *dev, struct kobj_uevent_env *env) return -ENODEV; pdev = to_pci_dev(dev); - if (!pdev) - return -ENODEV; if (add_uevent_var(env, "PCI_CLASS=%04X", pdev->class)) return -ENOMEM; @@ -1367,6 +1365,7 @@ static int pci_uevent(struct device *dev, struct kobj_uevent_env *env) (u8)(pdev->class >> 16), (u8)(pdev->class >> 8), (u8)(pdev->class))) return -ENOMEM; + return 0; } From 1e358f94c00570f88a590cabe718daf835440cc9 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 29 Apr 2014 12:51:55 -0600 Subject: [PATCH 21/21] PCI: Fix use of uninitialized MPS value If "pcie_bus_config == PCIE_BUS_PERFORMANCE", we don't initialize "smpss", so we pass a pointer to garbage into pcie_bus_configure_set(), where we compute "mps" based on the garbage. We then pass the garbage "mps" to pcie_write_mps(), which ignores it in the PCIE_BUS_PERFORMANCE case. Coverity isn't smart enough to deduce that we ignore the garbage (it's a lot to expect from a human, too), so initialize "smpss" to a safe value in all cases. Found by Coverity (CID 146454). Signed-off-by: Bjorn Helgaas --- drivers/pci/probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index fe89a982a3da8..490031fd21084 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1617,7 +1617,7 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data) */ void pcie_bus_configure_settings(struct pci_bus *bus) { - u8 smpss; + u8 smpss = 0; if (!bus->self) return;