@@ -2192,30 +2192,42 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
2192
2192
return rval ;
2193
2193
}
2194
2194
2195
- static void qla_put_tmf (fc_port_t * fcport )
2195
+ static void qla_put_tmf (struct tmf_arg * arg )
2196
2196
{
2197
- struct scsi_qla_host * vha = fcport -> vha ;
2197
+ struct scsi_qla_host * vha = arg -> vha ;
2198
2198
struct qla_hw_data * ha = vha -> hw ;
2199
2199
unsigned long flags ;
2200
2200
2201
2201
spin_lock_irqsave (& ha -> tgt .sess_lock , flags );
2202
- fcport -> active_tmf -- ;
2202
+ ha -> active_tmf -- ;
2203
+ list_del (& arg -> tmf_elem );
2203
2204
spin_unlock_irqrestore (& ha -> tgt .sess_lock , flags );
2204
2205
}
2205
2206
2206
2207
static
2207
- int qla_get_tmf (fc_port_t * fcport )
2208
+ int qla_get_tmf (struct tmf_arg * arg )
2208
2209
{
2209
- struct scsi_qla_host * vha = fcport -> vha ;
2210
+ struct scsi_qla_host * vha = arg -> vha ;
2210
2211
struct qla_hw_data * ha = vha -> hw ;
2211
2212
unsigned long flags ;
2213
+ fc_port_t * fcport = arg -> fcport ;
2212
2214
int rc = 0 ;
2213
- LIST_HEAD ( tmf_elem ) ;
2215
+ struct tmf_arg * t ;
2214
2216
2215
2217
spin_lock_irqsave (& ha -> tgt .sess_lock , flags );
2216
- list_add_tail (& tmf_elem , & fcport -> tmf_pending );
2218
+ list_for_each_entry (t , & ha -> tmf_active , tmf_elem ) {
2219
+ if (t -> fcport == arg -> fcport && t -> lun == arg -> lun ) {
2220
+ /* reject duplicate TMF */
2221
+ ql_log (ql_log_warn , vha , 0x802c ,
2222
+ "found duplicate TMF. Nexus=%ld:%06x:%llu.\n" ,
2223
+ vha -> host_no , fcport -> d_id .b24 , arg -> lun );
2224
+ spin_unlock_irqrestore (& ha -> tgt .sess_lock , flags );
2225
+ return - EINVAL ;
2226
+ }
2227
+ }
2217
2228
2218
- while (fcport -> active_tmf >= MAX_ACTIVE_TMF ) {
2229
+ list_add_tail (& arg -> tmf_elem , & ha -> tmf_pending );
2230
+ while (ha -> active_tmf >= MAX_ACTIVE_TMF ) {
2219
2231
spin_unlock_irqrestore (& ha -> tgt .sess_lock , flags );
2220
2232
2221
2233
msleep (1 );
@@ -2227,15 +2239,17 @@ int qla_get_tmf(fc_port_t *fcport)
2227
2239
rc = EIO ;
2228
2240
break ;
2229
2241
}
2230
- if (fcport -> active_tmf < MAX_ACTIVE_TMF &&
2231
- list_is_first (& tmf_elem , & fcport -> tmf_pending ))
2242
+ if (ha -> active_tmf < MAX_ACTIVE_TMF &&
2243
+ list_is_first (& arg -> tmf_elem , & ha -> tmf_pending ))
2232
2244
break ;
2233
2245
}
2234
2246
2235
- list_del (& tmf_elem );
2247
+ list_del (& arg -> tmf_elem );
2236
2248
2237
- if (!rc )
2238
- fcport -> active_tmf ++ ;
2249
+ if (!rc ) {
2250
+ ha -> active_tmf ++ ;
2251
+ list_add_tail (& arg -> tmf_elem , & ha -> tmf_active );
2252
+ }
2239
2253
2240
2254
spin_unlock_irqrestore (& ha -> tgt .sess_lock , flags );
2241
2255
@@ -2257,15 +2271,18 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
2257
2271
a .vha = fcport -> vha ;
2258
2272
a .fcport = fcport ;
2259
2273
a .lun = lun ;
2274
+ a .flags = flags ;
2275
+ INIT_LIST_HEAD (& a .tmf_elem );
2276
+
2260
2277
if (flags & (TCF_LUN_RESET |TCF_ABORT_TASK_SET |TCF_CLEAR_TASK_SET |TCF_CLEAR_ACA )) {
2261
2278
a .modifier = MK_SYNC_ID_LUN ;
2262
-
2263
- if (qla_get_tmf (fcport ))
2264
- return QLA_FUNCTION_FAILED ;
2265
2279
} else {
2266
2280
a .modifier = MK_SYNC_ID ;
2267
2281
}
2268
2282
2283
+ if (qla_get_tmf (& a ))
2284
+ return QLA_FUNCTION_FAILED ;
2285
+
2269
2286
if (vha -> hw -> mqenable ) {
2270
2287
for (i = 0 ; i < vha -> hw -> num_qpairs ; i ++ ) {
2271
2288
qpair = vha -> hw -> queue_pair_map [i ];
@@ -2291,13 +2308,10 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
2291
2308
goto bailout ;
2292
2309
2293
2310
a .qpair = vha -> hw -> base_qpair ;
2294
- a .flags = flags ;
2295
2311
rval = __qla2x00_async_tm_cmd (& a );
2296
2312
2297
2313
bailout :
2298
- if (a .modifier == MK_SYNC_ID_LUN )
2299
- qla_put_tmf (fcport );
2300
-
2314
+ qla_put_tmf (& a );
2301
2315
return rval ;
2302
2316
}
2303
2317
@@ -5526,7 +5540,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
5526
5540
INIT_WORK (& fcport -> reg_work , qla_register_fcport_fn );
5527
5541
INIT_LIST_HEAD (& fcport -> gnl_entry );
5528
5542
INIT_LIST_HEAD (& fcport -> list );
5529
- INIT_LIST_HEAD (& fcport -> tmf_pending );
5530
5543
5531
5544
INIT_LIST_HEAD (& fcport -> sess_cmd_list );
5532
5545
spin_lock_init (& fcport -> sess_cmd_lock );
0 commit comments