summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/crypto/cavium/nitrox/nitrox_main.c4
-rw-r--r--drivers/pci/pci.c56
-rw-r--r--drivers/pci/pcie/aer.c12
-rw-r--r--drivers/pci/quirks.c9
-rw-r--r--include/linux/pci.h2
5 files changed, 40 insertions, 43 deletions
diff --git a/drivers/crypto/cavium/nitrox/nitrox_main.c b/drivers/crypto/cavium/nitrox/nitrox_main.c
index 96bc7b5c6532..2db3fd5815c8 100644
--- a/drivers/crypto/cavium/nitrox/nitrox_main.c
+++ b/drivers/crypto/cavium/nitrox/nitrox_main.c
@@ -306,9 +306,7 @@ static int nitrox_device_flr(struct pci_dev *pdev)
return -ENOMEM;
}
- /* check flr support */
- if (pcie_has_flr(pdev))
- pcie_flr(pdev);
+ pcie_reset_flr(pdev, 0);
pci_restore_state(pdev);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index b7a9f680c513..b0a63bdf8207 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4623,28 +4623,11 @@ int pci_wait_for_pending_transaction(struct pci_dev *dev)
EXPORT_SYMBOL(pci_wait_for_pending_transaction);
/**
- * pcie_has_flr - check if a device supports function level resets
- * @dev: device to check
- *
- * Returns true if the device advertises support for PCIe function level
- * resets.
- */
-bool pcie_has_flr(struct pci_dev *dev)
-{
- if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET)
- return false;
-
- return FIELD_GET(PCI_EXP_DEVCAP_FLR, dev->devcap) == 1;
-}
-EXPORT_SYMBOL_GPL(pcie_has_flr);
-
-/**
* pcie_flr - initiate a PCIe function level reset
* @dev: device to reset
*
- * Initiate a function level reset on @dev. The caller should ensure the
- * device supports FLR before calling this function, e.g. by using the
- * pcie_has_flr() helper.
+ * Initiate a function level reset unconditionally on @dev without
+ * checking any flags and DEVCAP
*/
int pcie_flr(struct pci_dev *dev)
{
@@ -4667,6 +4650,28 @@ int pcie_flr(struct pci_dev *dev)
}
EXPORT_SYMBOL_GPL(pcie_flr);
+/**
+ * pcie_reset_flr - initiate a PCIe function level reset
+ * @dev: device to reset
+ * @probe: If set, only check if the device can be reset this way.
+ *
+ * Initiate a function level reset on @dev.
+ */
+int pcie_reset_flr(struct pci_dev *dev, int probe)
+{
+ if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET)
+ return -ENOTTY;
+
+ if (!(dev->devcap & PCI_EXP_DEVCAP_FLR))
+ return -ENOTTY;
+
+ if (probe)
+ return 0;
+
+ return pcie_flr(dev);
+}
+EXPORT_SYMBOL_GPL(pcie_reset_flr);
+
static int pci_af_flr(struct pci_dev *dev, int probe)
{
int pos;
@@ -5149,11 +5154,9 @@ int __pci_reset_function_locked(struct pci_dev *dev)
rc = pci_dev_specific_reset(dev, 0);
if (rc != -ENOTTY)
return rc;
- if (pcie_has_flr(dev)) {
- rc = pcie_flr(dev);
- if (rc != -ENOTTY)
- return rc;
- }
+ rc = pcie_reset_flr(dev, 0);
+ if (rc != -ENOTTY)
+ return rc;
rc = pci_af_flr(dev, 0);
if (rc != -ENOTTY)
return rc;
@@ -5184,8 +5187,9 @@ int pci_probe_reset_function(struct pci_dev *dev)
rc = pci_dev_specific_reset(dev, 1);
if (rc != -ENOTTY)
return rc;
- if (pcie_has_flr(dev))
- return 0;
+ rc = pcie_reset_flr(dev, 1);
+ if (rc != -ENOTTY)
+ return rc;
rc = pci_af_flr(dev, 1);
if (rc != -ENOTTY)
return rc;
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index df4ba9b384c2..031379deb130 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -1407,13 +1407,11 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
}
if (type == PCI_EXP_TYPE_RC_EC || type == PCI_EXP_TYPE_RC_END) {
- if (pcie_has_flr(dev)) {
- rc = pcie_flr(dev);
- pci_info(dev, "has been reset (%d)\n", rc);
- } else {
- pci_info(dev, "not reset (no FLR support)\n");
- rc = -ENOTTY;
- }
+ rc = pcie_reset_flr(dev, 0);
+ if (!rc)
+ pci_info(dev, "has been reset\n");
+ else
+ pci_info(dev, "not reset (no FLR support: %d)\n", rc);
} else {
rc = pci_bus_error_reset(dev);
pci_info(dev, "%s Port link has been reset (%d)\n",
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 6d74386eadc2..a8a167bbc1d7 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3852,7 +3852,7 @@ static int nvme_disable_and_flr(struct pci_dev *dev, int probe)
u32 cfg;
if (dev->class != PCI_CLASS_STORAGE_EXPRESS ||
- !pcie_has_flr(dev) || !pci_resource_start(dev, 0))
+ pcie_reset_flr(dev, 1) || !pci_resource_start(dev, 0))
return -ENOTTY;
if (probe)
@@ -3921,13 +3921,10 @@ static int nvme_disable_and_flr(struct pci_dev *dev, int probe)
*/
static int delay_250ms_after_flr(struct pci_dev *dev, int probe)
{
- if (!pcie_has_flr(dev))
- return -ENOTTY;
-
if (probe)
- return 0;
+ return pcie_reset_flr(dev, 1);
- pcie_flr(dev);
+ pcie_reset_flr(dev, 0);
msleep(250);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1179c0ee2bfb..1de37e3fc29d 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1229,7 +1229,7 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev,
enum pci_bus_speed *speed,
enum pcie_link_width *width);
void pcie_print_link_status(struct pci_dev *dev);
-bool pcie_has_flr(struct pci_dev *dev);
+int pcie_reset_flr(struct pci_dev *dev, int probe);
int pcie_flr(struct pci_dev *dev);
int __pci_reset_function_locked(struct pci_dev *dev);
int pci_reset_function(struct pci_dev *dev);