1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * zfcp device driver |
4 | * |
5 | * Error Recovery Procedures (ERP). |
6 | * |
7 | * Copyright IBM Corp. 2002, 2020 |
8 | */ |
9 | |
10 | #define KMSG_COMPONENT "zfcp" |
11 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
12 | |
13 | #include <linux/kthread.h> |
14 | #include <linux/bug.h> |
15 | #include "zfcp_ext.h" |
16 | #include "zfcp_reqlist.h" |
17 | #include "zfcp_diag.h" |
18 | |
19 | #define ZFCP_MAX_ERPS 3 |
20 | |
21 | enum zfcp_erp_act_flags { |
22 | ZFCP_STATUS_ERP_TIMEDOUT = 0x10000000, |
23 | ZFCP_STATUS_ERP_CLOSE_ONLY = 0x01000000, |
24 | ZFCP_STATUS_ERP_DISMISSED = 0x00200000, |
25 | ZFCP_STATUS_ERP_LOWMEM = 0x00400000, |
26 | ZFCP_STATUS_ERP_NO_REF = 0x00800000, |
27 | }; |
28 | |
29 | /* |
30 | * Eyecatcher pseudo flag to bitwise or-combine with enum zfcp_erp_act_type. |
31 | * Used to indicate that an ERP action could not be set up despite a detected |
32 | * need for some recovery. |
33 | */ |
34 | #define ZFCP_ERP_ACTION_NONE 0xc0 |
35 | /* |
36 | * Eyecatcher pseudo flag to bitwise or-combine with enum zfcp_erp_act_type. |
37 | * Used to indicate that ERP not needed because the object has |
38 | * ZFCP_STATUS_COMMON_ERP_FAILED. |
39 | */ |
40 | #define ZFCP_ERP_ACTION_FAILED 0xe0 |
41 | |
42 | enum zfcp_erp_act_result { |
43 | ZFCP_ERP_SUCCEEDED = 0, |
44 | ZFCP_ERP_FAILED = 1, |
45 | ZFCP_ERP_CONTINUES = 2, |
46 | ZFCP_ERP_EXIT = 3, |
47 | ZFCP_ERP_DISMISSED = 4, |
48 | ZFCP_ERP_NOMEM = 5, |
49 | }; |
50 | |
51 | static void zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int mask) |
52 | { |
53 | zfcp_erp_clear_adapter_status(adapter, |
54 | ZFCP_STATUS_COMMON_UNBLOCKED | mask); |
55 | } |
56 | |
57 | static bool zfcp_erp_action_is_running(struct zfcp_erp_action *act) |
58 | { |
59 | struct zfcp_erp_action *curr_act; |
60 | |
61 | list_for_each_entry(curr_act, &act->adapter->erp_running_head, list) |
62 | if (act == curr_act) |
63 | return true; |
64 | return false; |
65 | } |
66 | |
67 | static void zfcp_erp_action_ready(struct zfcp_erp_action *act) |
68 | { |
69 | struct zfcp_adapter *adapter = act->adapter; |
70 | |
71 | list_move(list: &act->list, head: &adapter->erp_ready_head); |
72 | zfcp_dbf_rec_run("erardy1" , act); |
73 | wake_up(&adapter->erp_ready_wq); |
74 | zfcp_dbf_rec_run("erardy2" , act); |
75 | } |
76 | |
77 | static void zfcp_erp_action_dismiss(struct zfcp_erp_action *act) |
78 | { |
79 | act->status |= ZFCP_STATUS_ERP_DISMISSED; |
80 | if (zfcp_erp_action_is_running(act)) |
81 | zfcp_erp_action_ready(act); |
82 | } |
83 | |
84 | static void zfcp_erp_action_dismiss_lun(struct scsi_device *sdev) |
85 | { |
86 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
87 | |
88 | if (atomic_read(v: &zfcp_sdev->status) & ZFCP_STATUS_COMMON_ERP_INUSE) |
89 | zfcp_erp_action_dismiss(act: &zfcp_sdev->erp_action); |
90 | } |
91 | |
92 | static void zfcp_erp_action_dismiss_port(struct zfcp_port *port) |
93 | { |
94 | struct scsi_device *sdev; |
95 | |
96 | if (atomic_read(v: &port->status) & ZFCP_STATUS_COMMON_ERP_INUSE) |
97 | zfcp_erp_action_dismiss(act: &port->erp_action); |
98 | else { |
99 | spin_lock(lock: port->adapter->scsi_host->host_lock); |
100 | __shost_for_each_device(sdev, port->adapter->scsi_host) |
101 | if (sdev_to_zfcp(sdev)->port == port) |
102 | zfcp_erp_action_dismiss_lun(sdev); |
103 | spin_unlock(lock: port->adapter->scsi_host->host_lock); |
104 | } |
105 | } |
106 | |
107 | static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) |
108 | { |
109 | struct zfcp_port *port; |
110 | |
111 | if (atomic_read(v: &adapter->status) & ZFCP_STATUS_COMMON_ERP_INUSE) |
112 | zfcp_erp_action_dismiss(act: &adapter->erp_action); |
113 | else { |
114 | read_lock(&adapter->port_list_lock); |
115 | list_for_each_entry(port, &adapter->port_list, list) |
116 | zfcp_erp_action_dismiss_port(port); |
117 | read_unlock(&adapter->port_list_lock); |
118 | } |
119 | } |
120 | |
121 | static enum zfcp_erp_act_type zfcp_erp_handle_failed( |
122 | enum zfcp_erp_act_type want, struct zfcp_adapter *adapter, |
123 | struct zfcp_port *port, struct scsi_device *sdev) |
124 | { |
125 | enum zfcp_erp_act_type need = want; |
126 | struct zfcp_scsi_dev *zsdev; |
127 | |
128 | switch (want) { |
129 | case ZFCP_ERP_ACTION_REOPEN_LUN: |
130 | zsdev = sdev_to_zfcp(sdev); |
131 | if (atomic_read(v: &zsdev->status) & ZFCP_STATUS_COMMON_ERP_FAILED) |
132 | need = 0; |
133 | break; |
134 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
135 | if (atomic_read(v: &port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) |
136 | need = 0; |
137 | break; |
138 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
139 | if (atomic_read(v: &port->status) & |
140 | ZFCP_STATUS_COMMON_ERP_FAILED) { |
141 | need = 0; |
142 | /* ensure propagation of failed status to new devices */ |
143 | zfcp_erp_set_port_status( |
144 | port, ZFCP_STATUS_COMMON_ERP_FAILED); |
145 | } |
146 | break; |
147 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
148 | if (atomic_read(v: &adapter->status) & |
149 | ZFCP_STATUS_COMMON_ERP_FAILED) { |
150 | need = 0; |
151 | /* ensure propagation of failed status to new devices */ |
152 | zfcp_erp_set_adapter_status( |
153 | adapter, ZFCP_STATUS_COMMON_ERP_FAILED); |
154 | } |
155 | break; |
156 | } |
157 | |
158 | return need; |
159 | } |
160 | |
161 | static enum zfcp_erp_act_type zfcp_erp_required_act(enum zfcp_erp_act_type want, |
162 | struct zfcp_adapter *adapter, |
163 | struct zfcp_port *port, |
164 | struct scsi_device *sdev) |
165 | { |
166 | enum zfcp_erp_act_type need = want; |
167 | int l_status, p_status, a_status; |
168 | struct zfcp_scsi_dev *zfcp_sdev; |
169 | |
170 | switch (want) { |
171 | case ZFCP_ERP_ACTION_REOPEN_LUN: |
172 | zfcp_sdev = sdev_to_zfcp(sdev); |
173 | l_status = atomic_read(v: &zfcp_sdev->status); |
174 | if (l_status & ZFCP_STATUS_COMMON_ERP_INUSE) |
175 | return 0; |
176 | p_status = atomic_read(v: &port->status); |
177 | if (!(p_status & ZFCP_STATUS_COMMON_RUNNING) || |
178 | p_status & ZFCP_STATUS_COMMON_ERP_FAILED) |
179 | return 0; |
180 | if (!(p_status & ZFCP_STATUS_COMMON_UNBLOCKED)) |
181 | need = ZFCP_ERP_ACTION_REOPEN_PORT; |
182 | fallthrough; |
183 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
184 | p_status = atomic_read(v: &port->status); |
185 | if (!(p_status & ZFCP_STATUS_COMMON_OPEN)) |
186 | need = ZFCP_ERP_ACTION_REOPEN_PORT; |
187 | fallthrough; |
188 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
189 | p_status = atomic_read(v: &port->status); |
190 | if (p_status & ZFCP_STATUS_COMMON_ERP_INUSE) |
191 | return 0; |
192 | a_status = atomic_read(v: &adapter->status); |
193 | if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) || |
194 | a_status & ZFCP_STATUS_COMMON_ERP_FAILED) |
195 | return 0; |
196 | if (p_status & ZFCP_STATUS_COMMON_NOESC) |
197 | return need; |
198 | if (!(a_status & ZFCP_STATUS_COMMON_UNBLOCKED)) |
199 | need = ZFCP_ERP_ACTION_REOPEN_ADAPTER; |
200 | fallthrough; |
201 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
202 | a_status = atomic_read(v: &adapter->status); |
203 | if (a_status & ZFCP_STATUS_COMMON_ERP_INUSE) |
204 | return 0; |
205 | if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) && |
206 | !(a_status & ZFCP_STATUS_COMMON_OPEN)) |
207 | return 0; /* shutdown requested for closed adapter */ |
208 | } |
209 | |
210 | return need; |
211 | } |
212 | |
213 | static struct zfcp_erp_action *zfcp_erp_setup_act(enum zfcp_erp_act_type need, |
214 | u32 act_status, |
215 | struct zfcp_adapter *adapter, |
216 | struct zfcp_port *port, |
217 | struct scsi_device *sdev) |
218 | { |
219 | struct zfcp_erp_action *erp_action; |
220 | struct zfcp_scsi_dev *zfcp_sdev; |
221 | |
222 | if (WARN_ON_ONCE(need != ZFCP_ERP_ACTION_REOPEN_LUN && |
223 | need != ZFCP_ERP_ACTION_REOPEN_PORT && |
224 | need != ZFCP_ERP_ACTION_REOPEN_PORT_FORCED && |
225 | need != ZFCP_ERP_ACTION_REOPEN_ADAPTER)) |
226 | return NULL; |
227 | |
228 | switch (need) { |
229 | case ZFCP_ERP_ACTION_REOPEN_LUN: |
230 | zfcp_sdev = sdev_to_zfcp(sdev); |
231 | if (!(act_status & ZFCP_STATUS_ERP_NO_REF)) |
232 | if (scsi_device_get(sdev)) |
233 | return NULL; |
234 | atomic_or(ZFCP_STATUS_COMMON_ERP_INUSE, |
235 | v: &zfcp_sdev->status); |
236 | erp_action = &zfcp_sdev->erp_action; |
237 | WARN_ON_ONCE(erp_action->port != port); |
238 | WARN_ON_ONCE(erp_action->sdev != sdev); |
239 | if (!(atomic_read(v: &zfcp_sdev->status) & |
240 | ZFCP_STATUS_COMMON_RUNNING)) |
241 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; |
242 | break; |
243 | |
244 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
245 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
246 | if (!get_device(dev: &port->dev)) |
247 | return NULL; |
248 | zfcp_erp_action_dismiss_port(port); |
249 | atomic_or(ZFCP_STATUS_COMMON_ERP_INUSE, v: &port->status); |
250 | erp_action = &port->erp_action; |
251 | WARN_ON_ONCE(erp_action->port != port); |
252 | WARN_ON_ONCE(erp_action->sdev != NULL); |
253 | if (!(atomic_read(v: &port->status) & ZFCP_STATUS_COMMON_RUNNING)) |
254 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; |
255 | break; |
256 | |
257 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
258 | kref_get(kref: &adapter->ref); |
259 | zfcp_erp_action_dismiss_adapter(adapter); |
260 | atomic_or(ZFCP_STATUS_COMMON_ERP_INUSE, v: &adapter->status); |
261 | erp_action = &adapter->erp_action; |
262 | WARN_ON_ONCE(erp_action->port != NULL); |
263 | WARN_ON_ONCE(erp_action->sdev != NULL); |
264 | if (!(atomic_read(v: &adapter->status) & |
265 | ZFCP_STATUS_COMMON_RUNNING)) |
266 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; |
267 | break; |
268 | } |
269 | |
270 | WARN_ON_ONCE(erp_action->adapter != adapter); |
271 | memset(&erp_action->list, 0, sizeof(erp_action->list)); |
272 | memset(&erp_action->timer, 0, sizeof(erp_action->timer)); |
273 | erp_action->step = ZFCP_ERP_STEP_UNINITIALIZED; |
274 | erp_action->fsf_req_id = 0; |
275 | erp_action->type = need; |
276 | erp_action->status = act_status; |
277 | |
278 | return erp_action; |
279 | } |
280 | |
281 | static void zfcp_erp_action_enqueue(enum zfcp_erp_act_type want, |
282 | struct zfcp_adapter *adapter, |
283 | struct zfcp_port *port, |
284 | struct scsi_device *sdev, |
285 | char *dbftag, u32 act_status) |
286 | { |
287 | enum zfcp_erp_act_type need; |
288 | struct zfcp_erp_action *act; |
289 | |
290 | need = zfcp_erp_handle_failed(want, adapter, port, sdev); |
291 | if (!need) { |
292 | need = ZFCP_ERP_ACTION_FAILED; /* marker for trace */ |
293 | goto out; |
294 | } |
295 | |
296 | if (!adapter->erp_thread) { |
297 | need = ZFCP_ERP_ACTION_NONE; /* marker for trace */ |
298 | goto out; |
299 | } |
300 | |
301 | need = zfcp_erp_required_act(want, adapter, port, sdev); |
302 | if (!need) |
303 | goto out; |
304 | |
305 | act = zfcp_erp_setup_act(need, act_status, adapter, port, sdev); |
306 | if (!act) { |
307 | need |= ZFCP_ERP_ACTION_NONE; /* marker for trace */ |
308 | goto out; |
309 | } |
310 | atomic_or(ZFCP_STATUS_ADAPTER_ERP_PENDING, v: &adapter->status); |
311 | ++adapter->erp_total_count; |
312 | list_add_tail(new: &act->list, head: &adapter->erp_ready_head); |
313 | wake_up(&adapter->erp_ready_wq); |
314 | out: |
315 | zfcp_dbf_rec_trig(dbftag, adapter, port, sdev, want, need); |
316 | } |
317 | |
318 | void zfcp_erp_port_forced_no_port_dbf(char *dbftag, |
319 | struct zfcp_adapter *adapter, |
320 | u64 port_name, u32 port_id) |
321 | { |
322 | unsigned long flags; |
323 | static /* don't waste stack */ struct zfcp_port tmpport; |
324 | |
325 | write_lock_irqsave(&adapter->erp_lock, flags); |
326 | /* Stand-in zfcp port with fields just good enough for |
327 | * zfcp_dbf_rec_trig() and zfcp_dbf_set_common(). |
328 | * Under lock because tmpport is static. |
329 | */ |
330 | atomic_set(v: &tmpport.status, i: -1); /* unknown */ |
331 | tmpport.wwpn = port_name; |
332 | tmpport.d_id = port_id; |
333 | zfcp_dbf_rec_trig(dbftag, adapter, &tmpport, NULL, |
334 | ZFCP_ERP_ACTION_REOPEN_PORT_FORCED, |
335 | ZFCP_ERP_ACTION_NONE); |
336 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
337 | } |
338 | |
339 | static void _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, |
340 | int clear_mask, char *dbftag) |
341 | { |
342 | zfcp_erp_adapter_block(adapter, mask: clear_mask); |
343 | zfcp_scsi_schedule_rports_block(adapter); |
344 | |
345 | zfcp_erp_action_enqueue(want: ZFCP_ERP_ACTION_REOPEN_ADAPTER, |
346 | adapter, NULL, NULL, dbftag, act_status: 0); |
347 | } |
348 | |
349 | /** |
350 | * zfcp_erp_adapter_reopen - Reopen adapter. |
351 | * @adapter: Adapter to reopen. |
352 | * @clear: Status flags to clear. |
353 | * @dbftag: Tag for debug trace event. |
354 | */ |
355 | void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear, |
356 | char *dbftag) |
357 | { |
358 | unsigned long flags; |
359 | |
360 | zfcp_erp_adapter_block(adapter, mask: clear); |
361 | zfcp_scsi_schedule_rports_block(adapter); |
362 | |
363 | write_lock_irqsave(&adapter->erp_lock, flags); |
364 | zfcp_erp_action_enqueue(want: ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter, |
365 | NULL, NULL, dbftag, act_status: 0); |
366 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
367 | } |
368 | |
369 | /** |
370 | * zfcp_erp_adapter_shutdown - Shutdown adapter. |
371 | * @adapter: Adapter to shut down. |
372 | * @clear: Status flags to clear. |
373 | * @dbftag: Tag for debug trace event. |
374 | */ |
375 | void zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear, |
376 | char *dbftag) |
377 | { |
378 | int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; |
379 | zfcp_erp_adapter_reopen(adapter, clear: clear | flags, dbftag); |
380 | } |
381 | |
382 | /** |
383 | * zfcp_erp_port_shutdown - Shutdown port |
384 | * @port: Port to shut down. |
385 | * @clear: Status flags to clear. |
386 | * @dbftag: Tag for debug trace event. |
387 | */ |
388 | void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, char *dbftag) |
389 | { |
390 | int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; |
391 | zfcp_erp_port_reopen(port, clear: clear | flags, dbftag); |
392 | } |
393 | |
394 | static void zfcp_erp_port_block(struct zfcp_port *port, int clear) |
395 | { |
396 | zfcp_erp_clear_port_status(port, |
397 | ZFCP_STATUS_COMMON_UNBLOCKED | clear); |
398 | } |
399 | |
400 | static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, |
401 | char *dbftag) |
402 | { |
403 | zfcp_erp_port_block(port, clear); |
404 | zfcp_scsi_schedule_rport_block(port); |
405 | |
406 | zfcp_erp_action_enqueue(want: ZFCP_ERP_ACTION_REOPEN_PORT_FORCED, |
407 | adapter: port->adapter, port, NULL, dbftag, act_status: 0); |
408 | } |
409 | |
410 | /** |
411 | * zfcp_erp_port_forced_reopen - Forced close of port and open again |
412 | * @port: Port to force close and to reopen. |
413 | * @clear: Status flags to clear. |
414 | * @dbftag: Tag for debug trace event. |
415 | */ |
416 | void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, |
417 | char *dbftag) |
418 | { |
419 | unsigned long flags; |
420 | struct zfcp_adapter *adapter = port->adapter; |
421 | |
422 | write_lock_irqsave(&adapter->erp_lock, flags); |
423 | _zfcp_erp_port_forced_reopen(port, clear, dbftag); |
424 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
425 | } |
426 | |
427 | static void _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, |
428 | char *dbftag) |
429 | { |
430 | zfcp_erp_port_block(port, clear); |
431 | zfcp_scsi_schedule_rport_block(port); |
432 | |
433 | zfcp_erp_action_enqueue(want: ZFCP_ERP_ACTION_REOPEN_PORT, |
434 | adapter: port->adapter, port, NULL, dbftag, act_status: 0); |
435 | } |
436 | |
437 | /** |
438 | * zfcp_erp_port_reopen - trigger remote port recovery |
439 | * @port: port to recover |
440 | * @clear: flags in port status to be cleared |
441 | * @dbftag: Tag for debug trace event. |
442 | */ |
443 | void zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *dbftag) |
444 | { |
445 | unsigned long flags; |
446 | struct zfcp_adapter *adapter = port->adapter; |
447 | |
448 | write_lock_irqsave(&adapter->erp_lock, flags); |
449 | _zfcp_erp_port_reopen(port, clear, dbftag); |
450 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
451 | } |
452 | |
453 | static void zfcp_erp_lun_block(struct scsi_device *sdev, int clear_mask) |
454 | { |
455 | zfcp_erp_clear_lun_status(sdev, |
456 | ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask); |
457 | } |
458 | |
459 | static void _zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, |
460 | char *dbftag, u32 act_status) |
461 | { |
462 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
463 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; |
464 | |
465 | zfcp_erp_lun_block(sdev, clear_mask: clear); |
466 | |
467 | zfcp_erp_action_enqueue(want: ZFCP_ERP_ACTION_REOPEN_LUN, adapter, |
468 | port: zfcp_sdev->port, sdev, dbftag, act_status); |
469 | } |
470 | |
471 | /** |
472 | * zfcp_erp_lun_reopen - initiate reopen of a LUN |
473 | * @sdev: SCSI device / LUN to be reopened |
474 | * @clear: specifies flags in LUN status to be cleared |
475 | * @dbftag: Tag for debug trace event. |
476 | * |
477 | * Return: 0 on success, < 0 on error |
478 | */ |
479 | void zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *dbftag) |
480 | { |
481 | unsigned long flags; |
482 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
483 | struct zfcp_port *port = zfcp_sdev->port; |
484 | struct zfcp_adapter *adapter = port->adapter; |
485 | |
486 | write_lock_irqsave(&adapter->erp_lock, flags); |
487 | _zfcp_erp_lun_reopen(sdev, clear, dbftag, act_status: 0); |
488 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
489 | } |
490 | |
491 | /** |
492 | * zfcp_erp_lun_shutdown - Shutdown LUN |
493 | * @sdev: SCSI device / LUN to shut down. |
494 | * @clear: Status flags to clear. |
495 | * @dbftag: Tag for debug trace event. |
496 | */ |
497 | void zfcp_erp_lun_shutdown(struct scsi_device *sdev, int clear, char *dbftag) |
498 | { |
499 | int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; |
500 | zfcp_erp_lun_reopen(sdev, clear: clear | flags, dbftag); |
501 | } |
502 | |
503 | /** |
504 | * zfcp_erp_lun_shutdown_wait - Shutdown LUN and wait for erp completion |
505 | * @sdev: SCSI device / LUN to shut down. |
506 | * @dbftag: Tag for debug trace event. |
507 | * |
508 | * Do not acquire a reference for the LUN when creating the ERP |
509 | * action. It is safe, because this function waits for the ERP to |
510 | * complete first. This allows to shutdown the LUN, even when the SCSI |
511 | * device is in the state SDEV_DEL when scsi_device_get will fail. |
512 | */ |
513 | void zfcp_erp_lun_shutdown_wait(struct scsi_device *sdev, char *dbftag) |
514 | { |
515 | unsigned long flags; |
516 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
517 | struct zfcp_port *port = zfcp_sdev->port; |
518 | struct zfcp_adapter *adapter = port->adapter; |
519 | int clear = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; |
520 | |
521 | write_lock_irqsave(&adapter->erp_lock, flags); |
522 | _zfcp_erp_lun_reopen(sdev, clear, dbftag, act_status: ZFCP_STATUS_ERP_NO_REF); |
523 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
524 | |
525 | zfcp_erp_wait(adapter); |
526 | } |
527 | |
528 | static int zfcp_erp_status_change_set(unsigned long mask, atomic_t *status) |
529 | { |
530 | return (atomic_read(v: status) ^ mask) & mask; |
531 | } |
532 | |
533 | static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter) |
534 | { |
535 | if (zfcp_erp_status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, |
536 | status: &adapter->status)) |
537 | zfcp_dbf_rec_run("eraubl1" , &adapter->erp_action); |
538 | atomic_or(ZFCP_STATUS_COMMON_UNBLOCKED, v: &adapter->status); |
539 | } |
540 | |
541 | static void zfcp_erp_port_unblock(struct zfcp_port *port) |
542 | { |
543 | if (zfcp_erp_status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, |
544 | status: &port->status)) |
545 | zfcp_dbf_rec_run("erpubl1" , &port->erp_action); |
546 | atomic_or(ZFCP_STATUS_COMMON_UNBLOCKED, v: &port->status); |
547 | } |
548 | |
549 | static void zfcp_erp_lun_unblock(struct scsi_device *sdev) |
550 | { |
551 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
552 | |
553 | if (zfcp_erp_status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, |
554 | status: &zfcp_sdev->status)) |
555 | zfcp_dbf_rec_run("erlubl1" , &sdev_to_zfcp(sdev)->erp_action); |
556 | atomic_or(ZFCP_STATUS_COMMON_UNBLOCKED, v: &zfcp_sdev->status); |
557 | } |
558 | |
559 | static void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action) |
560 | { |
561 | list_move(list: &erp_action->list, head: &erp_action->adapter->erp_running_head); |
562 | zfcp_dbf_rec_run("erator1" , erp_action); |
563 | } |
564 | |
565 | static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act) |
566 | { |
567 | struct zfcp_adapter *adapter = act->adapter; |
568 | struct zfcp_fsf_req *req; |
569 | |
570 | if (!act->fsf_req_id) |
571 | return; |
572 | |
573 | spin_lock(lock: &adapter->req_list->lock); |
574 | req = _zfcp_reqlist_find(rl: adapter->req_list, req_id: act->fsf_req_id); |
575 | if (req && req->erp_action == act) { |
576 | if (act->status & (ZFCP_STATUS_ERP_DISMISSED | |
577 | ZFCP_STATUS_ERP_TIMEDOUT)) { |
578 | req->status |= ZFCP_STATUS_FSFREQ_DISMISSED; |
579 | zfcp_dbf_rec_run("erscf_1" , act); |
580 | /* lock-free concurrent access with |
581 | * zfcp_erp_timeout_handler() |
582 | */ |
583 | WRITE_ONCE(req->erp_action, NULL); |
584 | } |
585 | if (act->status & ZFCP_STATUS_ERP_TIMEDOUT) |
586 | zfcp_dbf_rec_run("erscf_2" , act); |
587 | if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) |
588 | act->fsf_req_id = 0; |
589 | } else |
590 | act->fsf_req_id = 0; |
591 | spin_unlock(lock: &adapter->req_list->lock); |
592 | } |
593 | |
594 | /** |
595 | * zfcp_erp_notify - Trigger ERP action. |
596 | * @erp_action: ERP action to continue. |
597 | * @set_mask: ERP action status flags to set. |
598 | */ |
599 | void zfcp_erp_notify(struct zfcp_erp_action *erp_action, unsigned long set_mask) |
600 | { |
601 | struct zfcp_adapter *adapter = erp_action->adapter; |
602 | unsigned long flags; |
603 | |
604 | write_lock_irqsave(&adapter->erp_lock, flags); |
605 | if (zfcp_erp_action_is_running(act: erp_action)) { |
606 | erp_action->status |= set_mask; |
607 | zfcp_erp_action_ready(act: erp_action); |
608 | } |
609 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
610 | } |
611 | |
612 | /** |
613 | * zfcp_erp_timeout_handler - Trigger ERP action from timed out ERP request |
614 | * @t: timer list entry embedded in zfcp FSF request |
615 | */ |
616 | void zfcp_erp_timeout_handler(struct timer_list *t) |
617 | { |
618 | struct zfcp_fsf_req *fsf_req = from_timer(fsf_req, t, timer); |
619 | struct zfcp_erp_action *act; |
620 | |
621 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) |
622 | return; |
623 | /* lock-free concurrent access with zfcp_erp_strategy_check_fsfreq() */ |
624 | act = READ_ONCE(fsf_req->erp_action); |
625 | if (!act) |
626 | return; |
627 | zfcp_erp_notify(erp_action: act, set_mask: ZFCP_STATUS_ERP_TIMEDOUT); |
628 | } |
629 | |
630 | static void zfcp_erp_memwait_handler(struct timer_list *t) |
631 | { |
632 | struct zfcp_erp_action *act = from_timer(act, t, timer); |
633 | |
634 | zfcp_erp_notify(erp_action: act, set_mask: 0); |
635 | } |
636 | |
637 | static void zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action) |
638 | { |
639 | timer_setup(&erp_action->timer, zfcp_erp_memwait_handler, 0); |
640 | erp_action->timer.expires = jiffies + HZ; |
641 | add_timer(timer: &erp_action->timer); |
642 | } |
643 | |
644 | void zfcp_erp_port_forced_reopen_all(struct zfcp_adapter *adapter, |
645 | int clear, char *dbftag) |
646 | { |
647 | unsigned long flags; |
648 | struct zfcp_port *port; |
649 | |
650 | write_lock_irqsave(&adapter->erp_lock, flags); |
651 | read_lock(&adapter->port_list_lock); |
652 | list_for_each_entry(port, &adapter->port_list, list) |
653 | _zfcp_erp_port_forced_reopen(port, clear, dbftag); |
654 | read_unlock(&adapter->port_list_lock); |
655 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
656 | } |
657 | |
658 | static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, |
659 | int clear, char *dbftag) |
660 | { |
661 | struct zfcp_port *port; |
662 | |
663 | read_lock(&adapter->port_list_lock); |
664 | list_for_each_entry(port, &adapter->port_list, list) |
665 | _zfcp_erp_port_reopen(port, clear, dbftag); |
666 | read_unlock(&adapter->port_list_lock); |
667 | } |
668 | |
669 | static void _zfcp_erp_lun_reopen_all(struct zfcp_port *port, int clear, |
670 | char *dbftag) |
671 | { |
672 | struct scsi_device *sdev; |
673 | |
674 | spin_lock(lock: port->adapter->scsi_host->host_lock); |
675 | __shost_for_each_device(sdev, port->adapter->scsi_host) |
676 | if (sdev_to_zfcp(sdev)->port == port) |
677 | _zfcp_erp_lun_reopen(sdev, clear, dbftag, act_status: 0); |
678 | spin_unlock(lock: port->adapter->scsi_host->host_lock); |
679 | } |
680 | |
681 | static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act) |
682 | { |
683 | switch (act->type) { |
684 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
685 | _zfcp_erp_adapter_reopen(adapter: act->adapter, clear_mask: 0, dbftag: "ersff_1" ); |
686 | break; |
687 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
688 | _zfcp_erp_port_forced_reopen(port: act->port, clear: 0, dbftag: "ersff_2" ); |
689 | break; |
690 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
691 | _zfcp_erp_port_reopen(port: act->port, clear: 0, dbftag: "ersff_3" ); |
692 | break; |
693 | case ZFCP_ERP_ACTION_REOPEN_LUN: |
694 | _zfcp_erp_lun_reopen(sdev: act->sdev, clear: 0, dbftag: "ersff_4" , act_status: 0); |
695 | break; |
696 | } |
697 | } |
698 | |
699 | static void zfcp_erp_strategy_followup_success(struct zfcp_erp_action *act) |
700 | { |
701 | switch (act->type) { |
702 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
703 | _zfcp_erp_port_reopen_all(adapter: act->adapter, clear: 0, dbftag: "ersfs_1" ); |
704 | break; |
705 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
706 | _zfcp_erp_port_reopen(port: act->port, clear: 0, dbftag: "ersfs_2" ); |
707 | break; |
708 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
709 | _zfcp_erp_lun_reopen_all(port: act->port, clear: 0, dbftag: "ersfs_3" ); |
710 | break; |
711 | case ZFCP_ERP_ACTION_REOPEN_LUN: |
712 | /* NOP */ |
713 | break; |
714 | } |
715 | } |
716 | |
717 | static void zfcp_erp_wakeup(struct zfcp_adapter *adapter) |
718 | { |
719 | unsigned long flags; |
720 | |
721 | read_lock_irqsave(&adapter->erp_lock, flags); |
722 | if (list_empty(head: &adapter->erp_ready_head) && |
723 | list_empty(head: &adapter->erp_running_head)) { |
724 | atomic_andnot(ZFCP_STATUS_ADAPTER_ERP_PENDING, |
725 | v: &adapter->status); |
726 | wake_up(&adapter->erp_done_wqh); |
727 | } |
728 | read_unlock_irqrestore(&adapter->erp_lock, flags); |
729 | } |
730 | |
731 | static void zfcp_erp_enqueue_ptp_port(struct zfcp_adapter *adapter) |
732 | { |
733 | struct zfcp_port *port; |
734 | port = zfcp_port_enqueue(adapter, adapter->peer_wwpn, 0, |
735 | adapter->peer_d_id); |
736 | if (IS_ERR(ptr: port)) /* error or port already attached */ |
737 | return; |
738 | zfcp_erp_port_reopen(port, clear: 0, dbftag: "ereptp1" ); |
739 | } |
740 | |
741 | static enum zfcp_erp_act_result zfcp_erp_adapter_strat_fsf_xconf( |
742 | struct zfcp_erp_action *erp_action) |
743 | { |
744 | int retries; |
745 | int sleep = 1; |
746 | struct zfcp_adapter *adapter = erp_action->adapter; |
747 | |
748 | atomic_andnot(ZFCP_STATUS_ADAPTER_XCONFIG_OK, v: &adapter->status); |
749 | |
750 | for (retries = 7; retries; retries--) { |
751 | atomic_andnot(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, |
752 | v: &adapter->status); |
753 | write_lock_irq(&adapter->erp_lock); |
754 | zfcp_erp_action_to_running(erp_action); |
755 | write_unlock_irq(&adapter->erp_lock); |
756 | if (zfcp_fsf_exchange_config_data(erp_action)) { |
757 | atomic_andnot(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, |
758 | v: &adapter->status); |
759 | return ZFCP_ERP_FAILED; |
760 | } |
761 | |
762 | wait_event(adapter->erp_ready_wq, |
763 | !list_empty(&adapter->erp_ready_head)); |
764 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) |
765 | break; |
766 | |
767 | if (!(atomic_read(v: &adapter->status) & |
768 | ZFCP_STATUS_ADAPTER_HOST_CON_INIT)) |
769 | break; |
770 | |
771 | ssleep(seconds: sleep); |
772 | sleep *= 2; |
773 | } |
774 | |
775 | atomic_andnot(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, |
776 | v: &adapter->status); |
777 | |
778 | if (!(atomic_read(v: &adapter->status) & ZFCP_STATUS_ADAPTER_XCONFIG_OK)) |
779 | return ZFCP_ERP_FAILED; |
780 | |
781 | return ZFCP_ERP_SUCCEEDED; |
782 | } |
783 | |
784 | static void |
785 | zfcp_erp_adapter_strategy_open_ptp_port(struct zfcp_adapter *const adapter) |
786 | { |
787 | if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) |
788 | zfcp_erp_enqueue_ptp_port(adapter); |
789 | } |
790 | |
791 | static enum zfcp_erp_act_result zfcp_erp_adapter_strategy_open_fsf_xport( |
792 | struct zfcp_erp_action *act) |
793 | { |
794 | int ret; |
795 | struct zfcp_adapter *adapter = act->adapter; |
796 | |
797 | write_lock_irq(&adapter->erp_lock); |
798 | zfcp_erp_action_to_running(erp_action: act); |
799 | write_unlock_irq(&adapter->erp_lock); |
800 | |
801 | ret = zfcp_fsf_exchange_port_data(act); |
802 | if (ret == -EOPNOTSUPP) |
803 | return ZFCP_ERP_SUCCEEDED; |
804 | if (ret) |
805 | return ZFCP_ERP_FAILED; |
806 | |
807 | zfcp_dbf_rec_run("erasox1" , act); |
808 | wait_event(adapter->erp_ready_wq, |
809 | !list_empty(&adapter->erp_ready_head)); |
810 | zfcp_dbf_rec_run("erasox2" , act); |
811 | if (act->status & ZFCP_STATUS_ERP_TIMEDOUT) |
812 | return ZFCP_ERP_FAILED; |
813 | |
814 | return ZFCP_ERP_SUCCEEDED; |
815 | } |
816 | |
817 | static enum zfcp_erp_act_result |
818 | zfcp_erp_adapter_strategy_alloc_shost(struct zfcp_adapter *const adapter) |
819 | { |
820 | struct zfcp_diag_adapter_config_data *const config_data = |
821 | &adapter->diagnostics->config_data; |
822 | struct zfcp_diag_adapter_port_data *const port_data = |
823 | &adapter->diagnostics->port_data; |
824 | unsigned long flags; |
825 | int rc; |
826 | |
827 | rc = zfcp_scsi_adapter_register(adapter); |
828 | if (rc == -EEXIST) |
829 | return ZFCP_ERP_SUCCEEDED; |
830 | else if (rc) |
831 | return ZFCP_ERP_FAILED; |
832 | |
833 | /* |
834 | * We allocated the shost for the first time. Before it was NULL, |
835 | * and so we deferred all updates in the xconf- and xport-data |
836 | * handlers. We need to make up for that now, and make all the updates |
837 | * that would have been done before. |
838 | * |
839 | * We can be sure that xconf- and xport-data succeeded, because |
840 | * otherwise this function is not called. But they might have been |
841 | * incomplete. |
842 | */ |
843 | |
844 | spin_lock_irqsave(&config_data->header.access_lock, flags); |
845 | zfcp_scsi_shost_update_config_data(adapter, bottom: &config_data->data, |
846 | bottom_incomplete: !!config_data->header.incomplete); |
847 | spin_unlock_irqrestore(lock: &config_data->header.access_lock, flags); |
848 | |
849 | if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) { |
850 | spin_lock_irqsave(&port_data->header.access_lock, flags); |
851 | zfcp_scsi_shost_update_port_data(adapter, bottom: &port_data->data); |
852 | spin_unlock_irqrestore(lock: &port_data->header.access_lock, flags); |
853 | } |
854 | |
855 | /* |
856 | * There is a remote possibility that the 'Exchange Port Data' request |
857 | * reports a different connectivity status than 'Exchange Config Data'. |
858 | * But any change to the connectivity status of the local optic that |
859 | * happens after the initial xconf request is expected to be reported |
860 | * to us, as soon as we post Status Read Buffers to the FCP channel |
861 | * firmware after this function. So any resulting inconsistency will |
862 | * only be momentary. |
863 | */ |
864 | if (config_data->header.incomplete) |
865 | zfcp_fsf_fc_host_link_down(adapter); |
866 | |
867 | return ZFCP_ERP_SUCCEEDED; |
868 | } |
869 | |
870 | static enum zfcp_erp_act_result zfcp_erp_adapter_strategy_open_fsf( |
871 | struct zfcp_erp_action *act) |
872 | { |
873 | if (zfcp_erp_adapter_strat_fsf_xconf(erp_action: act) == ZFCP_ERP_FAILED) |
874 | return ZFCP_ERP_FAILED; |
875 | |
876 | if (zfcp_erp_adapter_strategy_open_fsf_xport(act) == ZFCP_ERP_FAILED) |
877 | return ZFCP_ERP_FAILED; |
878 | |
879 | if (zfcp_erp_adapter_strategy_alloc_shost(adapter: act->adapter) == |
880 | ZFCP_ERP_FAILED) |
881 | return ZFCP_ERP_FAILED; |
882 | |
883 | zfcp_erp_adapter_strategy_open_ptp_port(adapter: act->adapter); |
884 | |
885 | if (mempool_resize(pool: act->adapter->pool.sr_data, |
886 | new_min_nr: act->adapter->stat_read_buf_num)) |
887 | return ZFCP_ERP_FAILED; |
888 | |
889 | if (mempool_resize(pool: act->adapter->pool.status_read_req, |
890 | new_min_nr: act->adapter->stat_read_buf_num)) |
891 | return ZFCP_ERP_FAILED; |
892 | |
893 | atomic_set(v: &act->adapter->stat_miss, i: act->adapter->stat_read_buf_num); |
894 | if (zfcp_status_read_refill(adapter: act->adapter)) |
895 | return ZFCP_ERP_FAILED; |
896 | |
897 | return ZFCP_ERP_SUCCEEDED; |
898 | } |
899 | |
900 | static void zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *act) |
901 | { |
902 | struct zfcp_adapter *adapter = act->adapter; |
903 | |
904 | /* close queues to ensure that buffers are not accessed by adapter */ |
905 | zfcp_qdio_close(adapter->qdio); |
906 | zfcp_fsf_req_dismiss_all(adapter); |
907 | adapter->fsf_req_seq_no = 0; |
908 | zfcp_fc_wka_ports_force_offline(adapter->gs); |
909 | /* all ports and LUNs are closed */ |
910 | zfcp_erp_clear_adapter_status(adapter, ZFCP_STATUS_COMMON_OPEN); |
911 | |
912 | atomic_andnot(ZFCP_STATUS_ADAPTER_XCONFIG_OK | |
913 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, v: &adapter->status); |
914 | } |
915 | |
916 | static enum zfcp_erp_act_result zfcp_erp_adapter_strategy_open( |
917 | struct zfcp_erp_action *act) |
918 | { |
919 | struct zfcp_adapter *adapter = act->adapter; |
920 | |
921 | if (zfcp_qdio_open(adapter->qdio)) { |
922 | atomic_andnot(ZFCP_STATUS_ADAPTER_XCONFIG_OK | |
923 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, |
924 | v: &adapter->status); |
925 | return ZFCP_ERP_FAILED; |
926 | } |
927 | |
928 | if (zfcp_erp_adapter_strategy_open_fsf(act)) { |
929 | zfcp_erp_adapter_strategy_close(act); |
930 | return ZFCP_ERP_FAILED; |
931 | } |
932 | |
933 | atomic_or(ZFCP_STATUS_COMMON_OPEN, v: &adapter->status); |
934 | |
935 | return ZFCP_ERP_SUCCEEDED; |
936 | } |
937 | |
938 | static enum zfcp_erp_act_result zfcp_erp_adapter_strategy( |
939 | struct zfcp_erp_action *act) |
940 | { |
941 | struct zfcp_adapter *adapter = act->adapter; |
942 | |
943 | if (atomic_read(v: &adapter->status) & ZFCP_STATUS_COMMON_OPEN) { |
944 | zfcp_erp_adapter_strategy_close(act); |
945 | if (act->status & ZFCP_STATUS_ERP_CLOSE_ONLY) |
946 | return ZFCP_ERP_EXIT; |
947 | } |
948 | |
949 | if (zfcp_erp_adapter_strategy_open(act)) { |
950 | ssleep(seconds: 8); |
951 | return ZFCP_ERP_FAILED; |
952 | } |
953 | |
954 | return ZFCP_ERP_SUCCEEDED; |
955 | } |
956 | |
957 | static enum zfcp_erp_act_result zfcp_erp_port_forced_strategy_close( |
958 | struct zfcp_erp_action *act) |
959 | { |
960 | int retval; |
961 | |
962 | retval = zfcp_fsf_close_physical_port(act); |
963 | if (retval == -ENOMEM) |
964 | return ZFCP_ERP_NOMEM; |
965 | act->step = ZFCP_ERP_STEP_PHYS_PORT_CLOSING; |
966 | if (retval) |
967 | return ZFCP_ERP_FAILED; |
968 | |
969 | return ZFCP_ERP_CONTINUES; |
970 | } |
971 | |
972 | static enum zfcp_erp_act_result zfcp_erp_port_forced_strategy( |
973 | struct zfcp_erp_action *erp_action) |
974 | { |
975 | struct zfcp_port *port = erp_action->port; |
976 | int status = atomic_read(v: &port->status); |
977 | |
978 | switch (erp_action->step) { |
979 | case ZFCP_ERP_STEP_UNINITIALIZED: |
980 | if ((status & ZFCP_STATUS_PORT_PHYS_OPEN) && |
981 | (status & ZFCP_STATUS_COMMON_OPEN)) |
982 | return zfcp_erp_port_forced_strategy_close(act: erp_action); |
983 | else |
984 | return ZFCP_ERP_FAILED; |
985 | |
986 | case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: |
987 | if (!(status & ZFCP_STATUS_PORT_PHYS_OPEN)) |
988 | return ZFCP_ERP_SUCCEEDED; |
989 | break; |
990 | case ZFCP_ERP_STEP_PORT_CLOSING: |
991 | case ZFCP_ERP_STEP_PORT_OPENING: |
992 | case ZFCP_ERP_STEP_LUN_CLOSING: |
993 | case ZFCP_ERP_STEP_LUN_OPENING: |
994 | /* NOP */ |
995 | break; |
996 | } |
997 | return ZFCP_ERP_FAILED; |
998 | } |
999 | |
1000 | static enum zfcp_erp_act_result zfcp_erp_port_strategy_close( |
1001 | struct zfcp_erp_action *erp_action) |
1002 | { |
1003 | int retval; |
1004 | |
1005 | retval = zfcp_fsf_close_port(erp_action); |
1006 | if (retval == -ENOMEM) |
1007 | return ZFCP_ERP_NOMEM; |
1008 | erp_action->step = ZFCP_ERP_STEP_PORT_CLOSING; |
1009 | if (retval) |
1010 | return ZFCP_ERP_FAILED; |
1011 | return ZFCP_ERP_CONTINUES; |
1012 | } |
1013 | |
1014 | static enum zfcp_erp_act_result zfcp_erp_port_strategy_open_port( |
1015 | struct zfcp_erp_action *erp_action) |
1016 | { |
1017 | int retval; |
1018 | |
1019 | retval = zfcp_fsf_open_port(erp_action); |
1020 | if (retval == -ENOMEM) |
1021 | return ZFCP_ERP_NOMEM; |
1022 | erp_action->step = ZFCP_ERP_STEP_PORT_OPENING; |
1023 | if (retval) |
1024 | return ZFCP_ERP_FAILED; |
1025 | return ZFCP_ERP_CONTINUES; |
1026 | } |
1027 | |
1028 | static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act) |
1029 | { |
1030 | struct zfcp_adapter *adapter = act->adapter; |
1031 | struct zfcp_port *port = act->port; |
1032 | |
1033 | if (port->wwpn != adapter->peer_wwpn) { |
1034 | zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_ERP_FAILED); |
1035 | return ZFCP_ERP_FAILED; |
1036 | } |
1037 | port->d_id = adapter->peer_d_id; |
1038 | return zfcp_erp_port_strategy_open_port(erp_action: act); |
1039 | } |
1040 | |
1041 | static enum zfcp_erp_act_result zfcp_erp_port_strategy_open_common( |
1042 | struct zfcp_erp_action *act) |
1043 | { |
1044 | struct zfcp_adapter *adapter = act->adapter; |
1045 | struct zfcp_port *port = act->port; |
1046 | int p_status = atomic_read(v: &port->status); |
1047 | |
1048 | switch (act->step) { |
1049 | case ZFCP_ERP_STEP_UNINITIALIZED: |
1050 | case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: |
1051 | case ZFCP_ERP_STEP_PORT_CLOSING: |
1052 | if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) |
1053 | return zfcp_erp_open_ptp_port(act); |
1054 | if (!port->d_id) { |
1055 | zfcp_fc_trigger_did_lookup(port); |
1056 | return ZFCP_ERP_EXIT; |
1057 | } |
1058 | return zfcp_erp_port_strategy_open_port(erp_action: act); |
1059 | |
1060 | case ZFCP_ERP_STEP_PORT_OPENING: |
1061 | /* D_ID might have changed during open */ |
1062 | if (p_status & ZFCP_STATUS_COMMON_OPEN) { |
1063 | if (!port->d_id) { |
1064 | zfcp_fc_trigger_did_lookup(port); |
1065 | return ZFCP_ERP_EXIT; |
1066 | } |
1067 | return ZFCP_ERP_SUCCEEDED; |
1068 | } |
1069 | if (port->d_id && !(p_status & ZFCP_STATUS_COMMON_NOESC)) { |
1070 | port->d_id = 0; |
1071 | return ZFCP_ERP_FAILED; |
1072 | } |
1073 | /* no early return otherwise, continue after switch case */ |
1074 | break; |
1075 | case ZFCP_ERP_STEP_LUN_CLOSING: |
1076 | case ZFCP_ERP_STEP_LUN_OPENING: |
1077 | /* NOP */ |
1078 | break; |
1079 | } |
1080 | return ZFCP_ERP_FAILED; |
1081 | } |
1082 | |
1083 | static enum zfcp_erp_act_result zfcp_erp_port_strategy( |
1084 | struct zfcp_erp_action *erp_action) |
1085 | { |
1086 | struct zfcp_port *port = erp_action->port; |
1087 | int p_status = atomic_read(v: &port->status); |
1088 | |
1089 | if ((p_status & ZFCP_STATUS_COMMON_NOESC) && |
1090 | !(p_status & ZFCP_STATUS_COMMON_OPEN)) |
1091 | goto close_init_done; |
1092 | |
1093 | switch (erp_action->step) { |
1094 | case ZFCP_ERP_STEP_UNINITIALIZED: |
1095 | if (p_status & ZFCP_STATUS_COMMON_OPEN) |
1096 | return zfcp_erp_port_strategy_close(erp_action); |
1097 | break; |
1098 | |
1099 | case ZFCP_ERP_STEP_PORT_CLOSING: |
1100 | if (p_status & ZFCP_STATUS_COMMON_OPEN) |
1101 | return ZFCP_ERP_FAILED; |
1102 | break; |
1103 | case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: |
1104 | case ZFCP_ERP_STEP_PORT_OPENING: |
1105 | case ZFCP_ERP_STEP_LUN_CLOSING: |
1106 | case ZFCP_ERP_STEP_LUN_OPENING: |
1107 | /* NOP */ |
1108 | break; |
1109 | } |
1110 | |
1111 | close_init_done: |
1112 | if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY) |
1113 | return ZFCP_ERP_EXIT; |
1114 | |
1115 | return zfcp_erp_port_strategy_open_common(act: erp_action); |
1116 | } |
1117 | |
1118 | static void zfcp_erp_lun_strategy_clearstati(struct scsi_device *sdev) |
1119 | { |
1120 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
1121 | |
1122 | atomic_andnot(ZFCP_STATUS_COMMON_ACCESS_DENIED, |
1123 | v: &zfcp_sdev->status); |
1124 | } |
1125 | |
1126 | static enum zfcp_erp_act_result zfcp_erp_lun_strategy_close( |
1127 | struct zfcp_erp_action *erp_action) |
1128 | { |
1129 | int retval = zfcp_fsf_close_lun(erp_action); |
1130 | if (retval == -ENOMEM) |
1131 | return ZFCP_ERP_NOMEM; |
1132 | erp_action->step = ZFCP_ERP_STEP_LUN_CLOSING; |
1133 | if (retval) |
1134 | return ZFCP_ERP_FAILED; |
1135 | return ZFCP_ERP_CONTINUES; |
1136 | } |
1137 | |
1138 | static enum zfcp_erp_act_result zfcp_erp_lun_strategy_open( |
1139 | struct zfcp_erp_action *erp_action) |
1140 | { |
1141 | int retval = zfcp_fsf_open_lun(erp_action); |
1142 | if (retval == -ENOMEM) |
1143 | return ZFCP_ERP_NOMEM; |
1144 | erp_action->step = ZFCP_ERP_STEP_LUN_OPENING; |
1145 | if (retval) |
1146 | return ZFCP_ERP_FAILED; |
1147 | return ZFCP_ERP_CONTINUES; |
1148 | } |
1149 | |
1150 | static enum zfcp_erp_act_result zfcp_erp_lun_strategy( |
1151 | struct zfcp_erp_action *erp_action) |
1152 | { |
1153 | struct scsi_device *sdev = erp_action->sdev; |
1154 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
1155 | |
1156 | switch (erp_action->step) { |
1157 | case ZFCP_ERP_STEP_UNINITIALIZED: |
1158 | zfcp_erp_lun_strategy_clearstati(sdev); |
1159 | if (atomic_read(v: &zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN) |
1160 | return zfcp_erp_lun_strategy_close(erp_action); |
1161 | /* already closed */ |
1162 | fallthrough; |
1163 | case ZFCP_ERP_STEP_LUN_CLOSING: |
1164 | if (atomic_read(v: &zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN) |
1165 | return ZFCP_ERP_FAILED; |
1166 | if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY) |
1167 | return ZFCP_ERP_EXIT; |
1168 | return zfcp_erp_lun_strategy_open(erp_action); |
1169 | |
1170 | case ZFCP_ERP_STEP_LUN_OPENING: |
1171 | if (atomic_read(v: &zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN) |
1172 | return ZFCP_ERP_SUCCEEDED; |
1173 | break; |
1174 | case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: |
1175 | case ZFCP_ERP_STEP_PORT_CLOSING: |
1176 | case ZFCP_ERP_STEP_PORT_OPENING: |
1177 | /* NOP */ |
1178 | break; |
1179 | } |
1180 | return ZFCP_ERP_FAILED; |
1181 | } |
1182 | |
1183 | static enum zfcp_erp_act_result zfcp_erp_strategy_check_lun( |
1184 | struct scsi_device *sdev, enum zfcp_erp_act_result result) |
1185 | { |
1186 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
1187 | |
1188 | switch (result) { |
1189 | case ZFCP_ERP_SUCCEEDED : |
1190 | atomic_set(v: &zfcp_sdev->erp_counter, i: 0); |
1191 | zfcp_erp_lun_unblock(sdev); |
1192 | break; |
1193 | case ZFCP_ERP_FAILED : |
1194 | atomic_inc(v: &zfcp_sdev->erp_counter); |
1195 | if (atomic_read(v: &zfcp_sdev->erp_counter) > ZFCP_MAX_ERPS) { |
1196 | dev_err(&zfcp_sdev->port->adapter->ccw_device->dev, |
1197 | "ERP failed for LUN 0x%016Lx on " |
1198 | "port 0x%016Lx\n" , |
1199 | (unsigned long long)zfcp_scsi_dev_lun(sdev), |
1200 | (unsigned long long)zfcp_sdev->port->wwpn); |
1201 | zfcp_erp_set_lun_status(sdev, |
1202 | ZFCP_STATUS_COMMON_ERP_FAILED); |
1203 | } |
1204 | break; |
1205 | case ZFCP_ERP_CONTINUES: |
1206 | case ZFCP_ERP_EXIT: |
1207 | case ZFCP_ERP_DISMISSED: |
1208 | case ZFCP_ERP_NOMEM: |
1209 | /* NOP */ |
1210 | break; |
1211 | } |
1212 | |
1213 | if (atomic_read(v: &zfcp_sdev->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { |
1214 | zfcp_erp_lun_block(sdev, clear_mask: 0); |
1215 | result = ZFCP_ERP_EXIT; |
1216 | } |
1217 | return result; |
1218 | } |
1219 | |
1220 | static enum zfcp_erp_act_result zfcp_erp_strategy_check_port( |
1221 | struct zfcp_port *port, enum zfcp_erp_act_result result) |
1222 | { |
1223 | switch (result) { |
1224 | case ZFCP_ERP_SUCCEEDED : |
1225 | atomic_set(v: &port->erp_counter, i: 0); |
1226 | zfcp_erp_port_unblock(port); |
1227 | break; |
1228 | |
1229 | case ZFCP_ERP_FAILED : |
1230 | if (atomic_read(v: &port->status) & ZFCP_STATUS_COMMON_NOESC) { |
1231 | zfcp_erp_port_block(port, clear: 0); |
1232 | result = ZFCP_ERP_EXIT; |
1233 | } |
1234 | atomic_inc(v: &port->erp_counter); |
1235 | if (atomic_read(v: &port->erp_counter) > ZFCP_MAX_ERPS) { |
1236 | dev_err(&port->adapter->ccw_device->dev, |
1237 | "ERP failed for remote port 0x%016Lx\n" , |
1238 | (unsigned long long)port->wwpn); |
1239 | zfcp_erp_set_port_status(port, |
1240 | ZFCP_STATUS_COMMON_ERP_FAILED); |
1241 | } |
1242 | break; |
1243 | case ZFCP_ERP_CONTINUES: |
1244 | case ZFCP_ERP_EXIT: |
1245 | case ZFCP_ERP_DISMISSED: |
1246 | case ZFCP_ERP_NOMEM: |
1247 | /* NOP */ |
1248 | break; |
1249 | } |
1250 | |
1251 | if (atomic_read(v: &port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { |
1252 | zfcp_erp_port_block(port, clear: 0); |
1253 | result = ZFCP_ERP_EXIT; |
1254 | } |
1255 | return result; |
1256 | } |
1257 | |
1258 | static enum zfcp_erp_act_result zfcp_erp_strategy_check_adapter( |
1259 | struct zfcp_adapter *adapter, enum zfcp_erp_act_result result) |
1260 | { |
1261 | switch (result) { |
1262 | case ZFCP_ERP_SUCCEEDED : |
1263 | atomic_set(v: &adapter->erp_counter, i: 0); |
1264 | zfcp_erp_adapter_unblock(adapter); |
1265 | break; |
1266 | |
1267 | case ZFCP_ERP_FAILED : |
1268 | atomic_inc(v: &adapter->erp_counter); |
1269 | if (atomic_read(v: &adapter->erp_counter) > ZFCP_MAX_ERPS) { |
1270 | dev_err(&adapter->ccw_device->dev, |
1271 | "ERP cannot recover an error " |
1272 | "on the FCP device\n" ); |
1273 | zfcp_erp_set_adapter_status(adapter, |
1274 | ZFCP_STATUS_COMMON_ERP_FAILED); |
1275 | } |
1276 | break; |
1277 | case ZFCP_ERP_CONTINUES: |
1278 | case ZFCP_ERP_EXIT: |
1279 | case ZFCP_ERP_DISMISSED: |
1280 | case ZFCP_ERP_NOMEM: |
1281 | /* NOP */ |
1282 | break; |
1283 | } |
1284 | |
1285 | if (atomic_read(v: &adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { |
1286 | zfcp_erp_adapter_block(adapter, mask: 0); |
1287 | result = ZFCP_ERP_EXIT; |
1288 | } |
1289 | return result; |
1290 | } |
1291 | |
1292 | static enum zfcp_erp_act_result zfcp_erp_strategy_check_target( |
1293 | struct zfcp_erp_action *erp_action, enum zfcp_erp_act_result result) |
1294 | { |
1295 | struct zfcp_adapter *adapter = erp_action->adapter; |
1296 | struct zfcp_port *port = erp_action->port; |
1297 | struct scsi_device *sdev = erp_action->sdev; |
1298 | |
1299 | switch (erp_action->type) { |
1300 | |
1301 | case ZFCP_ERP_ACTION_REOPEN_LUN: |
1302 | result = zfcp_erp_strategy_check_lun(sdev, result); |
1303 | break; |
1304 | |
1305 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
1306 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
1307 | result = zfcp_erp_strategy_check_port(port, result); |
1308 | break; |
1309 | |
1310 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
1311 | result = zfcp_erp_strategy_check_adapter(adapter, result); |
1312 | break; |
1313 | } |
1314 | return result; |
1315 | } |
1316 | |
1317 | static int zfcp_erp_strat_change_det(atomic_t *target_status, u32 erp_status) |
1318 | { |
1319 | int status = atomic_read(v: target_status); |
1320 | |
1321 | if ((status & ZFCP_STATUS_COMMON_RUNNING) && |
1322 | (erp_status & ZFCP_STATUS_ERP_CLOSE_ONLY)) |
1323 | return 1; /* take it online */ |
1324 | |
1325 | if (!(status & ZFCP_STATUS_COMMON_RUNNING) && |
1326 | !(erp_status & ZFCP_STATUS_ERP_CLOSE_ONLY)) |
1327 | return 1; /* take it offline */ |
1328 | |
1329 | return 0; |
1330 | } |
1331 | |
1332 | static enum zfcp_erp_act_result zfcp_erp_strategy_statechange( |
1333 | struct zfcp_erp_action *act, enum zfcp_erp_act_result result) |
1334 | { |
1335 | enum zfcp_erp_act_type type = act->type; |
1336 | struct zfcp_adapter *adapter = act->adapter; |
1337 | struct zfcp_port *port = act->port; |
1338 | struct scsi_device *sdev = act->sdev; |
1339 | struct zfcp_scsi_dev *zfcp_sdev; |
1340 | u32 erp_status = act->status; |
1341 | |
1342 | switch (type) { |
1343 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
1344 | if (zfcp_erp_strat_change_det(target_status: &adapter->status, erp_status)) { |
1345 | _zfcp_erp_adapter_reopen(adapter, |
1346 | ZFCP_STATUS_COMMON_ERP_FAILED, |
1347 | dbftag: "ersscg1" ); |
1348 | return ZFCP_ERP_EXIT; |
1349 | } |
1350 | break; |
1351 | |
1352 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
1353 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
1354 | if (zfcp_erp_strat_change_det(target_status: &port->status, erp_status)) { |
1355 | _zfcp_erp_port_reopen(port, |
1356 | ZFCP_STATUS_COMMON_ERP_FAILED, |
1357 | dbftag: "ersscg2" ); |
1358 | return ZFCP_ERP_EXIT; |
1359 | } |
1360 | break; |
1361 | |
1362 | case ZFCP_ERP_ACTION_REOPEN_LUN: |
1363 | zfcp_sdev = sdev_to_zfcp(sdev); |
1364 | if (zfcp_erp_strat_change_det(target_status: &zfcp_sdev->status, erp_status)) { |
1365 | _zfcp_erp_lun_reopen(sdev, |
1366 | ZFCP_STATUS_COMMON_ERP_FAILED, |
1367 | dbftag: "ersscg3" , act_status: 0); |
1368 | return ZFCP_ERP_EXIT; |
1369 | } |
1370 | break; |
1371 | } |
1372 | return result; |
1373 | } |
1374 | |
1375 | static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action) |
1376 | { |
1377 | struct zfcp_adapter *adapter = erp_action->adapter; |
1378 | struct zfcp_scsi_dev *zfcp_sdev; |
1379 | |
1380 | adapter->erp_total_count--; |
1381 | if (erp_action->status & ZFCP_STATUS_ERP_LOWMEM) { |
1382 | adapter->erp_low_mem_count--; |
1383 | erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM; |
1384 | } |
1385 | |
1386 | list_del(entry: &erp_action->list); |
1387 | zfcp_dbf_rec_run("eractd1" , erp_action); |
1388 | |
1389 | switch (erp_action->type) { |
1390 | case ZFCP_ERP_ACTION_REOPEN_LUN: |
1391 | zfcp_sdev = sdev_to_zfcp(sdev: erp_action->sdev); |
1392 | atomic_andnot(ZFCP_STATUS_COMMON_ERP_INUSE, |
1393 | v: &zfcp_sdev->status); |
1394 | break; |
1395 | |
1396 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
1397 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
1398 | atomic_andnot(ZFCP_STATUS_COMMON_ERP_INUSE, |
1399 | v: &erp_action->port->status); |
1400 | break; |
1401 | |
1402 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
1403 | atomic_andnot(ZFCP_STATUS_COMMON_ERP_INUSE, |
1404 | v: &erp_action->adapter->status); |
1405 | break; |
1406 | } |
1407 | } |
1408 | |
1409 | /** |
1410 | * zfcp_erp_try_rport_unblock - unblock rport if no more/new recovery |
1411 | * @port: zfcp_port whose fc_rport we should try to unblock |
1412 | */ |
1413 | static void zfcp_erp_try_rport_unblock(struct zfcp_port *port) |
1414 | { |
1415 | unsigned long flags; |
1416 | struct zfcp_adapter *adapter = port->adapter; |
1417 | int port_status; |
1418 | struct Scsi_Host *shost = adapter->scsi_host; |
1419 | struct scsi_device *sdev; |
1420 | |
1421 | write_lock_irqsave(&adapter->erp_lock, flags); |
1422 | port_status = atomic_read(v: &port->status); |
1423 | if ((port_status & ZFCP_STATUS_COMMON_UNBLOCKED) == 0 || |
1424 | (port_status & (ZFCP_STATUS_COMMON_ERP_INUSE | |
1425 | ZFCP_STATUS_COMMON_ERP_FAILED)) != 0) { |
1426 | /* new ERP of severity >= port triggered elsewhere meanwhile or |
1427 | * local link down (adapter erp_failed but not clear unblock) |
1428 | */ |
1429 | zfcp_dbf_rec_run_lvl(level: 4, tag: "ertru_p" , erp: &port->erp_action); |
1430 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
1431 | return; |
1432 | } |
1433 | spin_lock(lock: shost->host_lock); |
1434 | __shost_for_each_device(sdev, shost) { |
1435 | struct zfcp_scsi_dev *zsdev = sdev_to_zfcp(sdev); |
1436 | int lun_status; |
1437 | |
1438 | if (sdev->sdev_state == SDEV_DEL || |
1439 | sdev->sdev_state == SDEV_CANCEL) |
1440 | continue; |
1441 | if (zsdev->port != port) |
1442 | continue; |
1443 | /* LUN under port of interest */ |
1444 | lun_status = atomic_read(v: &zsdev->status); |
1445 | if ((lun_status & ZFCP_STATUS_COMMON_ERP_FAILED) != 0) |
1446 | continue; /* unblock rport despite failed LUNs */ |
1447 | /* LUN recovery not given up yet [maybe follow-up pending] */ |
1448 | if ((lun_status & ZFCP_STATUS_COMMON_UNBLOCKED) == 0 || |
1449 | (lun_status & ZFCP_STATUS_COMMON_ERP_INUSE) != 0) { |
1450 | /* LUN blocked: |
1451 | * not yet unblocked [LUN recovery pending] |
1452 | * or meanwhile blocked [new LUN recovery triggered] |
1453 | */ |
1454 | zfcp_dbf_rec_run_lvl(level: 4, tag: "ertru_l" , erp: &zsdev->erp_action); |
1455 | spin_unlock(lock: shost->host_lock); |
1456 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
1457 | return; |
1458 | } |
1459 | } |
1460 | /* now port has no child or all children have completed recovery, |
1461 | * and no ERP of severity >= port was meanwhile triggered elsewhere |
1462 | */ |
1463 | zfcp_scsi_schedule_rport_register(port); |
1464 | spin_unlock(lock: shost->host_lock); |
1465 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
1466 | } |
1467 | |
1468 | static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, |
1469 | enum zfcp_erp_act_result result) |
1470 | { |
1471 | struct zfcp_adapter *adapter = act->adapter; |
1472 | struct zfcp_port *port = act->port; |
1473 | struct scsi_device *sdev = act->sdev; |
1474 | |
1475 | switch (act->type) { |
1476 | case ZFCP_ERP_ACTION_REOPEN_LUN: |
1477 | if (!(act->status & ZFCP_STATUS_ERP_NO_REF)) |
1478 | scsi_device_put(sdev); |
1479 | zfcp_erp_try_rport_unblock(port); |
1480 | break; |
1481 | |
1482 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
1483 | /* This switch case might also happen after a forced reopen |
1484 | * was successfully done and thus overwritten with a new |
1485 | * non-forced reopen at `ersfs_2'. In this case, we must not |
1486 | * do the clean-up of the non-forced version. |
1487 | */ |
1488 | if (act->step != ZFCP_ERP_STEP_UNINITIALIZED) |
1489 | if (result == ZFCP_ERP_SUCCEEDED) |
1490 | zfcp_erp_try_rport_unblock(port); |
1491 | fallthrough; |
1492 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
1493 | put_device(dev: &port->dev); |
1494 | break; |
1495 | |
1496 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
1497 | if (result == ZFCP_ERP_SUCCEEDED) { |
1498 | register_service_level(&adapter->service_level); |
1499 | zfcp_fc_conditional_port_scan(adapter); |
1500 | queue_work(wq: adapter->work_queue, work: &adapter->ns_up_work); |
1501 | } else |
1502 | unregister_service_level(&adapter->service_level); |
1503 | |
1504 | kref_put(kref: &adapter->ref, release: zfcp_adapter_release); |
1505 | break; |
1506 | } |
1507 | } |
1508 | |
1509 | static enum zfcp_erp_act_result zfcp_erp_strategy_do_action( |
1510 | struct zfcp_erp_action *erp_action) |
1511 | { |
1512 | switch (erp_action->type) { |
1513 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
1514 | return zfcp_erp_adapter_strategy(act: erp_action); |
1515 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
1516 | return zfcp_erp_port_forced_strategy(erp_action); |
1517 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
1518 | return zfcp_erp_port_strategy(erp_action); |
1519 | case ZFCP_ERP_ACTION_REOPEN_LUN: |
1520 | return zfcp_erp_lun_strategy(erp_action); |
1521 | } |
1522 | return ZFCP_ERP_FAILED; |
1523 | } |
1524 | |
1525 | static enum zfcp_erp_act_result zfcp_erp_strategy( |
1526 | struct zfcp_erp_action *erp_action) |
1527 | { |
1528 | enum zfcp_erp_act_result result; |
1529 | unsigned long flags; |
1530 | struct zfcp_adapter *adapter = erp_action->adapter; |
1531 | |
1532 | kref_get(kref: &adapter->ref); |
1533 | |
1534 | write_lock_irqsave(&adapter->erp_lock, flags); |
1535 | zfcp_erp_strategy_check_fsfreq(act: erp_action); |
1536 | |
1537 | if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) { |
1538 | zfcp_erp_action_dequeue(erp_action); |
1539 | result = ZFCP_ERP_DISMISSED; |
1540 | goto unlock; |
1541 | } |
1542 | |
1543 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { |
1544 | result = ZFCP_ERP_FAILED; |
1545 | goto check_target; |
1546 | } |
1547 | |
1548 | zfcp_erp_action_to_running(erp_action); |
1549 | |
1550 | /* no lock to allow for blocking operations */ |
1551 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
1552 | result = zfcp_erp_strategy_do_action(erp_action); |
1553 | write_lock_irqsave(&adapter->erp_lock, flags); |
1554 | |
1555 | if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) |
1556 | result = ZFCP_ERP_CONTINUES; |
1557 | |
1558 | switch (result) { |
1559 | case ZFCP_ERP_NOMEM: |
1560 | if (!(erp_action->status & ZFCP_STATUS_ERP_LOWMEM)) { |
1561 | ++adapter->erp_low_mem_count; |
1562 | erp_action->status |= ZFCP_STATUS_ERP_LOWMEM; |
1563 | } |
1564 | if (adapter->erp_total_count == adapter->erp_low_mem_count) |
1565 | _zfcp_erp_adapter_reopen(adapter, clear_mask: 0, dbftag: "erstgy1" ); |
1566 | else { |
1567 | zfcp_erp_strategy_memwait(erp_action); |
1568 | result = ZFCP_ERP_CONTINUES; |
1569 | } |
1570 | goto unlock; |
1571 | |
1572 | case ZFCP_ERP_CONTINUES: |
1573 | if (erp_action->status & ZFCP_STATUS_ERP_LOWMEM) { |
1574 | --adapter->erp_low_mem_count; |
1575 | erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM; |
1576 | } |
1577 | goto unlock; |
1578 | case ZFCP_ERP_SUCCEEDED: |
1579 | case ZFCP_ERP_FAILED: |
1580 | case ZFCP_ERP_EXIT: |
1581 | case ZFCP_ERP_DISMISSED: |
1582 | /* NOP */ |
1583 | break; |
1584 | } |
1585 | |
1586 | check_target: |
1587 | result = zfcp_erp_strategy_check_target(erp_action, result); |
1588 | zfcp_erp_action_dequeue(erp_action); |
1589 | result = zfcp_erp_strategy_statechange(act: erp_action, result); |
1590 | if (result == ZFCP_ERP_EXIT) |
1591 | goto unlock; |
1592 | if (result == ZFCP_ERP_SUCCEEDED) |
1593 | zfcp_erp_strategy_followup_success(act: erp_action); |
1594 | if (result == ZFCP_ERP_FAILED) |
1595 | zfcp_erp_strategy_followup_failed(act: erp_action); |
1596 | |
1597 | unlock: |
1598 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
1599 | |
1600 | if (result != ZFCP_ERP_CONTINUES) |
1601 | zfcp_erp_action_cleanup(act: erp_action, result); |
1602 | |
1603 | kref_put(kref: &adapter->ref, release: zfcp_adapter_release); |
1604 | return result; |
1605 | } |
1606 | |
1607 | static int zfcp_erp_thread(void *data) |
1608 | { |
1609 | struct zfcp_adapter *adapter = (struct zfcp_adapter *) data; |
1610 | struct zfcp_erp_action *act; |
1611 | unsigned long flags; |
1612 | |
1613 | for (;;) { |
1614 | wait_event_interruptible(adapter->erp_ready_wq, |
1615 | !list_empty(&adapter->erp_ready_head) || |
1616 | kthread_should_stop()); |
1617 | |
1618 | if (kthread_should_stop()) |
1619 | break; |
1620 | |
1621 | write_lock_irqsave(&adapter->erp_lock, flags); |
1622 | act = list_first_entry_or_null(&adapter->erp_ready_head, |
1623 | struct zfcp_erp_action, list); |
1624 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
1625 | |
1626 | if (act) { |
1627 | /* there is more to come after dismission, no notify */ |
1628 | if (zfcp_erp_strategy(erp_action: act) != ZFCP_ERP_DISMISSED) |
1629 | zfcp_erp_wakeup(adapter); |
1630 | } |
1631 | } |
1632 | |
1633 | return 0; |
1634 | } |
1635 | |
1636 | /** |
1637 | * zfcp_erp_thread_setup - Start ERP thread for adapter |
1638 | * @adapter: Adapter to start the ERP thread for |
1639 | * |
1640 | * Return: 0 on success, or error code from kthread_run(). |
1641 | */ |
1642 | int zfcp_erp_thread_setup(struct zfcp_adapter *adapter) |
1643 | { |
1644 | struct task_struct *thread; |
1645 | |
1646 | thread = kthread_run(zfcp_erp_thread, adapter, "zfcperp%s" , |
1647 | dev_name(&adapter->ccw_device->dev)); |
1648 | if (IS_ERR(ptr: thread)) { |
1649 | dev_err(&adapter->ccw_device->dev, |
1650 | "Creating an ERP thread for the FCP device failed.\n" ); |
1651 | return PTR_ERR(ptr: thread); |
1652 | } |
1653 | |
1654 | adapter->erp_thread = thread; |
1655 | return 0; |
1656 | } |
1657 | |
1658 | /** |
1659 | * zfcp_erp_thread_kill - Stop ERP thread. |
1660 | * @adapter: Adapter where the ERP thread should be stopped. |
1661 | * |
1662 | * The caller of this routine ensures that the specified adapter has |
1663 | * been shut down and that this operation has been completed. Thus, |
1664 | * there are no pending erp_actions which would need to be handled |
1665 | * here. |
1666 | */ |
1667 | void zfcp_erp_thread_kill(struct zfcp_adapter *adapter) |
1668 | { |
1669 | kthread_stop(k: adapter->erp_thread); |
1670 | adapter->erp_thread = NULL; |
1671 | WARN_ON(!list_empty(&adapter->erp_ready_head)); |
1672 | WARN_ON(!list_empty(&adapter->erp_running_head)); |
1673 | } |
1674 | |
1675 | /** |
1676 | * zfcp_erp_wait - wait for completion of error recovery on an adapter |
1677 | * @adapter: adapter for which to wait for completion of its error recovery |
1678 | */ |
1679 | void zfcp_erp_wait(struct zfcp_adapter *adapter) |
1680 | { |
1681 | wait_event(adapter->erp_done_wqh, |
1682 | !(atomic_read(&adapter->status) & |
1683 | ZFCP_STATUS_ADAPTER_ERP_PENDING)); |
1684 | } |
1685 | |
1686 | /** |
1687 | * zfcp_erp_set_adapter_status - set adapter status bits |
1688 | * @adapter: adapter to change the status |
1689 | * @mask: status bits to change |
1690 | * |
1691 | * Changes in common status bits are propagated to attached ports and LUNs. |
1692 | */ |
1693 | void zfcp_erp_set_adapter_status(struct zfcp_adapter *adapter, u32 mask) |
1694 | { |
1695 | struct zfcp_port *port; |
1696 | struct scsi_device *sdev; |
1697 | unsigned long flags; |
1698 | u32 common_mask = mask & ZFCP_COMMON_FLAGS; |
1699 | |
1700 | atomic_or(i: mask, v: &adapter->status); |
1701 | |
1702 | if (!common_mask) |
1703 | return; |
1704 | |
1705 | read_lock_irqsave(&adapter->port_list_lock, flags); |
1706 | list_for_each_entry(port, &adapter->port_list, list) |
1707 | atomic_or(i: common_mask, v: &port->status); |
1708 | read_unlock_irqrestore(&adapter->port_list_lock, flags); |
1709 | |
1710 | /* |
1711 | * if `scsi_host` is missing, xconfig/xport data has never completed |
1712 | * yet, so we can't access it, but there are also no SDEVs yet |
1713 | */ |
1714 | if (adapter->scsi_host == NULL) |
1715 | return; |
1716 | |
1717 | spin_lock_irqsave(adapter->scsi_host->host_lock, flags); |
1718 | __shost_for_each_device(sdev, adapter->scsi_host) |
1719 | atomic_or(i: common_mask, v: &sdev_to_zfcp(sdev)->status); |
1720 | spin_unlock_irqrestore(lock: adapter->scsi_host->host_lock, flags); |
1721 | } |
1722 | |
1723 | /** |
1724 | * zfcp_erp_clear_adapter_status - clear adapter status bits |
1725 | * @adapter: adapter to change the status |
1726 | * @mask: status bits to change |
1727 | * |
1728 | * Changes in common status bits are propagated to attached ports and LUNs. |
1729 | */ |
1730 | void zfcp_erp_clear_adapter_status(struct zfcp_adapter *adapter, u32 mask) |
1731 | { |
1732 | struct zfcp_port *port; |
1733 | struct scsi_device *sdev; |
1734 | unsigned long flags; |
1735 | u32 common_mask = mask & ZFCP_COMMON_FLAGS; |
1736 | u32 clear_counter = mask & ZFCP_STATUS_COMMON_ERP_FAILED; |
1737 | |
1738 | atomic_andnot(i: mask, v: &adapter->status); |
1739 | |
1740 | if (!common_mask) |
1741 | return; |
1742 | |
1743 | if (clear_counter) |
1744 | atomic_set(v: &adapter->erp_counter, i: 0); |
1745 | |
1746 | read_lock_irqsave(&adapter->port_list_lock, flags); |
1747 | list_for_each_entry(port, &adapter->port_list, list) { |
1748 | atomic_andnot(i: common_mask, v: &port->status); |
1749 | if (clear_counter) |
1750 | atomic_set(v: &port->erp_counter, i: 0); |
1751 | } |
1752 | read_unlock_irqrestore(&adapter->port_list_lock, flags); |
1753 | |
1754 | /* |
1755 | * if `scsi_host` is missing, xconfig/xport data has never completed |
1756 | * yet, so we can't access it, but there are also no SDEVs yet |
1757 | */ |
1758 | if (adapter->scsi_host == NULL) |
1759 | return; |
1760 | |
1761 | spin_lock_irqsave(adapter->scsi_host->host_lock, flags); |
1762 | __shost_for_each_device(sdev, adapter->scsi_host) { |
1763 | atomic_andnot(i: common_mask, v: &sdev_to_zfcp(sdev)->status); |
1764 | if (clear_counter) |
1765 | atomic_set(v: &sdev_to_zfcp(sdev)->erp_counter, i: 0); |
1766 | } |
1767 | spin_unlock_irqrestore(lock: adapter->scsi_host->host_lock, flags); |
1768 | } |
1769 | |
1770 | /** |
1771 | * zfcp_erp_set_port_status - set port status bits |
1772 | * @port: port to change the status |
1773 | * @mask: status bits to change |
1774 | * |
1775 | * Changes in common status bits are propagated to attached LUNs. |
1776 | */ |
1777 | void zfcp_erp_set_port_status(struct zfcp_port *port, u32 mask) |
1778 | { |
1779 | struct scsi_device *sdev; |
1780 | u32 common_mask = mask & ZFCP_COMMON_FLAGS; |
1781 | unsigned long flags; |
1782 | |
1783 | atomic_or(i: mask, v: &port->status); |
1784 | |
1785 | if (!common_mask) |
1786 | return; |
1787 | |
1788 | spin_lock_irqsave(port->adapter->scsi_host->host_lock, flags); |
1789 | __shost_for_each_device(sdev, port->adapter->scsi_host) |
1790 | if (sdev_to_zfcp(sdev)->port == port) |
1791 | atomic_or(i: common_mask, |
1792 | v: &sdev_to_zfcp(sdev)->status); |
1793 | spin_unlock_irqrestore(lock: port->adapter->scsi_host->host_lock, flags); |
1794 | } |
1795 | |
1796 | /** |
1797 | * zfcp_erp_clear_port_status - clear port status bits |
1798 | * @port: adapter to change the status |
1799 | * @mask: status bits to change |
1800 | * |
1801 | * Changes in common status bits are propagated to attached LUNs. |
1802 | */ |
1803 | void zfcp_erp_clear_port_status(struct zfcp_port *port, u32 mask) |
1804 | { |
1805 | struct scsi_device *sdev; |
1806 | u32 common_mask = mask & ZFCP_COMMON_FLAGS; |
1807 | u32 clear_counter = mask & ZFCP_STATUS_COMMON_ERP_FAILED; |
1808 | unsigned long flags; |
1809 | |
1810 | atomic_andnot(i: mask, v: &port->status); |
1811 | |
1812 | if (!common_mask) |
1813 | return; |
1814 | |
1815 | if (clear_counter) |
1816 | atomic_set(v: &port->erp_counter, i: 0); |
1817 | |
1818 | spin_lock_irqsave(port->adapter->scsi_host->host_lock, flags); |
1819 | __shost_for_each_device(sdev, port->adapter->scsi_host) |
1820 | if (sdev_to_zfcp(sdev)->port == port) { |
1821 | atomic_andnot(i: common_mask, |
1822 | v: &sdev_to_zfcp(sdev)->status); |
1823 | if (clear_counter) |
1824 | atomic_set(v: &sdev_to_zfcp(sdev)->erp_counter, i: 0); |
1825 | } |
1826 | spin_unlock_irqrestore(lock: port->adapter->scsi_host->host_lock, flags); |
1827 | } |
1828 | |
1829 | /** |
1830 | * zfcp_erp_set_lun_status - set lun status bits |
1831 | * @sdev: SCSI device / lun to set the status bits |
1832 | * @mask: status bits to change |
1833 | */ |
1834 | void zfcp_erp_set_lun_status(struct scsi_device *sdev, u32 mask) |
1835 | { |
1836 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
1837 | |
1838 | atomic_or(i: mask, v: &zfcp_sdev->status); |
1839 | } |
1840 | |
1841 | /** |
1842 | * zfcp_erp_clear_lun_status - clear lun status bits |
1843 | * @sdev: SCSi device / lun to clear the status bits |
1844 | * @mask: status bits to change |
1845 | */ |
1846 | void zfcp_erp_clear_lun_status(struct scsi_device *sdev, u32 mask) |
1847 | { |
1848 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
1849 | |
1850 | atomic_andnot(i: mask, v: &zfcp_sdev->status); |
1851 | |
1852 | if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) |
1853 | atomic_set(v: &zfcp_sdev->erp_counter, i: 0); |
1854 | } |
1855 | |
1856 | /** |
1857 | * zfcp_erp_adapter_reset_sync() - Really reopen adapter and wait. |
1858 | * @adapter: Pointer to zfcp_adapter to reopen. |
1859 | * @dbftag: Trace tag string of length %ZFCP_DBF_TAG_LEN. |
1860 | */ |
1861 | void zfcp_erp_adapter_reset_sync(struct zfcp_adapter *adapter, char *dbftag) |
1862 | { |
1863 | zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING); |
1864 | zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, dbftag); |
1865 | zfcp_erp_wait(adapter); |
1866 | } |
1867 | |