@@ -105,7 +105,7 @@ static void qlt_response_pkt(struct scsi_qla_host *ha, response_t *pkt);
105
105
static int qlt_issue_task_mgmt (struct qla_tgt_sess * sess , uint32_t lun ,
106
106
int fn , void * iocb , int flags );
107
107
static 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 );
109
109
static void qlt_reject_free_srr_imm (struct scsi_qla_host * ha ,
110
110
struct qla_tgt_srr_imm * imm , int ha_lock );
111
111
static 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
2665
/* no need to terminate. FW already freed exchange. */
2666
2666
qlt_abort_cmd_on_host_reset (cmd -> vha , cmd );
2667
2667
else
2668
- qlt_send_term_exchange (vha , cmd , & cmd -> atio , 1 );
2668
+ qlt_send_term_exchange (vha , cmd , & cmd -> atio , 1 , 0 );
2669
2669
spin_unlock_irqrestore (& ha -> hardware_lock , flags );
2670
2670
return 0 ;
2671
2671
}
@@ -3173,7 +3173,8 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
3173
3173
}
3174
3174
3175
3175
static 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
3179
unsigned long flags = 0 ;
3179
3180
int rc ;
@@ -3193,8 +3194,7 @@ static void qlt_send_term_exchange(struct scsi_qla_host *vha,
3193
3194
qlt_alloc_qfull_cmd (vha , atio , 0 , 0 );
3194
3195
3195
3196
done :
3196
- if (cmd && (!cmd -> aborted ||
3197
- !cmd -> cmd_sent_to_fw )) {
3197
+ if (cmd && !ul_abort && !cmd -> aborted ) {
3198
3198
if (cmd -> sg_mapped )
3199
3199
qlt_unmap_sg (vha , cmd );
3200
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
3256
- void qlt_abort_cmd (struct qla_tgt_cmd * cmd )
3256
+ int qlt_abort_cmd (struct qla_tgt_cmd * cmd )
3257
3257
{
3258
3258
struct qla_tgt * tgt = cmd -> tgt ;
3259
3259
struct scsi_qla_host * vha = tgt -> vha ;
3260
3260
struct se_cmd * se_cmd = & cmd -> se_cmd ;
3261
+ unsigned long flags ;
3261
3262
3262
3263
ql_dbg (ql_dbg_tgt_mgt , vha , 0xf014 ,
3263
3264
"qla_target(%d): terminating exchange for aborted cmd=%p "
3264
3265
"(se_cmd=%p, tag=%llu)" , vha -> vp_idx , cmd , & cmd -> se_cmd ,
3265
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
3282
cmd -> aborted = 1 ;
3268
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
}
3272
3289
EXPORT_SYMBOL (qlt_abort_cmd );
3273
3290
@@ -3282,6 +3299,9 @@ void qlt_free_cmd(struct qla_tgt_cmd *cmd)
3282
3299
3283
3300
BUG_ON (cmd -> cmd_in_wq );
3284
3301
3302
+ if (cmd -> sg_mapped )
3303
+ qlt_unmap_sg (cmd -> vha , cmd );
3304
+
3285
3305
if (!cmd -> q_full )
3286
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
3419
term = 1 ;
3400
3420
3401
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
3424
return term ;
3405
3425
}
@@ -3755,6 +3775,7 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
3755
3775
goto out_term ;
3756
3776
}
3757
3777
3778
+ spin_lock_init (& cmd -> cmd_lock );
3758
3779
cdb = & atio -> u .isp24 .fcp_cmnd .cdb [0 ];
3759
3780
cmd -> se_cmd .tag = atio -> u .isp24 .exchange_addr ;
3760
3781
cmd -> unpacked_lun = scsilun_to_int (
@@ -3797,7 +3818,7 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
3797
3818
*/
3798
3819
cmd -> cmd_flags |= BIT_2 ;
3799
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
3823
qlt_decr_num_pend_cmds (vha );
3803
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
3920
3941
out_term :
3921
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
3944
spin_unlock_irqrestore (& ha -> hardware_lock , flags );
3924
3945
kfree (op );
3925
3946
@@ -4772,7 +4793,7 @@ static void qlt_handle_srr(struct scsi_qla_host *vha,
4772
4793
dump_stack ();
4773
4794
} else {
4774
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
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
4972
sctio , sctio -> srr_id );
4952
4973
list_del (& sctio -> srr_list_entry );
4953
4974
qlt_send_term_exchange (vha , sctio -> cmd ,
4954
- & sctio -> cmd -> atio , 1 );
4975
+ & sctio -> cmd -> atio , 1 , 0 );
4955
4976
kfree (sctio );
4956
4977
}
4957
4978
}
@@ -5124,7 +5145,7 @@ static int __qlt_send_busy(struct scsi_qla_host *vha,
5124
5145
atio -> u .isp24 .fcp_hdr .s_id );
5125
5146
spin_unlock_irqrestore (& ha -> tgt .sess_lock , flags );
5126
5147
if (!sess ) {
5127
- qlt_send_term_exchange (vha , NULL , atio , 1 );
5148
+ qlt_send_term_exchange (vha , NULL , atio , 1 , 0 );
5128
5149
return 0 ;
5129
5150
}
5130
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
5428
#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
5408
5429
qlt_send_busy (vha , atio , SAM_STAT_BUSY );
5409
5430
#else
5410
- qlt_send_term_exchange (vha , NULL , atio , 1 );
5431
+ qlt_send_term_exchange (vha , NULL , atio , 1 , 0 );
5411
5432
#endif
5412
5433
5413
5434
if (!ha_locked )
@@ -5524,7 +5545,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
5524
5545
#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
5525
5546
qlt_send_busy (vha , atio , 0 );
5526
5547
#else
5527
- qlt_send_term_exchange (vha , NULL , atio , 1 );
5548
+ qlt_send_term_exchange (vha , NULL , atio , 1 , 0 );
5528
5549
#endif
5529
5550
} else {
5530
5551
if (tgt -> tgt_stop ) {
@@ -5533,7 +5554,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
5533
5554
"command to target, sending TERM "
5534
5555
"EXCHANGE for rsp\n" );
5535
5556
qlt_send_term_exchange (vha , NULL ,
5536
- atio , 1 );
5557
+ atio , 1 , 0 );
5537
5558
} else {
5538
5559
ql_dbg (ql_dbg_tgt , vha , 0xe060 ,
5539
5560
"qla_target(%d): Unable to send "
@@ -5961,7 +5982,7 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
5961
5982
return ;
5962
5983
5963
5984
out_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
5986
if (sess )
5966
5987
ha -> tgt .tgt_ops -> put_sess (sess );
5967
5988
spin_unlock_irqrestore (& ha -> tgt .sess_lock , flags );
0 commit comments