PCI: Add pci_reset_bus_function() Secondary Bus Reset interface
authorRaphael Norwitz <raphael.norwitz@nutanix.com>
Thu, 8 Apr 2021 18:23:40 +0000 (18:23 +0000)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 24 May 2021 22:30:02 +0000 (17:30 -0500)
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>
drivers/pci/pci.c

index b717680..4523510 100644 (file)
@@ -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);
 }
 
 /**