aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorArmen Baloyan <armen.baloyan@qlogic.com>2014-02-26 04:15:17 -0500
committerJames Bottomley <JBottomley@Parallels.com>2014-03-15 13:18:52 -0400
commitfaef62d134631c1f390006d51d49c76033f9504f (patch)
tree6da279f1d08a7be4a7a1c0995b5d1a1f653a1e22 /drivers/scsi/qla2xxx
parent43a9c38bf3867f4626107e17255db8c6a4bb16fc (diff)
[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 <armen.baloyan@qlogic.com> Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c1
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c79
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c46
-rw-r--r--drivers/scsi/qla2xxx/qla_mr.c66
4 files changed, 69 insertions, 123 deletions
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index c68b60051dfb..97255f7c3975 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -34,6 +34,7 @@
34 * | | | 0x5047,0x5052 | 34 * | | | 0x5047,0x5052 |
35 * | | | 0x5084,0x5075 | 35 * | | | 0x5084,0x5075 |
36 * | | | 0x503d,0x5044 | 36 * | | | 0x503d,0x5044 |
37 * | | | 0x507b |
37 * | Timer Routines | 0x6012 | | 38 * | Timer Routines | 0x6012 | |
38 * | User Space Interactions | 0x70e2 | 0x7018,0x702e | 39 * | User Space Interactions | 0x70e2 | 0x7018,0x702e |
39 * | | | 0x7020,0x7024 | 40 * | | | 0x7020,0x7024 |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index f75d19f497fe..27248425f86c 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -271,56 +271,46 @@ done:
271} 271}
272 272
273static void 273static void
274qla2x00_async_tm_cmd_done(void *data, void *ptr, int res) 274qla2x00_tmf_iocb_timeout(void *data)
275{ 275{
276 srb_t *sp = (srb_t *)ptr; 276 srb_t *sp = (srb_t *)data;
277 struct srb_iocb *iocb = &sp->u.iocb_cmd; 277 struct srb_iocb *tmf = &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;
286 278
287 /* Issue Marker IOCB */ 279 tmf->u.tmf.comp_status = CS_TIMEOUT;
288 rval = qla2x00_marker(vha, vha->hw->req_q_map[0], 280 complete(&tmf->u.tmf.comp);
289 vha->hw->rsp_q_map[0], sp->fcport->loop_id, lun, 281}
290 flags == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID);
291 282
292 if ((rval != QLA_SUCCESS) || iocb->u.tmf.data) { 283static void
293 ql_dbg(ql_dbg_taskm, vha, 0x8030, 284qla2x00_tmf_sp_done(void *data, void *ptr, int res)
294 "TM IOCB failed (%x).\n", rval); 285{
295 } 286 srb_t *sp = (srb_t *)ptr;
296 } 287 struct srb_iocb *tmf = &sp->u.iocb_cmd;
297 sp->free(sp->fcport->vha, sp); 288 complete(&tmf->u.tmf.comp);
298} 289}
299 290
300int 291int
301qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t tm_flags, uint32_t lun, 292qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
302 uint32_t tag) 293 uint32_t tag)
303{ 294{
304 struct scsi_qla_host *vha = fcport->vha; 295 struct scsi_qla_host *vha = fcport->vha;
296 struct srb_iocb *tm_iocb;
305 srb_t *sp; 297 srb_t *sp;
306 struct srb_iocb *tcf; 298 int rval = QLA_FUNCTION_FAILED;
307 int rval;
308 299
309 rval = QLA_FUNCTION_FAILED;
310 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); 300 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
311 if (!sp) 301 if (!sp)
312 goto done; 302 goto done;
313 303
304 tm_iocb = &sp->u.iocb_cmd;
314 sp->type = SRB_TM_CMD; 305 sp->type = SRB_TM_CMD;
315 sp->name = "tmf"; 306 sp->name = "tmf";
316 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 307 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha));
317 308 tm_iocb->u.tmf.flags = flags;
318 tcf = &sp->u.iocb_cmd; 309 tm_iocb->u.tmf.lun = lun;
319 tcf->u.tmf.flags = tm_flags; 310 tm_iocb->u.tmf.data = tag;
320 tcf->u.tmf.lun = lun; 311 sp->done = qla2x00_tmf_sp_done;
321 tcf->u.tmf.data = tag; 312 tm_iocb->timeout = qla2x00_tmf_iocb_timeout;
322 tcf->timeout = qla2x00_async_iocb_timeout; 313 init_completion(&tm_iocb->u.tmf.comp);
323 sp->done = qla2x00_async_tm_cmd_done;
324 314
325 rval = qla2x00_start_sp(sp); 315 rval = qla2x00_start_sp(sp);
326 if (rval != QLA_SUCCESS) 316 if (rval != QLA_SUCCESS)
@@ -330,10 +320,29 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t tm_flags, uint32_t lun,
330 "Async-tmf hdl=%x loop-id=%x portid=%02x%02x%02x.\n", 320 "Async-tmf hdl=%x loop-id=%x portid=%02x%02x%02x.\n",
331 sp->handle, fcport->loop_id, fcport->d_id.b.domain, 321 sp->handle, fcport->loop_id, fcport->d_id.b.domain,
332 fcport->d_id.b.area, fcport->d_id.b.al_pa); 322 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 }
334 343
335done_free_sp: 344done_free_sp:
336 sp->free(fcport->vha, sp); 345 sp->free(vha, sp);
337done: 346done:
338 return rval; 347 return rval;
339} 348}
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index c2aaf6a93cc1..293dbd565840 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1498,8 +1498,7 @@ logio_done:
1498} 1498}
1499 1499
1500static void 1500static void
1501qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, 1501qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
1502 struct tsk_mgmt_entry *tsk)
1503{ 1502{
1504 const char func[] = "TMF-IOCB"; 1503 const char func[] = "TMF-IOCB";
1505 const char *type; 1504 const char *type;
@@ -1507,7 +1506,6 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
1507 srb_t *sp; 1506 srb_t *sp;
1508 struct srb_iocb *iocb; 1507 struct srb_iocb *iocb;
1509 struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk; 1508 struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk;
1510 int error = 1;
1511 1509
1512 sp = qla2x00_get_sp_from_handle(vha, func, req, tsk); 1510 sp = qla2x00_get_sp_from_handle(vha, func, req, tsk);
1513 if (!sp) 1511 if (!sp)
@@ -1516,37 +1514,35 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
1516 iocb = &sp->u.iocb_cmd; 1514 iocb = &sp->u.iocb_cmd;
1517 type = sp->name; 1515 type = sp->name;
1518 fcport = sp->fcport; 1516 fcport = sp->fcport;
1517 iocb->u.tmf.data = QLA_SUCCESS;
1519 1518
1520 if (sts->entry_status) { 1519 if (sts->entry_status) {
1521 ql_log(ql_log_warn, fcport->vha, 0x5038, 1520 ql_log(ql_log_warn, fcport->vha, 0x5038,
1522 "Async-%s error - hdl=%x entry-status(%x).\n", 1521 "Async-%s error - hdl=%x entry-status(%x).\n",
1523 type, sp->handle, sts->entry_status); 1522 type, sp->handle, sts->entry_status);
1523 iocb->u.tmf.data = QLA_FUNCTION_FAILED;
1524 } else if (sts->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) { 1524 } else if (sts->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
1525 ql_log(ql_log_warn, fcport->vha, 0x5039, 1525 ql_log(ql_log_warn, fcport->vha, 0x5039,
1526 "Async-%s error - hdl=%x completion status(%x).\n", 1526 "Async-%s error - hdl=%x completion status(%x).\n",
1527 type, sp->handle, sts->comp_status); 1527 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) &
1529 SS_RESPONSE_INFO_LEN_VALID)) { 1530 SS_RESPONSE_INFO_LEN_VALID)) {
1530 ql_log(ql_log_warn, fcport->vha, 0x503a, 1531 if (le32_to_cpu(sts->rsp_data_len) < 4) {
1531 "Async-%s error - hdl=%x no response info(%x).\n", 1532 ql_log(ql_log_warn, fcport->vha, 0x503b,
1532 type, sp->handle, sts->scsi_status); 1533 "Async-%s error - hdl=%x not enough response(%d).\n",
1533 } else if (le32_to_cpu(sts->rsp_data_len) < 4) { 1534 type, sp->handle, sts->rsp_data_len);
1534 ql_log(ql_log_warn, fcport->vha, 0x503b, 1535 } else if (sts->data[3]) {
1535 "Async-%s error - hdl=%x not enough response(%d).\n", 1536 ql_log(ql_log_warn, fcport->vha, 0x503c,
1536 type, sp->handle, sts->rsp_data_len); 1537 "Async-%s error - hdl=%x response(%x).\n",
1537 } else if (sts->data[3]) { 1538 type, sp->handle, sts->data[3]);
1538 ql_log(ql_log_warn, fcport->vha, 0x503c, 1539 iocb->u.tmf.data = QLA_FUNCTION_FAILED;
1539 "Async-%s error - hdl=%x response(%x).\n", 1540 }
1540 type, sp->handle, sts->data[3]);
1541 } else {
1542 error = 0;
1543 } 1541 }
1544 1542
1545 if (error) { 1543 if (iocb->u.tmf.data != QLA_SUCCESS)
1546 iocb->u.tmf.data = error;
1547 ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5055, 1544 ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5055,
1548 (uint8_t *)sts, sizeof(*sts)); 1545 (uint8_t *)sts, sizeof(*sts));
1549 }
1550 1546
1551 sp->done(vha, sp, 0); 1547 sp->done(vha, sp, 0);
1552} 1548}
@@ -2026,6 +2022,12 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
2026 return; 2022 return;
2027 } 2023 }
2028 2024
2025 /* Task Management completion. */
2026 if (sp->type == SRB_TM_CMD) {
2027 qla24xx_tm_iocb_entry(vha, req, pkt);
2028 return;
2029 }
2030
2029 /* Fast path completion. */ 2031 /* Fast path completion. */
2030 if (comp_status == CS_COMPLETE && scsi_status == 0) { 2032 if (comp_status == CS_COMPLETE && scsi_status == 0) {
2031 qla2x00_process_completed_request(vha, req, handle); 2033 qla2x00_process_completed_request(vha, req, handle);
@@ -2475,10 +2477,6 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
2475 qla24xx_logio_entry(vha, rsp->req, 2477 qla24xx_logio_entry(vha, rsp->req,
2476 (struct logio_entry_24xx *)pkt); 2478 (struct logio_entry_24xx *)pkt);
2477 break; 2479 break;
2478 case TSK_MGMT_IOCB_TYPE:
2479 qla24xx_tm_iocb_entry(vha, rsp->req,
2480 (struct tsk_mgmt_entry *)pkt);
2481 break;
2482 case CT_IOCB_TYPE: 2480 case CT_IOCB_TYPE:
2483 qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE); 2481 qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE);
2484 break; 2482 break;
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index 046a1699cb79..165db12580af 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -685,78 +685,16 @@ qlafx00_disable_intrs(struct qla_hw_data *ha)
685 spin_unlock_irqrestore(&ha->hardware_lock, flags); 685 spin_unlock_irqrestore(&ha->hardware_lock, flags);
686} 686}
687 687
688static void
689qlafx00_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
698static void
699qlafx00_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
707static int
708qlafx00_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
744done_free_sp:
745 sp->free(vha, sp);
746done:
747 return rval;
748}
749
750int 688int
751qlafx00_abort_target(fc_port_t *fcport, unsigned int l, int tag) 689qlafx00_abort_target(fc_port_t *fcport, unsigned int l, int tag)
752{ 690{
753 return qlafx00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag); 691 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
754} 692}
755 693
756int 694int
757qlafx00_lun_reset(fc_port_t *fcport, unsigned int l, int tag) 695qlafx00_lun_reset(fc_port_t *fcport, unsigned int l, int tag)
758{ 696{
759 return qlafx00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag); 697 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
760} 698}
761 699
762int 700int