On Thu, Aug 05, 2021 at 09:59:10PM +0530, Amey Narkhede wrote: > Currently there is separate function pcie_has_flr() to probe if PCIe FLR > is supported by the device which does not match the calling convention > followed by reset methods which use second function argument to decide > whether to probe or not. Add new function pcie_reset_flr() that follows > the calling convention of reset methods. > > Signed-off-by: Amey Narkhede <ameynarkhede03@xxxxxxxxx> Reviewed-by: Raphael Norwitz <raphael.norwitz@xxxxxxxxxxx> > --- > drivers/crypto/cavium/nitrox/nitrox_main.c | 4 +-- > drivers/pci/pci.c | 40 +++++++++++++++------- > drivers/pci/pcie/aer.c | 12 +++---- > drivers/pci/quirks.c | 9 ++--- > include/linux/pci.h | 2 +- > 5 files changed, 38 insertions(+), 29 deletions(-) > > diff --git a/drivers/crypto/cavium/nitrox/nitrox_main.c b/drivers/crypto/cavium/nitrox/nitrox_main.c > index facc8e6bc580..15d6c8452807 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 1fafd05caa41..7d1d9671160b 100644 > --- a/drivers/pci/pci.c > +++ b/drivers/pci/pci.c > @@ -4619,22 +4619,20 @@ EXPORT_SYMBOL(pci_wait_for_pending_transaction); > * Returns true if the device advertises support for PCIe function level > * resets. > */ > -bool pcie_has_flr(struct pci_dev *dev) > +static 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) > { > @@ -4657,6 +4655,25 @@ 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 (!pcie_has_flr(dev)) > + 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; > @@ -5137,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; > @@ -5172,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 ec943cee5ecc..98077595a73e 100644 > --- a/drivers/pci/pcie/aer.c > +++ b/drivers/pci/pcie/aer.c > @@ -1405,13 +1405,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 d85914afe65a..b48e7ef8b641 100644 > --- a/drivers/pci/quirks.c > +++ b/drivers/pci/quirks.c > @@ -3819,7 +3819,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) > @@ -3888,13 +3888,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 697b1f085c7b..aa85e7d3147e 100644 > --- a/include/linux/pci.h > +++ b/include/linux/pci.h > @@ -1226,7 +1226,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); > -- > 2.32.0 > >