@@ -2150,25 +2150,74 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
2150
2150
return rval ;
2151
2151
}
2152
2152
2153
+ static void qla_put_tmf (fc_port_t * fcport )
2154
+ {
2155
+ struct scsi_qla_host * vha = fcport -> vha ;
2156
+ struct qla_hw_data * ha = vha -> hw ;
2157
+ unsigned long flags ;
2158
+
2159
+ spin_lock_irqsave (& ha -> tgt .sess_lock , flags );
2160
+ fcport -> active_tmf -- ;
2161
+ spin_unlock_irqrestore (& ha -> tgt .sess_lock , flags );
2162
+ }
2163
+
2164
+ static
2165
+ int qla_get_tmf (fc_port_t * fcport )
2166
+ {
2167
+ struct scsi_qla_host * vha = fcport -> vha ;
2168
+ struct qla_hw_data * ha = vha -> hw ;
2169
+ unsigned long flags ;
2170
+ int rc = 0 ;
2171
+ LIST_HEAD (tmf_elem );
2172
+
2173
+ spin_lock_irqsave (& ha -> tgt .sess_lock , flags );
2174
+ list_add_tail (& tmf_elem , & fcport -> tmf_pending );
2175
+
2176
+ while (fcport -> active_tmf >= MAX_ACTIVE_TMF ) {
2177
+ spin_unlock_irqrestore (& ha -> tgt .sess_lock , flags );
2178
+
2179
+ msleep (1 );
2180
+
2181
+ spin_lock_irqsave (& ha -> tgt .sess_lock , flags );
2182
+ if (fcport -> deleted ) {
2183
+ rc = EIO ;
2184
+ break ;
2185
+ }
2186
+ if (fcport -> active_tmf < MAX_ACTIVE_TMF &&
2187
+ list_is_first (& tmf_elem , & fcport -> tmf_pending ))
2188
+ break ;
2189
+ }
2190
+
2191
+ list_del (& tmf_elem );
2192
+
2193
+ if (!rc )
2194
+ fcport -> active_tmf ++ ;
2195
+
2196
+ spin_unlock_irqrestore (& ha -> tgt .sess_lock , flags );
2197
+
2198
+ return rc ;
2199
+ }
2200
+
2153
2201
int
2154
2202
qla2x00_async_tm_cmd (fc_port_t * fcport , uint32_t flags , uint64_t lun ,
2155
2203
uint32_t tag )
2156
2204
{
2157
2205
struct scsi_qla_host * vha = fcport -> vha ;
2158
2206
struct qla_qpair * qpair ;
2159
2207
struct tmf_arg a ;
2160
- struct completion comp ;
2161
2208
int i , rval ;
2162
2209
2163
- init_completion (& comp );
2164
2210
a .vha = fcport -> vha ;
2165
2211
a .fcport = fcport ;
2166
2212
a .lun = lun ;
2167
-
2168
- if (flags & (TCF_LUN_RESET |TCF_ABORT_TASK_SET |TCF_CLEAR_TASK_SET |TCF_CLEAR_ACA ))
2213
+ if (flags & (TCF_LUN_RESET |TCF_ABORT_TASK_SET |TCF_CLEAR_TASK_SET |TCF_CLEAR_ACA )) {
2169
2214
a .modifier = MK_SYNC_ID_LUN ;
2170
- else
2215
+
2216
+ if (qla_get_tmf (fcport ))
2217
+ return QLA_FUNCTION_FAILED ;
2218
+ } else {
2171
2219
a .modifier = MK_SYNC_ID ;
2220
+ }
2172
2221
2173
2222
if (vha -> hw -> mqenable ) {
2174
2223
for (i = 0 ; i < vha -> hw -> num_qpairs ; i ++ ) {
@@ -2187,6 +2236,9 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
2187
2236
a .flags = flags ;
2188
2237
rval = __qla2x00_async_tm_cmd (& a );
2189
2238
2239
+ if (a .modifier == MK_SYNC_ID_LUN )
2240
+ qla_put_tmf (fcport );
2241
+
2190
2242
return rval ;
2191
2243
}
2192
2244
@@ -5422,6 +5474,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
5422
5474
INIT_WORK (& fcport -> reg_work , qla_register_fcport_fn );
5423
5475
INIT_LIST_HEAD (& fcport -> gnl_entry );
5424
5476
INIT_LIST_HEAD (& fcport -> list );
5477
+ INIT_LIST_HEAD (& fcport -> tmf_pending );
5425
5478
5426
5479
INIT_LIST_HEAD (& fcport -> sess_cmd_list );
5427
5480
spin_lock_init (& fcport -> sess_cmd_lock );
0 commit comments