Skip to content

Commit ed382b9

Browse files
abattersbymartinkpetersen
authored andcommitted
scsi: qla2xxx: target: Fix term exchange when cmd_sent_to_fw == 1
Properly set the nport_handle field of the terminate exchange message. Previously when this field was not set properly, the term exchange would fail when cmd_sent_to_fw == 1 but work when cmd_sent_to_fw == 0 (i.e. it would fail when the HW was actively transferring data or status for the cmd but work when the HW was idle). With this change, term exchange works in any cmd state, which now makes it possible to abort a command that is locked up in the HW. Signed-off-by: Tony Battersby <tonyb@cybernetics.com> Link: https://patch.msgid.link/1a221699-969b-4f28-8ea4-395d2f7a7c0a@cybernetics.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent c34e373 commit ed382b9

1 file changed

Lines changed: 31 additions & 21 deletions

File tree

drivers/scsi/qla2xxx/qla_target.c

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3622,14 +3622,35 @@ static int __qlt_send_term_exchange(struct qla_qpair *qpair,
36223622
struct qla_tgt_cmd *cmd,
36233623
struct atio_from_isp *atio)
36243624
{
3625-
struct scsi_qla_host *vha = qpair->vha;
36263625
struct ctio7_to_24xx *ctio24;
3627-
request_t *pkt;
3628-
int ret = 0;
3626+
struct scsi_qla_host *vha;
3627+
uint16_t loop_id;
36293628
uint16_t temp;
36303629

3631-
if (cmd)
3630+
if (cmd) {
36323631
vha = cmd->vha;
3632+
loop_id = cmd->loop_id;
3633+
} else {
3634+
port_id_t id = be_to_port_id(atio->u.isp24.fcp_hdr.s_id);
3635+
struct qla_hw_data *ha;
3636+
struct fc_port *sess;
3637+
unsigned long flags;
3638+
3639+
vha = qpair->vha;
3640+
ha = vha->hw;
3641+
3642+
/*
3643+
* CTIO7_NHANDLE_UNRECOGNIZED works when aborting an idle
3644+
* command but not when aborting a command with an active CTIO
3645+
* exchange.
3646+
*/
3647+
loop_id = CTIO7_NHANDLE_UNRECOGNIZED;
3648+
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
3649+
sess = qla2x00_find_fcport_by_nportid(vha, &id, 1);
3650+
if (sess)
3651+
loop_id = sess->loop_id;
3652+
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
3653+
}
36333654

36343655
if (cmd) {
36353656
ql_dbg(ql_dbg_tgt_mgt, vha, 0xe009,
@@ -3642,31 +3663,20 @@ static int __qlt_send_term_exchange(struct qla_qpair *qpair,
36423663
vha->vp_idx, le32_to_cpu(atio->u.isp24.exchange_addr));
36433664
}
36443665

3645-
pkt = (request_t *)qla2x00_alloc_iocbs_ready(qpair, NULL);
3646-
if (pkt == NULL) {
3666+
ctio24 = qla2x00_alloc_iocbs_ready(qpair, NULL);
3667+
if (!ctio24) {
36473668
ql_dbg(ql_dbg_tgt, vha, 0xe050,
36483669
"qla_target(%d): %s failed: unable to allocate "
36493670
"request packet\n", vha->vp_idx, __func__);
36503671
return -ENOMEM;
36513672
}
36523673

3653-
if (cmd != NULL) {
3654-
if (cmd->state < QLA_TGT_STATE_PROCESSED) {
3655-
ql_dbg(ql_dbg_tgt, vha, 0xe051,
3656-
"qla_target(%d): Terminating cmd %p with "
3657-
"incorrect state %d\n", vha->vp_idx, cmd,
3658-
cmd->state);
3659-
} else
3660-
ret = 1;
3661-
}
3662-
36633674
qpair->tgt_counters.num_term_xchg_sent++;
3664-
pkt->entry_count = 1;
3665-
pkt->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK;
36663675

3667-
ctio24 = (struct ctio7_to_24xx *)pkt;
36683676
ctio24->entry_type = CTIO_TYPE7;
3669-
ctio24->nport_handle = cpu_to_le16(CTIO7_NHANDLE_UNRECOGNIZED);
3677+
ctio24->entry_count = 1;
3678+
ctio24->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK;
3679+
ctio24->nport_handle = cpu_to_le16(loop_id);
36703680
ctio24->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
36713681
ctio24->vp_index = vha->vp_idx;
36723682
ctio24->initiator_id = be_id_to_le(atio->u.isp24.fcp_hdr.s_id);
@@ -3683,7 +3693,7 @@ static int __qlt_send_term_exchange(struct qla_qpair *qpair,
36833693
qpair->reqq_start_iocbs(qpair);
36843694
else
36853695
qla2x00_start_iocbs(vha, qpair->req);
3686-
return ret;
3696+
return 0;
36873697
}
36883698

36893699
static void qlt_send_term_exchange(struct qla_qpair *qpair,

0 commit comments

Comments
 (0)