Skip to content

Commit

Permalink
scsi: qla2xxx: Fix out of order Termination and ABTS response
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Quinn Tran authored and Martin K. Petersen committed Sep 12, 2018
1 parent 0691094 commit 6b0431d
Show file tree
Hide file tree
Showing 4 changed files with 277 additions and 160 deletions.
1 change: 1 addition & 0 deletions drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ struct srb_iocb {
enum {
TYPE_SRB,
TYPE_TGT_CMD,
TYPE_TGT_TMCMD, /* task management */
};

typedef struct srb {
Expand Down
130 changes: 75 additions & 55 deletions drivers/scsi/qla2xxx/qla_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
/*
* 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);
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:
/*
* Get rid of extra reference
* if immediate exit from
* ql2xxx_eh_abort
* Currently, only ABTS response gets on
* the outstanding_cmds[]
*/
if (status == FAILED &&
(qla2x00_isp_reg_stat(ha)))
atomic_dec(
&sp->ref_count);
}
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;
ha->tgt.tgt_ops->free_mcmd(
(struct qla_tgt_mgmt_cmd *)sp);
break;
default:
break;
}
cmd = (struct qla_tgt_cmd *)sp;
qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
}
}
}
Expand Down
Loading

0 comments on commit 6b0431d

Please sign in to comment.