scsi: qla2xxx: Fix out of order Termination and ABTS response
Following changes are added by this patch - Prevent ABTS Response from getting in front of Termination of exchange. Firmware requires driver to cleanup exchanges before ABTS response can be sent. This reduces ABTS response error which triggers extra command re-termination and re-sending of ABTS response. - Add bits in driver and tracks CTIO/ATIO attribute bits for proper command Termination. A copy of the ATTR bits will be kept in the ABTS task management command as a back up copy, if an ABTS response encounters an error. 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>
This commit is contained in:
committed by
Martin K. Petersen
parent
0691094ff3
commit
6b0431d6fa
@@ -1732,64 +1732,84 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
|
||||
sp = req->outstanding_cmds[cnt];
|
||||
if (sp) {
|
||||
req->outstanding_cmds[cnt] = NULL;
|
||||
if (sp->cmd_type == TYPE_SRB) {
|
||||
if (sp->type == SRB_NVME_CMD ||
|
||||
sp->type == SRB_NVME_LS) {
|
||||
sp_get(sp);
|
||||
spin_unlock_irqrestore(qp->qp_lock_ptr,
|
||||
flags);
|
||||
qla_nvme_abort(ha, sp, res);
|
||||
spin_lock_irqsave(qp->qp_lock_ptr,
|
||||
flags);
|
||||
} else if (GET_CMD_SP(sp) &&
|
||||
!ha->flags.eeh_busy &&
|
||||
(!test_bit(ABORT_ISP_ACTIVE,
|
||||
&vha->dpc_flags)) &&
|
||||
(sp->type == SRB_SCSI_CMD)) {
|
||||
switch (sp->cmd_type) {
|
||||
case TYPE_SRB:
|
||||
if (sp->cmd_type == TYPE_SRB) {
|
||||
if (sp->type == SRB_NVME_CMD ||
|
||||
sp->type == SRB_NVME_LS) {
|
||||
sp_get(sp);
|
||||
spin_unlock_irqrestore
|
||||
(qp->qp_lock_ptr,
|
||||
flags);
|
||||
qla_nvme_abort(ha, sp, res);
|
||||
spin_lock_irqsave
|
||||
(qp->qp_lock_ptr,
|
||||
flags);
|
||||
} else if (GET_CMD_SP(sp) &&
|
||||
!ha->flags.eeh_busy &&
|
||||
(!test_bit(ABORT_ISP_ACTIVE,
|
||||
&vha->dpc_flags)) &&
|
||||
(sp->type == SRB_SCSI_CMD)) {
|
||||
/*
|
||||
* Don't abort commands in
|
||||
* adapter during EEH
|
||||
* recovery as it's not
|
||||
* accessible/responding.
|
||||
*
|
||||
* Get a reference to the sp
|
||||
* and drop the lock. The
|
||||
* reference ensures this
|
||||
* sp->done() call and not the
|
||||
* call in qla2xxx_eh_abort()
|
||||
* ends the SCSI command (with
|
||||
* result 'res').
|
||||
*/
|
||||
sp_get(sp);
|
||||
spin_unlock_irqrestore
|
||||
(qp->qp_lock_ptr,
|
||||
flags);
|
||||
status = qla2xxx_eh_abort(
|
||||
GET_CMD_SP(sp));
|
||||
spin_lock_irqsave
|
||||
(qp->qp_lock_ptr,
|
||||
flags);
|
||||
/*
|
||||
* Get rid of extra reference
|
||||
* if immediate exit from
|
||||
* ql2xxx_eh_abort
|
||||
*/
|
||||
if (status == FAILED &&
|
||||
(qla2x00_isp_reg_stat(ha)))
|
||||
atomic_dec(
|
||||
&sp->ref_count);
|
||||
}
|
||||
sp->done(sp, res);
|
||||
break;
|
||||
case TYPE_TGT_CMD:
|
||||
if (!vha->hw->tgt.tgt_ops ||
|
||||
!tgt || qla_ini_mode_enabled(vha)) {
|
||||
if (!trace)
|
||||
ql_dbg(ql_dbg_tgt_mgt,
|
||||
vha, 0xf003,
|
||||
"HOST-ABORT-HNDLR: dpc_flags=%lx. Target mode disabled\n",
|
||||
vha->dpc_flags);
|
||||
continue;
|
||||
}
|
||||
cmd = (struct qla_tgt_cmd *)sp;
|
||||
qlt_abort_cmd_on_host_reset(cmd->vha,
|
||||
cmd);
|
||||
break;
|
||||
case TYPE_TGT_TMCMD:
|
||||
/*
|
||||
* Don't abort commands in
|
||||
* adapter during EEH
|
||||
* recovery as it's not
|
||||
* accessible/responding.
|
||||
*
|
||||
* Get a reference to the sp
|
||||
* and drop the lock. The
|
||||
* reference ensures this
|
||||
* sp->done() call and not the
|
||||
* call in qla2xxx_eh_abort()
|
||||
* ends the SCSI command (with
|
||||
* result 'res').
|
||||
* Currently, only ABTS response gets on
|
||||
* the outstanding_cmds[]
|
||||
*/
|
||||
sp_get(sp);
|
||||
spin_unlock_irqrestore(qp->qp_lock_ptr,
|
||||
flags);
|
||||
status = qla2xxx_eh_abort(
|
||||
GET_CMD_SP(sp));
|
||||
spin_lock_irqsave(qp->qp_lock_ptr,
|
||||
flags);
|
||||
/*
|
||||
* Get rid of extra reference
|
||||
* if immediate exit from
|
||||
* ql2xxx_eh_abort
|
||||
*/
|
||||
if (status == FAILED &&
|
||||
(qla2x00_isp_reg_stat(ha)))
|
||||
atomic_dec(
|
||||
&sp->ref_count);
|
||||
ha->tgt.tgt_ops->free_mcmd(
|
||||
(struct qla_tgt_mgmt_cmd *)sp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sp->done(sp, res);
|
||||
} else {
|
||||
if (!vha->hw->tgt.tgt_ops || !tgt ||
|
||||
qla_ini_mode_enabled(vha)) {
|
||||
if (!trace)
|
||||
ql_dbg(ql_dbg_tgt_mgt,
|
||||
vha, 0xf003,
|
||||
"HOST-ABORT-HNDLR: dpc_flags=%lx. Target mode disabled\n",
|
||||
vha->dpc_flags);
|
||||
continue;
|
||||
}
|
||||
cmd = (struct qla_tgt_cmd *)sp;
|
||||
qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user