aboutsummaryrefslogtreecommitdiff
path: root/arch/s390/pci/pci_bus.c
diff options
context:
space:
mode:
authorNiklas Schnelle <[email protected]>2021-02-11 14:20:03 +0100
committerHeiko Carstens <[email protected]>2021-04-12 12:46:41 +0200
commitfaf29a4d93a98b4ccd8a10297353a9d0779d231f (patch)
tree2156f4af74e0b07a5850fc5ae448dfaa517357fb /arch/s390/pci/pci_bus.c
parent6f8daa2953ecd1e8e853939f2007b4160591b8a6 (diff)
s390/pci: introduce zpci_bus_scan_device()
To match zpci_bus_scan_device() and the PCI common code terminology and to remove some code duplication, we pull the multiple uses of pci_scan_single_device() into a function. For now this has the side effect of adding each device to the PCI bus separately and locking and unlocking the rescan/remove lock for each instead of just once per bus. This is clearly less efficient but provides a correct intermediate behavior until a follow on change does both the adding and scanning only once per bus. Reviewed-by: Matthew Rosato <[email protected]> Acked-by: Pierre Morel <[email protected]> Signed-off-by: Niklas Schnelle <[email protected]> Signed-off-by: Heiko Carstens <[email protected]>
Diffstat (limited to 'arch/s390/pci/pci_bus.c')
-rw-r--r--arch/s390/pci/pci_bus.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/arch/s390/pci/pci_bus.c b/arch/s390/pci/pci_bus.c
index ace9dbbe3bc1..7b37c4316e35 100644
--- a/arch/s390/pci/pci_bus.c
+++ b/arch/s390/pci/pci_bus.c
@@ -30,6 +30,29 @@ static LIST_HEAD(zbus_list);
static DEFINE_SPINLOCK(zbus_list_lock);
static int zpci_nb_devices;
+/* zpci_bus_scan_device - Scan a single device adding it to the PCI core
+ * @zdev: the zdev to be scanned
+ *
+ * Scans the PCI function making it available to the common PCI code.
+ *
+ * Return: 0 on success, an error value otherwise
+ */
+int zpci_bus_scan_device(struct zpci_dev *zdev)
+{
+ struct pci_dev *pdev;
+
+ pdev = pci_scan_single_device(zdev->zbus->bus, zdev->devfn);
+ if (!pdev)
+ return -ENODEV;
+
+ pci_bus_add_device(pdev);
+ pci_lock_rescan_remove();
+ pci_bus_add_devices(zdev->zbus->bus);
+ pci_unlock_rescan_remove();
+
+ return 0;
+}
+
/* zpci_bus_remove_device - Removes the given zdev from the PCI core
* @zdev: the zdev to be removed from the PCI core
* @set_error: if true the device's error state is set to permanent failure
@@ -176,10 +199,10 @@ void pcibios_bus_add_device(struct pci_dev *pdev)
static int zpci_bus_add_device(struct zpci_bus *zbus, struct zpci_dev *zdev)
{
- struct pci_bus *bus;
struct resource_entry *window, *n;
struct resource *res;
struct pci_dev *pdev;
+ struct pci_bus *bus;
int rc;
bus = zbus->bus;
@@ -203,11 +226,7 @@ static int zpci_bus_add_device(struct zpci_bus *zbus, struct zpci_dev *zdev)
pci_bus_add_resource(bus, res, 0);
}
- pdev = pci_scan_single_device(bus, zdev->devfn);
- if (pdev)
- pci_bus_add_device(pdev);
-
- return 0;
+ return zpci_bus_scan_device(zdev);
}
static void zpci_bus_add_devices(struct zpci_bus *zbus)
@@ -217,10 +236,6 @@ static void zpci_bus_add_devices(struct zpci_bus *zbus)
for (i = 1; i < ZPCI_FUNCTIONS_PER_BUS; i++)
if (zbus->function[i])
zpci_bus_add_device(zbus, zbus->function[i]);
-
- pci_lock_rescan_remove();
- pci_bus_add_devices(zbus->bus);
- pci_unlock_rescan_remove();
}
int zpci_bus_device_register(struct zpci_dev *zdev, struct pci_ops *ops)