Commit faf29a4d authored by Niklas Schnelle's avatar Niklas Schnelle Committed by Heiko Carstens
Browse files

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: default avatarMatthew Rosato <mjrosato@linux.ibm.com>
Acked-by: default avatarPierre Morel <pmorel@linux.ibm.com>
Signed-off-by: default avatarNiklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent 6f8daa29
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -757,7 +757,6 @@ int zpci_create_device(u32 fid, u32 fh, enum zpci_state state)
 */
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:
+25 −10
Original line number Diff line number Diff line
@@ -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)
+1 −0
Original line number Diff line number Diff line
@@ -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);