s390/pci: cleanup hotplug code

Provide wrappers for the [de]configure operations, add some error
handling, and use pci_scan_slot instead of pci_scan_single_device.

Reviewed-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c
index 46a7b73..b12acaa 100644
--- a/drivers/pci/hotplug/s390_pci_hpc.c
+++ b/drivers/pci/hotplug/s390_pci_hpc.c
@@ -41,6 +41,28 @@
 	struct zpci_dev *zdev;
 };
 
+static inline int slot_configure(struct slot *slot)
+{
+	int ret = sclp_pci_configure(slot->zdev->fid);
+
+	zpci_dbg(3, "conf fid:%x, rc:%d\n", slot->zdev->fid, ret);
+	if (!ret)
+		slot->zdev->state = ZPCI_FN_STATE_CONFIGURED;
+
+	return ret;
+}
+
+static inline int slot_deconfigure(struct slot *slot)
+{
+	int ret = sclp_pci_deconfigure(slot->zdev->fid);
+
+	zpci_dbg(3, "deconf fid:%x, rc:%d\n", slot->zdev->fid, ret);
+	if (!ret)
+		slot->zdev->state = ZPCI_FN_STATE_STANDBY;
+
+	return ret;
+}
+
 static int enable_slot(struct hotplug_slot *hotplug_slot)
 {
 	struct slot *slot = hotplug_slot->private;
@@ -49,14 +71,23 @@
 	if (slot->zdev->state != ZPCI_FN_STATE_STANDBY)
 		return -EIO;
 
-	rc = sclp_pci_configure(slot->zdev->fid);
-	zpci_dbg(3, "conf fid:%x, rc:%d\n", slot->zdev->fid, rc);
-	if (!rc) {
-		slot->zdev->state = ZPCI_FN_STATE_CONFIGURED;
-		/* automatically scan the device after is was configured */
-		zpci_enable_device(slot->zdev);
-		zpci_scan_device(slot->zdev);
-	}
+	rc = slot_configure(slot);
+	if (rc)
+		return rc;
+
+	rc = zpci_enable_device(slot->zdev);
+	if (rc)
+		goto out_deconfigure;
+
+	slot->zdev->state = ZPCI_FN_STATE_ONLINE;
+
+	pci_scan_slot(slot->zdev->bus, ZPCI_DEVFN);
+	pci_bus_add_devices(slot->zdev->bus);
+
+	return rc;
+
+out_deconfigure:
+	slot_deconfigure(slot);
 	return rc;
 }
 
@@ -74,11 +105,7 @@
 	/* TODO: we rely on the user to unbind/remove the device, is that plausible
 	 *	 or do we need to trigger that here?
 	 */
-	rc = sclp_pci_deconfigure(slot->zdev->fid);
-	zpci_dbg(3, "deconf fid:%x, rc:%d\n", slot->zdev->fid, rc);
-	if (!rc)
-		slot->zdev->state = ZPCI_FN_STATE_STANDBY;
-	return rc;
+	return slot_deconfigure(slot);
 }
 
 static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)