@@ -1170,6 +1170,70 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha,
1170
1170
FCP_TMF_CMPL , true);
1171
1171
}
1172
1172
1173
+ static int abort_cmd_for_tag (struct scsi_qla_host * vha , uint32_t tag )
1174
+ {
1175
+ struct qla_tgt_sess_op * op ;
1176
+ struct qla_tgt_cmd * cmd ;
1177
+
1178
+ spin_lock (& vha -> cmd_list_lock );
1179
+
1180
+ list_for_each_entry (op , & vha -> qla_sess_op_cmd_list , cmd_list ) {
1181
+ if (tag == op -> atio .u .isp24 .exchange_addr ) {
1182
+ op -> aborted = true;
1183
+ spin_unlock (& vha -> cmd_list_lock );
1184
+ return 1 ;
1185
+ }
1186
+ }
1187
+
1188
+ list_for_each_entry (cmd , & vha -> qla_cmd_list , cmd_list ) {
1189
+ if (tag == cmd -> atio .u .isp24 .exchange_addr ) {
1190
+ cmd -> state = QLA_TGT_STATE_ABORTED ;
1191
+ spin_unlock (& vha -> cmd_list_lock );
1192
+ return 1 ;
1193
+ }
1194
+ }
1195
+
1196
+ spin_unlock (& vha -> cmd_list_lock );
1197
+ return 0 ;
1198
+ }
1199
+
1200
+ /* drop cmds for the given lun
1201
+ * XXX only looks for cmds on the port through which lun reset was recieved
1202
+ * XXX does not go through the list of other port (which may have cmds
1203
+ * for the same lun)
1204
+ */
1205
+ static void abort_cmds_for_lun (struct scsi_qla_host * vha ,
1206
+ uint32_t lun , uint8_t * s_id )
1207
+ {
1208
+ struct qla_tgt_sess_op * op ;
1209
+ struct qla_tgt_cmd * cmd ;
1210
+ uint32_t key ;
1211
+
1212
+ key = sid_to_key (s_id );
1213
+ spin_lock (& vha -> cmd_list_lock );
1214
+ list_for_each_entry (op , & vha -> qla_sess_op_cmd_list , cmd_list ) {
1215
+ uint32_t op_key ;
1216
+ uint32_t op_lun ;
1217
+
1218
+ op_key = sid_to_key (op -> atio .u .isp24 .fcp_hdr .s_id );
1219
+ op_lun = scsilun_to_int (
1220
+ (struct scsi_lun * )& op -> atio .u .isp24 .fcp_cmnd .lun );
1221
+ if (op_key == key && op_lun == lun )
1222
+ op -> aborted = true;
1223
+ }
1224
+ list_for_each_entry (cmd , & vha -> qla_cmd_list , cmd_list ) {
1225
+ uint32_t cmd_key ;
1226
+ uint32_t cmd_lun ;
1227
+
1228
+ cmd_key = sid_to_key (cmd -> atio .u .isp24 .fcp_hdr .s_id );
1229
+ cmd_lun = scsilun_to_int (
1230
+ (struct scsi_lun * )& cmd -> atio .u .isp24 .fcp_cmnd .lun );
1231
+ if (cmd_key == key && cmd_lun == lun )
1232
+ cmd -> state = QLA_TGT_STATE_ABORTED ;
1233
+ }
1234
+ spin_unlock (& vha -> cmd_list_lock );
1235
+ }
1236
+
1173
1237
/* ha->hardware_lock supposed to be held on entry */
1174
1238
static int __qlt_24xx_handle_abts (struct scsi_qla_host * vha ,
1175
1239
struct abts_recv_from_24xx * abts , struct qla_tgt_sess * sess )
@@ -1194,8 +1258,19 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
1194
1258
}
1195
1259
spin_unlock (& se_sess -> sess_cmd_lock );
1196
1260
1197
- if (!found_lun )
1198
- return - ENOENT ;
1261
+ /* cmd not in LIO lists, look in qla list */
1262
+ if (!found_lun ) {
1263
+ if (abort_cmd_for_tag (vha , abts -> exchange_addr_to_abort )) {
1264
+ /* send TASK_ABORT response immediately */
1265
+ qlt_24xx_send_abts_resp (vha , abts , FCP_TMF_CMPL , false);
1266
+ return 0 ;
1267
+ } else {
1268
+ ql_dbg (ql_dbg_tgt_mgt , vha , 0xf081 ,
1269
+ "unable to find cmd in driver or LIO for tag 0x%x\n" ,
1270
+ abts -> exchange_addr_to_abort );
1271
+ return - ENOENT ;
1272
+ }
1273
+ }
1199
1274
1200
1275
ql_dbg (ql_dbg_tgt_mgt , vha , 0xf00f ,
1201
1276
"qla_target(%d): task abort (tag=%d)\n" ,
@@ -3264,6 +3339,13 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
3264
3339
if (tgt -> tgt_stop )
3265
3340
goto out_term ;
3266
3341
3342
+ if (cmd -> state == QLA_TGT_STATE_ABORTED ) {
3343
+ ql_dbg (ql_dbg_tgt_mgt , vha , 0xf082 ,
3344
+ "cmd with tag %u is aborted\n" ,
3345
+ cmd -> atio .u .isp24 .exchange_addr );
3346
+ goto out_term ;
3347
+ }
3348
+
3267
3349
cdb = & atio -> u .isp24 .fcp_cmnd .cdb [0 ];
3268
3350
cmd -> se_cmd .tag = atio -> u .isp24 .exchange_addr ;
3269
3351
cmd -> unpacked_lun = scsilun_to_int (
@@ -3317,6 +3399,12 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
3317
3399
static void qlt_do_work (struct work_struct * work )
3318
3400
{
3319
3401
struct qla_tgt_cmd * cmd = container_of (work , struct qla_tgt_cmd , work );
3402
+ scsi_qla_host_t * vha = cmd -> vha ;
3403
+ unsigned long flags ;
3404
+
3405
+ spin_lock_irqsave (& vha -> cmd_list_lock , flags );
3406
+ list_del (& cmd -> cmd_list );
3407
+ spin_unlock_irqrestore (& vha -> cmd_list_lock , flags );
3320
3408
3321
3409
__qlt_do_work (cmd );
3322
3410
}
@@ -3368,14 +3456,25 @@ static void qlt_create_sess_from_atio(struct work_struct *work)
3368
3456
unsigned long flags ;
3369
3457
uint8_t * s_id = op -> atio .u .isp24 .fcp_hdr .s_id ;
3370
3458
3459
+ spin_lock_irqsave (& vha -> cmd_list_lock , flags );
3460
+ list_del (& op -> cmd_list );
3461
+ spin_unlock_irqrestore (& vha -> cmd_list_lock , flags );
3462
+
3463
+ if (op -> aborted ) {
3464
+ ql_dbg (ql_dbg_tgt_mgt , vha , 0xf083 ,
3465
+ "sess_op with tag %u is aborted\n" ,
3466
+ op -> atio .u .isp24 .exchange_addr );
3467
+ goto out_term ;
3468
+ }
3469
+
3371
3470
ql_dbg (ql_dbg_tgt_mgt , vha , 0xf022 ,
3372
- "qla_target(%d): Unable to find wwn login"
3373
- " (s_id %x:%x:%x), trying to create it manually\n" ,
3374
- vha -> vp_idx , s_id [0 ], s_id [1 ], s_id [2 ]);
3471
+ "qla_target(%d): Unable to find wwn login"
3472
+ " (s_id %x:%x:%x), trying to create it manually\n" ,
3473
+ vha -> vp_idx , s_id [0 ], s_id [1 ], s_id [2 ]);
3375
3474
3376
3475
if (op -> atio .u .raw .entry_count > 1 ) {
3377
3476
ql_dbg (ql_dbg_tgt_mgt , vha , 0xf023 ,
3378
- "Dropping multy entry atio %p\n" , & op -> atio );
3477
+ "Dropping multy entry atio %p\n" , & op -> atio );
3379
3478
goto out_term ;
3380
3479
}
3381
3480
@@ -3440,6 +3539,11 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
3440
3539
3441
3540
memcpy (& op -> atio , atio , sizeof (* atio ));
3442
3541
op -> vha = vha ;
3542
+
3543
+ spin_lock (& vha -> cmd_list_lock );
3544
+ list_add_tail (& op -> cmd_list , & vha -> qla_sess_op_cmd_list );
3545
+ spin_unlock (& vha -> cmd_list_lock );
3546
+
3443
3547
INIT_WORK (& op -> work , qlt_create_sess_from_atio );
3444
3548
queue_work (qla_tgt_wq , & op -> work );
3445
3549
return 0 ;
@@ -3459,6 +3563,11 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
3459
3563
3460
3564
cmd -> cmd_in_wq = 1 ;
3461
3565
cmd -> cmd_flags |= BIT_0 ;
3566
+
3567
+ spin_lock (& vha -> cmd_list_lock );
3568
+ list_add_tail (& cmd -> cmd_list , & vha -> qla_cmd_list );
3569
+ spin_unlock (& vha -> cmd_list_lock );
3570
+
3462
3571
INIT_WORK (& cmd -> work , qlt_do_work );
3463
3572
queue_work (qla_tgt_wq , & cmd -> work );
3464
3573
return 0 ;
@@ -3472,6 +3581,7 @@ static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun,
3472
3581
struct scsi_qla_host * vha = sess -> vha ;
3473
3582
struct qla_hw_data * ha = vha -> hw ;
3474
3583
struct qla_tgt_mgmt_cmd * mcmd ;
3584
+ struct atio_from_isp * a = (struct atio_from_isp * )iocb ;
3475
3585
int res ;
3476
3586
uint8_t tmr_func ;
3477
3587
@@ -3512,6 +3622,7 @@ static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun,
3512
3622
ql_dbg (ql_dbg_tgt_tmr , vha , 0x10002 ,
3513
3623
"qla_target(%d): LUN_RESET received\n" , sess -> vha -> vp_idx );
3514
3624
tmr_func = TMR_LUN_RESET ;
3625
+ abort_cmds_for_lun (vha , lun , a -> u .isp24 .fcp_hdr .s_id );
3515
3626
break ;
3516
3627
3517
3628
case QLA_TGT_CLEAR_TS :
0 commit comments