diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2010-05-04 15:01:26 -0700 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-05-16 18:21:47 -0400 |
commit | 5ff1d58410ffb160b388d622ef0c6a0411a05559 (patch) | |
tree | a8d95de2c47bf3b0beaae6730b61b3d84c2bde56 /drivers/scsi/qla2xxx/qla_init.c | |
parent | 99b0bec7bbf3350d1a920a7138fa62c456a8ecf1 (diff) |
[SCSI] qla2xxx: Limit mailbox command contention for ADISC requests.
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 88 |
1 files changed, 82 insertions, 6 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index c3c2c3627a70..4e7a3d5493e6 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -119,6 +119,7 @@ qla2x00_async_logio_timeout(srb_t *sp) "scsi(%ld:%x): Async-%s timeout.\n", fcport->vha->host_no, sp->handle, lio->ctx.name)); + fcport->flags &= ~FCF_ASYNC_SENT; if (lio->ctx.type == SRB_LOGIN_CMD) qla2x00_post_async_logout_work(fcport->vha, fcport, NULL); } @@ -220,6 +221,56 @@ done: return rval; } +static void +qla2x00_async_adisc_ctx_done(srb_t *sp) +{ + struct srb_logio *lio = sp->ctx; + + qla2x00_post_async_adisc_done_work(sp->fcport->vha, sp->fcport, + lio->data); + lio->ctx.free(sp); +} + +int +qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport, + uint16_t *data) +{ + struct qla_hw_data *ha = vha->hw; + srb_t *sp; + struct srb_logio *lio; + int rval; + + rval = QLA_FUNCTION_FAILED; + sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_logio), + ELS_TMO_2_RATOV(ha) + 2); + if (!sp) + goto done; + + lio = sp->ctx; + lio->ctx.type = SRB_ADISC_CMD; + lio->ctx.name = "adisc"; + lio->ctx.timeout = qla2x00_async_logio_timeout; + lio->ctx.done = qla2x00_async_adisc_ctx_done; + if (data[1] & QLA_LOGIO_LOGIN_RETRIED) + lio->flags |= SRB_LOGIN_RETRIED; + rval = qla2x00_start_sp(sp); + if (rval != QLA_SUCCESS) + goto done_free_sp; + + DEBUG2(printk(KERN_DEBUG + "scsi(%ld:%x): Async-adisc - loop-id=%x portid=%02x%02x%02x.\n", + fcport->vha->host_no, sp->handle, fcport->loop_id, + fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa)); + + return rval; + +done_free_sp: + del_timer_sync(&lio->ctx.timer); + lio->ctx.free(sp); +done: + return rval; +} + int qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, uint16_t *data) @@ -229,15 +280,14 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, switch (data[0]) { case MBS_COMMAND_COMPLETE: if (fcport->flags & FCF_FCP2_DEVICE) { - rval = qla2x00_get_port_database(vha, fcport, BIT_1); - if (rval != QLA_SUCCESS) { - qla2x00_mark_device_lost(vha, fcport, 1, 0); - break; - } + fcport->flags |= FCF_ASYNC_SENT; + qla2x00_post_async_adisc_work(vha, fcport, data); + break; } qla2x00_update_fcport(vha, fcport); break; case MBS_COMMAND_ERROR: + fcport->flags &= ~FCF_ASYNC_SENT; if (data[1] & QLA_LOGIO_LOGIN_RETRIED) set_bit(RELOGIN_NEEDED, &vha->dpc_flags); else @@ -251,6 +301,7 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, fcport->loop_id++; rval = qla2x00_find_new_loop_id(vha, fcport); if (rval != QLA_SUCCESS) { + fcport->flags &= ~FCF_ASYNC_SENT; qla2x00_mark_device_lost(vha, fcport, 1, 0); break; } @@ -268,6 +319,26 @@ qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport, return QLA_SUCCESS; } +int +qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport, + uint16_t *data) +{ + if (data[0] == MBS_COMMAND_COMPLETE) { + qla2x00_update_fcport(vha, fcport); + + return QLA_SUCCESS; + } + + /* Retry login. */ + fcport->flags &= ~FCF_ASYNC_SENT; + if (data[1] & QLA_LOGIO_LOGIN_RETRIED) + set_bit(RELOGIN_NEEDED, &vha->dpc_flags); + else + qla2x00_mark_device_lost(vha, fcport, 1, 0); + + return QLA_SUCCESS; +} + /****************************************************************************/ /* QLogic ISP2x00 Hardware Support Functions. */ /****************************************************************************/ @@ -2062,6 +2133,7 @@ qla2x00_nvram_config(scsi_qla_host_t *vha) if (IS_QLA23XX(ha)) { nv->firmware_options[0] |= BIT_2; nv->firmware_options[0] &= ~BIT_3; + nv->firmware_options[0] &= ~BIT_6; nv->add_firmware_options[1] |= BIT_5 | BIT_4; if (IS_QLA2300(ha)) { @@ -2680,7 +2752,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) PORT_RETRY_TIME; atomic_set(&fcport->port_down_timer, ha->port_down_retry_count * PORT_RETRY_TIME); - fcport->flags &= ~FCF_LOGIN_NEEDED; + fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); qla2x00_iidma_fcport(vha, fcport); @@ -3326,11 +3398,15 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *vha, fc_port_t *fcport, retry = 0; if (IS_ALOGIO_CAPABLE(ha)) { + if (fcport->flags & FCF_ASYNC_SENT) + return rval; + fcport->flags |= FCF_ASYNC_SENT; rval = qla2x00_post_async_login_work(vha, fcport, NULL); if (!rval) return rval; } + fcport->flags &= ~FCF_ASYNC_SENT; rval = qla2x00_fabric_login(vha, fcport, next_loopid); if (rval == QLA_SUCCESS) { /* Send an ADISC to FCP2 devices.*/ |