|
@@ -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
|