Skip to content

Commit faef62d

Browse files
Armen BaloyanJames Bottomley
authored andcommitted
[SCSI] qla2xxx: Fix Task Management command asynchronous handling
- Fix interpreting the wrong IOCB type for task management functions in the response path. - Merge the task management function handling for various adapters. Signed-off-by: Armen Baloyan <[email protected]> Signed-off-by: Saurav Kashyap <[email protected]> Signed-off-by: James Bottomley <[email protected]>
1 parent 43a9c38 commit faef62d

File tree

4 files changed

+69
-123
lines changed

4 files changed

+69
-123
lines changed

drivers/scsi/qla2xxx/qla_dbg.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
* | | | 0x5047,0x5052 |
3535
* | | | 0x5084,0x5075 |
3636
* | | | 0x503d,0x5044 |
37+
* | | | 0x507b |
3738
* | Timer Routines | 0x6012 | |
3839
* | User Space Interactions | 0x70e2 | 0x7018,0x702e |
3940
* | | | 0x7020,0x7024 |

drivers/scsi/qla2xxx/qla_init.c

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -271,56 +271,46 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport,
271271
}
272272

273273
static void
274-
qla2x00_async_tm_cmd_done(void *data, void *ptr, int res)
274+
qla2x00_tmf_iocb_timeout(void *data)
275275
{
276-
srb_t *sp = (srb_t *)ptr;
277-
struct srb_iocb *iocb = &sp->u.iocb_cmd;
278-
struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
279-
uint32_t flags;
280-
uint16_t lun;
281-
int rval;
282-
283-
if (!test_bit(UNLOADING, &vha->dpc_flags)) {
284-
flags = iocb->u.tmf.flags;
285-
lun = (uint16_t)iocb->u.tmf.lun;
276+
srb_t *sp = (srb_t *)data;
277+
struct srb_iocb *tmf = &sp->u.iocb_cmd;
286278

287-
/* Issue Marker IOCB */
288-
rval = qla2x00_marker(vha, vha->hw->req_q_map[0],
289-
vha->hw->rsp_q_map[0], sp->fcport->loop_id, lun,
290-
flags == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID);
279+
tmf->u.tmf.comp_status = CS_TIMEOUT;
280+
complete(&tmf->u.tmf.comp);
281+
}
291282

292-
if ((rval != QLA_SUCCESS) || iocb->u.tmf.data) {
293-
ql_dbg(ql_dbg_taskm, vha, 0x8030,
294-
"TM IOCB failed (%x).\n", rval);
295-
}
296-
}
297-
sp->free(sp->fcport->vha, sp);
283+
static void
284+
qla2x00_tmf_sp_done(void *data, void *ptr, int res)
285+
{
286+
srb_t *sp = (srb_t *)ptr;
287+
struct srb_iocb *tmf = &sp->u.iocb_cmd;
288+
complete(&tmf->u.tmf.comp);
298289
}
299290

300291
int
301-
qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t tm_flags, uint32_t lun,
292+
qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
302293
uint32_t tag)
303294
{
304295
struct scsi_qla_host *vha = fcport->vha;
296+
struct srb_iocb *tm_iocb;
305297
srb_t *sp;
306-
struct srb_iocb *tcf;
307-
int rval;
298+
int rval = QLA_FUNCTION_FAILED;
308299

309-
rval = QLA_FUNCTION_FAILED;
310300
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
311301
if (!sp)
312302
goto done;
313303

304+
tm_iocb = &sp->u.iocb_cmd;
314305
sp->type = SRB_TM_CMD;
315306
sp->name = "tmf";
316-
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
317-
318-
tcf = &sp->u.iocb_cmd;
319-
tcf->u.tmf.flags = tm_flags;
320-
tcf->u.tmf.lun = lun;
321-
tcf->u.tmf.data = tag;
322-
tcf->timeout = qla2x00_async_iocb_timeout;
323-
sp->done = qla2x00_async_tm_cmd_done;
307+
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha));
308+
tm_iocb->u.tmf.flags = flags;
309+
tm_iocb->u.tmf.lun = lun;
310+
tm_iocb->u.tmf.data = tag;
311+
sp->done = qla2x00_tmf_sp_done;
312+
tm_iocb->timeout = qla2x00_tmf_iocb_timeout;
313+
init_completion(&tm_iocb->u.tmf.comp);
324314

325315
rval = qla2x00_start_sp(sp);
326316
if (rval != QLA_SUCCESS)
@@ -330,10 +320,29 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t tm_flags, uint32_t lun,
330320
"Async-tmf hdl=%x loop-id=%x portid=%02x%02x%02x.\n",
331321
sp->handle, fcport->loop_id, fcport->d_id.b.domain,
332322
fcport->d_id.b.area, fcport->d_id.b.al_pa);
333-
return rval;
323+
324+
wait_for_completion(&tm_iocb->u.tmf.comp);
325+
326+
rval = tm_iocb->u.tmf.comp_status == CS_COMPLETE ?
327+
QLA_SUCCESS : QLA_FUNCTION_FAILED;
328+
329+
if ((rval != QLA_SUCCESS) || tm_iocb->u.tmf.data) {
330+
ql_dbg(ql_dbg_taskm, vha, 0x8030,
331+
"TM IOCB failed (%x).\n", rval);
332+
}
333+
334+
if (!test_bit(UNLOADING, &vha->dpc_flags) && !IS_QLAFX00(vha->hw)) {
335+
flags = tm_iocb->u.tmf.flags;
336+
lun = (uint16_t)tm_iocb->u.tmf.lun;
337+
338+
/* Issue Marker IOCB */
339+
qla2x00_marker(vha, vha->hw->req_q_map[0],
340+
vha->hw->rsp_q_map[0], sp->fcport->loop_id, lun,
341+
flags == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID);
342+
}
334343

335344
done_free_sp:
336-
sp->free(fcport->vha, sp);
345+
sp->free(vha, sp);
337346
done:
338347
return rval;
339348
}

drivers/scsi/qla2xxx/qla_isr.c

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,16 +1498,14 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
14981498
}
14991499

15001500
static void
1501-
qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
1502-
struct tsk_mgmt_entry *tsk)
1501+
qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
15031502
{
15041503
const char func[] = "TMF-IOCB";
15051504
const char *type;
15061505
fc_port_t *fcport;
15071506
srb_t *sp;
15081507
struct srb_iocb *iocb;
15091508
struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk;
1510-
int error = 1;
15111509

15121510
sp = qla2x00_get_sp_from_handle(vha, func, req, tsk);
15131511
if (!sp)
@@ -1516,37 +1514,35 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
15161514
iocb = &sp->u.iocb_cmd;
15171515
type = sp->name;
15181516
fcport = sp->fcport;
1517+
iocb->u.tmf.data = QLA_SUCCESS;
15191518

15201519
if (sts->entry_status) {
15211520
ql_log(ql_log_warn, fcport->vha, 0x5038,
15221521
"Async-%s error - hdl=%x entry-status(%x).\n",
15231522
type, sp->handle, sts->entry_status);
1523+
iocb->u.tmf.data = QLA_FUNCTION_FAILED;
15241524
} else if (sts->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
15251525
ql_log(ql_log_warn, fcport->vha, 0x5039,
15261526
"Async-%s error - hdl=%x completion status(%x).\n",
15271527
type, sp->handle, sts->comp_status);
1528-
} else if (!(le16_to_cpu(sts->scsi_status) &
1528+
iocb->u.tmf.data = QLA_FUNCTION_FAILED;
1529+
} else if ((le16_to_cpu(sts->scsi_status) &
15291530
SS_RESPONSE_INFO_LEN_VALID)) {
1530-
ql_log(ql_log_warn, fcport->vha, 0x503a,
1531-
"Async-%s error - hdl=%x no response info(%x).\n",
1532-
type, sp->handle, sts->scsi_status);
1533-
} else if (le32_to_cpu(sts->rsp_data_len) < 4) {
1534-
ql_log(ql_log_warn, fcport->vha, 0x503b,
1535-
"Async-%s error - hdl=%x not enough response(%d).\n",
1536-
type, sp->handle, sts->rsp_data_len);
1537-
} else if (sts->data[3]) {
1538-
ql_log(ql_log_warn, fcport->vha, 0x503c,
1539-
"Async-%s error - hdl=%x response(%x).\n",
1540-
type, sp->handle, sts->data[3]);
1541-
} else {
1542-
error = 0;
1531+
if (le32_to_cpu(sts->rsp_data_len) < 4) {
1532+
ql_log(ql_log_warn, fcport->vha, 0x503b,
1533+
"Async-%s error - hdl=%x not enough response(%d).\n",
1534+
type, sp->handle, sts->rsp_data_len);
1535+
} else if (sts->data[3]) {
1536+
ql_log(ql_log_warn, fcport->vha, 0x503c,
1537+
"Async-%s error - hdl=%x response(%x).\n",
1538+
type, sp->handle, sts->data[3]);
1539+
iocb->u.tmf.data = QLA_FUNCTION_FAILED;
1540+
}
15431541
}
15441542

1545-
if (error) {
1546-
iocb->u.tmf.data = error;
1543+
if (iocb->u.tmf.data != QLA_SUCCESS)
15471544
ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5055,
15481545
(uint8_t *)sts, sizeof(*sts));
1549-
}
15501546

15511547
sp->done(vha, sp, 0);
15521548
}
@@ -2026,6 +2022,12 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
20262022
return;
20272023
}
20282024

2025+
/* Task Management completion. */
2026+
if (sp->type == SRB_TM_CMD) {
2027+
qla24xx_tm_iocb_entry(vha, req, pkt);
2028+
return;
2029+
}
2030+
20292031
/* Fast path completion. */
20302032
if (comp_status == CS_COMPLETE && scsi_status == 0) {
20312033
qla2x00_process_completed_request(vha, req, handle);
@@ -2475,10 +2477,6 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
24752477
qla24xx_logio_entry(vha, rsp->req,
24762478
(struct logio_entry_24xx *)pkt);
24772479
break;
2478-
case TSK_MGMT_IOCB_TYPE:
2479-
qla24xx_tm_iocb_entry(vha, rsp->req,
2480-
(struct tsk_mgmt_entry *)pkt);
2481-
break;
24822480
case CT_IOCB_TYPE:
24832481
qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE);
24842482
break;

drivers/scsi/qla2xxx/qla_mr.c

Lines changed: 2 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -685,78 +685,16 @@ qlafx00_disable_intrs(struct qla_hw_data *ha)
685685
spin_unlock_irqrestore(&ha->hardware_lock, flags);
686686
}
687687

688-
static void
689-
qlafx00_tmf_iocb_timeout(void *data)
690-
{
691-
srb_t *sp = (srb_t *)data;
692-
struct srb_iocb *tmf = &sp->u.iocb_cmd;
693-
694-
tmf->u.tmf.comp_status = cpu_to_le16((uint16_t)CS_TIMEOUT);
695-
complete(&tmf->u.tmf.comp);
696-
}
697-
698-
static void
699-
qlafx00_tmf_sp_done(void *data, void *ptr, int res)
700-
{
701-
srb_t *sp = (srb_t *)ptr;
702-
struct srb_iocb *tmf = &sp->u.iocb_cmd;
703-
704-
complete(&tmf->u.tmf.comp);
705-
}
706-
707-
static int
708-
qlafx00_async_tm_cmd(fc_port_t *fcport, uint32_t flags,
709-
uint32_t lun, uint32_t tag)
710-
{
711-
scsi_qla_host_t *vha = fcport->vha;
712-
struct srb_iocb *tm_iocb;
713-
srb_t *sp;
714-
int rval = QLA_FUNCTION_FAILED;
715-
716-
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
717-
if (!sp)
718-
goto done;
719-
720-
tm_iocb = &sp->u.iocb_cmd;
721-
sp->type = SRB_TM_CMD;
722-
sp->name = "tmf";
723-
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha));
724-
tm_iocb->u.tmf.flags = flags;
725-
tm_iocb->u.tmf.lun = lun;
726-
tm_iocb->u.tmf.data = tag;
727-
sp->done = qlafx00_tmf_sp_done;
728-
tm_iocb->timeout = qlafx00_tmf_iocb_timeout;
729-
init_completion(&tm_iocb->u.tmf.comp);
730-
731-
rval = qla2x00_start_sp(sp);
732-
if (rval != QLA_SUCCESS)
733-
goto done_free_sp;
734-
735-
ql_dbg(ql_dbg_async, vha, 0x507b,
736-
"Task management command issued target_id=%x\n",
737-
fcport->tgt_id);
738-
739-
wait_for_completion(&tm_iocb->u.tmf.comp);
740-
741-
rval = tm_iocb->u.tmf.comp_status == CS_COMPLETE ?
742-
QLA_SUCCESS : QLA_FUNCTION_FAILED;
743-
744-
done_free_sp:
745-
sp->free(vha, sp);
746-
done:
747-
return rval;
748-
}
749-
750688
int
751689
qlafx00_abort_target(fc_port_t *fcport, unsigned int l, int tag)
752690
{
753-
return qlafx00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
691+
return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
754692
}
755693

756694
int
757695
qlafx00_lun_reset(fc_port_t *fcport, unsigned int l, int tag)
758696
{
759-
return qlafx00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
697+
return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
760698
}
761699

762700
int

0 commit comments

Comments
 (0)