diff options
author | Chad Dupuis <chad.dupuis@qlogic.com> | 2013-02-08 07:58:04 +0100 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-02-22 16:06:24 +0100 |
commit | f356bef134dda564fcbe3b41a5c7b932c1964326 (patch) | |
tree | 6a55a1e6c50cb12e93b90ef1cba54b6253cb4f0a /drivers/scsi/qla2xxx/qla_bsg.c | |
parent | [SCSI] qla2xxx: Integrate generic card temperature with mezz card temperature. (diff) | |
download | linux-f356bef134dda564fcbe3b41a5c7b932c1964326.tar.xz linux-f356bef134dda564fcbe3b41a5c7b932c1964326.zip |
[SCSI] qla2xxx: Wait for IDC complete event to finish loopback operation.
Wait for the IDC complete AEN before returning the loopback operation back to
the application to make sure the port is put back into normal operations.
Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
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 747f440b1a93..ad54099cb805 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 |