@@ -21,6 +21,7 @@ enum zfcp_erp_act_flags {
21
21
ZFCP_STATUS_ERP_DISMISSING = 0x00100000 ,
22
22
ZFCP_STATUS_ERP_DISMISSED = 0x00200000 ,
23
23
ZFCP_STATUS_ERP_LOWMEM = 0x00400000 ,
24
+ ZFCP_STATUS_ERP_NO_REF = 0x00800000 ,
24
25
};
25
26
26
27
enum zfcp_erp_steps {
@@ -169,22 +170,22 @@ static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
169
170
return need ;
170
171
}
171
172
172
- static struct zfcp_erp_action * zfcp_erp_setup_act (int need ,
173
+ static struct zfcp_erp_action * zfcp_erp_setup_act (int need , u32 act_status ,
173
174
struct zfcp_adapter * adapter ,
174
175
struct zfcp_port * port ,
175
176
struct zfcp_unit * unit )
176
177
{
177
178
struct zfcp_erp_action * erp_action ;
178
- u32 status = 0 ;
179
179
180
180
switch (need ) {
181
181
case ZFCP_ERP_ACTION_REOPEN_UNIT :
182
- if (!get_device (& unit -> dev ))
183
- return NULL ;
182
+ if (!(act_status & ZFCP_STATUS_ERP_NO_REF ))
183
+ if (!get_device (& unit -> dev ))
184
+ return NULL ;
184
185
atomic_set_mask (ZFCP_STATUS_COMMON_ERP_INUSE , & unit -> status );
185
186
erp_action = & unit -> erp_action ;
186
187
if (!(atomic_read (& unit -> status ) & ZFCP_STATUS_COMMON_RUNNING ))
187
- status = ZFCP_STATUS_ERP_CLOSE_ONLY ;
188
+ act_status | = ZFCP_STATUS_ERP_CLOSE_ONLY ;
188
189
break ;
189
190
190
191
case ZFCP_ERP_ACTION_REOPEN_PORT :
@@ -195,7 +196,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
195
196
atomic_set_mask (ZFCP_STATUS_COMMON_ERP_INUSE , & port -> status );
196
197
erp_action = & port -> erp_action ;
197
198
if (!(atomic_read (& port -> status ) & ZFCP_STATUS_COMMON_RUNNING ))
198
- status = ZFCP_STATUS_ERP_CLOSE_ONLY ;
199
+ act_status | = ZFCP_STATUS_ERP_CLOSE_ONLY ;
199
200
break ;
200
201
201
202
case ZFCP_ERP_ACTION_REOPEN_ADAPTER :
@@ -205,7 +206,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
205
206
erp_action = & adapter -> erp_action ;
206
207
if (!(atomic_read (& adapter -> status ) &
207
208
ZFCP_STATUS_COMMON_RUNNING ))
208
- status = ZFCP_STATUS_ERP_CLOSE_ONLY ;
209
+ act_status | = ZFCP_STATUS_ERP_CLOSE_ONLY ;
209
210
break ;
210
211
211
212
default :
@@ -217,14 +218,15 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
217
218
erp_action -> port = port ;
218
219
erp_action -> unit = unit ;
219
220
erp_action -> action = need ;
220
- erp_action -> status = status ;
221
+ erp_action -> status = act_status ;
221
222
222
223
return erp_action ;
223
224
}
224
225
225
226
static int zfcp_erp_action_enqueue (int want , struct zfcp_adapter * adapter ,
226
227
struct zfcp_port * port ,
227
- struct zfcp_unit * unit , char * id , void * ref )
228
+ struct zfcp_unit * unit , char * id , void * ref ,
229
+ u32 act_status )
228
230
{
229
231
int retval = 1 , need ;
230
232
struct zfcp_erp_action * act = NULL ;
@@ -236,10 +238,10 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
236
238
if (!need )
237
239
goto out ;
238
240
239
- atomic_set_mask (ZFCP_STATUS_ADAPTER_ERP_PENDING , & adapter -> status );
240
- act = zfcp_erp_setup_act (need , adapter , port , unit );
241
+ act = zfcp_erp_setup_act (need , act_status , adapter , port , unit );
241
242
if (!act )
242
243
goto out ;
244
+ atomic_set_mask (ZFCP_STATUS_ADAPTER_ERP_PENDING , & adapter -> status );
243
245
++ adapter -> erp_total_count ;
244
246
list_add_tail (& act -> list , & adapter -> erp_ready_head );
245
247
wake_up (& adapter -> erp_ready_wq );
@@ -262,7 +264,7 @@ static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
262
264
return - EIO ;
263
265
}
264
266
return zfcp_erp_action_enqueue (ZFCP_ERP_ACTION_REOPEN_ADAPTER ,
265
- adapter , NULL , NULL , id , ref );
267
+ adapter , NULL , NULL , id , ref , 0 );
266
268
}
267
269
268
270
/**
@@ -285,7 +287,7 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
285
287
zfcp_erp_adapter_failed (adapter , "erareo1" , NULL );
286
288
else
287
289
zfcp_erp_action_enqueue (ZFCP_ERP_ACTION_REOPEN_ADAPTER , adapter ,
288
- NULL , NULL , id , ref );
290
+ NULL , NULL , id , ref , 0 );
289
291
write_unlock_irqrestore (& adapter -> erp_lock , flags );
290
292
}
291
293
@@ -317,20 +319,6 @@ void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, char *id,
317
319
zfcp_erp_port_reopen (port , clear | flags , id , ref );
318
320
}
319
321
320
- /**
321
- * zfcp_erp_unit_shutdown - Shutdown unit
322
- * @unit: Unit to shut down.
323
- * @clear: Status flags to clear.
324
- * @id: Id for debug trace event.
325
- * @ref: Reference for debug trace event.
326
- */
327
- void zfcp_erp_unit_shutdown (struct zfcp_unit * unit , int clear , char * id ,
328
- void * ref )
329
- {
330
- int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED ;
331
- zfcp_erp_unit_reopen (unit , clear | flags , id , ref );
332
- }
333
-
334
322
static void zfcp_erp_port_block (struct zfcp_port * port , int clear )
335
323
{
336
324
zfcp_erp_modify_port_status (port , "erpblk1" , NULL ,
@@ -348,7 +336,7 @@ static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port,
348
336
return ;
349
337
350
338
zfcp_erp_action_enqueue (ZFCP_ERP_ACTION_REOPEN_PORT_FORCED ,
351
- port -> adapter , port , NULL , id , ref );
339
+ port -> adapter , port , NULL , id , ref , 0 );
352
340
}
353
341
354
342
/**
@@ -381,7 +369,7 @@ static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id,
381
369
}
382
370
383
371
return zfcp_erp_action_enqueue (ZFCP_ERP_ACTION_REOPEN_PORT ,
384
- port -> adapter , port , NULL , id , ref );
372
+ port -> adapter , port , NULL , id , ref , 0 );
385
373
}
386
374
387
375
/**
@@ -412,7 +400,7 @@ static void zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask)
412
400
}
413
401
414
402
static void _zfcp_erp_unit_reopen (struct zfcp_unit * unit , int clear , char * id ,
415
- void * ref )
403
+ void * ref , u32 act_status )
416
404
{
417
405
struct zfcp_adapter * adapter = unit -> port -> adapter ;
418
406
@@ -422,7 +410,7 @@ static void _zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id,
422
410
return ;
423
411
424
412
zfcp_erp_action_enqueue (ZFCP_ERP_ACTION_REOPEN_UNIT ,
425
- adapter , unit -> port , unit , id , ref );
413
+ adapter , unit -> port , unit , id , ref , act_status );
426
414
}
427
415
428
416
/**
@@ -439,8 +427,45 @@ void zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id,
439
427
struct zfcp_adapter * adapter = port -> adapter ;
440
428
441
429
write_lock_irqsave (& adapter -> erp_lock , flags );
442
- _zfcp_erp_unit_reopen (unit , clear , id , ref );
430
+ _zfcp_erp_unit_reopen (unit , clear , id , ref , 0 );
431
+ write_unlock_irqrestore (& adapter -> erp_lock , flags );
432
+ }
433
+
434
+ /**
435
+ * zfcp_erp_unit_shutdown - Shutdown unit
436
+ * @unit: Unit to shut down.
437
+ * @clear: Status flags to clear.
438
+ * @id: Id for debug trace event.
439
+ * @ref: Reference for debug trace event.
440
+ */
441
+ void zfcp_erp_unit_shutdown (struct zfcp_unit * unit , int clear , char * id ,
442
+ void * ref )
443
+ {
444
+ int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED ;
445
+ zfcp_erp_unit_reopen (unit , clear | flags , id , ref );
446
+ }
447
+
448
+ /**
449
+ * zfcp_erp_unit_shutdown_wait - Shutdown unit and wait for erp completion
450
+ * @unit: Unit to shut down.
451
+ * @id: Id for debug trace event.
452
+ *
453
+ * Do not acquire a reference for the unit when creating the ERP
454
+ * action. It is safe, because this function waits for the ERP to
455
+ * complete first.
456
+ */
457
+ void zfcp_erp_unit_shutdown_wait (struct zfcp_unit * unit , char * id )
458
+ {
459
+ unsigned long flags ;
460
+ struct zfcp_port * port = unit -> port ;
461
+ struct zfcp_adapter * adapter = port -> adapter ;
462
+ int clear = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED ;
463
+
464
+ write_lock_irqsave (& adapter -> erp_lock , flags );
465
+ _zfcp_erp_unit_reopen (unit , clear , id , NULL , ZFCP_STATUS_ERP_NO_REF );
443
466
write_unlock_irqrestore (& adapter -> erp_lock , flags );
467
+
468
+ zfcp_erp_wait (adapter );
444
469
}
445
470
446
471
static int status_change_set (unsigned long mask , atomic_t * status )
@@ -566,7 +591,7 @@ static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear,
566
591
567
592
read_lock (& port -> unit_list_lock );
568
593
list_for_each_entry (unit , & port -> unit_list , list )
569
- _zfcp_erp_unit_reopen (unit , clear , id , ref );
594
+ _zfcp_erp_unit_reopen (unit , clear , id , ref , 0 );
570
595
read_unlock (& port -> unit_list_lock );
571
596
}
572
597
@@ -583,7 +608,7 @@ static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act)
583
608
_zfcp_erp_port_reopen (act -> port , 0 , "ersff_3" , NULL );
584
609
break ;
585
610
case ZFCP_ERP_ACTION_REOPEN_UNIT :
586
- _zfcp_erp_unit_reopen (act -> unit , 0 , "ersff_4" , NULL );
611
+ _zfcp_erp_unit_reopen (act -> unit , 0 , "ersff_4" , NULL , 0 );
587
612
break ;
588
613
}
589
614
}
@@ -1143,7 +1168,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
1143
1168
if (zfcp_erp_strat_change_det (& unit -> status , erp_status )) {
1144
1169
_zfcp_erp_unit_reopen (unit ,
1145
1170
ZFCP_STATUS_COMMON_ERP_FAILED ,
1146
- "ersscg3" , NULL );
1171
+ "ersscg3" , NULL , 0 );
1147
1172
return ZFCP_ERP_EXIT ;
1148
1173
}
1149
1174
break ;
@@ -1191,7 +1216,8 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
1191
1216
1192
1217
switch (act -> action ) {
1193
1218
case ZFCP_ERP_ACTION_REOPEN_UNIT :
1194
- put_device (& unit -> dev );
1219
+ if (!(act -> status & ZFCP_STATUS_ERP_NO_REF ))
1220
+ put_device (& unit -> dev );
1195
1221
break ;
1196
1222
1197
1223
case ZFCP_ERP_ACTION_REOPEN_PORT :
0 commit comments