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