aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/qla2xxx/qla_target.c55
-rw-r--r--drivers/scsi/qla2xxx/qla_target.h59
-rw-r--r--drivers/scsi/qla2xxx/tcm_qla2xxx.c73
3 files changed, 142 insertions, 45 deletions
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 2c71305d2563..74eb776d2faa 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -105,7 +105,7 @@ static void qlt_response_pkt(struct scsi_qla_host *ha, response_t *pkt);
105static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun, 105static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun,
106 int fn, void *iocb, int flags); 106 int fn, void *iocb, int flags);
107static void qlt_send_term_exchange(struct scsi_qla_host *ha, struct qla_tgt_cmd 107static void qlt_send_term_exchange(struct scsi_qla_host *ha, struct qla_tgt_cmd
108 *cmd, struct atio_from_isp *atio, int ha_locked); 108 *cmd, struct atio_from_isp *atio, int ha_locked, int ul_abort);
109static void qlt_reject_free_srr_imm(struct scsi_qla_host *ha, 109static void qlt_reject_free_srr_imm(struct scsi_qla_host *ha,
110 struct qla_tgt_srr_imm *imm, int ha_lock); 110 struct qla_tgt_srr_imm *imm, int ha_lock);
111static void qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha, 111static void qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha,
@@ -2665,7 +2665,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
2665 /* no need to terminate. FW already freed exchange. */ 2665 /* no need to terminate. FW already freed exchange. */
2666 qlt_abort_cmd_on_host_reset(cmd->vha, cmd); 2666 qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
2667 else 2667 else
2668 qlt_send_term_exchange(vha, cmd, &cmd->atio, 1); 2668 qlt_send_term_exchange(vha, cmd, &cmd->atio, 1, 0);
2669 spin_unlock_irqrestore(&ha->hardware_lock, flags); 2669 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2670 return 0; 2670 return 0;
2671 } 2671 }
@@ -3173,7 +3173,8 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
3173} 3173}
3174 3174
3175static void qlt_send_term_exchange(struct scsi_qla_host *vha, 3175static void qlt_send_term_exchange(struct scsi_qla_host *vha,
3176 struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked) 3176 struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked,
3177 int ul_abort)
3177{ 3178{
3178 unsigned long flags = 0; 3179 unsigned long flags = 0;
3179 int rc; 3180 int rc;
@@ -3193,8 +3194,7 @@ static void qlt_send_term_exchange(struct scsi_qla_host *vha,
3193 qlt_alloc_qfull_cmd(vha, atio, 0, 0); 3194 qlt_alloc_qfull_cmd(vha, atio, 0, 0);
3194 3195
3195done: 3196done:
3196 if (cmd && (!cmd->aborted || 3197 if (cmd && !ul_abort && !cmd->aborted) {
3197 !cmd->cmd_sent_to_fw)) {
3198 if (cmd->sg_mapped) 3198 if (cmd->sg_mapped)
3199 qlt_unmap_sg(vha, cmd); 3199 qlt_unmap_sg(vha, cmd);
3200 vha->hw->tgt.tgt_ops->free_cmd(cmd); 3200 vha->hw->tgt.tgt_ops->free_cmd(cmd);
@@ -3253,21 +3253,38 @@ static void qlt_chk_exch_leak_thresh_hold(struct scsi_qla_host *vha)
3253 3253
3254} 3254}
3255 3255
3256void qlt_abort_cmd(struct qla_tgt_cmd *cmd) 3256int qlt_abort_cmd(struct qla_tgt_cmd *cmd)
3257{ 3257{
3258 struct qla_tgt *tgt = cmd->tgt; 3258 struct qla_tgt *tgt = cmd->tgt;
3259 struct scsi_qla_host *vha = tgt->vha; 3259 struct scsi_qla_host *vha = tgt->vha;
3260 struct se_cmd *se_cmd = &cmd->se_cmd; 3260 struct se_cmd *se_cmd = &cmd->se_cmd;
3261 unsigned long flags;
3261 3262
3262 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf014, 3263 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf014,
3263 "qla_target(%d): terminating exchange for aborted cmd=%p " 3264 "qla_target(%d): terminating exchange for aborted cmd=%p "
3264 "(se_cmd=%p, tag=%llu)", vha->vp_idx, cmd, &cmd->se_cmd, 3265 "(se_cmd=%p, tag=%llu)", vha->vp_idx, cmd, &cmd->se_cmd,
3265 se_cmd->tag); 3266 se_cmd->tag);
3266 3267
3268 spin_lock_irqsave(&cmd->cmd_lock, flags);
3269 if (cmd->aborted) {
3270 spin_unlock_irqrestore(&cmd->cmd_lock, flags);
3271 /*
3272 * It's normal to see 2 calls in this path:
3273 * 1) XFER Rdy completion + CMD_T_ABORT
3274 * 2) TCM TMR - drain_state_list
3275 */
3276 ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
3277 "multiple abort. %p transport_state %x, t_state %x,"
3278 " se_cmd_flags %x \n", cmd, cmd->se_cmd.transport_state,
3279 cmd->se_cmd.t_state,cmd->se_cmd.se_cmd_flags);
3280 return EIO;
3281 }
3267 cmd->aborted = 1; 3282 cmd->aborted = 1;
3268 cmd->cmd_flags |= BIT_6; 3283 cmd->cmd_flags |= BIT_6;
3284 spin_unlock_irqrestore(&cmd->cmd_lock, flags);
3269 3285
3270 qlt_send_term_exchange(vha, cmd, &cmd->atio, 0); 3286 qlt_send_term_exchange(vha, cmd, &cmd->atio, 0, 1);
3287 return 0;
3271} 3288}
3272EXPORT_SYMBOL(qlt_abort_cmd); 3289EXPORT_SYMBOL(qlt_abort_cmd);
3273 3290
@@ -3282,6 +3299,9 @@ void qlt_free_cmd(struct qla_tgt_cmd *cmd)
3282 3299
3283 BUG_ON(cmd->cmd_in_wq); 3300 BUG_ON(cmd->cmd_in_wq);
3284 3301
3302 if (cmd->sg_mapped)
3303 qlt_unmap_sg(cmd->vha, cmd);
3304
3285 if (!cmd->q_full) 3305 if (!cmd->q_full)
3286 qlt_decr_num_pend_cmds(cmd->vha); 3306 qlt_decr_num_pend_cmds(cmd->vha);
3287 3307
@@ -3399,7 +3419,7 @@ static int qlt_term_ctio_exchange(struct scsi_qla_host *vha, void *ctio,
3399 term = 1; 3419 term = 1;
3400 3420
3401 if (term) 3421 if (term)
3402 qlt_send_term_exchange(vha, cmd, &cmd->atio, 1); 3422 qlt_send_term_exchange(vha, cmd, &cmd->atio, 1, 0);
3403 3423
3404 return term; 3424 return term;
3405} 3425}
@@ -3755,6 +3775,7 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
3755 goto out_term; 3775 goto out_term;
3756 } 3776 }
3757 3777
3778 spin_lock_init(&cmd->cmd_lock);
3758 cdb = &atio->u.isp24.fcp_cmnd.cdb[0]; 3779 cdb = &atio->u.isp24.fcp_cmnd.cdb[0];
3759 cmd->se_cmd.tag = atio->u.isp24.exchange_addr; 3780 cmd->se_cmd.tag = atio->u.isp24.exchange_addr;
3760 cmd->unpacked_lun = scsilun_to_int( 3781 cmd->unpacked_lun = scsilun_to_int(
@@ -3797,7 +3818,7 @@ out_term:
3797 */ 3818 */
3798 cmd->cmd_flags |= BIT_2; 3819 cmd->cmd_flags |= BIT_2;
3799 spin_lock_irqsave(&ha->hardware_lock, flags); 3820 spin_lock_irqsave(&ha->hardware_lock, flags);
3800 qlt_send_term_exchange(vha, NULL, &cmd->atio, 1); 3821 qlt_send_term_exchange(vha, NULL, &cmd->atio, 1, 0);
3801 3822
3802 qlt_decr_num_pend_cmds(vha); 3823 qlt_decr_num_pend_cmds(vha);
3803 percpu_ida_free(&sess->se_sess->sess_tag_pool, cmd->se_cmd.map_tag); 3824 percpu_ida_free(&sess->se_sess->sess_tag_pool, cmd->se_cmd.map_tag);
@@ -3919,7 +3940,7 @@ static void qlt_create_sess_from_atio(struct work_struct *work)
3919 3940
3920out_term: 3941out_term:
3921 spin_lock_irqsave(&ha->hardware_lock, flags); 3942 spin_lock_irqsave(&ha->hardware_lock, flags);
3922 qlt_send_term_exchange(vha, NULL, &op->atio, 1); 3943 qlt_send_term_exchange(vha, NULL, &op->atio, 1, 0);
3923 spin_unlock_irqrestore(&ha->hardware_lock, flags); 3944 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3924 kfree(op); 3945 kfree(op);
3925 3946
@@ -4772,7 +4793,7 @@ out_reject:
4772 dump_stack(); 4793 dump_stack();
4773 } else { 4794 } else {
4774 cmd->cmd_flags |= BIT_9; 4795 cmd->cmd_flags |= BIT_9;
4775 qlt_send_term_exchange(vha, cmd, &cmd->atio, 1); 4796 qlt_send_term_exchange(vha, cmd, &cmd->atio, 1, 0);
4776 } 4797 }
4777 spin_unlock_irqrestore(&ha->hardware_lock, flags); 4798 spin_unlock_irqrestore(&ha->hardware_lock, flags);
4778} 4799}
@@ -4951,7 +4972,7 @@ static void qlt_prepare_srr_imm(struct scsi_qla_host *vha,
4951 sctio, sctio->srr_id); 4972 sctio, sctio->srr_id);
4952 list_del(&sctio->srr_list_entry); 4973 list_del(&sctio->srr_list_entry);
4953 qlt_send_term_exchange(vha, sctio->cmd, 4974 qlt_send_term_exchange(vha, sctio->cmd,
4954 &sctio->cmd->atio, 1); 4975 &sctio->cmd->atio, 1, 0);
4955 kfree(sctio); 4976 kfree(sctio);
4956 } 4977 }
4957 } 4978 }
@@ -5124,7 +5145,7 @@ static int __qlt_send_busy(struct scsi_qla_host *vha,
5124 atio->u.isp24.fcp_hdr.s_id); 5145 atio->u.isp24.fcp_hdr.s_id);
5125 spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); 5146 spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
5126 if (!sess) { 5147 if (!sess) {
5127 qlt_send_term_exchange(vha, NULL, atio, 1); 5148 qlt_send_term_exchange(vha, NULL, atio, 1, 0);
5128 return 0; 5149 return 0;
5129 } 5150 }
5130 /* Sending marker isn't necessary, since we called from ISR */ 5151 /* Sending marker isn't necessary, since we called from ISR */
@@ -5407,7 +5428,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
5407#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */ 5428#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
5408 qlt_send_busy(vha, atio, SAM_STAT_BUSY); 5429 qlt_send_busy(vha, atio, SAM_STAT_BUSY);
5409#else 5430#else
5410 qlt_send_term_exchange(vha, NULL, atio, 1); 5431 qlt_send_term_exchange(vha, NULL, atio, 1, 0);
5411#endif 5432#endif
5412 5433
5413 if (!ha_locked) 5434 if (!ha_locked)
@@ -5524,7 +5545,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
5524#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */ 5545#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
5525 qlt_send_busy(vha, atio, 0); 5546 qlt_send_busy(vha, atio, 0);
5526#else 5547#else
5527 qlt_send_term_exchange(vha, NULL, atio, 1); 5548 qlt_send_term_exchange(vha, NULL, atio, 1, 0);
5528#endif 5549#endif
5529 } else { 5550 } else {
5530 if (tgt->tgt_stop) { 5551 if (tgt->tgt_stop) {
@@ -5533,7 +5554,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
5533 "command to target, sending TERM " 5554 "command to target, sending TERM "
5534 "EXCHANGE for rsp\n"); 5555 "EXCHANGE for rsp\n");
5535 qlt_send_term_exchange(vha, NULL, 5556 qlt_send_term_exchange(vha, NULL,
5536 atio, 1); 5557 atio, 1, 0);
5537 } else { 5558 } else {
5538 ql_dbg(ql_dbg_tgt, vha, 0xe060, 5559 ql_dbg(ql_dbg_tgt, vha, 0xe060,
5539 "qla_target(%d): Unable to send " 5560 "qla_target(%d): Unable to send "
@@ -5961,7 +5982,7 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
5961 return; 5982 return;
5962 5983
5963out_term: 5984out_term:
5964 qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 0); 5985 qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1, 0);
5965 if (sess) 5986 if (sess)
5966 ha->tgt.tgt_ops->put_sess(sess); 5987 ha->tgt.tgt_ops->put_sess(sess);
5967 spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); 5988 spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index 71b2865ba3c8..22a6a767fe07 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -943,6 +943,36 @@ struct qla_tgt_sess {
943 qlt_plogi_ack_t *plogi_link[QLT_PLOGI_LINK_MAX]; 943 qlt_plogi_ack_t *plogi_link[QLT_PLOGI_LINK_MAX];
944}; 944};
945 945
946typedef enum {
947 /*
948 * BIT_0 - Atio Arrival / schedule to work
949 * BIT_1 - qlt_do_work
950 * BIT_2 - qlt_do work failed
951 * BIT_3 - xfer rdy/tcm_qla2xxx_write_pending
952 * BIT_4 - read respond/tcm_qla2xx_queue_data_in
953 * BIT_5 - status respond / tcm_qla2xx_queue_status
954 * BIT_6 - tcm request to abort/Term exchange.
955 * pre_xmit_response->qlt_send_term_exchange
956 * BIT_7 - SRR received (qlt_handle_srr->qlt_xmit_response)
957 * BIT_8 - SRR received (qlt_handle_srr->qlt_rdy_to_xfer)
958 * BIT_9 - SRR received (qla_handle_srr->qlt_send_term_exchange)
959 * BIT_10 - Data in - hanlde_data->tcm_qla2xxx_handle_data
960
961 * BIT_12 - good completion - qlt_ctio_do_completion -->free_cmd
962 * BIT_13 - Bad completion -
963 * qlt_ctio_do_completion --> qlt_term_ctio_exchange
964 * BIT_14 - Back end data received/sent.
965 * BIT_15 - SRR prepare ctio
966 * BIT_16 - complete free
967 * BIT_17 - flush - qlt_abort_cmd_on_host_reset
968 * BIT_18 - completion w/abort status
969 * BIT_19 - completion w/unknown status
970 * BIT_20 - tcm_qla2xxx_free_cmd
971 */
972 CMD_FLAG_DATA_WORK = BIT_11,
973 CMD_FLAG_DATA_WORK_FREE = BIT_21,
974} cmd_flags_t;
975
946struct qla_tgt_cmd { 976struct qla_tgt_cmd {
947 struct se_cmd se_cmd; 977 struct se_cmd se_cmd;
948 struct qla_tgt_sess *sess; 978 struct qla_tgt_sess *sess;
@@ -952,6 +982,7 @@ struct qla_tgt_cmd {
952 /* Sense buffer that will be mapped into outgoing status */ 982 /* Sense buffer that will be mapped into outgoing status */
953 unsigned char sense_buffer[TRANSPORT_SENSE_BUFFER]; 983 unsigned char sense_buffer[TRANSPORT_SENSE_BUFFER];
954 984
985 spinlock_t cmd_lock;
955 /* to save extra sess dereferences */ 986 /* to save extra sess dereferences */
956 unsigned int conf_compl_supported:1; 987 unsigned int conf_compl_supported:1;
957 unsigned int sg_mapped:1; 988 unsigned int sg_mapped:1;
@@ -986,30 +1017,8 @@ struct qla_tgt_cmd {
986 1017
987 uint64_t jiffies_at_alloc; 1018 uint64_t jiffies_at_alloc;
988 uint64_t jiffies_at_free; 1019 uint64_t jiffies_at_free;
989 /* BIT_0 - Atio Arrival / schedule to work 1020
990 * BIT_1 - qlt_do_work 1021 cmd_flags_t cmd_flags;
991 * BIT_2 - qlt_do work failed
992 * BIT_3 - xfer rdy/tcm_qla2xxx_write_pending
993 * BIT_4 - read respond/tcm_qla2xx_queue_data_in
994 * BIT_5 - status respond / tcm_qla2xx_queue_status
995 * BIT_6 - tcm request to abort/Term exchange.
996 * pre_xmit_response->qlt_send_term_exchange
997 * BIT_7 - SRR received (qlt_handle_srr->qlt_xmit_response)
998 * BIT_8 - SRR received (qlt_handle_srr->qlt_rdy_to_xfer)
999 * BIT_9 - SRR received (qla_handle_srr->qlt_send_term_exchange)
1000 * BIT_10 - Data in - hanlde_data->tcm_qla2xxx_handle_data
1001 * BIT_11 - Data actually going to TCM : tcm_qla2xx_handle_data_work
1002 * BIT_12 - good completion - qlt_ctio_do_completion -->free_cmd
1003 * BIT_13 - Bad completion -
1004 * qlt_ctio_do_completion --> qlt_term_ctio_exchange
1005 * BIT_14 - Back end data received/sent.
1006 * BIT_15 - SRR prepare ctio
1007 * BIT_16 - complete free
1008 * BIT_17 - flush - qlt_abort_cmd_on_host_reset
1009 * BIT_18 - completion w/abort status
1010 * BIT_19 - completion w/unknown status
1011 */
1012 uint32_t cmd_flags;
1013}; 1022};
1014 1023
1015struct qla_tgt_sess_work_param { 1024struct qla_tgt_sess_work_param {
@@ -1148,7 +1157,7 @@ static inline void sid_to_portid(const uint8_t *s_id, port_id_t *p)
1148extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, response_t *); 1157extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, response_t *);
1149extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *); 1158extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *);
1150extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t); 1159extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t);
1151extern void qlt_abort_cmd(struct qla_tgt_cmd *); 1160extern int qlt_abort_cmd(struct qla_tgt_cmd *);
1152extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *); 1161extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *);
1153extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *); 1162extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *);
1154extern void qlt_free_cmd(struct qla_tgt_cmd *cmd); 1163extern void qlt_free_cmd(struct qla_tgt_cmd *cmd);
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index faf0a126627f..3eecdd1bc6fb 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -298,6 +298,10 @@ static void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd)
298{ 298{
299 cmd->vha->tgt_counters.core_qla_free_cmd++; 299 cmd->vha->tgt_counters.core_qla_free_cmd++;
300 cmd->cmd_in_wq = 1; 300 cmd->cmd_in_wq = 1;
301
302 BUG_ON(cmd->cmd_flags & BIT_20);
303 cmd->cmd_flags |= BIT_20;
304
301 INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free); 305 INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free);
302 queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work); 306 queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work);
303} 307}
@@ -374,6 +378,20 @@ static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd)
374{ 378{
375 struct qla_tgt_cmd *cmd = container_of(se_cmd, 379 struct qla_tgt_cmd *cmd = container_of(se_cmd,
376 struct qla_tgt_cmd, se_cmd); 380 struct qla_tgt_cmd, se_cmd);
381
382 if (cmd->aborted) {
383 /* Cmd can loop during Q-full. tcm_qla2xxx_aborted_task
384 * can get ahead of this cmd. tcm_qla2xxx_aborted_task
385 * already kick start the free.
386 */
387 pr_debug("write_pending aborted cmd[%p] refcount %d "
388 "transport_state %x, t_state %x, se_cmd_flags %x\n",
389 cmd,cmd->se_cmd.cmd_kref.refcount.counter,
390 cmd->se_cmd.transport_state,
391 cmd->se_cmd.t_state,
392 cmd->se_cmd.se_cmd_flags);
393 return 0;
394 }
377 cmd->cmd_flags |= BIT_3; 395 cmd->cmd_flags |= BIT_3;
378 cmd->bufflen = se_cmd->data_length; 396 cmd->bufflen = se_cmd->data_length;
379 cmd->dma_data_direction = target_reverse_dma_direction(se_cmd); 397 cmd->dma_data_direction = target_reverse_dma_direction(se_cmd);
@@ -405,7 +423,7 @@ static int tcm_qla2xxx_write_pending_status(struct se_cmd *se_cmd)
405 se_cmd->t_state == TRANSPORT_COMPLETE_QF_WP) { 423 se_cmd->t_state == TRANSPORT_COMPLETE_QF_WP) {
406 spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); 424 spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
407 wait_for_completion_timeout(&se_cmd->t_transport_stop_comp, 425 wait_for_completion_timeout(&se_cmd->t_transport_stop_comp,
408 3 * HZ); 426 50);
409 return 0; 427 return 0;
410 } 428 }
411 spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); 429 spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
@@ -465,13 +483,25 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
465static void tcm_qla2xxx_handle_data_work(struct work_struct *work) 483static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
466{ 484{
467 struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); 485 struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
486 unsigned long flags;
468 487
469 /* 488 /*
470 * Ensure that the complete FCP WRITE payload has been received. 489 * Ensure that the complete FCP WRITE payload has been received.
471 * Otherwise return an exception via CHECK_CONDITION status. 490 * Otherwise return an exception via CHECK_CONDITION status.
472 */ 491 */
473 cmd->cmd_in_wq = 0; 492 cmd->cmd_in_wq = 0;
474 cmd->cmd_flags |= BIT_11; 493
494 spin_lock_irqsave(&cmd->cmd_lock, flags);
495 cmd->cmd_flags |= CMD_FLAG_DATA_WORK;
496 if (cmd->aborted) {
497 cmd->cmd_flags |= CMD_FLAG_DATA_WORK_FREE;
498 spin_unlock_irqrestore(&cmd->cmd_lock, flags);
499
500 tcm_qla2xxx_free_cmd(cmd);
501 return;
502 }
503 spin_unlock_irqrestore(&cmd->cmd_lock, flags);
504
475 cmd->vha->tgt_counters.qla_core_ret_ctio++; 505 cmd->vha->tgt_counters.qla_core_ret_ctio++;
476 if (!cmd->write_data_transferred) { 506 if (!cmd->write_data_transferred) {
477 /* 507 /*
@@ -546,6 +576,20 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
546 struct qla_tgt_cmd *cmd = container_of(se_cmd, 576 struct qla_tgt_cmd *cmd = container_of(se_cmd,
547 struct qla_tgt_cmd, se_cmd); 577 struct qla_tgt_cmd, se_cmd);
548 578
579 if (cmd->aborted) {
580 /* Cmd can loop during Q-full. tcm_qla2xxx_aborted_task
581 * can get ahead of this cmd. tcm_qla2xxx_aborted_task
582 * already kick start the free.
583 */
584 pr_debug("queue_data_in aborted cmd[%p] refcount %d "
585 "transport_state %x, t_state %x, se_cmd_flags %x\n",
586 cmd,cmd->se_cmd.cmd_kref.refcount.counter,
587 cmd->se_cmd.transport_state,
588 cmd->se_cmd.t_state,
589 cmd->se_cmd.se_cmd_flags);
590 return 0;
591 }
592
549 cmd->cmd_flags |= BIT_4; 593 cmd->cmd_flags |= BIT_4;
550 cmd->bufflen = se_cmd->data_length; 594 cmd->bufflen = se_cmd->data_length;
551 cmd->dma_data_direction = target_reverse_dma_direction(se_cmd); 595 cmd->dma_data_direction = target_reverse_dma_direction(se_cmd);
@@ -637,11 +681,34 @@ static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
637 qlt_xmit_tm_rsp(mcmd); 681 qlt_xmit_tm_rsp(mcmd);
638} 682}
639 683
684
685#define DATA_WORK_NOT_FREE(_flags) \
686 (( _flags & (CMD_FLAG_DATA_WORK|CMD_FLAG_DATA_WORK_FREE)) == \
687 CMD_FLAG_DATA_WORK)
640static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd) 688static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
641{ 689{
642 struct qla_tgt_cmd *cmd = container_of(se_cmd, 690 struct qla_tgt_cmd *cmd = container_of(se_cmd,
643 struct qla_tgt_cmd, se_cmd); 691 struct qla_tgt_cmd, se_cmd);
644 qlt_abort_cmd(cmd); 692 unsigned long flags;
693
694 if (qlt_abort_cmd(cmd))
695 return;
696
697 spin_lock_irqsave(&cmd->cmd_lock, flags);
698 if ((cmd->state == QLA_TGT_STATE_NEW)||
699 ((cmd->state == QLA_TGT_STATE_DATA_IN) &&
700 DATA_WORK_NOT_FREE(cmd->cmd_flags)) ) {
701
702 cmd->cmd_flags |= CMD_FLAG_DATA_WORK_FREE;
703 spin_unlock_irqrestore(&cmd->cmd_lock, flags);
704 /* Cmd have not reached firmware.
705 * Use this trigger to free it. */
706 tcm_qla2xxx_free_cmd(cmd);
707 return;
708 }
709 spin_unlock_irqrestore(&cmd->cmd_lock, flags);
710 return;
711
645} 712}
646 713
647static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *, 714static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,