[S390] dasd: let device initialization wait for LCU setup

The first DASD that is set online for a specific logical control unit
has to do certain setup steps on the storage server to make full use
of it, for example it will enable PAV.
The features and characteristics reported by the storage server will
depend on this setup, so all other devices on the same LCU will need
to wait for the setup to be finished.

Signed-off-by: Stefan Weinhuber <wein@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index e38a09b..5819dc0 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1059,7 +1059,7 @@
 /*
  * Valide storage server of current device.
  */
-static int dasd_eckd_validate_server(struct dasd_device *device)
+static void dasd_eckd_validate_server(struct dasd_device *device)
 {
 	int rc;
 	struct dasd_eckd_private *private;
@@ -1076,8 +1076,6 @@
 	private = (struct dasd_eckd_private *) device->private;
 	DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x "
 			"returned rc=%d", private->uid.ssid, rc);
-	/* RE-Read Configuration Data */
-	return dasd_eckd_read_conf(device);
 }
 
 /*
@@ -1149,12 +1147,21 @@
 		rc = is_known;
 		goto out_err2;
 	}
+	/*
+	 * dasd_eckd_vaildate_server is done on the first device that
+	 * is found for an LCU. All later other devices have to wait
+	 * for it, so they will read the correct feature codes.
+	 */
 	if (!is_known) {
-		/* new lcu found */
-		rc = dasd_eckd_validate_server(device); /* will switch pav on */
-		if (rc)
-			goto out_err3;
-	}
+		dasd_eckd_validate_server(device);
+		dasd_alias_lcu_setup_complete(device);
+	} else
+		dasd_alias_wait_for_lcu_setup(device);
+
+	/* device may report different configuration data after LCU setup */
+	rc = dasd_eckd_read_conf(device);
+	if (rc)
+		goto out_err3;
 
 	/* Read Feature Codes */
 	dasd_eckd_read_features(device);
@@ -3282,11 +3289,15 @@
 	if (is_known < 0)
 		return is_known;
 	if (!is_known) {
-		/* new lcu found */
-		rc = dasd_eckd_validate_server(device); /* will switch pav on */
-		if (rc)
-			goto out_err;
-	}
+		dasd_eckd_validate_server(device);
+		dasd_alias_lcu_setup_complete(device);
+	} else
+		dasd_alias_wait_for_lcu_setup(device);
+
+	/* RE-Read Configuration Data */
+	rc = dasd_eckd_read_conf(device);
+	if (rc)
+		goto out_err;
 
 	/* Read Feature Codes */
 	dasd_eckd_read_features(device);