scsi: qla2xxx: Fix discovery issues in FC-AL topology
[sfrench/cifs-2.6.git] / drivers / scsi / qla2xxx / qla_init.c
index 83fae4c341ee6942888082d44177d38dc3d19343..e7fe0e52c11d4a4bbf4986427dc25ec590055ed1 100644 (file)
@@ -5516,6 +5516,22 @@ static int qla2x00_configure_n2n_loop(scsi_qla_host_t *vha)
        return QLA_FUNCTION_FAILED;
 }
 
+static void
+qla_reinitialize_link(scsi_qla_host_t *vha)
+{
+       int rval;
+
+       atomic_set(&vha->loop_state, LOOP_DOWN);
+       atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
+       rval = qla2x00_full_login_lip(vha);
+       if (rval == QLA_SUCCESS) {
+               ql_dbg(ql_dbg_disc, vha, 0xd050, "Link reinitialized\n");
+       } else {
+               ql_dbg(ql_dbg_disc, vha, 0xd051,
+                       "Link reinitialization failed (%d)\n", rval);
+       }
+}
+
 /*
  * qla2x00_configure_local_loop
  *     Updates Fibre Channel Device Database with local loop devices.
@@ -5567,6 +5583,19 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
                spin_unlock_irqrestore(&vha->work_lock, flags);
 
                if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
+                       u8 loop_map_entries = 0;
+                       int rc;
+
+                       rc = qla2x00_get_fcal_position_map(vha, NULL,
+                                               &loop_map_entries);
+                       if (rc == QLA_SUCCESS && loop_map_entries > 1) {
+                               /*
+                                * There are devices that are still not logged
+                                * in. Reinitialize to give them a chance.
+                                */
+                               qla_reinitialize_link(vha);
+                               return QLA_FUNCTION_FAILED;
+                       }
                        set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
                        set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
                }