INIT_WORK(&lcu->suc_data.worker, summary_unit_check_handling_work);
        INIT_DELAYED_WORK(&lcu->ruac_data.dwork, lcu_update_work);
        spin_lock_init(&lcu->lock);
+       init_completion(&lcu->lcu_setup);
        return lcu;
 
 out_err4:
        return is_lcu_known;
 }
 
+/*
+ * The first device to be registered on an LCU will have to do
+ * some additional setup steps to configure that LCU on the
+ * storage server. All further devices should wait with their
+ * initialization until the first device is done.
+ * To synchronize this work, the first device will call
+ * dasd_alias_lcu_setup_complete when it is done, and all
+ * other devices will wait for it with dasd_alias_wait_for_lcu_setup.
+ */
+void dasd_alias_lcu_setup_complete(struct dasd_device *device)
+{
+       struct dasd_eckd_private *private;
+       unsigned long flags;
+       struct alias_server *server;
+       struct alias_lcu *lcu;
+       struct dasd_uid *uid;
+
+       private = (struct dasd_eckd_private *) device->private;
+       uid = &private->uid;
+       lcu = NULL;
+       spin_lock_irqsave(&aliastree.lock, flags);
+       server = _find_server(uid);
+       if (server)
+               lcu = _find_lcu(server, uid);
+       spin_unlock_irqrestore(&aliastree.lock, flags);
+       if (!lcu) {
+               DBF_EVENT_DEVID(DBF_ERR, device->cdev,
+                               "could not find lcu for %04x %02x",
+                               uid->ssid, uid->real_unit_addr);
+               WARN_ON(1);
+               return;
+       }
+       complete_all(&lcu->lcu_setup);
+}
+
+void dasd_alias_wait_for_lcu_setup(struct dasd_device *device)
+{
+       struct dasd_eckd_private *private;
+       unsigned long flags;
+       struct alias_server *server;
+       struct alias_lcu *lcu;
+       struct dasd_uid *uid;
+
+       private = (struct dasd_eckd_private *) device->private;
+       uid = &private->uid;
+       lcu = NULL;
+       spin_lock_irqsave(&aliastree.lock, flags);
+       server = _find_server(uid);
+       if (server)
+               lcu = _find_lcu(server, uid);
+       spin_unlock_irqrestore(&aliastree.lock, flags);
+       if (!lcu) {
+               DBF_EVENT_DEVID(DBF_ERR, device->cdev,
+                               "could not find lcu for %04x %02x",
+                               uid->ssid, uid->real_unit_addr);
+               WARN_ON(1);
+               return;
+       }
+       wait_for_completion(&lcu->lcu_setup);
+}
+
 /*
  * This function removes a device from the scope of alias management.
  * The complicated part is to make sure that it is not in use by
 
 /*
  * 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;
        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);
 }
 
 /*
                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);
        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);
 
        struct summary_unit_check_work_data suc_data;
        struct read_uac_work_data ruac_data;
        struct dasd_ccw_req *rsu_cqr;
+       struct completion lcu_setup;
 };
 
 struct alias_pav_group {
 struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *);
 void dasd_alias_handle_summary_unit_check(struct dasd_device *, struct irb *);
 void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *);
-
+void dasd_alias_lcu_setup_complete(struct dasd_device *);
+void dasd_alias_wait_for_lcu_setup(struct dasd_device *);
 #endif                         /* DASD_ECKD_H */