diff options
author | Raphael Norwitz <raphael.norwitz@nutanix.com> | 2021-04-08 18:23:40 +0000 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2021-05-24 17:30:02 -0500 |
commit | 0dad3ce523c2917b1912fbde047207533e9f1eeb (patch) | |
tree | 8b8dbe7ecae51567629a33c6eeaa751762f66880 /drivers/pci/pci.c | |
parent | 6efb943b8616ec53a5e444193dccf1af9ad627b5 (diff) |
PCI: Add pci_reset_bus_function() Secondary Bus Reset interface
pci_parent_bus_reset() resets a device by performing a Secondary Bus Reset
on a PCI-to-PCI bridge leading to the device.
pci_dev_reset_slot_function() does the same, except that it uses a hotplug
driver to keep the reset from looking like a hot-remove followed by a
hot-add.
Add a pci_reset_bus_function() wrapper, which attempts the hotplug driver
slot reset and falls back to the parent bus reset if that fails. This
provides a single interface for performing a Secondary Bus Reset.
[bhelgaas: commit log, don't expose yet]
Suggested-by: Alex Williamson <alex.williamson@redhat.com>
Link: https://lore.kernel.org/r/20210323100625.0021a943@omen.home.shazbot.org/
Link: https://lore.kernel.org/r/20210408182328.12323-1-raphael.norwitz@nutanix.com
Signed-off-by: Amey Narkhede <ameynarkhede03@gmail.com>
Signed-off-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b717680377a9..452351025a09 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -5020,6 +5020,16 @@ static int pci_dev_reset_slot_function(struct pci_dev *dev, int probe) return pci_reset_hotplug_slot(dev->slot->hotplug, probe); } +static int pci_reset_bus_function(struct pci_dev *dev, int probe) +{ + int rc; + + rc = pci_dev_reset_slot_function(dev, probe); + if (rc != -ENOTTY) + return rc; + return pci_parent_bus_reset(dev, probe); +} + static void pci_dev_lock(struct pci_dev *dev) { pci_cfg_access_lock(dev); @@ -5140,10 +5150,7 @@ int __pci_reset_function_locked(struct pci_dev *dev) rc = pci_pm_reset(dev, 0); if (rc != -ENOTTY) return rc; - rc = pci_dev_reset_slot_function(dev, 0); - if (rc != -ENOTTY) - return rc; - return pci_parent_bus_reset(dev, 0); + return pci_reset_bus_function(dev, 0); } EXPORT_SYMBOL_GPL(__pci_reset_function_locked); @@ -5175,11 +5182,8 @@ int pci_probe_reset_function(struct pci_dev *dev) rc = pci_pm_reset(dev, 1); if (rc != -ENOTTY) return rc; - rc = pci_dev_reset_slot_function(dev, 1); - if (rc != -ENOTTY) - return rc; - return pci_parent_bus_reset(dev, 1); + return pci_reset_bus_function(dev, 1); } /** |