summaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2018-08-15 21:59:06 +0200
committerBjorn Helgaas <bhelgaas@google.com>2018-08-15 21:59:06 +0200
commit3a48dc6fc260c9cac302a9ffaeab95359431c485 (patch)
tree7dc85ea850ef81c756b55e2bdec5b7b6146f535e /drivers/pci/pci.c
parentMerge branch 'pci/switchtec' (diff)
parentPCI: Add function 1 DMA alias quirk for Marvell 88SS9183 (diff)
downloadlinux-3a48dc6fc260c9cac302a9ffaeab95359431c485.tar.xz
linux-3a48dc6fc260c9cac302a9ffaeab95359431c485.zip
Merge branch 'pci/virtualization'
- To avoid bus errors, enable PASID only if entire path supports End-End TLP prefixes (Sinan Kaya) - Unify slot and bus reset functions and remove hotplug knowledge from callers (Sinan Kaya) - Add Function-Level Reset quirks for Intel and Samsung NVMe devices to fix guest reboot issues (Alex Williamson) - Add function 1 DMA alias quirk for Marvell 88SS9183 PCIe SSD Controller (Bjorn Helgaas) * pci/virtualization: PCI: Add function 1 DMA alias quirk for Marvell 88SS9183 PCI: Delay after FLR of Intel DC P3700 NVMe PCI: Disable Samsung SM961/PM961 NVMe before FLR PCI: Export pcie_has_flr() PCI: Rename pci_try_reset_bus() to pci_reset_bus() PCI: Deprecate pci_reset_bus() and pci_reset_slot() functions PCI: Unify try slot and bus reset API PCI: Hide pci_reset_bridge_secondary_bus() from drivers IB/hfi1: Use pci_try_reset_bus() for initiating PCI Secondary Bus Reset PCI: Handle error return from pci_reset_bridge_secondary_bus() PCI/IOV: Tidy pci_sriov_set_totalvfs() PCI: Enable PASID only if entire path supports End-End TLP prefixes # Conflicts: # drivers/pci/hotplug/pciehp_hpc.c
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r--drivers/pci/pci.c92
1 files changed, 26 insertions, 66 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 77960fe9d9f3..80da4841c7d2 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4349,7 +4349,7 @@ static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout)
* Returns true if the device advertises support for PCIe function level
* resets.
*/
-static bool pcie_has_flr(struct pci_dev *dev)
+bool pcie_has_flr(struct pci_dev *dev)
{
u32 cap;
@@ -4359,6 +4359,7 @@ static bool pcie_has_flr(struct pci_dev *dev)
pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap);
return cap & PCI_EXP_DEVCAP_FLR;
}
+EXPORT_SYMBOL_GPL(pcie_has_flr);
/**
* pcie_flr - initiate a PCIe function level reset
@@ -4534,19 +4535,18 @@ void __weak pcibios_reset_secondary_bus(struct pci_dev *dev)
}
/**
- * pci_reset_bridge_secondary_bus - Reset the secondary bus on a PCI bridge.
+ * pci_bridge_secondary_bus_reset - Reset the secondary bus on a PCI bridge.
* @dev: Bridge device
*
* Use the bridge control register to assert reset on the secondary bus.
* Devices on the secondary bus are left in power-on state.
*/
-int pci_reset_bridge_secondary_bus(struct pci_dev *dev)
+int pci_bridge_secondary_bus_reset(struct pci_dev *dev)
{
pcibios_reset_secondary_bus(dev);
return pci_dev_wait(dev, "bus reset", PCIE_RESET_READY_POLL_MS);
}
-EXPORT_SYMBOL_GPL(pci_reset_bridge_secondary_bus);
static int pci_parent_bus_reset(struct pci_dev *dev, int probe)
{
@@ -4563,9 +4563,7 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe)
if (probe)
return 0;
- pci_reset_bridge_secondary_bus(dev->bus->self);
-
- return 0;
+ return pci_bridge_secondary_bus_reset(dev->bus->self);
}
static int pci_reset_hotplug_slot(struct hotplug_slot *hotplug, int probe)
@@ -5097,7 +5095,7 @@ int pci_probe_reset_slot(struct pci_slot *slot)
EXPORT_SYMBOL_GPL(pci_probe_reset_slot);
/**
- * pci_reset_slot - reset a PCI slot
+ * __pci_reset_slot - Try to reset a PCI slot
* @slot: PCI slot to reset
*
* A PCI bus may host multiple slots, each slot may support a reset mechanism
@@ -5109,33 +5107,9 @@ EXPORT_SYMBOL_GPL(pci_probe_reset_slot);
* through this function. PCI config space of all devices in the slot and
* behind the slot is saved before and restored after reset.
*
- * Return 0 on success, non-zero on error.
- */
-int pci_reset_slot(struct pci_slot *slot)
-{
- int rc;
-
- rc = pci_slot_reset(slot, 1);
- if (rc)
- return rc;
-
- pci_slot_save_and_disable(slot);
-
- rc = pci_slot_reset(slot, 0);
-
- pci_slot_restore(slot);
-
- return rc;
-}
-EXPORT_SYMBOL_GPL(pci_reset_slot);
-
-/**
- * pci_try_reset_slot - Try to reset a PCI slot
- * @slot: PCI slot to reset
- *
* Same as above except return -EAGAIN if the slot cannot be locked
*/
-int pci_try_reset_slot(struct pci_slot *slot)
+static int __pci_reset_slot(struct pci_slot *slot)
{
int rc;
@@ -5156,10 +5130,11 @@ int pci_try_reset_slot(struct pci_slot *slot)
return rc;
}
-EXPORT_SYMBOL_GPL(pci_try_reset_slot);
static int pci_bus_reset(struct pci_bus *bus, int probe)
{
+ int ret;
+
if (!bus->self || !pci_bus_resetable(bus))
return -ENOTTY;
@@ -5170,11 +5145,11 @@ static int pci_bus_reset(struct pci_bus *bus, int probe)
might_sleep();
- pci_reset_bridge_secondary_bus(bus->self);
+ ret = pci_bridge_secondary_bus_reset(bus->self);
pci_bus_unlock(bus);
- return 0;
+ return ret;
}
/**
@@ -5190,15 +5165,12 @@ int pci_probe_reset_bus(struct pci_bus *bus)
EXPORT_SYMBOL_GPL(pci_probe_reset_bus);
/**
- * pci_reset_bus - reset a PCI bus
+ * __pci_reset_bus - Try to reset a PCI bus
* @bus: top level PCI bus to reset
*
- * Do a bus reset on the given bus and any subordinate buses, saving
- * and restoring state of all devices.
- *
- * Return 0 on success, non-zero on error.
+ * Same as above except return -EAGAIN if the bus cannot be locked
*/
-int pci_reset_bus(struct pci_bus *bus)
+static int __pci_reset_bus(struct pci_bus *bus)
{
int rc;
@@ -5208,42 +5180,30 @@ int pci_reset_bus(struct pci_bus *bus)
pci_bus_save_and_disable(bus);
- rc = pci_bus_reset(bus, 0);
+ if (pci_bus_trylock(bus)) {
+ might_sleep();
+ rc = pci_bridge_secondary_bus_reset(bus->self);
+ pci_bus_unlock(bus);
+ } else
+ rc = -EAGAIN;
pci_bus_restore(bus);
return rc;
}
-EXPORT_SYMBOL_GPL(pci_reset_bus);
/**
- * pci_try_reset_bus - Try to reset a PCI bus
- * @bus: top level PCI bus to reset
+ * pci_reset_bus - Try to reset a PCI bus
+ * @pdev: top level PCI device to reset via slot/bus
*
* Same as above except return -EAGAIN if the bus cannot be locked
*/
-int pci_try_reset_bus(struct pci_bus *bus)
+int pci_reset_bus(struct pci_dev *pdev)
{
- int rc;
-
- rc = pci_bus_reset(bus, 1);
- if (rc)
- return rc;
-
- pci_bus_save_and_disable(bus);
-
- if (pci_bus_trylock(bus)) {
- might_sleep();
- pci_reset_bridge_secondary_bus(bus->self);
- pci_bus_unlock(bus);
- } else
- rc = -EAGAIN;
-
- pci_bus_restore(bus);
-
- return rc;
+ return pci_probe_reset_slot(pdev->slot) ?
+ __pci_reset_slot(pdev->slot) : __pci_reset_bus(pdev->bus);
}
-EXPORT_SYMBOL_GPL(pci_try_reset_bus);
+EXPORT_SYMBOL_GPL(pci_reset_bus);
/**
* pcix_get_max_mmrbc - get PCI-X maximum designed memory read byte count