@@ -21,6 +21,7 @@ enum zfcp_erp_act_flags {
2121 ZFCP_STATUS_ERP_DISMISSING = 0x00100000 ,
2222 ZFCP_STATUS_ERP_DISMISSED = 0x00200000 ,
2323 ZFCP_STATUS_ERP_LOWMEM = 0x00400000 ,
24+ ZFCP_STATUS_ERP_NO_REF = 0x00800000 ,
2425};
2526
2627enum zfcp_erp_steps {
@@ -169,22 +170,22 @@ static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
169170 return need ;
170171}
171172
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 ,
173174 struct zfcp_adapter * adapter ,
174175 struct zfcp_port * port ,
175176 struct zfcp_unit * unit )
176177{
177178 struct zfcp_erp_action * erp_action ;
178- u32 status = 0 ;
179179
180180 switch (need ) {
181181 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 ;
184185 atomic_set_mask (ZFCP_STATUS_COMMON_ERP_INUSE , & unit -> status );
185186 erp_action = & unit -> erp_action ;
186187 if (!(atomic_read (& unit -> status ) & ZFCP_STATUS_COMMON_RUNNING ))
187- status = ZFCP_STATUS_ERP_CLOSE_ONLY ;
188+ act_status | = ZFCP_STATUS_ERP_CLOSE_ONLY ;
188189 break ;
189190
190191 case ZFCP_ERP_ACTION_REOPEN_PORT :
@@ -195,7 +196,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
195196 atomic_set_mask (ZFCP_STATUS_COMMON_ERP_INUSE , & port -> status );
196197 erp_action = & port -> erp_action ;
197198 if (!(atomic_read (& port -> status ) & ZFCP_STATUS_COMMON_RUNNING ))
198- status = ZFCP_STATUS_ERP_CLOSE_ONLY ;
199+ act_status | = ZFCP_STATUS_ERP_CLOSE_ONLY ;
199200 break ;
200201
201202 case ZFCP_ERP_ACTION_REOPEN_ADAPTER :
@@ -205,7 +206,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
205206 erp_action = & adapter -> erp_action ;
206207 if (!(atomic_read (& adapter -> status ) &
207208 ZFCP_STATUS_COMMON_RUNNING ))
208- status = ZFCP_STATUS_ERP_CLOSE_ONLY ;
209+ act_status | = ZFCP_STATUS_ERP_CLOSE_ONLY ;
209210 break ;
210211
211212 default :
@@ -217,14 +218,15 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
217218 erp_action -> port = port ;
218219 erp_action -> unit = unit ;
219220 erp_action -> action = need ;
220- erp_action -> status = status ;
221+ erp_action -> status = act_status ;
221222
222223 return erp_action ;
223224}
224225
225226static int zfcp_erp_action_enqueue (int want , struct zfcp_adapter * adapter ,
226227 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 )
228230{
229231 int retval = 1 , need ;
230232 struct zfcp_erp_action * act = NULL ;
@@ -236,10 +238,10 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
236238 if (!need )
237239 goto out ;
238240
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 );
241242 if (!act )
242243 goto out ;
244+ atomic_set_mask (ZFCP_STATUS_ADAPTER_ERP_PENDING , & adapter -> status );
243245 ++ adapter -> erp_total_count ;
244246 list_add_tail (& act -> list , & adapter -> erp_ready_head );
245247 wake_up (& adapter -> erp_ready_wq );
@@ -262,7 +264,7 @@ static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
262264 return - EIO ;
263265 }
264266 return zfcp_erp_action_enqueue (ZFCP_ERP_ACTION_REOPEN_ADAPTER ,
265- adapter , NULL , NULL , id , ref );
267+ adapter , NULL , NULL , id , ref , 0 );
266268}
267269
268270/**
@@ -285,7 +287,7 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
285287 zfcp_erp_adapter_failed (adapter , "erareo1" , NULL );
286288 else
287289 zfcp_erp_action_enqueue (ZFCP_ERP_ACTION_REOPEN_ADAPTER , adapter ,
288- NULL , NULL , id , ref );
290+ NULL , NULL , id , ref , 0 );
289291 write_unlock_irqrestore (& adapter -> erp_lock , flags );
290292}
291293
@@ -317,20 +319,6 @@ void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, char *id,
317319 zfcp_erp_port_reopen (port , clear | flags , id , ref );
318320}
319321
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-
334322static void zfcp_erp_port_block (struct zfcp_port * port , int clear )
335323{
336324 zfcp_erp_modify_port_status (port , "erpblk1" , NULL ,
@@ -348,7 +336,7 @@ static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port,
348336 return ;
349337
350338 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 );
352340}
353341
354342/**
@@ -381,7 +369,7 @@ static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id,
381369 }
382370
383371 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 );
385373}
386374
387375/**
@@ -412,7 +400,7 @@ static void zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask)
412400}
413401
414402static void _zfcp_erp_unit_reopen (struct zfcp_unit * unit , int clear , char * id ,
415- void * ref )
403+ void * ref , u32 act_status )
416404{
417405 struct zfcp_adapter * adapter = unit -> port -> adapter ;
418406
@@ -422,7 +410,7 @@ static void _zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id,
422410 return ;
423411
424412 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 );
426414}
427415
428416/**
@@ -439,8 +427,45 @@ void zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id,
439427 struct zfcp_adapter * adapter = port -> adapter ;
440428
441429 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 );
443466 write_unlock_irqrestore (& adapter -> erp_lock , flags );
467+
468+ zfcp_erp_wait (adapter );
444469}
445470
446471static 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,
566591
567592 read_lock (& port -> unit_list_lock );
568593 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 );
570595 read_unlock (& port -> unit_list_lock );
571596}
572597
@@ -583,7 +608,7 @@ static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act)
583608 _zfcp_erp_port_reopen (act -> port , 0 , "ersff_3" , NULL );
584609 break ;
585610 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 );
587612 break ;
588613 }
589614}
@@ -1143,7 +1168,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
11431168 if (zfcp_erp_strat_change_det (& unit -> status , erp_status )) {
11441169 _zfcp_erp_unit_reopen (unit ,
11451170 ZFCP_STATUS_COMMON_ERP_FAILED ,
1146- "ersscg3" , NULL );
1171+ "ersscg3" , NULL , 0 );
11471172 return ZFCP_ERP_EXIT ;
11481173 }
11491174 break ;
@@ -1191,7 +1216,8 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
11911216
11921217 switch (act -> action ) {
11931218 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 );
11951221 break ;
11961222
11971223 case ZFCP_ERP_ACTION_REOPEN_PORT :
0 commit comments