.. | .. |
---|
4 | 4 | * |
---|
5 | 5 | * Error Recovery Procedures (ERP). |
---|
6 | 6 | * |
---|
7 | | - * Copyright IBM Corp. 2002, 2016 |
---|
| 7 | + * Copyright IBM Corp. 2002, 2020 |
---|
8 | 8 | */ |
---|
9 | 9 | |
---|
10 | 10 | #define KMSG_COMPONENT "zfcp" |
---|
.. | .. |
---|
14 | 14 | #include <linux/bug.h> |
---|
15 | 15 | #include "zfcp_ext.h" |
---|
16 | 16 | #include "zfcp_reqlist.h" |
---|
| 17 | +#include "zfcp_diag.h" |
---|
17 | 18 | |
---|
18 | 19 | #define ZFCP_MAX_ERPS 3 |
---|
19 | 20 | |
---|
.. | .. |
---|
25 | 26 | ZFCP_STATUS_ERP_NO_REF = 0x00800000, |
---|
26 | 27 | }; |
---|
27 | 28 | |
---|
28 | | -enum zfcp_erp_steps { |
---|
29 | | - ZFCP_ERP_STEP_UNINITIALIZED = 0x0000, |
---|
30 | | - ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010, |
---|
31 | | - ZFCP_ERP_STEP_PORT_CLOSING = 0x0100, |
---|
32 | | - ZFCP_ERP_STEP_PORT_OPENING = 0x0800, |
---|
33 | | - ZFCP_ERP_STEP_LUN_CLOSING = 0x1000, |
---|
34 | | - ZFCP_ERP_STEP_LUN_OPENING = 0x2000, |
---|
35 | | -}; |
---|
36 | | - |
---|
37 | | -/** |
---|
38 | | - * enum zfcp_erp_act_type - Type of ERP action object. |
---|
39 | | - * @ZFCP_ERP_ACTION_REOPEN_LUN: LUN recovery. |
---|
40 | | - * @ZFCP_ERP_ACTION_REOPEN_PORT: Port recovery. |
---|
41 | | - * @ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: Forced port recovery. |
---|
42 | | - * @ZFCP_ERP_ACTION_REOPEN_ADAPTER: Adapter recovery. |
---|
43 | | - * @ZFCP_ERP_ACTION_NONE: Eyecatcher pseudo flag to bitwise or-combine with |
---|
44 | | - * either of the first four enum values. |
---|
45 | | - * Used to indicate that an ERP action could not be |
---|
46 | | - * set up despite a detected need for some recovery. |
---|
47 | | - * @ZFCP_ERP_ACTION_FAILED: Eyecatcher pseudo flag to bitwise or-combine with |
---|
48 | | - * either of the first four enum values. |
---|
49 | | - * Used to indicate that ERP not needed because |
---|
50 | | - * the object has ZFCP_STATUS_COMMON_ERP_FAILED. |
---|
| 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. |
---|
51 | 33 | */ |
---|
52 | | -enum zfcp_erp_act_type { |
---|
53 | | - ZFCP_ERP_ACTION_REOPEN_LUN = 1, |
---|
54 | | - ZFCP_ERP_ACTION_REOPEN_PORT = 2, |
---|
55 | | - ZFCP_ERP_ACTION_REOPEN_PORT_FORCED = 3, |
---|
56 | | - ZFCP_ERP_ACTION_REOPEN_ADAPTER = 4, |
---|
57 | | - ZFCP_ERP_ACTION_NONE = 0xc0, |
---|
58 | | - ZFCP_ERP_ACTION_FAILED = 0xe0, |
---|
59 | | -}; |
---|
| 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 |
---|
60 | 41 | |
---|
61 | 42 | enum zfcp_erp_act_result { |
---|
62 | 43 | ZFCP_ERP_SUCCEEDED = 0, |
---|
.. | .. |
---|
87 | 68 | { |
---|
88 | 69 | struct zfcp_adapter *adapter = act->adapter; |
---|
89 | 70 | |
---|
90 | | - list_move(&act->list, &act->adapter->erp_ready_head); |
---|
| 71 | + list_move(&act->list, &adapter->erp_ready_head); |
---|
91 | 72 | zfcp_dbf_rec_run("erardy1", act); |
---|
92 | 73 | wake_up(&adapter->erp_ready_wq); |
---|
93 | 74 | zfcp_dbf_rec_run("erardy2", act); |
---|
.. | .. |
---|
137 | 118 | } |
---|
138 | 119 | } |
---|
139 | 120 | |
---|
140 | | -static int zfcp_erp_handle_failed(int want, struct zfcp_adapter *adapter, |
---|
141 | | - struct zfcp_port *port, |
---|
142 | | - struct scsi_device *sdev) |
---|
| 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) |
---|
143 | 124 | { |
---|
144 | | - int need = want; |
---|
| 125 | + enum zfcp_erp_act_type need = want; |
---|
145 | 126 | struct zfcp_scsi_dev *zsdev; |
---|
146 | 127 | |
---|
147 | 128 | switch (want) { |
---|
.. | .. |
---|
177 | 158 | return need; |
---|
178 | 159 | } |
---|
179 | 160 | |
---|
180 | | -static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter, |
---|
| 161 | +static enum zfcp_erp_act_type zfcp_erp_required_act(enum zfcp_erp_act_type want, |
---|
| 162 | + struct zfcp_adapter *adapter, |
---|
181 | 163 | struct zfcp_port *port, |
---|
182 | 164 | struct scsi_device *sdev) |
---|
183 | 165 | { |
---|
184 | | - int need = want; |
---|
| 166 | + enum zfcp_erp_act_type need = want; |
---|
185 | 167 | int l_status, p_status, a_status; |
---|
186 | 168 | struct zfcp_scsi_dev *zfcp_sdev; |
---|
187 | 169 | |
---|
.. | .. |
---|
193 | 175 | return 0; |
---|
194 | 176 | p_status = atomic_read(&port->status); |
---|
195 | 177 | if (!(p_status & ZFCP_STATUS_COMMON_RUNNING) || |
---|
196 | | - p_status & ZFCP_STATUS_COMMON_ERP_FAILED) |
---|
| 178 | + p_status & ZFCP_STATUS_COMMON_ERP_FAILED) |
---|
197 | 179 | return 0; |
---|
198 | 180 | if (!(p_status & ZFCP_STATUS_COMMON_UNBLOCKED)) |
---|
199 | 181 | need = ZFCP_ERP_ACTION_REOPEN_PORT; |
---|
200 | | - /* fall through */ |
---|
| 182 | + fallthrough; |
---|
201 | 183 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
---|
202 | 184 | p_status = atomic_read(&port->status); |
---|
203 | 185 | if (!(p_status & ZFCP_STATUS_COMMON_OPEN)) |
---|
204 | 186 | need = ZFCP_ERP_ACTION_REOPEN_PORT; |
---|
205 | | - /* fall through */ |
---|
| 187 | + fallthrough; |
---|
206 | 188 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
---|
207 | 189 | p_status = atomic_read(&port->status); |
---|
208 | 190 | if (p_status & ZFCP_STATUS_COMMON_ERP_INUSE) |
---|
209 | 191 | return 0; |
---|
210 | 192 | a_status = atomic_read(&adapter->status); |
---|
211 | 193 | if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) || |
---|
212 | | - a_status & ZFCP_STATUS_COMMON_ERP_FAILED) |
---|
| 194 | + a_status & ZFCP_STATUS_COMMON_ERP_FAILED) |
---|
213 | 195 | return 0; |
---|
214 | 196 | if (p_status & ZFCP_STATUS_COMMON_NOESC) |
---|
215 | 197 | return need; |
---|
216 | 198 | if (!(a_status & ZFCP_STATUS_COMMON_UNBLOCKED)) |
---|
217 | 199 | need = ZFCP_ERP_ACTION_REOPEN_ADAPTER; |
---|
218 | | - /* fall through */ |
---|
| 200 | + fallthrough; |
---|
219 | 201 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
---|
220 | 202 | a_status = atomic_read(&adapter->status); |
---|
221 | 203 | if (a_status & ZFCP_STATUS_COMMON_ERP_INUSE) |
---|
.. | .. |
---|
228 | 210 | return need; |
---|
229 | 211 | } |
---|
230 | 212 | |
---|
231 | | -static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, |
---|
| 213 | +static struct zfcp_erp_action *zfcp_erp_setup_act(enum zfcp_erp_act_type need, |
---|
| 214 | + u32 act_status, |
---|
232 | 215 | struct zfcp_adapter *adapter, |
---|
233 | 216 | struct zfcp_port *port, |
---|
234 | 217 | struct scsi_device *sdev) |
---|
.. | .. |
---|
282 | 265 | ZFCP_STATUS_COMMON_RUNNING)) |
---|
283 | 266 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; |
---|
284 | 267 | break; |
---|
285 | | - |
---|
286 | | - default: |
---|
287 | | - return NULL; |
---|
288 | 268 | } |
---|
289 | 269 | |
---|
290 | 270 | WARN_ON_ONCE(erp_action->adapter != adapter); |
---|
.. | .. |
---|
292 | 272 | memset(&erp_action->timer, 0, sizeof(erp_action->timer)); |
---|
293 | 273 | erp_action->step = ZFCP_ERP_STEP_UNINITIALIZED; |
---|
294 | 274 | erp_action->fsf_req_id = 0; |
---|
295 | | - erp_action->action = need; |
---|
| 275 | + erp_action->type = need; |
---|
296 | 276 | erp_action->status = act_status; |
---|
297 | 277 | |
---|
298 | 278 | return erp_action; |
---|
299 | 279 | } |
---|
300 | 280 | |
---|
301 | | -static void zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter, |
---|
| 281 | +static void zfcp_erp_action_enqueue(enum zfcp_erp_act_type want, |
---|
| 282 | + struct zfcp_adapter *adapter, |
---|
302 | 283 | struct zfcp_port *port, |
---|
303 | 284 | struct scsi_device *sdev, |
---|
304 | | - char *id, u32 act_status) |
---|
| 285 | + char *dbftag, u32 act_status) |
---|
305 | 286 | { |
---|
306 | | - int need; |
---|
| 287 | + enum zfcp_erp_act_type need; |
---|
307 | 288 | struct zfcp_erp_action *act; |
---|
308 | 289 | |
---|
309 | 290 | need = zfcp_erp_handle_failed(want, adapter, port, sdev); |
---|
.. | .. |
---|
331 | 312 | list_add_tail(&act->list, &adapter->erp_ready_head); |
---|
332 | 313 | wake_up(&adapter->erp_ready_wq); |
---|
333 | 314 | out: |
---|
334 | | - zfcp_dbf_rec_trig(id, adapter, port, sdev, want, need); |
---|
| 315 | + zfcp_dbf_rec_trig(dbftag, adapter, port, sdev, want, need); |
---|
335 | 316 | } |
---|
336 | 317 | |
---|
337 | | -void zfcp_erp_port_forced_no_port_dbf(char *id, struct zfcp_adapter *adapter, |
---|
| 318 | +void zfcp_erp_port_forced_no_port_dbf(char *dbftag, |
---|
| 319 | + struct zfcp_adapter *adapter, |
---|
338 | 320 | u64 port_name, u32 port_id) |
---|
339 | 321 | { |
---|
340 | 322 | unsigned long flags; |
---|
.. | .. |
---|
348 | 330 | atomic_set(&tmpport.status, -1); /* unknown */ |
---|
349 | 331 | tmpport.wwpn = port_name; |
---|
350 | 332 | tmpport.d_id = port_id; |
---|
351 | | - zfcp_dbf_rec_trig(id, adapter, &tmpport, NULL, |
---|
| 333 | + zfcp_dbf_rec_trig(dbftag, adapter, &tmpport, NULL, |
---|
352 | 334 | ZFCP_ERP_ACTION_REOPEN_PORT_FORCED, |
---|
353 | 335 | ZFCP_ERP_ACTION_NONE); |
---|
354 | 336 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
---|
355 | 337 | } |
---|
356 | 338 | |
---|
357 | 339 | static void _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, |
---|
358 | | - int clear_mask, char *id) |
---|
| 340 | + int clear_mask, char *dbftag) |
---|
359 | 341 | { |
---|
360 | 342 | zfcp_erp_adapter_block(adapter, clear_mask); |
---|
361 | 343 | zfcp_scsi_schedule_rports_block(adapter); |
---|
362 | 344 | |
---|
363 | 345 | zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, |
---|
364 | | - adapter, NULL, NULL, id, 0); |
---|
| 346 | + adapter, NULL, NULL, dbftag, 0); |
---|
365 | 347 | } |
---|
366 | 348 | |
---|
367 | 349 | /** |
---|
368 | 350 | * zfcp_erp_adapter_reopen - Reopen adapter. |
---|
369 | 351 | * @adapter: Adapter to reopen. |
---|
370 | 352 | * @clear: Status flags to clear. |
---|
371 | | - * @id: Id for debug trace event. |
---|
| 353 | + * @dbftag: Tag for debug trace event. |
---|
372 | 354 | */ |
---|
373 | | -void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear, char *id) |
---|
| 355 | +void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear, |
---|
| 356 | + char *dbftag) |
---|
374 | 357 | { |
---|
375 | 358 | unsigned long flags; |
---|
376 | 359 | |
---|
.. | .. |
---|
379 | 362 | |
---|
380 | 363 | write_lock_irqsave(&adapter->erp_lock, flags); |
---|
381 | 364 | zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter, |
---|
382 | | - NULL, NULL, id, 0); |
---|
| 365 | + NULL, NULL, dbftag, 0); |
---|
383 | 366 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
---|
384 | 367 | } |
---|
385 | 368 | |
---|
.. | .. |
---|
387 | 370 | * zfcp_erp_adapter_shutdown - Shutdown adapter. |
---|
388 | 371 | * @adapter: Adapter to shut down. |
---|
389 | 372 | * @clear: Status flags to clear. |
---|
390 | | - * @id: Id for debug trace event. |
---|
| 373 | + * @dbftag: Tag for debug trace event. |
---|
391 | 374 | */ |
---|
392 | 375 | void zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear, |
---|
393 | | - char *id) |
---|
| 376 | + char *dbftag) |
---|
394 | 377 | { |
---|
395 | 378 | int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; |
---|
396 | | - zfcp_erp_adapter_reopen(adapter, clear | flags, id); |
---|
| 379 | + zfcp_erp_adapter_reopen(adapter, clear | flags, dbftag); |
---|
397 | 380 | } |
---|
398 | 381 | |
---|
399 | 382 | /** |
---|
400 | 383 | * zfcp_erp_port_shutdown - Shutdown port |
---|
401 | 384 | * @port: Port to shut down. |
---|
402 | 385 | * @clear: Status flags to clear. |
---|
403 | | - * @id: Id for debug trace event. |
---|
| 386 | + * @dbftag: Tag for debug trace event. |
---|
404 | 387 | */ |
---|
405 | | -void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, char *id) |
---|
| 388 | +void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, char *dbftag) |
---|
406 | 389 | { |
---|
407 | 390 | int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; |
---|
408 | | - zfcp_erp_port_reopen(port, clear | flags, id); |
---|
| 391 | + zfcp_erp_port_reopen(port, clear | flags, dbftag); |
---|
409 | 392 | } |
---|
410 | 393 | |
---|
411 | 394 | static void zfcp_erp_port_block(struct zfcp_port *port, int clear) |
---|
.. | .. |
---|
415 | 398 | } |
---|
416 | 399 | |
---|
417 | 400 | static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, |
---|
418 | | - char *id) |
---|
| 401 | + char *dbftag) |
---|
419 | 402 | { |
---|
420 | 403 | zfcp_erp_port_block(port, clear); |
---|
421 | 404 | zfcp_scsi_schedule_rport_block(port); |
---|
422 | 405 | |
---|
423 | 406 | zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED, |
---|
424 | | - port->adapter, port, NULL, id, 0); |
---|
| 407 | + port->adapter, port, NULL, dbftag, 0); |
---|
425 | 408 | } |
---|
426 | 409 | |
---|
427 | 410 | /** |
---|
428 | 411 | * zfcp_erp_port_forced_reopen - Forced close of port and open again |
---|
429 | 412 | * @port: Port to force close and to reopen. |
---|
430 | 413 | * @clear: Status flags to clear. |
---|
431 | | - * @id: Id for debug trace event. |
---|
| 414 | + * @dbftag: Tag for debug trace event. |
---|
432 | 415 | */ |
---|
433 | | -void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, char *id) |
---|
| 416 | +void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, |
---|
| 417 | + char *dbftag) |
---|
434 | 418 | { |
---|
435 | 419 | unsigned long flags; |
---|
436 | 420 | struct zfcp_adapter *adapter = port->adapter; |
---|
437 | 421 | |
---|
438 | 422 | write_lock_irqsave(&adapter->erp_lock, flags); |
---|
439 | | - _zfcp_erp_port_forced_reopen(port, clear, id); |
---|
| 423 | + _zfcp_erp_port_forced_reopen(port, clear, dbftag); |
---|
440 | 424 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
---|
441 | 425 | } |
---|
442 | 426 | |
---|
443 | | -static void _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id) |
---|
| 427 | +static void _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, |
---|
| 428 | + char *dbftag) |
---|
444 | 429 | { |
---|
445 | 430 | zfcp_erp_port_block(port, clear); |
---|
446 | 431 | zfcp_scsi_schedule_rport_block(port); |
---|
447 | 432 | |
---|
448 | 433 | zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT, |
---|
449 | | - port->adapter, port, NULL, id, 0); |
---|
| 434 | + port->adapter, port, NULL, dbftag, 0); |
---|
450 | 435 | } |
---|
451 | 436 | |
---|
452 | 437 | /** |
---|
453 | 438 | * zfcp_erp_port_reopen - trigger remote port recovery |
---|
454 | 439 | * @port: port to recover |
---|
455 | | - * @clear_mask: flags in port status to be cleared |
---|
456 | | - * @id: Id for debug trace event. |
---|
| 440 | + * @clear: flags in port status to be cleared |
---|
| 441 | + * @dbftag: Tag for debug trace event. |
---|
457 | 442 | */ |
---|
458 | | -void zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id) |
---|
| 443 | +void zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *dbftag) |
---|
459 | 444 | { |
---|
460 | 445 | unsigned long flags; |
---|
461 | 446 | struct zfcp_adapter *adapter = port->adapter; |
---|
462 | 447 | |
---|
463 | 448 | write_lock_irqsave(&adapter->erp_lock, flags); |
---|
464 | | - _zfcp_erp_port_reopen(port, clear, id); |
---|
| 449 | + _zfcp_erp_port_reopen(port, clear, dbftag); |
---|
465 | 450 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
---|
466 | 451 | } |
---|
467 | 452 | |
---|
.. | .. |
---|
471 | 456 | ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask); |
---|
472 | 457 | } |
---|
473 | 458 | |
---|
474 | | -static void _zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id, |
---|
475 | | - u32 act_status) |
---|
| 459 | +static void _zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, |
---|
| 460 | + char *dbftag, u32 act_status) |
---|
476 | 461 | { |
---|
477 | 462 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
---|
478 | 463 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; |
---|
.. | .. |
---|
480 | 465 | zfcp_erp_lun_block(sdev, clear); |
---|
481 | 466 | |
---|
482 | 467 | zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_LUN, adapter, |
---|
483 | | - zfcp_sdev->port, sdev, id, act_status); |
---|
| 468 | + zfcp_sdev->port, sdev, dbftag, act_status); |
---|
484 | 469 | } |
---|
485 | 470 | |
---|
486 | 471 | /** |
---|
487 | 472 | * zfcp_erp_lun_reopen - initiate reopen of a LUN |
---|
488 | 473 | * @sdev: SCSI device / LUN to be reopened |
---|
489 | | - * @clear_mask: specifies flags in LUN status to be cleared |
---|
490 | | - * @id: Id for debug trace event. |
---|
| 474 | + * @clear: specifies flags in LUN status to be cleared |
---|
| 475 | + * @dbftag: Tag for debug trace event. |
---|
491 | 476 | * |
---|
492 | 477 | * Return: 0 on success, < 0 on error |
---|
493 | 478 | */ |
---|
494 | | -void zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id) |
---|
| 479 | +void zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *dbftag) |
---|
495 | 480 | { |
---|
496 | 481 | unsigned long flags; |
---|
497 | 482 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
---|
.. | .. |
---|
499 | 484 | struct zfcp_adapter *adapter = port->adapter; |
---|
500 | 485 | |
---|
501 | 486 | write_lock_irqsave(&adapter->erp_lock, flags); |
---|
502 | | - _zfcp_erp_lun_reopen(sdev, clear, id, 0); |
---|
| 487 | + _zfcp_erp_lun_reopen(sdev, clear, dbftag, 0); |
---|
503 | 488 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
---|
504 | 489 | } |
---|
505 | 490 | |
---|
.. | .. |
---|
507 | 492 | * zfcp_erp_lun_shutdown - Shutdown LUN |
---|
508 | 493 | * @sdev: SCSI device / LUN to shut down. |
---|
509 | 494 | * @clear: Status flags to clear. |
---|
510 | | - * @id: Id for debug trace event. |
---|
| 495 | + * @dbftag: Tag for debug trace event. |
---|
511 | 496 | */ |
---|
512 | | -void zfcp_erp_lun_shutdown(struct scsi_device *sdev, int clear, char *id) |
---|
| 497 | +void zfcp_erp_lun_shutdown(struct scsi_device *sdev, int clear, char *dbftag) |
---|
513 | 498 | { |
---|
514 | 499 | int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; |
---|
515 | | - zfcp_erp_lun_reopen(sdev, clear | flags, id); |
---|
| 500 | + zfcp_erp_lun_reopen(sdev, clear | flags, dbftag); |
---|
516 | 501 | } |
---|
517 | 502 | |
---|
518 | 503 | /** |
---|
519 | 504 | * zfcp_erp_lun_shutdown_wait - Shutdown LUN and wait for erp completion |
---|
520 | 505 | * @sdev: SCSI device / LUN to shut down. |
---|
521 | | - * @id: Id for debug trace event. |
---|
| 506 | + * @dbftag: Tag for debug trace event. |
---|
522 | 507 | * |
---|
523 | 508 | * Do not acquire a reference for the LUN when creating the ERP |
---|
524 | 509 | * action. It is safe, because this function waits for the ERP to |
---|
525 | 510 | * complete first. This allows to shutdown the LUN, even when the SCSI |
---|
526 | 511 | * device is in the state SDEV_DEL when scsi_device_get will fail. |
---|
527 | 512 | */ |
---|
528 | | -void zfcp_erp_lun_shutdown_wait(struct scsi_device *sdev, char *id) |
---|
| 513 | +void zfcp_erp_lun_shutdown_wait(struct scsi_device *sdev, char *dbftag) |
---|
529 | 514 | { |
---|
530 | 515 | unsigned long flags; |
---|
531 | 516 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
---|
.. | .. |
---|
534 | 519 | int clear = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; |
---|
535 | 520 | |
---|
536 | 521 | write_lock_irqsave(&adapter->erp_lock, flags); |
---|
537 | | - _zfcp_erp_lun_reopen(sdev, clear, id, ZFCP_STATUS_ERP_NO_REF); |
---|
| 522 | + _zfcp_erp_lun_reopen(sdev, clear, dbftag, ZFCP_STATUS_ERP_NO_REF); |
---|
538 | 523 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
---|
539 | 524 | |
---|
540 | 525 | zfcp_erp_wait(adapter); |
---|
.. | .. |
---|
626 | 611 | |
---|
627 | 612 | /** |
---|
628 | 613 | * zfcp_erp_timeout_handler - Trigger ERP action from timed out ERP request |
---|
629 | | - * @data: ERP action (from timer data) |
---|
| 614 | + * @t: timer list entry embedded in zfcp FSF request |
---|
630 | 615 | */ |
---|
631 | 616 | void zfcp_erp_timeout_handler(struct timer_list *t) |
---|
632 | 617 | { |
---|
.. | .. |
---|
671 | 656 | } |
---|
672 | 657 | |
---|
673 | 658 | static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, |
---|
674 | | - int clear, char *id) |
---|
| 659 | + int clear, char *dbftag) |
---|
675 | 660 | { |
---|
676 | 661 | struct zfcp_port *port; |
---|
677 | 662 | |
---|
678 | 663 | read_lock(&adapter->port_list_lock); |
---|
679 | 664 | list_for_each_entry(port, &adapter->port_list, list) |
---|
680 | | - _zfcp_erp_port_reopen(port, clear, id); |
---|
| 665 | + _zfcp_erp_port_reopen(port, clear, dbftag); |
---|
681 | 666 | read_unlock(&adapter->port_list_lock); |
---|
682 | 667 | } |
---|
683 | 668 | |
---|
684 | 669 | static void _zfcp_erp_lun_reopen_all(struct zfcp_port *port, int clear, |
---|
685 | | - char *id) |
---|
| 670 | + char *dbftag) |
---|
686 | 671 | { |
---|
687 | 672 | struct scsi_device *sdev; |
---|
688 | 673 | |
---|
689 | 674 | spin_lock(port->adapter->scsi_host->host_lock); |
---|
690 | 675 | __shost_for_each_device(sdev, port->adapter->scsi_host) |
---|
691 | 676 | if (sdev_to_zfcp(sdev)->port == port) |
---|
692 | | - _zfcp_erp_lun_reopen(sdev, clear, id, 0); |
---|
| 677 | + _zfcp_erp_lun_reopen(sdev, clear, dbftag, 0); |
---|
693 | 678 | spin_unlock(port->adapter->scsi_host->host_lock); |
---|
694 | 679 | } |
---|
695 | 680 | |
---|
696 | 681 | static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act) |
---|
697 | 682 | { |
---|
698 | | - switch (act->action) { |
---|
| 683 | + switch (act->type) { |
---|
699 | 684 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
---|
700 | 685 | _zfcp_erp_adapter_reopen(act->adapter, 0, "ersff_1"); |
---|
701 | 686 | break; |
---|
.. | .. |
---|
713 | 698 | |
---|
714 | 699 | static void zfcp_erp_strategy_followup_success(struct zfcp_erp_action *act) |
---|
715 | 700 | { |
---|
716 | | - switch (act->action) { |
---|
| 701 | + switch (act->type) { |
---|
717 | 702 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
---|
718 | 703 | _zfcp_erp_port_reopen_all(act->adapter, 0, "ersfs_1"); |
---|
719 | 704 | break; |
---|
.. | .. |
---|
722 | 707 | break; |
---|
723 | 708 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
---|
724 | 709 | _zfcp_erp_lun_reopen_all(act->port, 0, "ersfs_3"); |
---|
| 710 | + break; |
---|
| 711 | + case ZFCP_ERP_ACTION_REOPEN_LUN: |
---|
| 712 | + /* NOP */ |
---|
725 | 713 | break; |
---|
726 | 714 | } |
---|
727 | 715 | } |
---|
.. | .. |
---|
750 | 738 | zfcp_erp_port_reopen(port, 0, "ereptp1"); |
---|
751 | 739 | } |
---|
752 | 740 | |
---|
753 | | -static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action) |
---|
| 741 | +static enum zfcp_erp_act_result zfcp_erp_adapter_strat_fsf_xconf( |
---|
| 742 | + struct zfcp_erp_action *erp_action) |
---|
754 | 743 | { |
---|
755 | 744 | int retries; |
---|
756 | 745 | int sleep = 1; |
---|
.. | .. |
---|
789 | 778 | if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_XCONFIG_OK)) |
---|
790 | 779 | return ZFCP_ERP_FAILED; |
---|
791 | 780 | |
---|
792 | | - if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) |
---|
793 | | - zfcp_erp_enqueue_ptp_port(adapter); |
---|
794 | | - |
---|
795 | 781 | return ZFCP_ERP_SUCCEEDED; |
---|
796 | 782 | } |
---|
797 | 783 | |
---|
798 | | -static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *act) |
---|
| 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) |
---|
799 | 793 | { |
---|
800 | 794 | int ret; |
---|
801 | 795 | struct zfcp_adapter *adapter = act->adapter; |
---|
.. | .. |
---|
820 | 814 | return ZFCP_ERP_SUCCEEDED; |
---|
821 | 815 | } |
---|
822 | 816 | |
---|
823 | | -static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *act) |
---|
| 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, &config_data->data, |
---|
| 846 | + !!config_data->header.incomplete); |
---|
| 847 | + spin_unlock_irqrestore(&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, &port_data->data); |
---|
| 852 | + spin_unlock_irqrestore(&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) |
---|
824 | 872 | { |
---|
825 | 873 | if (zfcp_erp_adapter_strat_fsf_xconf(act) == ZFCP_ERP_FAILED) |
---|
826 | 874 | return ZFCP_ERP_FAILED; |
---|
827 | 875 | |
---|
828 | 876 | if (zfcp_erp_adapter_strategy_open_fsf_xport(act) == ZFCP_ERP_FAILED) |
---|
829 | 877 | return ZFCP_ERP_FAILED; |
---|
| 878 | + |
---|
| 879 | + if (zfcp_erp_adapter_strategy_alloc_shost(act->adapter) == |
---|
| 880 | + ZFCP_ERP_FAILED) |
---|
| 881 | + return ZFCP_ERP_FAILED; |
---|
| 882 | + |
---|
| 883 | + zfcp_erp_adapter_strategy_open_ptp_port(act->adapter); |
---|
830 | 884 | |
---|
831 | 885 | if (mempool_resize(act->adapter->pool.sr_data, |
---|
832 | 886 | act->adapter->stat_read_buf_num)) |
---|
.. | .. |
---|
859 | 913 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status); |
---|
860 | 914 | } |
---|
861 | 915 | |
---|
862 | | -static int zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *act) |
---|
| 916 | +static enum zfcp_erp_act_result zfcp_erp_adapter_strategy_open( |
---|
| 917 | + struct zfcp_erp_action *act) |
---|
863 | 918 | { |
---|
864 | 919 | struct zfcp_adapter *adapter = act->adapter; |
---|
865 | 920 | |
---|
.. | .. |
---|
880 | 935 | return ZFCP_ERP_SUCCEEDED; |
---|
881 | 936 | } |
---|
882 | 937 | |
---|
883 | | -static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *act) |
---|
| 938 | +static enum zfcp_erp_act_result zfcp_erp_adapter_strategy( |
---|
| 939 | + struct zfcp_erp_action *act) |
---|
884 | 940 | { |
---|
885 | 941 | struct zfcp_adapter *adapter = act->adapter; |
---|
886 | 942 | |
---|
.. | .. |
---|
898 | 954 | return ZFCP_ERP_SUCCEEDED; |
---|
899 | 955 | } |
---|
900 | 956 | |
---|
901 | | -static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *act) |
---|
| 957 | +static enum zfcp_erp_act_result zfcp_erp_port_forced_strategy_close( |
---|
| 958 | + struct zfcp_erp_action *act) |
---|
902 | 959 | { |
---|
903 | 960 | int retval; |
---|
904 | 961 | |
---|
.. | .. |
---|
912 | 969 | return ZFCP_ERP_CONTINUES; |
---|
913 | 970 | } |
---|
914 | 971 | |
---|
915 | | -static int zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action) |
---|
| 972 | +static enum zfcp_erp_act_result zfcp_erp_port_forced_strategy( |
---|
| 973 | + struct zfcp_erp_action *erp_action) |
---|
916 | 974 | { |
---|
917 | 975 | struct zfcp_port *port = erp_action->port; |
---|
918 | 976 | int status = atomic_read(&port->status); |
---|
.. | .. |
---|
928 | 986 | case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: |
---|
929 | 987 | if (!(status & ZFCP_STATUS_PORT_PHYS_OPEN)) |
---|
930 | 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; |
---|
931 | 996 | } |
---|
932 | 997 | return ZFCP_ERP_FAILED; |
---|
933 | 998 | } |
---|
934 | 999 | |
---|
935 | | -static int zfcp_erp_port_strategy_close(struct zfcp_erp_action *erp_action) |
---|
| 1000 | +static enum zfcp_erp_act_result zfcp_erp_port_strategy_close( |
---|
| 1001 | + struct zfcp_erp_action *erp_action) |
---|
936 | 1002 | { |
---|
937 | 1003 | int retval; |
---|
938 | 1004 | |
---|
.. | .. |
---|
945 | 1011 | return ZFCP_ERP_CONTINUES; |
---|
946 | 1012 | } |
---|
947 | 1013 | |
---|
948 | | -static int zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action) |
---|
| 1014 | +static enum zfcp_erp_act_result zfcp_erp_port_strategy_open_port( |
---|
| 1015 | + struct zfcp_erp_action *erp_action) |
---|
949 | 1016 | { |
---|
950 | 1017 | int retval; |
---|
951 | 1018 | |
---|
.. | .. |
---|
971 | 1038 | return zfcp_erp_port_strategy_open_port(act); |
---|
972 | 1039 | } |
---|
973 | 1040 | |
---|
974 | | -static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) |
---|
| 1041 | +static enum zfcp_erp_act_result zfcp_erp_port_strategy_open_common( |
---|
| 1042 | + struct zfcp_erp_action *act) |
---|
975 | 1043 | { |
---|
976 | 1044 | struct zfcp_adapter *adapter = act->adapter; |
---|
977 | 1045 | struct zfcp_port *port = act->port; |
---|
.. | .. |
---|
1002 | 1070 | port->d_id = 0; |
---|
1003 | 1071 | return ZFCP_ERP_FAILED; |
---|
1004 | 1072 | } |
---|
1005 | | - /* fall through otherwise */ |
---|
| 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; |
---|
1006 | 1079 | } |
---|
1007 | 1080 | return ZFCP_ERP_FAILED; |
---|
1008 | 1081 | } |
---|
1009 | 1082 | |
---|
1010 | | -static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) |
---|
| 1083 | +static enum zfcp_erp_act_result zfcp_erp_port_strategy( |
---|
| 1084 | + struct zfcp_erp_action *erp_action) |
---|
1011 | 1085 | { |
---|
1012 | 1086 | struct zfcp_port *port = erp_action->port; |
---|
1013 | 1087 | int p_status = atomic_read(&port->status); |
---|
.. | .. |
---|
1026 | 1100 | if (p_status & ZFCP_STATUS_COMMON_OPEN) |
---|
1027 | 1101 | return ZFCP_ERP_FAILED; |
---|
1028 | 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; |
---|
1029 | 1109 | } |
---|
1030 | 1110 | |
---|
1031 | 1111 | close_init_done: |
---|
.. | .. |
---|
1043 | 1123 | &zfcp_sdev->status); |
---|
1044 | 1124 | } |
---|
1045 | 1125 | |
---|
1046 | | -static int zfcp_erp_lun_strategy_close(struct zfcp_erp_action *erp_action) |
---|
| 1126 | +static enum zfcp_erp_act_result zfcp_erp_lun_strategy_close( |
---|
| 1127 | + struct zfcp_erp_action *erp_action) |
---|
1047 | 1128 | { |
---|
1048 | 1129 | int retval = zfcp_fsf_close_lun(erp_action); |
---|
1049 | 1130 | if (retval == -ENOMEM) |
---|
.. | .. |
---|
1054 | 1135 | return ZFCP_ERP_CONTINUES; |
---|
1055 | 1136 | } |
---|
1056 | 1137 | |
---|
1057 | | -static int zfcp_erp_lun_strategy_open(struct zfcp_erp_action *erp_action) |
---|
| 1138 | +static enum zfcp_erp_act_result zfcp_erp_lun_strategy_open( |
---|
| 1139 | + struct zfcp_erp_action *erp_action) |
---|
1058 | 1140 | { |
---|
1059 | 1141 | int retval = zfcp_fsf_open_lun(erp_action); |
---|
1060 | 1142 | if (retval == -ENOMEM) |
---|
.. | .. |
---|
1065 | 1147 | return ZFCP_ERP_CONTINUES; |
---|
1066 | 1148 | } |
---|
1067 | 1149 | |
---|
1068 | | -static int zfcp_erp_lun_strategy(struct zfcp_erp_action *erp_action) |
---|
| 1150 | +static enum zfcp_erp_act_result zfcp_erp_lun_strategy( |
---|
| 1151 | + struct zfcp_erp_action *erp_action) |
---|
1069 | 1152 | { |
---|
1070 | 1153 | struct scsi_device *sdev = erp_action->sdev; |
---|
1071 | 1154 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
---|
.. | .. |
---|
1075 | 1158 | zfcp_erp_lun_strategy_clearstati(sdev); |
---|
1076 | 1159 | if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN) |
---|
1077 | 1160 | return zfcp_erp_lun_strategy_close(erp_action); |
---|
1078 | | - /* already closed, fall through */ |
---|
| 1161 | + /* already closed */ |
---|
| 1162 | + fallthrough; |
---|
1079 | 1163 | case ZFCP_ERP_STEP_LUN_CLOSING: |
---|
1080 | 1164 | if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN) |
---|
1081 | 1165 | return ZFCP_ERP_FAILED; |
---|
.. | .. |
---|
1086 | 1170 | case ZFCP_ERP_STEP_LUN_OPENING: |
---|
1087 | 1171 | if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN) |
---|
1088 | 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; |
---|
1089 | 1179 | } |
---|
1090 | 1180 | return ZFCP_ERP_FAILED; |
---|
1091 | 1181 | } |
---|
1092 | 1182 | |
---|
1093 | | -static int zfcp_erp_strategy_check_lun(struct scsi_device *sdev, int result) |
---|
| 1183 | +static enum zfcp_erp_act_result zfcp_erp_strategy_check_lun( |
---|
| 1184 | + struct scsi_device *sdev, enum zfcp_erp_act_result result) |
---|
1094 | 1185 | { |
---|
1095 | 1186 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
---|
1096 | 1187 | |
---|
.. | .. |
---|
1111 | 1202 | ZFCP_STATUS_COMMON_ERP_FAILED); |
---|
1112 | 1203 | } |
---|
1113 | 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; |
---|
1114 | 1211 | } |
---|
1115 | 1212 | |
---|
1116 | 1213 | if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { |
---|
.. | .. |
---|
1120 | 1217 | return result; |
---|
1121 | 1218 | } |
---|
1122 | 1219 | |
---|
1123 | | -static int zfcp_erp_strategy_check_port(struct zfcp_port *port, int result) |
---|
| 1220 | +static enum zfcp_erp_act_result zfcp_erp_strategy_check_port( |
---|
| 1221 | + struct zfcp_port *port, enum zfcp_erp_act_result result) |
---|
1124 | 1222 | { |
---|
1125 | 1223 | switch (result) { |
---|
1126 | 1224 | case ZFCP_ERP_SUCCEEDED : |
---|
.. | .. |
---|
1142 | 1240 | ZFCP_STATUS_COMMON_ERP_FAILED); |
---|
1143 | 1241 | } |
---|
1144 | 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; |
---|
1145 | 1249 | } |
---|
1146 | 1250 | |
---|
1147 | 1251 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { |
---|
.. | .. |
---|
1151 | 1255 | return result; |
---|
1152 | 1256 | } |
---|
1153 | 1257 | |
---|
1154 | | -static int zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, |
---|
1155 | | - int result) |
---|
| 1258 | +static enum zfcp_erp_act_result zfcp_erp_strategy_check_adapter( |
---|
| 1259 | + struct zfcp_adapter *adapter, enum zfcp_erp_act_result result) |
---|
1156 | 1260 | { |
---|
1157 | 1261 | switch (result) { |
---|
1158 | 1262 | case ZFCP_ERP_SUCCEEDED : |
---|
.. | .. |
---|
1170 | 1274 | ZFCP_STATUS_COMMON_ERP_FAILED); |
---|
1171 | 1275 | } |
---|
1172 | 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; |
---|
1173 | 1283 | } |
---|
1174 | 1284 | |
---|
1175 | 1285 | if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { |
---|
.. | .. |
---|
1179 | 1289 | return result; |
---|
1180 | 1290 | } |
---|
1181 | 1291 | |
---|
1182 | | -static int zfcp_erp_strategy_check_target(struct zfcp_erp_action *erp_action, |
---|
1183 | | - int result) |
---|
| 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) |
---|
1184 | 1294 | { |
---|
1185 | 1295 | struct zfcp_adapter *adapter = erp_action->adapter; |
---|
1186 | 1296 | struct zfcp_port *port = erp_action->port; |
---|
1187 | 1297 | struct scsi_device *sdev = erp_action->sdev; |
---|
1188 | 1298 | |
---|
1189 | | - switch (erp_action->action) { |
---|
| 1299 | + switch (erp_action->type) { |
---|
1190 | 1300 | |
---|
1191 | 1301 | case ZFCP_ERP_ACTION_REOPEN_LUN: |
---|
1192 | 1302 | result = zfcp_erp_strategy_check_lun(sdev, result); |
---|
.. | .. |
---|
1219 | 1329 | return 0; |
---|
1220 | 1330 | } |
---|
1221 | 1331 | |
---|
1222 | | -static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret) |
---|
| 1332 | +static enum zfcp_erp_act_result zfcp_erp_strategy_statechange( |
---|
| 1333 | + struct zfcp_erp_action *act, enum zfcp_erp_act_result result) |
---|
1223 | 1334 | { |
---|
1224 | | - int action = act->action; |
---|
| 1335 | + enum zfcp_erp_act_type type = act->type; |
---|
1225 | 1336 | struct zfcp_adapter *adapter = act->adapter; |
---|
1226 | 1337 | struct zfcp_port *port = act->port; |
---|
1227 | 1338 | struct scsi_device *sdev = act->sdev; |
---|
1228 | 1339 | struct zfcp_scsi_dev *zfcp_sdev; |
---|
1229 | 1340 | u32 erp_status = act->status; |
---|
1230 | 1341 | |
---|
1231 | | - switch (action) { |
---|
| 1342 | + switch (type) { |
---|
1232 | 1343 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
---|
1233 | 1344 | if (zfcp_erp_strat_change_det(&adapter->status, erp_status)) { |
---|
1234 | 1345 | _zfcp_erp_adapter_reopen(adapter, |
---|
.. | .. |
---|
1258 | 1369 | } |
---|
1259 | 1370 | break; |
---|
1260 | 1371 | } |
---|
1261 | | - return ret; |
---|
| 1372 | + return result; |
---|
1262 | 1373 | } |
---|
1263 | 1374 | |
---|
1264 | 1375 | static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action) |
---|
.. | .. |
---|
1275 | 1386 | list_del(&erp_action->list); |
---|
1276 | 1387 | zfcp_dbf_rec_run("eractd1", erp_action); |
---|
1277 | 1388 | |
---|
1278 | | - switch (erp_action->action) { |
---|
| 1389 | + switch (erp_action->type) { |
---|
1279 | 1390 | case ZFCP_ERP_ACTION_REOPEN_LUN: |
---|
1280 | 1391 | zfcp_sdev = sdev_to_zfcp(erp_action->sdev); |
---|
1281 | 1392 | atomic_andnot(ZFCP_STATUS_COMMON_ERP_INUSE, |
---|
.. | .. |
---|
1354 | 1465 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
---|
1355 | 1466 | } |
---|
1356 | 1467 | |
---|
1357 | | -static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) |
---|
| 1468 | +static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, |
---|
| 1469 | + enum zfcp_erp_act_result result) |
---|
1358 | 1470 | { |
---|
1359 | 1471 | struct zfcp_adapter *adapter = act->adapter; |
---|
1360 | 1472 | struct zfcp_port *port = act->port; |
---|
1361 | 1473 | struct scsi_device *sdev = act->sdev; |
---|
1362 | 1474 | |
---|
1363 | | - switch (act->action) { |
---|
| 1475 | + switch (act->type) { |
---|
1364 | 1476 | case ZFCP_ERP_ACTION_REOPEN_LUN: |
---|
1365 | 1477 | if (!(act->status & ZFCP_STATUS_ERP_NO_REF)) |
---|
1366 | 1478 | scsi_device_put(sdev); |
---|
.. | .. |
---|
1376 | 1488 | if (act->step != ZFCP_ERP_STEP_UNINITIALIZED) |
---|
1377 | 1489 | if (result == ZFCP_ERP_SUCCEEDED) |
---|
1378 | 1490 | zfcp_erp_try_rport_unblock(port); |
---|
1379 | | - /* fall through */ |
---|
| 1491 | + fallthrough; |
---|
1380 | 1492 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
---|
1381 | 1493 | put_device(&port->dev); |
---|
1382 | 1494 | break; |
---|
.. | .. |
---|
1394 | 1506 | } |
---|
1395 | 1507 | } |
---|
1396 | 1508 | |
---|
1397 | | -static int zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action) |
---|
| 1509 | +static enum zfcp_erp_act_result zfcp_erp_strategy_do_action( |
---|
| 1510 | + struct zfcp_erp_action *erp_action) |
---|
1398 | 1511 | { |
---|
1399 | | - switch (erp_action->action) { |
---|
| 1512 | + switch (erp_action->type) { |
---|
1400 | 1513 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
---|
1401 | 1514 | return zfcp_erp_adapter_strategy(erp_action); |
---|
1402 | 1515 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
---|
.. | .. |
---|
1409 | 1522 | return ZFCP_ERP_FAILED; |
---|
1410 | 1523 | } |
---|
1411 | 1524 | |
---|
1412 | | -static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action) |
---|
| 1525 | +static enum zfcp_erp_act_result zfcp_erp_strategy( |
---|
| 1526 | + struct zfcp_erp_action *erp_action) |
---|
1413 | 1527 | { |
---|
1414 | | - int retval; |
---|
| 1528 | + enum zfcp_erp_act_result result; |
---|
1415 | 1529 | unsigned long flags; |
---|
1416 | 1530 | struct zfcp_adapter *adapter = erp_action->adapter; |
---|
1417 | 1531 | |
---|
.. | .. |
---|
1422 | 1536 | |
---|
1423 | 1537 | if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) { |
---|
1424 | 1538 | zfcp_erp_action_dequeue(erp_action); |
---|
1425 | | - retval = ZFCP_ERP_DISMISSED; |
---|
| 1539 | + result = ZFCP_ERP_DISMISSED; |
---|
1426 | 1540 | goto unlock; |
---|
1427 | 1541 | } |
---|
1428 | 1542 | |
---|
1429 | 1543 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { |
---|
1430 | | - retval = ZFCP_ERP_FAILED; |
---|
| 1544 | + result = ZFCP_ERP_FAILED; |
---|
1431 | 1545 | goto check_target; |
---|
1432 | 1546 | } |
---|
1433 | 1547 | |
---|
.. | .. |
---|
1435 | 1549 | |
---|
1436 | 1550 | /* no lock to allow for blocking operations */ |
---|
1437 | 1551 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
---|
1438 | | - retval = zfcp_erp_strategy_do_action(erp_action); |
---|
| 1552 | + result = zfcp_erp_strategy_do_action(erp_action); |
---|
1439 | 1553 | write_lock_irqsave(&adapter->erp_lock, flags); |
---|
1440 | 1554 | |
---|
1441 | 1555 | if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) |
---|
1442 | | - retval = ZFCP_ERP_CONTINUES; |
---|
| 1556 | + result = ZFCP_ERP_CONTINUES; |
---|
1443 | 1557 | |
---|
1444 | | - switch (retval) { |
---|
| 1558 | + switch (result) { |
---|
1445 | 1559 | case ZFCP_ERP_NOMEM: |
---|
1446 | 1560 | if (!(erp_action->status & ZFCP_STATUS_ERP_LOWMEM)) { |
---|
1447 | 1561 | ++adapter->erp_low_mem_count; |
---|
.. | .. |
---|
1451 | 1565 | _zfcp_erp_adapter_reopen(adapter, 0, "erstgy1"); |
---|
1452 | 1566 | else { |
---|
1453 | 1567 | zfcp_erp_strategy_memwait(erp_action); |
---|
1454 | | - retval = ZFCP_ERP_CONTINUES; |
---|
| 1568 | + result = ZFCP_ERP_CONTINUES; |
---|
1455 | 1569 | } |
---|
1456 | 1570 | goto unlock; |
---|
1457 | 1571 | |
---|
.. | .. |
---|
1461 | 1575 | erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM; |
---|
1462 | 1576 | } |
---|
1463 | 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; |
---|
1464 | 1584 | } |
---|
1465 | 1585 | |
---|
1466 | 1586 | check_target: |
---|
1467 | | - retval = zfcp_erp_strategy_check_target(erp_action, retval); |
---|
| 1587 | + result = zfcp_erp_strategy_check_target(erp_action, result); |
---|
1468 | 1588 | zfcp_erp_action_dequeue(erp_action); |
---|
1469 | | - retval = zfcp_erp_strategy_statechange(erp_action, retval); |
---|
1470 | | - if (retval == ZFCP_ERP_EXIT) |
---|
| 1589 | + result = zfcp_erp_strategy_statechange(erp_action, result); |
---|
| 1590 | + if (result == ZFCP_ERP_EXIT) |
---|
1471 | 1591 | goto unlock; |
---|
1472 | | - if (retval == ZFCP_ERP_SUCCEEDED) |
---|
| 1592 | + if (result == ZFCP_ERP_SUCCEEDED) |
---|
1473 | 1593 | zfcp_erp_strategy_followup_success(erp_action); |
---|
1474 | | - if (retval == ZFCP_ERP_FAILED) |
---|
| 1594 | + if (result == ZFCP_ERP_FAILED) |
---|
1475 | 1595 | zfcp_erp_strategy_followup_failed(erp_action); |
---|
1476 | 1596 | |
---|
1477 | 1597 | unlock: |
---|
1478 | 1598 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
---|
1479 | 1599 | |
---|
1480 | | - if (retval != ZFCP_ERP_CONTINUES) |
---|
1481 | | - zfcp_erp_action_cleanup(erp_action, retval); |
---|
| 1600 | + if (result != ZFCP_ERP_CONTINUES) |
---|
| 1601 | + zfcp_erp_action_cleanup(erp_action, result); |
---|
1482 | 1602 | |
---|
1483 | 1603 | kref_put(&adapter->ref, zfcp_adapter_release); |
---|
1484 | | - return retval; |
---|
| 1604 | + return result; |
---|
1485 | 1605 | } |
---|
1486 | 1606 | |
---|
1487 | 1607 | static int zfcp_erp_thread(void *data) |
---|
1488 | 1608 | { |
---|
1489 | 1609 | struct zfcp_adapter *adapter = (struct zfcp_adapter *) data; |
---|
1490 | | - struct list_head *next; |
---|
1491 | 1610 | struct zfcp_erp_action *act; |
---|
1492 | 1611 | unsigned long flags; |
---|
1493 | 1612 | |
---|
.. | .. |
---|
1500 | 1619 | break; |
---|
1501 | 1620 | |
---|
1502 | 1621 | write_lock_irqsave(&adapter->erp_lock, flags); |
---|
1503 | | - next = adapter->erp_ready_head.next; |
---|
| 1622 | + act = list_first_entry_or_null(&adapter->erp_ready_head, |
---|
| 1623 | + struct zfcp_erp_action, list); |
---|
1504 | 1624 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
---|
1505 | 1625 | |
---|
1506 | | - if (next != &adapter->erp_ready_head) { |
---|
1507 | | - act = list_entry(next, struct zfcp_erp_action, list); |
---|
1508 | | - |
---|
| 1626 | + if (act) { |
---|
1509 | 1627 | /* there is more to come after dismission, no notify */ |
---|
1510 | 1628 | if (zfcp_erp_strategy(act) != ZFCP_ERP_DISMISSED) |
---|
1511 | 1629 | zfcp_erp_wakeup(adapter); |
---|
.. | .. |
---|
1519 | 1637 | * zfcp_erp_thread_setup - Start ERP thread for adapter |
---|
1520 | 1638 | * @adapter: Adapter to start the ERP thread for |
---|
1521 | 1639 | * |
---|
1522 | | - * Returns 0 on success or error code from kernel_thread() |
---|
| 1640 | + * Return: 0 on success, or error code from kthread_run(). |
---|
1523 | 1641 | */ |
---|
1524 | 1642 | int zfcp_erp_thread_setup(struct zfcp_adapter *adapter) |
---|
1525 | 1643 | { |
---|
.. | .. |
---|
1589 | 1707 | atomic_or(common_mask, &port->status); |
---|
1590 | 1708 | read_unlock_irqrestore(&adapter->port_list_lock, flags); |
---|
1591 | 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 | + |
---|
1592 | 1717 | spin_lock_irqsave(adapter->scsi_host->host_lock, flags); |
---|
1593 | 1718 | __shost_for_each_device(sdev, adapter->scsi_host) |
---|
1594 | 1719 | atomic_or(common_mask, &sdev_to_zfcp(sdev)->status); |
---|
.. | .. |
---|
1625 | 1750 | atomic_set(&port->erp_counter, 0); |
---|
1626 | 1751 | } |
---|
1627 | 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; |
---|
1628 | 1760 | |
---|
1629 | 1761 | spin_lock_irqsave(adapter->scsi_host->host_lock, flags); |
---|
1630 | 1762 | __shost_for_each_device(sdev, adapter->scsi_host) { |
---|
.. | .. |
---|
1724 | 1856 | /** |
---|
1725 | 1857 | * zfcp_erp_adapter_reset_sync() - Really reopen adapter and wait. |
---|
1726 | 1858 | * @adapter: Pointer to zfcp_adapter to reopen. |
---|
1727 | | - * @id: Trace tag string of length %ZFCP_DBF_TAG_LEN. |
---|
| 1859 | + * @dbftag: Trace tag string of length %ZFCP_DBF_TAG_LEN. |
---|
1728 | 1860 | */ |
---|
1729 | | -void zfcp_erp_adapter_reset_sync(struct zfcp_adapter *adapter, char *id) |
---|
| 1861 | +void zfcp_erp_adapter_reset_sync(struct zfcp_adapter *adapter, char *dbftag) |
---|
1730 | 1862 | { |
---|
1731 | 1863 | zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING); |
---|
1732 | | - zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, id); |
---|
| 1864 | + zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, dbftag); |
---|
1733 | 1865 | zfcp_erp_wait(adapter); |
---|
1734 | 1866 | } |
---|