diff options
author | Niklas Schnelle <[email protected]> | 2021-02-11 14:20:03 +0100 |
---|---|---|
committer | Heiko Carstens <[email protected]> | 2021-04-12 12:46:41 +0200 |
commit | faf29a4d93a98b4ccd8a10297353a9d0779d231f (patch) | |
tree | 2156f4af74e0b07a5850fc5ae448dfaa517357fb /arch/s390/pci/pci_bus.c | |
parent | 6f8daa2953ecd1e8e853939f2007b4160591b8a6 (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.c | 35 |
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) |