Commit 56f107d7 authored by Amey Narkhede's avatar Amey Narkhede Committed by Bjorn Helgaas
Browse files

PCI: Add pcie_reset_flr() with 'probe' argument

Most reset methods are of the form "pci_*_reset(dev, probe)".  pcie_flr()
was an exception because it relied on a separate pcie_has_flr() function
instead of taking a "probe" argument.

Add "pcie_reset_flr(dev, probe)" to follow the convention.  Remove
pcie_has_flr().

Some pcie_flr() callers that did not use pcie_has_flr() remain.

[bhelgaas: commit log, rework pcie_reset_flr() to use dev->devcap directly]
Link: https://lore.kernel.org/r/20210817180500.1253-3-ameynarkhede03@gmail.com


Signed-off-by: default avatarAmey Narkhede <ameynarkhede03@gmail.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarRaphael Norwitz <raphael.norwitz@nutanix.com>
parent 69139244
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -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);

+30 −26
Original line number Diff line number Diff line
@@ -4622,29 +4622,12 @@ 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);
	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;
+5 −7
Original line number Diff line number Diff line
@@ -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",
+3 −6
Original line number Diff line number Diff line
@@ -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);

+1 −1
Original line number Diff line number Diff line
@@ -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);