If device doesn't support as many MSI vectors as the driver requested, we
previously returned -EINVAL from __pci_enable_msi_range() and
pci_enable_msi_range(). In other similar situations in both
__pci_enable_msi_range() and __pci_enable_msix_range(), we returned
-ENOSPC.
Return -ENOSPC from __pci_enable_msi_range() so we do it consistently.
[bhelgaas: changelog]
Signed-off-by: Dennis Chen <dennis.chen@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: Tejun Heo <tj@kernel.org>
CC: Christoph Hellwig <hch@lst.de>
CC: Tom Long Nguyen <tom.l.nguyen@intel.com>
CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
CC: Marc Zyngier <marc.zyngier@arm.com>
CC: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
CC: Steve Capper <steve.capper@arm.com>
Use pci_irq_alloc_vectors() and greatly simplify the code by managing the
vector number for the subservices directly.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
It seems like there are some devices (e.g. the PCIe root port driver) that
may not always have a INTx interrupt. Check for dev->irq before returning
a legacy interrupt in pci_irq_alloc_vectors to properly handle this case.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
rockchip_pcie_probe() calls of_pci_get_host_bridge_resources() to parse
resources from DT and build a resource list. The caller is responsible for
disposing of the resource list. This is normally done by
pci_release_host_bridge_dev() when the host bridge is removed.
If the host bridge probe fails, dispose of the resource list in the probe
error path.
[bhelgaas: changelog]
Suggested-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
The devfn of 00:02.0 is 0x10. devfn_to_wslot(0x10) == 0x2, and
wslot_to_devfn(0x2) should be 0x10, while it's 0x2 in the current code.
Due to this, hv_eject_device_work() -> pci_get_domain_bus_and_slot()
returns NULL and pci_stop_and_remove_bus_device() is not called.
Later when the real device driver's .remove() is invoked by
hv_pci_remove() -> pci_stop_root_bus(), some warnings can be noticed
because the VM has lost the access to the underlying device at that
time.
Signed-off-by: Jake Oshins <jakeo@microsoft.com>
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Haiyang Zhang <haiyangz@microsoft.com>
CC: stable@vger.kernel.org
CC: K. Y. Srinivasan <kys@microsoft.com>
CC: Stephen Hemminger <sthemmin@microsoft.com>
Function __pci_device_probe() tries to be careful about a PCI driver
probe() hook returning a positive value, but this is not really necessary,
since the same fix up is already done in local_pci_probe() (preceded by a
noisy warning), which renders this instance dead code.
Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.co.uk>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Per PCIe r3.1, sec 6.2.10 and sec 7.13.4, on Root Ports that support "RP
Extensions for DPC",
When the DPC Trigger Status bit is Set and the DPC RP Busy bit is Set,
software must leave the Root Port in DPC until the DPC RP Busy bit reads
0b.
Wait up to 1 second for the Root Port to become non-busy.
[bhelgaas: changelog, spec references]
Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Decode the currently defined extended event reasons rather than just using
the generic "extended" explanation.
Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Just call the msi_* version directly instead of having trivial wrappers for
one or two callsites.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
pci_msi_create_default_irq_domain() is never called in the whole tree, so
remove it as well as all the supporting code for a default PCI MSI domain.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Remove support for vendor-defined messages which are not supported by AXI.
Signed-off-by: Bharat Kumar Gogada <bharatku@xilinx.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
If alloc_msi_entry() fails, we free resources and set ret = -ENOMEM.
However, msix_setup_entries() returns 0 unconditionally. Return the error
code instead.
Fixes: e75eafb9b0 ("genirq/msi: Switch to new irq spreading infrastructure")
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Make sure PCIe MPS settings are valid when we enumerate a new hierarchy.
Based-on-patch-by: Jon Mason <jon.mason@broadcom.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Every PCIe device can generate 5-bit transaction Tags, which allow up to 32
concurrent requests. Some devices can generate 8-bit Extended Tags, which
allow up to 256 concurrent requests.
Per the ECN mentioned below, all PCIe Receivers are expected to support
Extended Tags, so devices are allowed (but not required) to enable them by
default.
If a device supports Extended Tags but does not enable them by default,
enable them. This allows the device to have up to 256 outstanding
transactions at a time, which may improve performance.
[bhelgaas: changelog, check for PCIe device]
Link: https://pcisig.com/sites/default/files/specification_documents/ECN_Extended_Tag_Enable_Default_05Sept2008_final.pdf
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
pci_fixup_irqs() is problematic because:
- it's called when we enumerate a host bridge, so we don't fixup IRQs for
hot-added PCI devices, and
- it fixes up IRQs for all PCI devices in the system, so if we call it
multiple times, e.g., if we have several host controllers, we may
reallocate an IRQ for a device after a driver has already claimed it.
We plan to replace pci_fixup_irqs() soon, but we still need it on ARM
because we don't have any other generic method for doing this.
On ARM64, we don't need pci_fixup_irqs() because we do IRQ setup when we
bind a driver to the device (in the pci_device_probe() ->
pcibios_alloc_irq() path).
pci-host-common.c is currently only used on ARM and ARM64. In principle,
it could be used on x86, and we wouldn't want pci_fixup_irqs() there
either, because x86 does IRQ setup in the pci_enable_device() path.
[bhelgaas: changelog, use #ifdef ARM, not #ifndef ARM64]
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Reviewed-by: Zhou Wang <wangzhou1@hisilicon.com>
Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
The PCIe Root Port in Hip06/Hip07 SoCs advertises an MSI capability, but it
cannot generate MSIs. It can transfer MSI/MSI-X from downstream devices,
but does not support MSI/MSI-X itself.
Add a quirk to prevent use of MSI/MSI-X by the Root Port.
[bhelgaas: changelog, sort vendor ID #define, drop device ID #define]
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Reviewed-by: Zhou Wang <wangzhou1@hisilicon.com>
There's nothing ACPI-specific about the config space accessors
hisi_pcie_acpi_rd_conf() and hisi_pcie_acpi_wr_conf(), and they're used for
both the ACPI and the DT driver model.
Rename them to hisi_pcie_rd_conf() and hisi_pcie_wr_conf(). No functional
change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
The Broadcom Northstar2 SoC has a number of quirks for the PAXC
(internal/fake) PCI bus. Specifically, the PCI config space is shared
between the root port and the first PF (ie., PF0), and a number of fields
are tied to zero (thus preventing them from being set). These cannot be
"fixed" in device firmware, so we must fix them with a quirk.
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Make sure PCIe MPS settings are valid when we enumerate a new hierarchy.
Based-on-patch-by: Jon Mason <jon.mason@broadcom.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Make sure PCIe MPS settings are valid when we enumerate a new hierarchy.
Based-on-patch-by: Jon Mason <jon.mason@broadcom.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Remove unnecessary local variables: elbi_base, phy_base, block_base. We
need one resource structure for assigning each resource. Reuse the single
'res' variable for all.
Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Pankaj Dubey <pankaj.dubey@samsung.com>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
The current default of 20ms cause some devices, which are slow to
initialize, to not show up during the bus scanning. Change this to the
PCIe spec mandated 100ms and document this in the DT binding.
From PCIe base spec rev 3.0, chapter "6.6.1. Conventional Reset":
To allow components to perform internal initialization, system software
must wait a specified minimum period following the end of a Conventional
Reset of one or more devices before it is permitted to issue
Configuration Requests to those devices.
With a Downstream Port that does not support Link speeds greater than 5.0
GT/s, software must wait a minimum of 100 ms before sending a
Configuration Request to the device immediately below that Port.
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Jason Cooper <jason@lakedaemon.net>
The conflict was an interaction between a bug fix in the
netvsc driver in 'net' and an optimization of the RX path
in 'net-next'.
Signed-off-by: David S. Miller <davem@davemloft.net>
The PCIe controller in HiSilicon Hip06/Hip07 SoCs is not completely
ECAM-compliant. It is non-ECAM only for the RC bus config space; for any
other bus underneath the root bus it does support ECAM access.
Add DT support for the almost-ECAM Hip06/Hip07 controllers.
[bhelgaas: drop dev->of_node test, driver name "hisi-pcie-almost-ecam"]
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Reviewed-by: Zhou Wang <wangzhou1@hisilicon.com>
The only way to call hisi_pcie_probe() is to match an entry in
hisi_pcie_of_match[], so match cannot be NULL.
Use of_device_get_match_data() to retrieve the soc_ops pointer. No
functional change intended.
[bhelgaas: use of_device_get_match_data(), changelog]
Based-on-suggestion-from: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Shailendra Verma <shailendra.v@samsung.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
The PCI core uses a fixed 50ms timeout when waiting for VPD accesses to
complete. When an access does not complete within this period, a warning
is logged and an error returned to the caller.
While this default timeout is valid for most hardware, some devices can
experience longer access delays under certain circumstances. For example,
one of the IBM CXL Flash devices can take up to ~120ms in a worst-case
scenario. These types of devices can benefit from an extended timeout.
To support devices with a longer access delay, increase the timeout in
pci_vpd_wait() to 125ms. The PCI specification is silent with respect to
VPD delays, therefore there is no concern for violating a threshold.
Tested-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
Signed-off-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Bart reported a problem wіth an out of bounds access in the low-level IRQ
affinity code, which we root caused to the qla2xxx driver assigning all its
MSI-X vectors to the pre and post vectors, and not having any left for the
actually spread IRQs.
Fix this issue by not asking for affinity assignment when there are no
vectors to assign left.
Fixes: 402723ad5c ("PCI/MSI: Provide pci_alloc_irq_vectors_affinity()")
Link: https://lkml.kernel.org/r/1485359225.3093.3.camel@sandisk.com
Reported-by: Bart Van Assche <bart.vanassche@sandisk.com>
Tested-by: Bart Van Assche <bart.vanassche@sandisk.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
The only way to call iproc_pcie_pltfm_probe() is to match an entry in
iproc_pcie_of_match_table[], so match cannot be NULL.
Use of_device_get_match_data() to retrieve the pcie->type. No functional
change intended.
Based-on-suggestion-from: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
The only way to call ls_pcie_probe() is to match an entry in
ls_pcie_of_match[], so match cannot be NULL.
Use of_device_get_match_data() to retrieve the drvdata pointer. No
functional change intended.
Based-on-suggestion-from: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This is a DT-only driver, so the only way to call rcar_pcie_probe() is to
match an entry in rcar_pcie_of_match[], so of_id cannot be NULL.
Furthermore, of_id->data can only be NULL if an rcar_pcie_of_match[] entry
has a NULL .data member. That's a driver defect, and we don't want to
return -EINVAL, which is easy to ignore. We'd rather take the NULL pointer
dereference so we notice the problem and fix it.
Use of_device_get_match_data() to retrieve the hw_init_fn pointer. No
functional change intended.
Suggested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Simon Horman <horms+renesas@verge.net.au>
The "port" variable was allocated with devm_kzalloc() so if we free it with
kfree() it will be freed twice. Also I changed it to propogate the error
from devm_ioremap_resource() instead of returning -ENOMEM.
Fixes: c5d4603961 ("PCI: Add MCFG quirks for X-Gene host controller")
Also-posted-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Tanmay Inamdar <tinamdar@apm.com>
This causes CPU hangs when the system is reset by the watchdog, as the GPRs
aren't cleared, but the clocks are back to disabled state.
If the bootloader uses PCIe, it must take care to bring it down into a safe
state, before passing control to the Linux kernel. This is the only way to
get a properly operating system at all times and circumstances.
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
pci_lock is an IRQ-safe spinlock that protects all accesses to PCI
configuration space (see PCI_OP_READ() and PCI_OP_WRITE() in pci/access.c).
The pci_cfg_access_unlock() path acquires pci_lock, then p->pi_lock (inside
wake_up_all()). According to lockdep, there is a possible path involving
snbep_uncore_pci_read_counter() that could acquire them in the reverse
order: acquiring p->pi_lock, then pci_lock, which could result in a
deadlock. Lockdep details are in the bugzilla below.
Avoid the possible deadlock by dropping pci_lock before waking up any
config access waiters.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=192901
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
When CONFIG_PM_SLEEP is disabled, we get harmless build warnings:
host/pcie-rockchip.c:1267:12: error: 'rockchip_pcie_resume_noirq' defined but not used [-Werror=unused-function]
host/pcie-rockchip.c:1240:12: error: 'rockchip_pcie_suspend_noirq' defined but not used [-Werror=unused-function]
Marking both functions as __maybe_unused avoids the warning without the
need for #ifdef around them.
Fixes: 013dd3d5e1 ("PCI: rockchip: Add system PM support")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Shawn Lin <shawn.lin@rock-chips.com>
The PCI core will write to the bridge window config multiple times while
they are enabled. This can lead to mbus failures like this:
mvebu_mbus: cannot add window '4:e8', conflicts with another window
mvebu-pcie mbus:pex@e0000000: Could not create MBus window at [mem 0xe0000000-0xe00fffff]: -22
For me this is happening during a hotplug cycle. The PCI core is not
changing the values, just writing them twice while active.
The patch addresses the general case of any change to an active window, but
not atomically. The code is slightly refactored so io and mem can share
more of the window logic.
Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Jason Cooper <jason@lakedaemon.net>
Intel 200-series chipsets have the same errata as 100-series: the ACS
capability doesn't follow the PCIe spec, the capability and control
registers are dwords rather than words. Add PCIe root port device IDs to
existing quirk.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
In a struct pcie_link_state, link->root points to the pcie_link_state of
the root of the PCIe hierarchy. For the topmost link, this points to
itself (link->root = link). For others, we copy the pointer from the
parent (link->root = link->parent->root).
Previously we recognized that Root Ports originated PCIe hierarchies, but
we treated PCI/PCI-X to PCIe Bridges as being in the middle of the
hierarchy, and when we tried to copy the pointer from link->parent->root,
there was no parent, and we dereferenced a NULL pointer:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000090
IP: [<ffffffff9e424350>] pcie_aspm_init_link_state+0x170/0x820
Recognize that PCI/PCI-X to PCIe Bridges originate PCIe hierarchies just
like Root Ports do, so link->root for these devices should also point to
itself.
Fixes: 51ebfc92b7 ("PCI: Enumerate switches below PCI-to-PCIe bridges")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=193411
Link: https://bugzilla.opensuse.org/show_bug.cgi?id=1022181
Tested-by: lists@ssl-mail.com
Tested-by: Jayachandran C. <jnair@caviumnetworks.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: stable@vger.kernel.org # v4.2+
The conversion to the new hotplug state machine introduced a regression
where a successful hotplug registration would be treated as an error,
effectively disabling the MSI driver forever.
Fix it by doing the proper check on the return value.
Fixes: 9c248f8896 ("PCI/xgene-msi: Convert to hotplug state machine")
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Tested-by: Duc Dang <dhdang@apm.com>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: stable@vger.kernel.org