aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorQuinn Tran <quinn.tran@qlogic.com>2014-09-25 06:14:57 -0400
committerChristoph Hellwig <hch@lst.de>2014-09-25 08:25:08 -0400
commitd564a372b0047de8014614fa66f2d071815605ed (patch)
tree07dc148ea0a0e7762c2d97ad648134c58bf93a63 /drivers/scsi
parentda6b0ace34378e928a6cba6010d7856664c46746 (diff)
qla2xxx: Fix hang due to cmd_kref not decrementing
Signed-off-by: Quinn Tran <quinn.tran@qlogic.com> Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/qla2xxx/qla_target.c18
-rw-r--r--drivers/scsi/qla2xxx/qla_target.h1
2 files changed, 7 insertions, 12 deletions
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 94b726ed21e1..2ba44334fb84 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -2409,6 +2409,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
2409 2409
2410 2410
2411 cmd->state = QLA_TGT_STATE_PROCESSED; /* Mid-level is done processing */ 2411 cmd->state = QLA_TGT_STATE_PROCESSED; /* Mid-level is done processing */
2412 cmd->cmd_sent_to_fw = 1;
2412 2413
2413 qla2x00_start_iocbs(vha, vha->req); 2414 qla2x00_start_iocbs(vha, vha->req);
2414 spin_unlock_irqrestore(&ha->hardware_lock, flags); 2415 spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -2484,6 +2485,7 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
2484 qlt_load_data_segments(&prm, vha); 2485 qlt_load_data_segments(&prm, vha);
2485 2486
2486 cmd->state = QLA_TGT_STATE_NEED_DATA; 2487 cmd->state = QLA_TGT_STATE_NEED_DATA;
2488 cmd->cmd_sent_to_fw = 1;
2487 2489
2488 qla2x00_start_iocbs(vha, vha->req); 2490 qla2x00_start_iocbs(vha, vha->req);
2489 spin_unlock_irqrestore(&ha->hardware_lock, flags); 2491 spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -2717,19 +2719,10 @@ static void qlt_send_term_exchange(struct scsi_qla_host *vha,
2717 if (rc == -ENOMEM) 2719 if (rc == -ENOMEM)
2718 qlt_alloc_qfull_cmd(vha, atio, 0, 0); 2720 qlt_alloc_qfull_cmd(vha, atio, 0, 0);
2719 spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); 2721 spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
2722
2720done: 2723done:
2721 /* 2724 if (cmd && ((cmd->state != QLA_TGT_STATE_ABORTED) ||
2722 * Terminate exchange will tell fw to release any active CTIO 2725 !cmd->cmd_sent_to_fw)) {
2723 * that's in FW posession and cleanup the exchange.
2724 *
2725 * "cmd->state == QLA_TGT_STATE_ABORTED" means CTIO is still
2726 * down at FW. Free the cmd later when CTIO comes back later
2727 * w/aborted(0x2) status.
2728 *
2729 * "cmd->state != QLA_TGT_STATE_ABORTED" means CTIO is already
2730 * back w/some err. Free the cmd now.
2731 */
2732 if ((rc == 1) && (cmd->state != QLA_TGT_STATE_ABORTED)) {
2733 if (!ha_locked && !in_interrupt()) 2726 if (!ha_locked && !in_interrupt())
2734 msleep(250); /* just in case */ 2727 msleep(250); /* just in case */
2735 2728
@@ -3071,6 +3064,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
3071 3064
3072 se_cmd = &cmd->se_cmd; 3065 se_cmd = &cmd->se_cmd;
3073 tfo = se_cmd->se_tfo; 3066 tfo = se_cmd->se_tfo;
3067 cmd->cmd_sent_to_fw = 0;
3074 3068
3075 if (cmd->sg_mapped) 3069 if (cmd->sg_mapped)
3076 qlt_unmap_sg(vha, cmd); 3070 qlt_unmap_sg(vha, cmd);
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index 0c768f5e885a..b07b230b14cc 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -917,6 +917,7 @@ struct qla_tgt_cmd {
917 unsigned int ctx_dsd_alloced:1; 917 unsigned int ctx_dsd_alloced:1;
918 unsigned int q_full:1; 918 unsigned int q_full:1;
919 unsigned int term_exchg:1; 919 unsigned int term_exchg:1;
920 unsigned int cmd_sent_to_fw:1;
920 921
921 struct scatterlist *sg; /* cmd data buffer SG vector */ 922 struct scatterlist *sg; /* cmd data buffer SG vector */
922 int sg_cnt; /* SG segments count */ 923 int sg_cnt; /* SG segments count */