diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_bsg.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_bsg.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 747f440b1a9..ad54099cb80 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -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 |