diff options
author | Niklas Schnelle <schnelle@linux.ibm.com> | 2021-02-11 16:20:03 +0300 |
---|---|---|
committer | Heiko Carstens <hca@linux.ibm.com> | 2021-04-12 13:46:41 +0300 |
commit | faf29a4d93a98b4ccd8a10297353a9d0779d231f (patch) | |
tree | 2156f4af74e0b07a5850fc5ae448dfaa517357fb /arch/s390 | |
parent | 6f8daa2953ecd1e8e853939f2007b4160591b8a6 (diff) | |
download | linux-faf29a4d93a98b4ccd8a10297353a9d0779d231f.tar.xz |
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 <mjrosato@linux.ibm.com>
Acked-by: Pierre Morel <pmorel@linux.ibm.com>
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/pci/pci.c | 9 | ||||
-rw-r--r-- | arch/s390/pci/pci_bus.c | 35 | ||||
-rw-r--r-- | arch/s390/pci/pci_bus.h | 1 |
3 files changed, 28 insertions, 17 deletions
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index dd14641b2d20..0bce6078bfd6 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -757,7 +757,6 @@ error: */ int zpci_configure_device(struct zpci_dev *zdev, u32 fh) { - struct pci_dev *pdev; int rc; zdev->fh = fh; @@ -777,14 +776,10 @@ int zpci_configure_device(struct zpci_dev *zdev, u32 fh) if (!zdev->zbus->bus) return 0; - pdev = pci_scan_single_device(zdev->zbus->bus, zdev->devfn); - if (!pdev) + rc = zpci_bus_scan_device(zdev); + if (rc) goto error_disable; - pci_bus_add_device(pdev); - pci_lock_rescan_remove(); - pci_bus_add_devices(zdev->zbus->bus); - pci_unlock_rescan_remove(); return 0; error_disable: 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) diff --git a/arch/s390/pci/pci_bus.h b/arch/s390/pci/pci_bus.h index e04ca06a71b6..2649238f6cde 100644 --- a/arch/s390/pci/pci_bus.h +++ b/arch/s390/pci/pci_bus.h @@ -10,6 +10,7 @@ int zpci_bus_device_register(struct zpci_dev *zdev, struct pci_ops *ops); void zpci_bus_device_unregister(struct zpci_dev *zdev); +int zpci_bus_scan_device(struct zpci_dev *zdev); void zpci_bus_remove_device(struct zpci_dev *zdev, bool set_error); void zpci_release_device(struct kref *kref); |