[SCSI] qla2xxx: Wait for IDC complete event to finish loopback operation.
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / scsi / qla2xxx / qla_bsg.c
index 747f440..ad54099 100644 (file)
@@ -535,7 +535,7 @@ done:
 /* Disable loopback mode */
 static inline int
 qla81xx_reset_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
-                           int wait)
+                           int wait, int wait2)
 {
        int ret = 0;
        int rval = 0;
@@ -556,28 +556,45 @@ qla81xx_reset_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
                memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3) ;
 
                ha->notify_dcbx_comp = wait;
+               ha->notify_lb_portup_comp = wait2;
+
                ret = qla81xx_set_port_config(vha, new_config);
                if (ret != QLA_SUCCESS) {
                        ql_log(ql_log_warn, vha, 0x7025,
                            "Set port config failed.\n");
                        ha->notify_dcbx_comp = 0;
+                       ha->notify_lb_portup_comp = 0;
                        rval = -EINVAL;
                        goto done_reset_internal;
                }
 
                /* Wait for DCBX complete event */
                if (wait && !wait_for_completion_timeout(&ha->dcbx_comp,
-                       (20 * HZ))) {
+                       (DCBX_COMP_TIMEOUT * HZ))) {
                        ql_dbg(ql_dbg_user, vha, 0x7026,
-                           "State change notification not received.\n");
+                           "DCBX completion not received.\n");
                        ha->notify_dcbx_comp = 0;
+                       ha->notify_lb_portup_comp = 0;
                        rval = -EINVAL;
                        goto done_reset_internal;
                } else
                        ql_dbg(ql_dbg_user, vha, 0x7027,
-                           "State change received.\n");
+                           "DCBX completion received.\n");
+
+               if (wait2 &&
+                   !wait_for_completion_timeout(&ha->lb_portup_comp,
+                   (LB_PORTUP_COMP_TIMEOUT * HZ))) {
+                       ql_dbg(ql_dbg_user, vha, 0x70c5,
+                           "Port up completion not received.\n");
+                       ha->notify_lb_portup_comp = 0;
+                       rval = -EINVAL;
+                       goto done_reset_internal;
+               } else
+                       ql_dbg(ql_dbg_user, vha, 0x70c6,
+                           "Port up completion received.\n");
 
                ha->notify_dcbx_comp = 0;
+               ha->notify_lb_portup_comp = 0;
        }
 done_reset_internal:
        return rval;
@@ -618,10 +635,11 @@ qla81xx_set_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
        }
 
        /* Wait for DCBX complete event */
-       if (!wait_for_completion_timeout(&ha->dcbx_comp, (20 * HZ))) {
+       if (!wait_for_completion_timeout(&ha->dcbx_comp,
+           (DCBX_COMP_TIMEOUT * HZ))) {
                ql_dbg(ql_dbg_user, vha, 0x7022,
-                   "State change notification not received.\n");
-               ret = qla81xx_reset_loopback_mode(vha, new_config, 0);
+                   "DCBX completion not received.\n");
+               ret = qla81xx_reset_loopback_mode(vha, new_config, 0, 0);
                /*
                 * If the reset of the loopback mode doesn't work take a FCoE
                 * dump and reset the chip.
@@ -639,7 +657,7 @@ qla81xx_set_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
                        ha->flags.idc_compl_status = 0;
                } else
                        ql_dbg(ql_dbg_user, vha, 0x7023,
-                           "State change received.\n");
+                           "DCBX completion received.\n");
        }
 
        ha->notify_dcbx_comp = 0;
@@ -749,6 +767,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
                if (IS_QLA81XX(ha) || IS_QLA8031(ha)) {
                        memset(config, 0, sizeof(config));
                        memset(new_config, 0, sizeof(new_config));
+
                        if (qla81xx_get_port_config(vha, config)) {
                                ql_log(ql_log_warn, vha, 0x701f,
                                    "Get port config failed.\n");
@@ -773,7 +792,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
                                            config, new_config, elreq.options);
                                else
                                        rval = qla81xx_reset_loopback_mode(vha,
-                                           config, 1);
+                                           config, 1, 0);
                        else
                                rval = qla81xx_set_loopback_mode(vha, config,
                                    new_config, elreq.options);
@@ -817,7 +836,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
                                 * Also clear internal loopback
                                 */
                                ret = qla81xx_reset_loopback_mode(vha,
-                                   new_config, 0);
+                                   new_config, 0, 1);
                                if (ret) {
                                        /*
                                         * If the reset of the loopback mode