diff options
author | Quinn Tran <quinn.tran@cavium.com> | 2017-12-28 23:33:26 +0300 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-01-04 07:41:06 +0300 |
commit | a4239945b8ad112fb914d0605c8f6c5fd3330f61 (patch) | |
tree | b151d91a7e0a21d0d07689a7e341244acbbceee4 /drivers/scsi/qla2xxx/qla_target.c | |
parent | 1429f0446a5b119bd80c1235ea4490c89b6c2f50 (diff) | |
download | linux-a4239945b8ad112fb914d0605c8f6c5fd3330f61.tar.xz |
scsi: qla2xxx: Add switch command to simplify fabric discovery
- add "async" gpn_ft, gnn_ft, gfpn_id, gnn_id switch commands.
- For 8G and newer adapters, use async commands when it comes to
fabric scan to reduce bottle neck.
Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_target.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 62 |
1 files changed, 54 insertions, 8 deletions
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 3c25be73005d..d4ead404100c 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -969,7 +969,6 @@ static void qlt_free_session_done(struct work_struct *work) struct qla_hw_data *ha = vha->hw; unsigned long flags; bool logout_started = false; - struct event_arg ea; scsi_qla_host_t *base_vha; struct qlt_plogi_ack_t *own = sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN]; @@ -1121,11 +1120,18 @@ static void qlt_free_session_done(struct work_struct *work) if (test_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags)) return; - if (!tgt || !tgt->tgt_stop) { - memset(&ea, 0, sizeof(ea)); - ea.event = FCME_DELETE_DONE; - ea.fcport = sess; - qla2x00_fcport_event_handler(vha, &ea); + if ((!tgt || !tgt->tgt_stop) && !LOOP_TRANSITION(vha)) { + switch (vha->host->active_mode) { + case MODE_INITIATOR: + case MODE_DUAL: + set_bit(RELOGIN_NEEDED, &vha->dpc_flags); + qla2xxx_wake_dpc(vha); + break; + case MODE_TARGET: + default: + /* no-op */ + break; + } } } @@ -4318,6 +4324,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, struct fc_port *sess; struct qla_tgt_cmd *cmd; unsigned long flags; + port_id_t id; if (unlikely(tgt->tgt_stop)) { ql_dbg(ql_dbg_io, vha, 0x3061, @@ -4325,6 +4332,12 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, return -EFAULT; } + id.b.al_pa = atio->u.isp24.fcp_hdr.s_id[2]; + id.b.area = atio->u.isp24.fcp_hdr.s_id[1]; + id.b.domain = atio->u.isp24.fcp_hdr.s_id[0]; + if (IS_SW_RESV_ADDR(id)) + return -EBUSY; + sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, atio->u.isp24.fcp_hdr.s_id); if (unlikely(!sess)) { struct qla_tgt_sess_op *op = kzalloc(sizeof(struct qla_tgt_sess_op), @@ -4739,8 +4752,16 @@ static int qlt_handle_login(struct scsi_qla_host *vha, ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC post new sess\n", __func__, __LINE__, iocb->u.isp24.port_name); - qla24xx_post_newsess_work(vha, &port_id, - iocb->u.isp24.port_name, pla); + if (iocb->u.isp24.status_subcode == ELS_PLOGI) + qla24xx_post_newsess_work(vha, &port_id, + iocb->u.isp24.port_name, + iocb->u.isp24.u.plogi.node_name, + pla, FC4_TYPE_UNKNOWN); + else + qla24xx_post_newsess_work(vha, &port_id, + iocb->u.isp24.port_name, NULL, + pla, FC4_TYPE_UNKNOWN); + goto out; } @@ -4869,6 +4890,11 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha, break; } + if (IS_SW_RESV_ADDR(port_id)) { + res = 1; + break; + } + wd3_lo = le16_to_cpu(iocb->u.isp24.u.prli.wd3_lo); if (wwn) { @@ -4896,12 +4922,32 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha, } if (sess != NULL) { + bool delete = false; spin_lock_irqsave(&tgt->ha->tgt.sess_lock, flags); switch (sess->fw_login_state) { + case DSC_LS_PLOGI_PEND: case DSC_LS_PLOGI_COMP: case DSC_LS_PRLI_COMP: break; default: + delete = true; + break; + } + + switch (sess->disc_state) { + case DSC_LOGIN_PEND: + case DSC_GPDB: + case DSC_GPSC: + case DSC_UPD_FCPORT: + case DSC_LOGIN_COMPLETE: + case DSC_ADISC: + delete = false; + break; + default: + break; + } + + if (delete) { spin_unlock_irqrestore(&tgt->ha->tgt.sess_lock, flags); /* |