From faf29a4d93a98b4ccd8a10297353a9d0779d231f Mon Sep 17 00:00:00 2001 From: Niklas Schnelle Date: Thu, 11 Feb 2021 14:20:03 +0100 Subject: [PATCH] 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 Acked-by: Pierre Morel Signed-off-by: Niklas Schnelle Signed-off-by: Heiko Carstens --- arch/s390/pci/pci.c | 9 ++------- arch/s390/pci/pci_bus.c | 35 +++++++++++++++++++++++++---------- 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);