val.i  = 0; val.role  = new_role;
 
        while (try++ < max_tries) {
-               rv = _drbd_request_state(device, mask, val, CS_WAIT_COMPLETE);
+               rv = _drbd_request_state_holding_state_mutex(device, mask, val, CS_WAIT_COMPLETE);
 
                /* in case we first succeeded to outdate,
                 * but now suddenly could establish a connection */
 
        return rv;
 }
 
+static void wake_up_all_devices(struct drbd_connection *connection)
+{
+       struct drbd_peer_device *peer_device;
+       int vnr;
+
+       rcu_read_lock();
+       idr_for_each_entry(&connection->peer_devices, peer_device, vnr)
+               wake_up(&peer_device->device->state_wait);
+       rcu_read_unlock();
+
+}
+
 
 /**
  * cl_wide_st_chg() - true if the state change is a cluster wide one
        return rv;
 }
 
+enum drbd_state_rv
+_drbd_request_state_holding_state_mutex(struct drbd_device *device, union drbd_state mask,
+                   union drbd_state val, enum chg_state_flags f)
+{
+       enum drbd_state_rv rv;
+
+       BUG_ON(f & CS_SERIALIZE);
+
+       wait_event_cmd(device->state_wait,
+                      (rv = drbd_req_state(device, mask, val, f)) != SS_IN_TRANSIENT_STATE,
+                      mutex_unlock(device->state_mutex),
+                      mutex_lock(device->state_mutex));
+
+       return rv;
+}
+
 static void print_st(struct drbd_device *device, const char *name, union drbd_state ns)
 {
        drbd_err(device, " %s = { cs:%s ro:%s/%s ds:%s/%s %c%c%c%c%c%c }\n",
        if (ns.conn == C_DISCONNECTING && os.conn == C_UNCONNECTED)
                rv = SS_IN_TRANSIENT_STATE;
 
-       /* if (ns.conn == os.conn && ns.conn == C_WF_REPORT_PARAMS)
-          rv = SS_IN_TRANSIENT_STATE; */
-
        /* While establishing a connection only allow cstate to change.
-          Delay/refuse role changes, detach attach etc... */
+          Delay/refuse role changes, detach attach etc... (they do not touch cstate) */
        if (test_bit(STATE_SENT, &connection->flags) &&
-           !(os.conn == C_WF_REPORT_PARAMS ||
-             (ns.conn == C_WF_REPORT_PARAMS && os.conn == C_WF_CONNECTION)))
+           !((ns.conn == C_WF_REPORT_PARAMS && os.conn == C_WF_CONNECTION) ||
+             (ns.conn >= C_CONNECTED && os.conn == C_WF_REPORT_PARAMS)))
                rv = SS_IN_TRANSIENT_STATE;
 
        if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) && os.conn < C_CONNECTED)
 
        /* Wake up role changes, that were delayed because of connection establishing */
        if (os.conn == C_WF_REPORT_PARAMS && ns.conn != C_WF_REPORT_PARAMS &&
-           no_peer_wf_report_params(connection))
+           no_peer_wf_report_params(connection)) {
                clear_bit(STATE_SENT, &connection->flags);
+               wake_up_all_devices(connection);
+       }
 
        wake_up(&device->misc_wait);
        wake_up(&device->state_wait);