blob: f74412bd9d6ad9c2100b7f4637d93f543a4b011c [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Andreas Herrmann4a9d2d82006-05-22 18:14:08 +02002 * This file is part of the zfcp device driver for
3 * FCP adapters for IBM System z9 and zSeries.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 *
Andreas Herrmann4a9d2d82006-05-22 18:14:08 +02005 * (C) Copyright IBM Corp. 2002, 2006
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#define ZFCP_LOG_AREA ZFCP_LOG_AREA_ERP
23
Linus Torvalds1da177e2005-04-16 15:20:36 -070024#include "zfcp_ext.h"
25
Andreas Herrmann64b29a132005-06-13 13:18:56 +020026static int zfcp_erp_adisc(struct zfcp_port *);
Linus Torvalds1da177e2005-04-16 15:20:36 -070027static void zfcp_erp_adisc_handler(unsigned long);
28
29static int zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *, int);
30static int zfcp_erp_port_forced_reopen_internal(struct zfcp_port *, int);
31static int zfcp_erp_port_reopen_internal(struct zfcp_port *, int);
32static int zfcp_erp_unit_reopen_internal(struct zfcp_unit *, int);
33
34static int zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *, int);
35static int zfcp_erp_unit_reopen_all_internal(struct zfcp_port *, int);
36
37static void zfcp_erp_adapter_block(struct zfcp_adapter *, int);
38static void zfcp_erp_adapter_unblock(struct zfcp_adapter *);
39static void zfcp_erp_port_block(struct zfcp_port *, int);
40static void zfcp_erp_port_unblock(struct zfcp_port *);
41static void zfcp_erp_unit_block(struct zfcp_unit *, int);
42static void zfcp_erp_unit_unblock(struct zfcp_unit *);
43
44static int zfcp_erp_thread(void *);
45
46static int zfcp_erp_strategy(struct zfcp_erp_action *);
47
48static int zfcp_erp_strategy_do_action(struct zfcp_erp_action *);
49static int zfcp_erp_strategy_memwait(struct zfcp_erp_action *);
50static int zfcp_erp_strategy_check_target(struct zfcp_erp_action *, int);
51static int zfcp_erp_strategy_check_unit(struct zfcp_unit *, int);
52static int zfcp_erp_strategy_check_port(struct zfcp_port *, int);
53static int zfcp_erp_strategy_check_adapter(struct zfcp_adapter *, int);
54static int zfcp_erp_strategy_statechange(int, u32, struct zfcp_adapter *,
55 struct zfcp_port *,
56 struct zfcp_unit *, int);
57static inline int zfcp_erp_strategy_statechange_detected(atomic_t *, u32);
58static int zfcp_erp_strategy_followup_actions(int, struct zfcp_adapter *,
59 struct zfcp_port *,
60 struct zfcp_unit *, int);
61static int zfcp_erp_strategy_check_queues(struct zfcp_adapter *);
62static int zfcp_erp_strategy_check_action(struct zfcp_erp_action *, int);
63
64static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *);
65static int zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *, int);
66static int zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *);
67static int zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *);
68static int zfcp_erp_adapter_strategy_close_fsf(struct zfcp_erp_action *);
69static int zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *);
70static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *);
71static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *);
72static int zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *);
Maxim Shchetyninaef4a982005-09-13 21:51:16 +020073static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *);
Linus Torvalds1da177e2005-04-16 15:20:36 -070074static int zfcp_erp_adapter_strategy_open_fsf_statusread(
75 struct zfcp_erp_action *);
76
77static int zfcp_erp_port_forced_strategy(struct zfcp_erp_action *);
78static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *);
79
80static int zfcp_erp_port_strategy(struct zfcp_erp_action *);
81static int zfcp_erp_port_strategy_clearstati(struct zfcp_port *);
82static int zfcp_erp_port_strategy_close(struct zfcp_erp_action *);
83static int zfcp_erp_port_strategy_open(struct zfcp_erp_action *);
84static int zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *);
85static int zfcp_erp_port_strategy_open_nameserver_wakeup(
86 struct zfcp_erp_action *);
87static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *);
88static int zfcp_erp_port_strategy_open_common_lookup(struct zfcp_erp_action *);
89static int zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *);
90
91static int zfcp_erp_unit_strategy(struct zfcp_erp_action *);
92static int zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *);
93static int zfcp_erp_unit_strategy_close(struct zfcp_erp_action *);
94static int zfcp_erp_unit_strategy_open(struct zfcp_erp_action *);
95
96static int zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *);
97static int zfcp_erp_action_dismiss_port(struct zfcp_port *);
98static int zfcp_erp_action_dismiss_unit(struct zfcp_unit *);
99static int zfcp_erp_action_dismiss(struct zfcp_erp_action *);
100
101static int zfcp_erp_action_enqueue(int, struct zfcp_adapter *,
102 struct zfcp_port *, struct zfcp_unit *);
103static int zfcp_erp_action_dequeue(struct zfcp_erp_action *);
104static void zfcp_erp_action_cleanup(int, struct zfcp_adapter *,
105 struct zfcp_port *, struct zfcp_unit *,
106 int);
107
108static void zfcp_erp_action_ready(struct zfcp_erp_action *);
109static int zfcp_erp_action_exists(struct zfcp_erp_action *);
110
111static inline void zfcp_erp_action_to_ready(struct zfcp_erp_action *);
112static inline void zfcp_erp_action_to_running(struct zfcp_erp_action *);
113
114static void zfcp_erp_memwait_handler(unsigned long);
115static void zfcp_erp_timeout_handler(unsigned long);
116static inline void zfcp_erp_timeout_init(struct zfcp_erp_action *);
117
118/**
119 * zfcp_fsf_request_timeout_handler - called if a request timed out
120 * @data: pointer to adapter for handler function
121 *
122 * This function needs to be called if requests (ELS, Generic Service,
123 * or SCSI commands) exceed a certain time limit. The assumption is
124 * that after the time limit the adapter get stuck. So we trigger a reopen of
125 * the adapter. This should not be used for error recovery, SCSI abort
126 * commands and SCSI requests from SCSI mid-layer.
127 */
128void
129zfcp_fsf_request_timeout_handler(unsigned long data)
130{
131 struct zfcp_adapter *adapter;
132
133 adapter = (struct zfcp_adapter *) data;
134
135 zfcp_erp_adapter_reopen(adapter, 0);
136}
137
138/*
139 * function: zfcp_fsf_scsi_er_timeout_handler
140 *
141 * purpose: This function needs to be called whenever a SCSI error recovery
142 * action (abort/reset) does not return.
143 * Re-opening the adapter means that the command can be returned
144 * by zfcp (it is guarranteed that it does not return via the
145 * adapter anymore). The buffer can then be used again.
146 *
147 * returns: sod all
148 */
149void
150zfcp_fsf_scsi_er_timeout_handler(unsigned long data)
151{
152 struct zfcp_adapter *adapter = (struct zfcp_adapter *) data;
153
154 ZFCP_LOG_NORMAL("warning: SCSI error recovery timed out. "
155 "Restarting all operations on the adapter %s\n",
156 zfcp_get_busid_by_adapter(adapter));
157 debug_text_event(adapter->erp_dbf, 1, "eh_lmem_tout");
158 zfcp_erp_adapter_reopen(adapter, 0);
159
160 return;
161}
162
163/*
164 * function:
165 *
166 * purpose: called if an adapter failed,
167 * initiates adapter recovery which is done
168 * asynchronously
169 *
Andreas Mohrd6e05ed2006-06-26 18:35:02 +0200170 * returns: 0 - initiated action successfully
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171 * <0 - failed to initiate action
172 */
173int
174zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, int clear_mask)
175{
176 int retval;
177
178 debug_text_event(adapter->erp_dbf, 5, "a_ro");
179 ZFCP_LOG_DEBUG("reopen adapter %s\n",
180 zfcp_get_busid_by_adapter(adapter));
181
182 zfcp_erp_adapter_block(adapter, clear_mask);
183
184 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &adapter->status)) {
185 ZFCP_LOG_DEBUG("skipped reopen of failed adapter %s\n",
186 zfcp_get_busid_by_adapter(adapter));
187 debug_text_event(adapter->erp_dbf, 5, "a_ro_f");
188 /* ensure propagation of failed status to new devices */
189 zfcp_erp_adapter_failed(adapter);
190 retval = -EIO;
191 goto out;
192 }
193 retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER,
194 adapter, NULL, NULL);
195
196 out:
197 return retval;
198}
199
200/*
201 * function:
202 *
203 * purpose: Wrappper for zfcp_erp_adapter_reopen_internal
204 * used to ensure the correct locking
205 *
Andreas Mohrd6e05ed2006-06-26 18:35:02 +0200206 * returns: 0 - initiated action successfully
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207 * <0 - failed to initiate action
208 */
209int
210zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear_mask)
211{
212 int retval;
213 unsigned long flags;
214
215 read_lock_irqsave(&zfcp_data.config_lock, flags);
216 write_lock(&adapter->erp_lock);
217 retval = zfcp_erp_adapter_reopen_internal(adapter, clear_mask);
218 write_unlock(&adapter->erp_lock);
219 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
220
221 return retval;
222}
223
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224int
225zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear_mask)
226{
227 int retval;
228
229 retval = zfcp_erp_adapter_reopen(adapter,
230 ZFCP_STATUS_COMMON_RUNNING |
231 ZFCP_STATUS_COMMON_ERP_FAILED |
232 clear_mask);
233
234 return retval;
235}
236
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237int
238zfcp_erp_port_shutdown(struct zfcp_port *port, int clear_mask)
239{
240 int retval;
241
242 retval = zfcp_erp_port_reopen(port,
243 ZFCP_STATUS_COMMON_RUNNING |
244 ZFCP_STATUS_COMMON_ERP_FAILED |
245 clear_mask);
246
247 return retval;
248}
249
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250int
251zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear_mask)
252{
253 int retval;
254
255 retval = zfcp_erp_unit_reopen(unit,
256 ZFCP_STATUS_COMMON_RUNNING |
257 ZFCP_STATUS_COMMON_ERP_FAILED |
258 clear_mask);
259
260 return retval;
261}
262
263
264/**
265 * zfcp_erp_adisc - send ADISC ELS command
Andreas Herrmann64b29a132005-06-13 13:18:56 +0200266 * @port: port structure
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 */
268int
Andreas Herrmann64b29a132005-06-13 13:18:56 +0200269zfcp_erp_adisc(struct zfcp_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270{
Andreas Herrmann64b29a132005-06-13 13:18:56 +0200271 struct zfcp_adapter *adapter = port->adapter;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272 struct zfcp_send_els *send_els;
273 struct zfcp_ls_adisc *adisc;
274 void *address = NULL;
275 int retval = 0;
276 struct timer_list *timer;
277
Andreas Herrmannec4081c2006-05-22 18:17:30 +0200278 send_els = kzalloc(sizeof(struct zfcp_send_els), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 if (send_els == NULL)
280 goto nomem;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281
Andreas Herrmannec4081c2006-05-22 18:17:30 +0200282 send_els->req = kzalloc(sizeof(struct scatterlist), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 if (send_els->req == NULL)
284 goto nomem;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285
Andreas Herrmannec4081c2006-05-22 18:17:30 +0200286 send_els->resp = kzalloc(sizeof(struct scatterlist), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287 if (send_els->resp == NULL)
288 goto nomem;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289
290 address = (void *) get_zeroed_page(GFP_ATOMIC);
291 if (address == NULL)
292 goto nomem;
293
294 zfcp_address_to_sg(address, send_els->req);
295 address += PAGE_SIZE >> 1;
296 zfcp_address_to_sg(address, send_els->resp);
297 send_els->req_count = send_els->resp_count = 1;
298
299 send_els->adapter = adapter;
Andreas Herrmann64b29a132005-06-13 13:18:56 +0200300 send_els->port = port;
301 send_els->d_id = port->d_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 send_els->handler = zfcp_erp_adisc_handler;
303 send_els->handler_data = (unsigned long) send_els;
304
305 adisc = zfcp_sg_to_address(send_els->req);
306 send_els->ls_code = adisc->code = ZFCP_LS_ADISC;
307
308 send_els->req->length = sizeof(struct zfcp_ls_adisc);
309 send_els->resp->length = sizeof(struct zfcp_ls_adisc_acc);
310
311 /* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports
312 without FC-AL-2 capability, so we don't set it */
Andreas Herrmann13e1e1f2005-09-19 16:56:17 +0200313 adisc->wwpn = fc_host_port_name(adapter->scsi_host);
314 adisc->wwnn = fc_host_node_name(adapter->scsi_host);
315 adisc->nport_id = fc_host_port_id(adapter->scsi_host);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316 ZFCP_LOG_INFO("ADISC request from s_id 0x%08x to d_id 0x%08x "
317 "(wwpn=0x%016Lx, wwnn=0x%016Lx, "
318 "hard_nport_id=0x%08x, nport_id=0x%08x)\n",
Andreas Herrmann13e1e1f2005-09-19 16:56:17 +0200319 adisc->nport_id, send_els->d_id, (wwn_t) adisc->wwpn,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320 (wwn_t) adisc->wwnn, adisc->hard_nport_id,
321 adisc->nport_id);
322
323 timer = kmalloc(sizeof(struct timer_list), GFP_ATOMIC);
324 if (!timer)
325 goto nomem;
326
327 init_timer(timer);
328 timer->function = zfcp_fsf_request_timeout_handler;
329 timer->data = (unsigned long) adapter;
330 timer->expires = ZFCP_FSF_REQUEST_TIMEOUT;
331 send_els->timer = timer;
332
333 retval = zfcp_fsf_send_els(send_els);
334 if (retval != 0) {
335 ZFCP_LOG_NORMAL("error: initiation of Send ELS failed for port "
Andreas Herrmann64b29a132005-06-13 13:18:56 +0200336 "0x%08x on adapter %s\n", send_els->d_id,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337 zfcp_get_busid_by_adapter(adapter));
338 del_timer(send_els->timer);
339 goto freemem;
340 }
341
342 goto out;
343
344 nomem:
345 retval = -ENOMEM;
346 freemem:
347 if (address != NULL)
348 __free_pages(send_els->req->page, 0);
349 if (send_els != NULL) {
350 kfree(send_els->timer);
351 kfree(send_els->req);
352 kfree(send_els->resp);
353 kfree(send_els);
354 }
355 out:
356 return retval;
357}
358
359
360/**
361 * zfcp_erp_adisc_handler - handler for ADISC ELS command
362 * @data: pointer to struct zfcp_send_els
363 *
364 * If ADISC failed (LS_RJT or timed out) forced reopen of the port is triggered.
365 */
366void
367zfcp_erp_adisc_handler(unsigned long data)
368{
369 struct zfcp_send_els *send_els;
370 struct zfcp_port *port;
371 struct zfcp_adapter *adapter;
Andreas Herrmann13e1e1f2005-09-19 16:56:17 +0200372 u32 d_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 struct zfcp_ls_adisc_acc *adisc;
374
375 send_els = (struct zfcp_send_els *) data;
376
377 del_timer(send_els->timer);
378
379 adapter = send_els->adapter;
Andreas Herrmann64b29a132005-06-13 13:18:56 +0200380 port = send_els->port;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 d_id = send_els->d_id;
382
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 /* request rejected or timed out */
384 if (send_els->status != 0) {
385 ZFCP_LOG_NORMAL("ELS request rejected/timed out, "
386 "force physical port reopen "
387 "(adapter %s, port d_id=0x%08x)\n",
388 zfcp_get_busid_by_adapter(adapter), d_id);
389 debug_text_event(adapter->erp_dbf, 3, "forcreop");
390 if (zfcp_erp_port_forced_reopen(port, 0))
391 ZFCP_LOG_NORMAL("failed reopen of port "
392 "(adapter %s, wwpn=0x%016Lx)\n",
393 zfcp_get_busid_by_port(port),
394 port->wwpn);
395 goto out;
396 }
397
398 adisc = zfcp_sg_to_address(send_els->resp);
399
400 ZFCP_LOG_INFO("ADISC response from d_id 0x%08x to s_id "
401 "0x%08x (wwpn=0x%016Lx, wwnn=0x%016Lx, "
402 "hard_nport_id=0x%08x, nport_id=0x%08x)\n",
Andreas Herrmann13e1e1f2005-09-19 16:56:17 +0200403 d_id, fc_host_port_id(adapter->scsi_host),
404 (wwn_t) adisc->wwpn, (wwn_t) adisc->wwnn,
405 adisc->hard_nport_id, adisc->nport_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406
407 /* set wwnn for port */
408 if (port->wwnn == 0)
409 port->wwnn = adisc->wwnn;
410
411 if (port->wwpn != adisc->wwpn) {
412 ZFCP_LOG_NORMAL("d_id assignment changed, reopening "
413 "port (adapter %s, wwpn=0x%016Lx, "
414 "adisc_resp_wwpn=0x%016Lx)\n",
415 zfcp_get_busid_by_port(port),
416 port->wwpn, (wwn_t) adisc->wwpn);
417 if (zfcp_erp_port_reopen(port, 0))
418 ZFCP_LOG_NORMAL("failed reopen of port "
419 "(adapter %s, wwpn=0x%016Lx)\n",
420 zfcp_get_busid_by_port(port),
421 port->wwpn);
422 }
423
424 out:
425 zfcp_port_put(port);
426 __free_pages(send_els->req->page, 0);
427 kfree(send_els->timer);
428 kfree(send_els->req);
429 kfree(send_els->resp);
430 kfree(send_els);
431}
432
433
434/**
435 * zfcp_test_link - lightweight link test procedure
436 * @port: port to be tested
437 *
438 * Test status of a link to a remote port using the ELS command ADISC.
439 */
440int
441zfcp_test_link(struct zfcp_port *port)
442{
443 int retval;
444
445 zfcp_port_get(port);
Andreas Herrmann64b29a132005-06-13 13:18:56 +0200446 retval = zfcp_erp_adisc(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 if (retval != 0) {
448 zfcp_port_put(port);
449 ZFCP_LOG_NORMAL("reopen needed for port 0x%016Lx "
450 "on adapter %s\n ", port->wwpn,
451 zfcp_get_busid_by_port(port));
452 retval = zfcp_erp_port_forced_reopen(port, 0);
453 if (retval != 0) {
454 ZFCP_LOG_NORMAL("reopen of remote port 0x%016Lx "
455 "on adapter %s failed\n", port->wwpn,
456 zfcp_get_busid_by_port(port));
457 retval = -EPERM;
458 }
459 }
460
461 return retval;
462}
463
464
465/*
466 * function:
467 *
468 * purpose: called if a port failed to be opened normally
469 * initiates Forced Reopen recovery which is done
470 * asynchronously
471 *
Andreas Mohrd6e05ed2006-06-26 18:35:02 +0200472 * returns: 0 - initiated action successfully
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 * <0 - failed to initiate action
474 */
475static int
476zfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, int clear_mask)
477{
478 int retval;
479 struct zfcp_adapter *adapter = port->adapter;
480
481 debug_text_event(adapter->erp_dbf, 5, "pf_ro");
482 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
483
484 ZFCP_LOG_DEBUG("forced reopen of port 0x%016Lx on adapter %s\n",
485 port->wwpn, zfcp_get_busid_by_port(port));
486
487 zfcp_erp_port_block(port, clear_mask);
488
489 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) {
490 ZFCP_LOG_DEBUG("skipped forced reopen of failed port 0x%016Lx "
491 "on adapter %s\n", port->wwpn,
492 zfcp_get_busid_by_port(port));
493 debug_text_event(adapter->erp_dbf, 5, "pf_ro_f");
494 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
495 retval = -EIO;
496 goto out;
497 }
498
499 retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,
500 port->adapter, port, NULL);
501
502 out:
503 return retval;
504}
505
506/*
507 * function:
508 *
509 * purpose: Wrappper for zfcp_erp_port_forced_reopen_internal
510 * used to ensure the correct locking
511 *
Andreas Mohrd6e05ed2006-06-26 18:35:02 +0200512 * returns: 0 - initiated action successfully
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513 * <0 - failed to initiate action
514 */
515int
516zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask)
517{
518 int retval;
519 unsigned long flags;
520 struct zfcp_adapter *adapter;
521
522 adapter = port->adapter;
523 read_lock_irqsave(&zfcp_data.config_lock, flags);
524 write_lock(&adapter->erp_lock);
525 retval = zfcp_erp_port_forced_reopen_internal(port, clear_mask);
526 write_unlock(&adapter->erp_lock);
527 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
528
529 return retval;
530}
531
532/*
533 * function:
534 *
535 * purpose: called if a port is to be opened
536 * initiates Reopen recovery which is done
537 * asynchronously
538 *
Andreas Mohrd6e05ed2006-06-26 18:35:02 +0200539 * returns: 0 - initiated action successfully
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 * <0 - failed to initiate action
541 */
542static int
543zfcp_erp_port_reopen_internal(struct zfcp_port *port, int clear_mask)
544{
545 int retval;
546 struct zfcp_adapter *adapter = port->adapter;
547
548 debug_text_event(adapter->erp_dbf, 5, "p_ro");
549 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
550
551 ZFCP_LOG_DEBUG("reopen of port 0x%016Lx on adapter %s\n",
552 port->wwpn, zfcp_get_busid_by_port(port));
553
554 zfcp_erp_port_block(port, clear_mask);
555
556 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) {
557 ZFCP_LOG_DEBUG("skipped reopen of failed port 0x%016Lx "
558 "on adapter %s\n", port->wwpn,
559 zfcp_get_busid_by_port(port));
560 debug_text_event(adapter->erp_dbf, 5, "p_ro_f");
561 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
562 /* ensure propagation of failed status to new devices */
563 zfcp_erp_port_failed(port);
564 retval = -EIO;
565 goto out;
566 }
567
568 retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT,
569 port->adapter, port, NULL);
570
571 out:
572 return retval;
573}
574
575/**
576 * zfcp_erp_port_reopen - initiate reopen of a remote port
577 * @port: port to be reopened
578 * @clear_mask: specifies flags in port status to be cleared
579 * Return: 0 on success, < 0 on error
580 *
581 * This is a wrappper function for zfcp_erp_port_reopen_internal. It ensures
582 * correct locking. An error recovery task is initiated to do the reopen.
583 * To wait for the completion of the reopen zfcp_erp_wait should be used.
584 */
585int
586zfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask)
587{
588 int retval;
589 unsigned long flags;
590 struct zfcp_adapter *adapter = port->adapter;
591
592 read_lock_irqsave(&zfcp_data.config_lock, flags);
593 write_lock(&adapter->erp_lock);
594 retval = zfcp_erp_port_reopen_internal(port, clear_mask);
595 write_unlock(&adapter->erp_lock);
596 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
597
598 return retval;
599}
600
601/*
602 * function:
603 *
604 * purpose: called if a unit is to be opened
605 * initiates Reopen recovery which is done
606 * asynchronously
607 *
Andreas Mohrd6e05ed2006-06-26 18:35:02 +0200608 * returns: 0 - initiated action successfully
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 * <0 - failed to initiate action
610 */
611static int
612zfcp_erp_unit_reopen_internal(struct zfcp_unit *unit, int clear_mask)
613{
614 int retval;
615 struct zfcp_adapter *adapter = unit->port->adapter;
616
617 debug_text_event(adapter->erp_dbf, 5, "u_ro");
618 debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, sizeof (fcp_lun_t));
619 ZFCP_LOG_DEBUG("reopen of unit 0x%016Lx on port 0x%016Lx "
620 "on adapter %s\n", unit->fcp_lun,
621 unit->port->wwpn, zfcp_get_busid_by_unit(unit));
622
623 zfcp_erp_unit_block(unit, clear_mask);
624
625 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &unit->status)) {
626 ZFCP_LOG_DEBUG("skipped reopen of failed unit 0x%016Lx "
627 "on port 0x%016Lx on adapter %s\n",
628 unit->fcp_lun, unit->port->wwpn,
629 zfcp_get_busid_by_unit(unit));
630 debug_text_event(adapter->erp_dbf, 5, "u_ro_f");
631 debug_event(adapter->erp_dbf, 5, &unit->fcp_lun,
632 sizeof (fcp_lun_t));
633 retval = -EIO;
634 goto out;
635 }
636
637 retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_UNIT,
638 unit->port->adapter, unit->port, unit);
639 out:
640 return retval;
641}
642
643/**
644 * zfcp_erp_unit_reopen - initiate reopen of a unit
645 * @unit: unit to be reopened
646 * @clear_mask: specifies flags in unit status to be cleared
647 * Return: 0 on success, < 0 on error
648 *
649 * This is a wrappper for zfcp_erp_unit_reopen_internal. It ensures correct
650 * locking. An error recovery task is initiated to do the reopen.
651 * To wait for the completion of the reopen zfcp_erp_wait should be used.
652 */
653int
654zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear_mask)
655{
656 int retval;
657 unsigned long flags;
658 struct zfcp_adapter *adapter;
659 struct zfcp_port *port;
660
661 port = unit->port;
662 adapter = port->adapter;
663
664 read_lock_irqsave(&zfcp_data.config_lock, flags);
665 write_lock(&adapter->erp_lock);
666 retval = zfcp_erp_unit_reopen_internal(unit, clear_mask);
667 write_unlock(&adapter->erp_lock);
668 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
669
670 return retval;
671}
672
673/*
674 * function:
675 *
676 * purpose: disable I/O,
677 * return any open requests and clean them up,
678 * aim: no pending and incoming I/O
679 *
680 * returns:
681 */
682static void
683zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int clear_mask)
684{
685 debug_text_event(adapter->erp_dbf, 6, "a_bl");
686 zfcp_erp_modify_adapter_status(adapter,
687 ZFCP_STATUS_COMMON_UNBLOCKED |
688 clear_mask, ZFCP_CLEAR);
689}
690
691/*
692 * function:
693 *
694 * purpose: enable I/O
695 *
696 * returns:
697 */
698static void
699zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter)
700{
701 debug_text_event(adapter->erp_dbf, 6, "a_ubl");
702 atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status);
703}
704
705/*
706 * function:
707 *
708 * purpose: disable I/O,
709 * return any open requests and clean them up,
710 * aim: no pending and incoming I/O
711 *
712 * returns:
713 */
714static void
715zfcp_erp_port_block(struct zfcp_port *port, int clear_mask)
716{
717 struct zfcp_adapter *adapter = port->adapter;
718
719 debug_text_event(adapter->erp_dbf, 6, "p_bl");
720 debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));
721 zfcp_erp_modify_port_status(port,
722 ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask,
723 ZFCP_CLEAR);
724}
725
726/*
727 * function:
728 *
729 * purpose: enable I/O
730 *
731 * returns:
732 */
733static void
734zfcp_erp_port_unblock(struct zfcp_port *port)
735{
736 struct zfcp_adapter *adapter = port->adapter;
737
738 debug_text_event(adapter->erp_dbf, 6, "p_ubl");
739 debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));
740 atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status);
741}
742
743/*
744 * function:
745 *
746 * purpose: disable I/O,
747 * return any open requests and clean them up,
748 * aim: no pending and incoming I/O
749 *
750 * returns:
751 */
752static void
753zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask)
754{
755 struct zfcp_adapter *adapter = unit->port->adapter;
756
757 debug_text_event(adapter->erp_dbf, 6, "u_bl");
758 debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t));
759 zfcp_erp_modify_unit_status(unit,
760 ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask,
761 ZFCP_CLEAR);
762}
763
764/*
765 * function:
766 *
767 * purpose: enable I/O
768 *
769 * returns:
770 */
771static void
772zfcp_erp_unit_unblock(struct zfcp_unit *unit)
773{
774 struct zfcp_adapter *adapter = unit->port->adapter;
775
776 debug_text_event(adapter->erp_dbf, 6, "u_ubl");
777 debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t));
778 atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status);
779}
780
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781static void
782zfcp_erp_action_ready(struct zfcp_erp_action *erp_action)
783{
784 struct zfcp_adapter *adapter = erp_action->adapter;
785
786 debug_text_event(adapter->erp_dbf, 4, "a_ar");
787 debug_event(adapter->erp_dbf, 4, &erp_action->action, sizeof (int));
788
789 zfcp_erp_action_to_ready(erp_action);
790 up(&adapter->erp_ready_sem);
791}
792
793/*
794 * function:
795 *
796 * purpose:
797 *
798 * returns: <0 erp_action not found in any list
799 * ZFCP_ERP_ACTION_READY erp_action is in ready list
800 * ZFCP_ERP_ACTION_RUNNING erp_action is in running list
801 *
802 * locks: erp_lock must be held
803 */
804static int
805zfcp_erp_action_exists(struct zfcp_erp_action *erp_action)
806{
807 int retval = -EINVAL;
808 struct list_head *entry;
809 struct zfcp_erp_action *entry_erp_action;
810 struct zfcp_adapter *adapter = erp_action->adapter;
811
812 /* search in running list */
813 list_for_each(entry, &adapter->erp_running_head) {
814 entry_erp_action =
815 list_entry(entry, struct zfcp_erp_action, list);
816 if (entry_erp_action == erp_action) {
817 retval = ZFCP_ERP_ACTION_RUNNING;
818 goto out;
819 }
820 }
821 /* search in ready list */
822 list_for_each(entry, &adapter->erp_ready_head) {
823 entry_erp_action =
824 list_entry(entry, struct zfcp_erp_action, list);
825 if (entry_erp_action == erp_action) {
826 retval = ZFCP_ERP_ACTION_READY;
827 goto out;
828 }
829 }
830
831 out:
832 return retval;
833}
834
835/*
836 * purpose: checks current status of action (timed out, dismissed, ...)
837 * and does appropriate preparations (dismiss fsf request, ...)
838 *
839 * locks: called under erp_lock (disabled interrupts)
840 *
841 * returns: 0
842 */
843static int
844zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
845{
846 int retval = 0;
Andreas Herrmann3734d242005-09-13 21:47:11 +0200847 struct zfcp_fsf_req *fsf_req = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 struct zfcp_adapter *adapter = erp_action->adapter;
849
850 if (erp_action->fsf_req) {
Volker Sameskefea9d6c2006-08-02 11:05:16 +0200851 /* take lock to ensure that request is not deleted meanwhile */
852 spin_lock(&adapter->req_list_lock);
853 if ((!zfcp_reqlist_ismember(adapter,
854 erp_action->fsf_req->req_id)) &&
855 (fsf_req->erp_action == erp_action)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 /* fsf_req still exists */
857 debug_text_event(adapter->erp_dbf, 3, "a_ca_req");
858 debug_event(adapter->erp_dbf, 3, &fsf_req,
859 sizeof (unsigned long));
Volker Sameskefea9d6c2006-08-02 11:05:16 +0200860 /* dismiss fsf_req of timed out/dismissed erp_action */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861 if (erp_action->status & (ZFCP_STATUS_ERP_DISMISSED |
862 ZFCP_STATUS_ERP_TIMEDOUT)) {
863 debug_text_event(adapter->erp_dbf, 3,
864 "a_ca_disreq");
865 fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
866 }
867 if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
868 ZFCP_LOG_NORMAL("error: erp step timed out "
869 "(action=%d, fsf_req=%p)\n ",
870 erp_action->action,
871 erp_action->fsf_req);
872 }
873 /*
874 * If fsf_req is neither dismissed nor completed
875 * then keep it running asynchronously and don't mess
876 * with the association of erp_action and fsf_req.
877 */
878 if (fsf_req->status & (ZFCP_STATUS_FSFREQ_COMPLETED |
879 ZFCP_STATUS_FSFREQ_DISMISSED)) {
880 /* forget about association between fsf_req
881 and erp_action */
882 fsf_req->erp_action = NULL;
883 erp_action->fsf_req = NULL;
884 }
885 } else {
886 debug_text_event(adapter->erp_dbf, 3, "a_ca_gonereq");
887 /*
888 * even if this fsf_req has gone, forget about
889 * association between erp_action and fsf_req
890 */
891 erp_action->fsf_req = NULL;
892 }
Volker Sameskefea9d6c2006-08-02 11:05:16 +0200893 spin_unlock(&adapter->req_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894 } else
895 debug_text_event(adapter->erp_dbf, 3, "a_ca_noreq");
896
897 return retval;
898}
899
900/*
901 * purpose: generic handler for asynchronous events related to erp_action events
902 * (normal completion, time-out, dismissing, retry after
903 * low memory condition)
904 *
905 * note: deletion of timer is not required (e.g. in case of a time-out),
906 * but a second try does no harm,
907 * we leave it in here to allow for greater simplification
908 *
909 * returns: 0 - there was an action to handle
910 * !0 - otherwise
911 */
912static int
913zfcp_erp_async_handler_nolock(struct zfcp_erp_action *erp_action,
914 unsigned long set_mask)
915{
916 int retval;
917 struct zfcp_adapter *adapter = erp_action->adapter;
918
919 if (zfcp_erp_action_exists(erp_action) == ZFCP_ERP_ACTION_RUNNING) {
920 debug_text_event(adapter->erp_dbf, 2, "a_asyh_ex");
921 debug_event(adapter->erp_dbf, 2, &erp_action->action,
922 sizeof (int));
923 if (!(set_mask & ZFCP_STATUS_ERP_TIMEDOUT))
924 del_timer(&erp_action->timer);
925 erp_action->status |= set_mask;
926 zfcp_erp_action_ready(erp_action);
927 retval = 0;
928 } else {
929 /* action is ready or gone - nothing to do */
930 debug_text_event(adapter->erp_dbf, 3, "a_asyh_gone");
931 debug_event(adapter->erp_dbf, 3, &erp_action->action,
932 sizeof (int));
933 retval = 1;
934 }
935
936 return retval;
937}
938
939/*
940 * purpose: generic handler for asynchronous events related to erp_action
941 * events (normal completion, time-out, dismissing, retry after
942 * low memory condition)
943 *
944 * note: deletion of timer is not required (e.g. in case of a time-out),
945 * but a second try does no harm,
946 * we leave it in here to allow for greater simplification
947 *
948 * returns: 0 - there was an action to handle
949 * !0 - otherwise
950 */
951int
952zfcp_erp_async_handler(struct zfcp_erp_action *erp_action,
953 unsigned long set_mask)
954{
955 struct zfcp_adapter *adapter = erp_action->adapter;
956 unsigned long flags;
957 int retval;
958
959 write_lock_irqsave(&adapter->erp_lock, flags);
960 retval = zfcp_erp_async_handler_nolock(erp_action, set_mask);
961 write_unlock_irqrestore(&adapter->erp_lock, flags);
962
963 return retval;
964}
965
966/*
967 * purpose: is called for erp_action which was slept waiting for
968 * memory becoming avaliable,
969 * will trigger that this action will be continued
970 */
971static void
972zfcp_erp_memwait_handler(unsigned long data)
973{
974 struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data;
975 struct zfcp_adapter *adapter = erp_action->adapter;
976
977 debug_text_event(adapter->erp_dbf, 2, "a_mwh");
978 debug_event(adapter->erp_dbf, 2, &erp_action->action, sizeof (int));
979
980 zfcp_erp_async_handler(erp_action, 0);
981}
982
983/*
984 * purpose: is called if an asynchronous erp step timed out,
985 * action gets an appropriate flag and will be processed
986 * accordingly
987 */
988static void
989zfcp_erp_timeout_handler(unsigned long data)
990{
991 struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data;
992 struct zfcp_adapter *adapter = erp_action->adapter;
993
994 debug_text_event(adapter->erp_dbf, 2, "a_th");
995 debug_event(adapter->erp_dbf, 2, &erp_action->action, sizeof (int));
996
997 zfcp_erp_async_handler(erp_action, ZFCP_STATUS_ERP_TIMEDOUT);
998}
999
1000/*
1001 * purpose: is called for an erp_action which needs to be ended
1002 * though not being done,
1003 * this is usually required if an higher is generated,
1004 * action gets an appropriate flag and will be processed
1005 * accordingly
1006 *
1007 * locks: erp_lock held (thus we need to call another handler variant)
1008 */
1009static int
1010zfcp_erp_action_dismiss(struct zfcp_erp_action *erp_action)
1011{
1012 struct zfcp_adapter *adapter = erp_action->adapter;
1013
1014 debug_text_event(adapter->erp_dbf, 2, "a_adis");
1015 debug_event(adapter->erp_dbf, 2, &erp_action->action, sizeof (int));
1016
1017 zfcp_erp_async_handler_nolock(erp_action, ZFCP_STATUS_ERP_DISMISSED);
1018
1019 return 0;
1020}
1021
1022int
1023zfcp_erp_thread_setup(struct zfcp_adapter *adapter)
1024{
1025 int retval = 0;
1026
1027 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
1028
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD);
1030 if (retval < 0) {
1031 ZFCP_LOG_NORMAL("error: creation of erp thread failed for "
1032 "adapter %s\n",
1033 zfcp_get_busid_by_adapter(adapter));
1034 debug_text_event(adapter->erp_dbf, 5, "a_thset_fail");
1035 } else {
1036 wait_event(adapter->erp_thread_wqh,
1037 atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP,
1038 &adapter->status));
1039 debug_text_event(adapter->erp_dbf, 5, "a_thset_ok");
1040 }
1041
1042 return (retval < 0);
1043}
1044
1045/*
1046 * function:
1047 *
1048 * purpose:
1049 *
1050 * returns:
1051 *
1052 * context: process (i.e. proc-fs or rmmod/insmod)
1053 *
1054 * note: The caller of this routine ensures that the specified
1055 * adapter has been shut down and that this operation
1056 * has been completed. Thus, there are no pending erp_actions
1057 * which would need to be handled here.
1058 */
1059int
1060zfcp_erp_thread_kill(struct zfcp_adapter *adapter)
1061{
1062 int retval = 0;
1063
1064 atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status);
1065 up(&adapter->erp_ready_sem);
1066
1067 wait_event(adapter->erp_thread_wqh,
1068 !atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP,
1069 &adapter->status));
1070
1071 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL,
1072 &adapter->status);
1073
1074 debug_text_event(adapter->erp_dbf, 5, "a_thki_ok");
1075
1076 return retval;
1077}
1078
1079/*
1080 * purpose: is run as a kernel thread,
1081 * goes through list of error recovery actions of associated adapter
1082 * and delegates single action to execution
1083 *
1084 * returns: 0
1085 */
1086static int
1087zfcp_erp_thread(void *data)
1088{
1089 struct zfcp_adapter *adapter = (struct zfcp_adapter *) data;
1090 struct list_head *next;
1091 struct zfcp_erp_action *erp_action;
1092 unsigned long flags;
1093
1094 daemonize("zfcperp%s", zfcp_get_busid_by_adapter(adapter));
1095 /* Block all signals */
1096 siginitsetinv(&current->blocked, 0);
1097 atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
1098 debug_text_event(adapter->erp_dbf, 5, "a_th_run");
1099 wake_up(&adapter->erp_thread_wqh);
1100
1101 while (!atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL,
1102 &adapter->status)) {
1103
1104 write_lock_irqsave(&adapter->erp_lock, flags);
1105 next = adapter->erp_ready_head.prev;
1106 write_unlock_irqrestore(&adapter->erp_lock, flags);
1107
1108 if (next != &adapter->erp_ready_head) {
1109 erp_action =
1110 list_entry(next, struct zfcp_erp_action, list);
1111 /*
1112 * process action (incl. [re]moving it
1113 * from 'ready' queue)
1114 */
1115 zfcp_erp_strategy(erp_action);
1116 }
1117
1118 /*
1119 * sleep as long as there is nothing to do, i.e.
1120 * no action in 'ready' queue to be processed and
1121 * thread is not to be killed
1122 */
1123 down_interruptible(&adapter->erp_ready_sem);
1124 debug_text_event(adapter->erp_dbf, 5, "a_th_woken");
1125 }
1126
1127 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
1128 debug_text_event(adapter->erp_dbf, 5, "a_th_stop");
1129 wake_up(&adapter->erp_thread_wqh);
1130
1131 return 0;
1132}
1133
1134/*
1135 * function:
1136 *
1137 * purpose: drives single error recovery action and schedules higher and
1138 * subordinate actions, if necessary
1139 *
1140 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
1141 * ZFCP_ERP_SUCCEEDED - action finished successfully (deqd)
1142 * ZFCP_ERP_FAILED - action finished unsuccessfully (deqd)
1143 * ZFCP_ERP_EXIT - action finished (dequeued), offline
1144 * ZFCP_ERP_DISMISSED - action canceled (dequeued)
1145 */
1146static int
1147zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
1148{
1149 int retval = 0;
1150 struct zfcp_adapter *adapter = erp_action->adapter;
1151 struct zfcp_port *port = erp_action->port;
1152 struct zfcp_unit *unit = erp_action->unit;
1153 int action = erp_action->action;
1154 u32 status = erp_action->status;
1155 unsigned long flags;
1156
1157 /* serialise dismissing, timing out, moving, enqueueing */
1158 read_lock_irqsave(&zfcp_data.config_lock, flags);
1159 write_lock(&adapter->erp_lock);
1160
1161 /* dequeue dismissed action and leave, if required */
1162 retval = zfcp_erp_strategy_check_action(erp_action, retval);
1163 if (retval == ZFCP_ERP_DISMISSED) {
1164 debug_text_event(adapter->erp_dbf, 4, "a_st_dis1");
1165 goto unlock;
1166 }
1167
1168 /*
1169 * move action to 'running' queue before processing it
1170 * (to avoid a race condition regarding moving the
1171 * action to the 'running' queue and back)
1172 */
1173 zfcp_erp_action_to_running(erp_action);
1174
1175 /*
1176 * try to process action as far as possible,
1177 * no lock to allow for blocking operations (kmalloc, qdio, ...),
1178 * afterwards the lock is required again for the following reasons:
1179 * - dequeueing of finished action and enqueueing of
1180 * follow-up actions must be atomic so that any other
1181 * reopen-routine does not believe there is nothing to do
1182 * and that it is safe to enqueue something else,
1183 * - we want to force any control thread which is dismissing
1184 * actions to finish this before we decide about
1185 * necessary steps to be taken here further
1186 */
1187 write_unlock(&adapter->erp_lock);
1188 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
1189 retval = zfcp_erp_strategy_do_action(erp_action);
1190 read_lock_irqsave(&zfcp_data.config_lock, flags);
1191 write_lock(&adapter->erp_lock);
1192
1193 /*
1194 * check for dismissed status again to avoid follow-up actions,
1195 * failing of targets and so on for dismissed actions
1196 */
1197 retval = zfcp_erp_strategy_check_action(erp_action, retval);
1198
1199 switch (retval) {
1200 case ZFCP_ERP_DISMISSED:
1201 /* leave since this action has ridden to its ancestors */
1202 debug_text_event(adapter->erp_dbf, 6, "a_st_dis2");
1203 goto unlock;
1204 case ZFCP_ERP_NOMEM:
1205 /* no memory to continue immediately, let it sleep */
1206 if (!(erp_action->status & ZFCP_STATUS_ERP_LOWMEM)) {
1207 ++adapter->erp_low_mem_count;
1208 erp_action->status |= ZFCP_STATUS_ERP_LOWMEM;
1209 }
1210 /* This condition is true if there is no memory available
1211 for any erp_action on this adapter. This implies that there
1212 are no elements in the memory pool(s) left for erp_actions.
1213 This might happen if an erp_action that used a memory pool
1214 element was timed out.
1215 */
1216 if (adapter->erp_total_count == adapter->erp_low_mem_count) {
1217 debug_text_event(adapter->erp_dbf, 3, "a_st_lowmem");
1218 ZFCP_LOG_NORMAL("error: no mempool elements available, "
1219 "restarting I/O on adapter %s "
1220 "to free mempool\n",
1221 zfcp_get_busid_by_adapter(adapter));
1222 zfcp_erp_adapter_reopen_internal(adapter, 0);
1223 } else {
1224 debug_text_event(adapter->erp_dbf, 2, "a_st_memw");
1225 retval = zfcp_erp_strategy_memwait(erp_action);
1226 }
1227 goto unlock;
1228 case ZFCP_ERP_CONTINUES:
1229 /* leave since this action runs asynchronously */
1230 debug_text_event(adapter->erp_dbf, 6, "a_st_cont");
1231 if (erp_action->status & ZFCP_STATUS_ERP_LOWMEM) {
1232 --adapter->erp_low_mem_count;
1233 erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM;
1234 }
1235 goto unlock;
1236 }
1237 /* ok, finished action (whatever its result is) */
1238
1239 /* check for unrecoverable targets */
1240 retval = zfcp_erp_strategy_check_target(erp_action, retval);
1241
1242 /* action must be dequeued (here to allow for further ones) */
1243 zfcp_erp_action_dequeue(erp_action);
1244
1245 /*
1246 * put this target through the erp mill again if someone has
1247 * requested to change the status of a target being online
1248 * to offline or the other way around
1249 * (old retval is preserved if nothing has to be done here)
1250 */
1251 retval = zfcp_erp_strategy_statechange(action, status, adapter,
1252 port, unit, retval);
1253
1254 /*
1255 * leave if target is in permanent error state or if
1256 * action is repeated in order to process state change
1257 */
1258 if (retval == ZFCP_ERP_EXIT) {
1259 debug_text_event(adapter->erp_dbf, 2, "a_st_exit");
1260 goto unlock;
1261 }
1262
1263 /* trigger follow up actions */
1264 zfcp_erp_strategy_followup_actions(action, adapter, port, unit, retval);
1265
1266 unlock:
1267 write_unlock(&adapter->erp_lock);
1268 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
1269
1270 if (retval != ZFCP_ERP_CONTINUES)
1271 zfcp_erp_action_cleanup(action, adapter, port, unit, retval);
1272
1273 /*
1274 * a few tasks remain when the erp queues are empty
1275 * (don't do that if the last action evaluated was dismissed
1276 * since this clearly indicates that there is more to come) :
1277 * - close the name server port if it is open yet
1278 * (enqueues another [probably] final action)
1279 * - otherwise, wake up whoever wants to be woken when we are
1280 * done with erp
1281 */
1282 if (retval != ZFCP_ERP_DISMISSED)
1283 zfcp_erp_strategy_check_queues(adapter);
1284
1285 debug_text_event(adapter->erp_dbf, 6, "a_st_done");
1286
1287 return retval;
1288}
1289
1290/*
1291 * function:
1292 *
1293 * purpose:
1294 *
1295 * returns: ZFCP_ERP_DISMISSED - if action has been dismissed
1296 * retval - otherwise
1297 */
1298static int
1299zfcp_erp_strategy_check_action(struct zfcp_erp_action *erp_action, int retval)
1300{
1301 struct zfcp_adapter *adapter = erp_action->adapter;
1302
1303 zfcp_erp_strategy_check_fsfreq(erp_action);
1304
1305 debug_event(adapter->erp_dbf, 5, &erp_action->action, sizeof (int));
1306 if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) {
1307 debug_text_event(adapter->erp_dbf, 3, "a_stcd_dis");
1308 zfcp_erp_action_dequeue(erp_action);
1309 retval = ZFCP_ERP_DISMISSED;
1310 } else
1311 debug_text_event(adapter->erp_dbf, 5, "a_stcd_nodis");
1312
1313 return retval;
1314}
1315
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316static int
1317zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action)
1318{
1319 int retval = ZFCP_ERP_FAILED;
1320 struct zfcp_adapter *adapter = erp_action->adapter;
1321
1322 /*
1323 * try to execute/continue action as far as possible,
1324 * note: no lock in subsequent strategy routines
1325 * (this allows these routine to call schedule, e.g.
1326 * kmalloc with such flags or qdio_initialize & friends)
1327 * Note: in case of timeout, the seperate strategies will fail
1328 * anyhow. No need for a special action. Even worse, a nameserver
1329 * failure would not wake up waiting ports without the call.
1330 */
1331 switch (erp_action->action) {
1332
1333 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
1334 retval = zfcp_erp_adapter_strategy(erp_action);
1335 break;
1336
1337 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
1338 retval = zfcp_erp_port_forced_strategy(erp_action);
1339 break;
1340
1341 case ZFCP_ERP_ACTION_REOPEN_PORT:
1342 retval = zfcp_erp_port_strategy(erp_action);
1343 break;
1344
1345 case ZFCP_ERP_ACTION_REOPEN_UNIT:
1346 retval = zfcp_erp_unit_strategy(erp_action);
1347 break;
1348
1349 default:
1350 debug_text_exception(adapter->erp_dbf, 1, "a_stda_bug");
1351 debug_event(adapter->erp_dbf, 1, &erp_action->action,
1352 sizeof (int));
1353 ZFCP_LOG_NORMAL("bug: unknown erp action requested on "
1354 "adapter %s (action=%d)\n",
1355 zfcp_get_busid_by_adapter(erp_action->adapter),
1356 erp_action->action);
1357 }
1358
1359 return retval;
1360}
1361
1362/*
1363 * function:
1364 *
1365 * purpose: triggers retry of this action after a certain amount of time
1366 * by means of timer provided by erp_action
1367 *
1368 * returns: ZFCP_ERP_CONTINUES - erp_action sleeps in erp running queue
1369 */
1370static int
1371zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action)
1372{
1373 int retval = ZFCP_ERP_CONTINUES;
1374 struct zfcp_adapter *adapter = erp_action->adapter;
1375
1376 debug_text_event(adapter->erp_dbf, 6, "a_mwinit");
1377 debug_event(adapter->erp_dbf, 6, &erp_action->action, sizeof (int));
1378 init_timer(&erp_action->timer);
1379 erp_action->timer.function = zfcp_erp_memwait_handler;
1380 erp_action->timer.data = (unsigned long) erp_action;
1381 erp_action->timer.expires = jiffies + ZFCP_ERP_MEMWAIT_TIMEOUT;
1382 add_timer(&erp_action->timer);
1383
1384 return retval;
1385}
1386
1387/*
1388 * function: zfcp_erp_adapter_failed
1389 *
1390 * purpose: sets the adapter and all underlying devices to ERP_FAILED
1391 *
1392 */
1393void
1394zfcp_erp_adapter_failed(struct zfcp_adapter *adapter)
1395{
1396 zfcp_erp_modify_adapter_status(adapter,
1397 ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
1398 ZFCP_LOG_NORMAL("adapter erp failed on adapter %s\n",
1399 zfcp_get_busid_by_adapter(adapter));
1400 debug_text_event(adapter->erp_dbf, 2, "a_afail");
1401}
1402
1403/*
1404 * function: zfcp_erp_port_failed
1405 *
1406 * purpose: sets the port and all underlying devices to ERP_FAILED
1407 *
1408 */
1409void
1410zfcp_erp_port_failed(struct zfcp_port *port)
1411{
1412 zfcp_erp_modify_port_status(port,
1413 ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
1414
1415 if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
1416 ZFCP_LOG_NORMAL("port erp failed (adapter %s, "
1417 "port d_id=0x%08x)\n",
1418 zfcp_get_busid_by_port(port), port->d_id);
1419 else
1420 ZFCP_LOG_NORMAL("port erp failed (adapter %s, wwpn=0x%016Lx)\n",
1421 zfcp_get_busid_by_port(port), port->wwpn);
1422
1423 debug_text_event(port->adapter->erp_dbf, 2, "p_pfail");
1424 debug_event(port->adapter->erp_dbf, 2, &port->wwpn, sizeof (wwn_t));
1425}
1426
1427/*
1428 * function: zfcp_erp_unit_failed
1429 *
1430 * purpose: sets the unit to ERP_FAILED
1431 *
1432 */
1433void
1434zfcp_erp_unit_failed(struct zfcp_unit *unit)
1435{
1436 zfcp_erp_modify_unit_status(unit,
1437 ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
1438
1439 ZFCP_LOG_NORMAL("unit erp failed on unit 0x%016Lx on port 0x%016Lx "
1440 " on adapter %s\n", unit->fcp_lun,
1441 unit->port->wwpn, zfcp_get_busid_by_unit(unit));
1442 debug_text_event(unit->port->adapter->erp_dbf, 2, "u_ufail");
1443 debug_event(unit->port->adapter->erp_dbf, 2,
1444 &unit->fcp_lun, sizeof (fcp_lun_t));
1445}
1446
1447/*
1448 * function: zfcp_erp_strategy_check_target
1449 *
1450 * purpose: increments the erp action count on the device currently in
1451 * recovery if the action failed or resets the count in case of
1452 * success. If a maximum count is exceeded the device is marked
1453 * as ERP_FAILED.
1454 * The 'blocked' state of a target which has been recovered
1455 * successfully is reset.
1456 *
1457 * returns: ZFCP_ERP_CONTINUES - action continues (not considered)
1458 * ZFCP_ERP_SUCCEEDED - action finished successfully
1459 * ZFCP_ERP_EXIT - action failed and will not continue
1460 */
1461static int
1462zfcp_erp_strategy_check_target(struct zfcp_erp_action *erp_action, int result)
1463{
1464 struct zfcp_adapter *adapter = erp_action->adapter;
1465 struct zfcp_port *port = erp_action->port;
1466 struct zfcp_unit *unit = erp_action->unit;
1467
1468 debug_text_event(adapter->erp_dbf, 5, "a_stct_norm");
1469 debug_event(adapter->erp_dbf, 5, &erp_action->action, sizeof (int));
1470 debug_event(adapter->erp_dbf, 5, &result, sizeof (int));
1471
1472 switch (erp_action->action) {
1473
1474 case ZFCP_ERP_ACTION_REOPEN_UNIT:
1475 result = zfcp_erp_strategy_check_unit(unit, result);
1476 break;
1477
1478 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
1479 case ZFCP_ERP_ACTION_REOPEN_PORT:
1480 result = zfcp_erp_strategy_check_port(port, result);
1481 break;
1482
1483 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
1484 result = zfcp_erp_strategy_check_adapter(adapter, result);
1485 break;
1486 }
1487
1488 return result;
1489}
1490
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491static int
1492zfcp_erp_strategy_statechange(int action,
1493 u32 status,
1494 struct zfcp_adapter *adapter,
1495 struct zfcp_port *port,
1496 struct zfcp_unit *unit, int retval)
1497{
1498 debug_text_event(adapter->erp_dbf, 3, "a_stsc");
1499 debug_event(adapter->erp_dbf, 3, &action, sizeof (int));
1500
1501 switch (action) {
1502
1503 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
1504 if (zfcp_erp_strategy_statechange_detected(&adapter->status,
1505 status)) {
1506 zfcp_erp_adapter_reopen_internal(adapter, ZFCP_STATUS_COMMON_ERP_FAILED);
1507 retval = ZFCP_ERP_EXIT;
1508 }
1509 break;
1510
1511 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
1512 case ZFCP_ERP_ACTION_REOPEN_PORT:
1513 if (zfcp_erp_strategy_statechange_detected(&port->status,
1514 status)) {
1515 zfcp_erp_port_reopen_internal(port, ZFCP_STATUS_COMMON_ERP_FAILED);
1516 retval = ZFCP_ERP_EXIT;
1517 }
1518 break;
1519
1520 case ZFCP_ERP_ACTION_REOPEN_UNIT:
1521 if (zfcp_erp_strategy_statechange_detected(&unit->status,
1522 status)) {
1523 zfcp_erp_unit_reopen_internal(unit, ZFCP_STATUS_COMMON_ERP_FAILED);
1524 retval = ZFCP_ERP_EXIT;
1525 }
1526 break;
1527 }
1528
1529 return retval;
1530}
1531
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532static inline int
1533zfcp_erp_strategy_statechange_detected(atomic_t * target_status, u32 erp_status)
1534{
1535 return
1536 /* take it online */
1537 (atomic_test_mask(ZFCP_STATUS_COMMON_RUNNING, target_status) &&
1538 (ZFCP_STATUS_ERP_CLOSE_ONLY & erp_status)) ||
1539 /* take it offline */
1540 (!atomic_test_mask(ZFCP_STATUS_COMMON_RUNNING, target_status) &&
1541 !(ZFCP_STATUS_ERP_CLOSE_ONLY & erp_status));
1542}
1543
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544static int
1545zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result)
1546{
1547 debug_text_event(unit->port->adapter->erp_dbf, 5, "u_stct");
1548 debug_event(unit->port->adapter->erp_dbf, 5, &unit->fcp_lun,
1549 sizeof (fcp_lun_t));
1550
1551 switch (result) {
1552 case ZFCP_ERP_SUCCEEDED :
1553 atomic_set(&unit->erp_counter, 0);
1554 zfcp_erp_unit_unblock(unit);
1555 break;
1556 case ZFCP_ERP_FAILED :
1557 atomic_inc(&unit->erp_counter);
1558 if (atomic_read(&unit->erp_counter) > ZFCP_MAX_ERPS)
1559 zfcp_erp_unit_failed(unit);
1560 break;
1561 case ZFCP_ERP_EXIT :
1562 /* nothing */
1563 break;
1564 }
1565
1566 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &unit->status)) {
1567 zfcp_erp_unit_block(unit, 0); /* for ZFCP_ERP_SUCCEEDED */
1568 result = ZFCP_ERP_EXIT;
1569 }
1570
1571 return result;
1572}
1573
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574static int
1575zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
1576{
1577 debug_text_event(port->adapter->erp_dbf, 5, "p_stct");
1578 debug_event(port->adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
1579
1580 switch (result) {
1581 case ZFCP_ERP_SUCCEEDED :
1582 atomic_set(&port->erp_counter, 0);
1583 zfcp_erp_port_unblock(port);
1584 break;
1585 case ZFCP_ERP_FAILED :
1586 atomic_inc(&port->erp_counter);
1587 if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS)
1588 zfcp_erp_port_failed(port);
1589 break;
1590 case ZFCP_ERP_EXIT :
1591 /* nothing */
1592 break;
1593 }
1594
1595 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) {
1596 zfcp_erp_port_block(port, 0); /* for ZFCP_ERP_SUCCEEDED */
1597 result = ZFCP_ERP_EXIT;
1598 }
1599
1600 return result;
1601}
1602
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603static int
1604zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, int result)
1605{
1606 debug_text_event(adapter->erp_dbf, 5, "a_stct");
1607
1608 switch (result) {
1609 case ZFCP_ERP_SUCCEEDED :
1610 atomic_set(&adapter->erp_counter, 0);
1611 zfcp_erp_adapter_unblock(adapter);
1612 break;
1613 case ZFCP_ERP_FAILED :
1614 atomic_inc(&adapter->erp_counter);
1615 if (atomic_read(&adapter->erp_counter) > ZFCP_MAX_ERPS)
1616 zfcp_erp_adapter_failed(adapter);
1617 break;
1618 case ZFCP_ERP_EXIT :
1619 /* nothing */
1620 break;
1621 }
1622
1623 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &adapter->status)) {
1624 zfcp_erp_adapter_block(adapter, 0); /* for ZFCP_ERP_SUCCEEDED */
1625 result = ZFCP_ERP_EXIT;
1626 }
1627
1628 return result;
1629}
1630
1631/*
1632 * function:
1633 *
1634 * purpose: remaining things in good cases,
1635 * escalation in bad cases
1636 *
1637 * returns:
1638 */
1639static int
1640zfcp_erp_strategy_followup_actions(int action,
1641 struct zfcp_adapter *adapter,
1642 struct zfcp_port *port,
1643 struct zfcp_unit *unit, int status)
1644{
1645 debug_text_event(adapter->erp_dbf, 5, "a_stfol");
1646 debug_event(adapter->erp_dbf, 5, &action, sizeof (int));
1647
1648 /* initiate follow-up actions depending on success of finished action */
1649 switch (action) {
1650
1651 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
1652 if (status == ZFCP_ERP_SUCCEEDED)
1653 zfcp_erp_port_reopen_all_internal(adapter, 0);
1654 else
1655 zfcp_erp_adapter_reopen_internal(adapter, 0);
1656 break;
1657
1658 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
1659 if (status == ZFCP_ERP_SUCCEEDED)
1660 zfcp_erp_port_reopen_internal(port, 0);
1661 else
1662 zfcp_erp_adapter_reopen_internal(adapter, 0);
1663 break;
1664
1665 case ZFCP_ERP_ACTION_REOPEN_PORT:
1666 if (status == ZFCP_ERP_SUCCEEDED)
1667 zfcp_erp_unit_reopen_all_internal(port, 0);
1668 else
1669 zfcp_erp_port_forced_reopen_internal(port, 0);
1670 break;
1671
1672 case ZFCP_ERP_ACTION_REOPEN_UNIT:
1673 if (status == ZFCP_ERP_SUCCEEDED) ; /* no further action */
1674 else
1675 zfcp_erp_port_reopen_internal(unit->port, 0);
1676 break;
1677 }
1678
1679 return 0;
1680}
1681
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682static int
1683zfcp_erp_strategy_check_queues(struct zfcp_adapter *adapter)
1684{
1685 unsigned long flags;
1686
1687 read_lock_irqsave(&zfcp_data.config_lock, flags);
1688 read_lock(&adapter->erp_lock);
1689 if (list_empty(&adapter->erp_ready_head) &&
1690 list_empty(&adapter->erp_running_head)) {
1691 debug_text_event(adapter->erp_dbf, 4, "a_cq_wake");
1692 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING,
1693 &adapter->status);
1694 wake_up(&adapter->erp_done_wqh);
1695 } else
1696 debug_text_event(adapter->erp_dbf, 5, "a_cq_notempty");
1697 read_unlock(&adapter->erp_lock);
1698 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
1699
1700 return 0;
1701}
1702
1703/**
1704 * zfcp_erp_wait - wait for completion of error recovery on an adapter
1705 * @adapter: adapter for which to wait for completion of its error recovery
1706 * Return: 0
1707 */
1708int
1709zfcp_erp_wait(struct zfcp_adapter *adapter)
1710{
1711 int retval = 0;
1712
1713 wait_event(adapter->erp_done_wqh,
1714 !atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING,
1715 &adapter->status));
1716
1717 return retval;
1718}
1719
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720void
1721zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter,
1722 u32 mask, int set_or_clear)
1723{
1724 struct zfcp_port *port;
1725 u32 common_mask = mask & ZFCP_COMMON_FLAGS;
1726
1727 if (set_or_clear == ZFCP_SET) {
1728 atomic_set_mask(mask, &adapter->status);
1729 debug_text_event(adapter->erp_dbf, 3, "a_mod_as_s");
1730 } else {
1731 atomic_clear_mask(mask, &adapter->status);
1732 if (mask & ZFCP_STATUS_COMMON_ERP_FAILED)
1733 atomic_set(&adapter->erp_counter, 0);
1734 debug_text_event(adapter->erp_dbf, 3, "a_mod_as_c");
1735 }
1736 debug_event(adapter->erp_dbf, 3, &mask, sizeof (u32));
1737
1738 /* Deal with all underlying devices, only pass common_mask */
1739 if (common_mask)
1740 list_for_each_entry(port, &adapter->port_list_head, list)
1741 zfcp_erp_modify_port_status(port, common_mask,
1742 set_or_clear);
1743}
1744
1745/*
1746 * function: zfcp_erp_modify_port_status
1747 *
1748 * purpose: sets the port and all underlying devices to ERP_FAILED
1749 *
1750 */
1751void
1752zfcp_erp_modify_port_status(struct zfcp_port *port, u32 mask, int set_or_clear)
1753{
1754 struct zfcp_unit *unit;
1755 u32 common_mask = mask & ZFCP_COMMON_FLAGS;
1756
1757 if (set_or_clear == ZFCP_SET) {
1758 atomic_set_mask(mask, &port->status);
1759 debug_text_event(port->adapter->erp_dbf, 3, "p_mod_ps_s");
1760 } else {
1761 atomic_clear_mask(mask, &port->status);
1762 if (mask & ZFCP_STATUS_COMMON_ERP_FAILED)
1763 atomic_set(&port->erp_counter, 0);
1764 debug_text_event(port->adapter->erp_dbf, 3, "p_mod_ps_c");
1765 }
1766 debug_event(port->adapter->erp_dbf, 3, &port->wwpn, sizeof (wwn_t));
1767 debug_event(port->adapter->erp_dbf, 3, &mask, sizeof (u32));
1768
1769 /* Modify status of all underlying devices, only pass common mask */
1770 if (common_mask)
1771 list_for_each_entry(unit, &port->unit_list_head, list)
1772 zfcp_erp_modify_unit_status(unit, common_mask,
1773 set_or_clear);
1774}
1775
1776/*
1777 * function: zfcp_erp_modify_unit_status
1778 *
1779 * purpose: sets the unit to ERP_FAILED
1780 *
1781 */
1782void
1783zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u32 mask, int set_or_clear)
1784{
1785 if (set_or_clear == ZFCP_SET) {
1786 atomic_set_mask(mask, &unit->status);
1787 debug_text_event(unit->port->adapter->erp_dbf, 3, "u_mod_us_s");
1788 } else {
1789 atomic_clear_mask(mask, &unit->status);
1790 if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) {
1791 atomic_set(&unit->erp_counter, 0);
1792 }
1793 debug_text_event(unit->port->adapter->erp_dbf, 3, "u_mod_us_c");
1794 }
1795 debug_event(unit->port->adapter->erp_dbf, 3, &unit->fcp_lun,
1796 sizeof (fcp_lun_t));
1797 debug_event(unit->port->adapter->erp_dbf, 3, &mask, sizeof (u32));
1798}
1799
1800/*
1801 * function:
1802 *
1803 * purpose: Wrappper for zfcp_erp_port_reopen_all_internal
1804 * used to ensure the correct locking
1805 *
Andreas Mohrd6e05ed2006-06-26 18:35:02 +02001806 * returns: 0 - initiated action successfully
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 * <0 - failed to initiate action
1808 */
1809int
1810zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, int clear_mask)
1811{
1812 int retval;
1813 unsigned long flags;
1814
1815 read_lock_irqsave(&zfcp_data.config_lock, flags);
1816 write_lock(&adapter->erp_lock);
1817 retval = zfcp_erp_port_reopen_all_internal(adapter, clear_mask);
1818 write_unlock(&adapter->erp_lock);
1819 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
1820
1821 return retval;
1822}
1823
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824static int
1825zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *adapter, int clear_mask)
1826{
1827 int retval = 0;
1828 struct zfcp_port *port;
1829
1830 list_for_each_entry(port, &adapter->port_list_head, list)
1831 if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
1832 zfcp_erp_port_reopen_internal(port, clear_mask);
1833
1834 return retval;
1835}
1836
1837/*
1838 * function:
1839 *
1840 * purpose:
1841 *
1842 * returns: FIXME
1843 */
1844static int
1845zfcp_erp_unit_reopen_all_internal(struct zfcp_port *port, int clear_mask)
1846{
1847 int retval = 0;
1848 struct zfcp_unit *unit;
1849
1850 list_for_each_entry(unit, &port->unit_list_head, list)
1851 zfcp_erp_unit_reopen_internal(unit, clear_mask);
1852
1853 return retval;
1854}
1855
1856/*
1857 * function:
1858 *
1859 * purpose: this routine executes the 'Reopen Adapter' action
1860 * (the entire action is processed synchronously, since
1861 * there are no actions which might be run concurrently
1862 * per definition)
1863 *
1864 * returns: ZFCP_ERP_SUCCEEDED - action finished successfully
1865 * ZFCP_ERP_FAILED - action finished unsuccessfully
1866 */
1867static int
1868zfcp_erp_adapter_strategy(struct zfcp_erp_action *erp_action)
1869{
1870 int retval;
1871 struct zfcp_adapter *adapter = erp_action->adapter;
1872
1873 retval = zfcp_erp_adapter_strategy_close(erp_action);
1874 if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
1875 retval = ZFCP_ERP_EXIT;
1876 else
1877 retval = zfcp_erp_adapter_strategy_open(erp_action);
1878
1879 debug_text_event(adapter->erp_dbf, 3, "a_ast/ret");
1880 debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int));
1881 debug_event(adapter->erp_dbf, 3, &retval, sizeof (int));
1882
1883 if (retval == ZFCP_ERP_FAILED) {
1884 ZFCP_LOG_INFO("Waiting to allow the adapter %s "
1885 "to recover itself\n",
1886 zfcp_get_busid_by_adapter(adapter));
1887 msleep(jiffies_to_msecs(ZFCP_TYPE2_RECOVERY_TIME));
1888 }
1889
1890 return retval;
1891}
1892
1893/*
1894 * function:
1895 *
1896 * purpose:
1897 *
1898 * returns: ZFCP_ERP_SUCCEEDED - action finished successfully
1899 * ZFCP_ERP_FAILED - action finished unsuccessfully
1900 */
1901static int
1902zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *erp_action)
1903{
1904 int retval;
1905
1906 atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING,
1907 &erp_action->adapter->status);
1908 retval = zfcp_erp_adapter_strategy_generic(erp_action, 1);
1909 atomic_clear_mask(ZFCP_STATUS_COMMON_CLOSING,
1910 &erp_action->adapter->status);
1911
1912 return retval;
1913}
1914
1915/*
1916 * function:
1917 *
1918 * purpose:
1919 *
1920 * returns: ZFCP_ERP_SUCCEEDED - action finished successfully
1921 * ZFCP_ERP_FAILED - action finished unsuccessfully
1922 */
1923static int
1924zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *erp_action)
1925{
1926 int retval;
1927
1928 atomic_set_mask(ZFCP_STATUS_COMMON_OPENING,
1929 &erp_action->adapter->status);
1930 retval = zfcp_erp_adapter_strategy_generic(erp_action, 0);
1931 atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING,
1932 &erp_action->adapter->status);
1933
1934 return retval;
1935}
1936
1937/*
1938 * function: zfcp_register_adapter
1939 *
1940 * purpose: allocate the irq associated with this devno and register
1941 * the FSF adapter with the SCSI stack
1942 *
1943 * returns:
1944 */
1945static int
1946zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *erp_action, int close)
1947{
1948 int retval = ZFCP_ERP_SUCCEEDED;
1949
1950 if (close)
1951 goto close_only;
1952
1953 retval = zfcp_erp_adapter_strategy_open_qdio(erp_action);
1954 if (retval != ZFCP_ERP_SUCCEEDED)
1955 goto failed_qdio;
1956
1957 retval = zfcp_erp_adapter_strategy_open_fsf(erp_action);
1958 if (retval != ZFCP_ERP_SUCCEEDED)
1959 goto failed_openfcp;
1960
1961 atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &erp_action->adapter->status);
1962 goto out;
1963
1964 close_only:
1965 atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN,
1966 &erp_action->adapter->status);
1967
1968 failed_openfcp:
1969 zfcp_erp_adapter_strategy_close_qdio(erp_action);
1970 zfcp_erp_adapter_strategy_close_fsf(erp_action);
1971 failed_qdio:
1972 out:
1973 return retval;
1974}
1975
1976/*
1977 * function: zfcp_qdio_init
1978 *
1979 * purpose: setup QDIO operation for specified adapter
1980 *
1981 * returns: 0 - successful setup
1982 * !0 - failed setup
1983 */
1984int
1985zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
1986{
1987 int retval;
1988 int i;
1989 volatile struct qdio_buffer_element *sbale;
1990 struct zfcp_adapter *adapter = erp_action->adapter;
1991
1992 if (atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) {
1993 ZFCP_LOG_NORMAL("bug: second attempt to set up QDIO on "
1994 "adapter %s\n",
1995 zfcp_get_busid_by_adapter(adapter));
1996 goto failed_sanity;
1997 }
1998
1999 if (qdio_establish(&adapter->qdio_init_data) != 0) {
2000 ZFCP_LOG_INFO("error: establishment of QDIO queues failed "
2001 "on adapter %s\n",
2002 zfcp_get_busid_by_adapter(adapter));
2003 goto failed_qdio_establish;
2004 }
2005 debug_text_event(adapter->erp_dbf, 3, "qdio_est");
2006
2007 if (qdio_activate(adapter->ccw_device, 0) != 0) {
2008 ZFCP_LOG_INFO("error: activation of QDIO queues failed "
2009 "on adapter %s\n",
2010 zfcp_get_busid_by_adapter(adapter));
2011 goto failed_qdio_activate;
2012 }
2013 debug_text_event(adapter->erp_dbf, 3, "qdio_act");
2014
2015 /*
2016 * put buffers into response queue,
2017 */
2018 for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) {
2019 sbale = &(adapter->response_queue.buffer[i]->element[0]);
2020 sbale->length = 0;
2021 sbale->flags = SBAL_FLAGS_LAST_ENTRY;
2022 sbale->addr = 0;
2023 }
2024
2025 ZFCP_LOG_TRACE("calling do_QDIO on adapter %s (flags=0x%x, "
2026 "queue_no=%i, index_in_queue=%i, count=%i)\n",
2027 zfcp_get_busid_by_adapter(adapter),
2028 QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q);
2029
2030 retval = do_QDIO(adapter->ccw_device,
2031 QDIO_FLAG_SYNC_INPUT,
2032 0, 0, QDIO_MAX_BUFFERS_PER_Q, NULL);
2033
2034 if (retval) {
2035 ZFCP_LOG_NORMAL("bug: setup of QDIO failed (retval=%d)\n",
2036 retval);
2037 goto failed_do_qdio;
2038 } else {
2039 adapter->response_queue.free_index = 0;
2040 atomic_set(&adapter->response_queue.free_count, 0);
2041 ZFCP_LOG_DEBUG("%i buffers successfully enqueued to "
2042 "response queue\n", QDIO_MAX_BUFFERS_PER_Q);
2043 }
2044 /* set index of first avalable SBALS / number of available SBALS */
2045 adapter->request_queue.free_index = 0;
2046 atomic_set(&adapter->request_queue.free_count, QDIO_MAX_BUFFERS_PER_Q);
2047 adapter->request_queue.distance_from_int = 0;
2048
2049 /* initialize waitqueue used to wait for free SBALs in requests queue */
2050 init_waitqueue_head(&adapter->request_wq);
2051
2052 /* ok, we did it - skip all cleanups for different failures */
2053 atomic_set_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
2054 retval = ZFCP_ERP_SUCCEEDED;
2055 goto out;
2056
2057 failed_do_qdio:
2058 /* NOP */
2059
2060 failed_qdio_activate:
2061 debug_text_event(adapter->erp_dbf, 3, "qdio_down1a");
2062 while (qdio_shutdown(adapter->ccw_device,
2063 QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS)
2064 msleep(1000);
2065 debug_text_event(adapter->erp_dbf, 3, "qdio_down1b");
2066
2067 failed_qdio_establish:
2068 failed_sanity:
2069 retval = ZFCP_ERP_FAILED;
2070
2071 out:
2072 return retval;
2073}
2074
2075/*
2076 * function: zfcp_qdio_cleanup
2077 *
2078 * purpose: cleans up QDIO operation for the specified adapter
2079 *
2080 * returns: 0 - successful cleanup
2081 * !0 - failed cleanup
2082 */
2083int
2084zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action)
2085{
2086 int retval = ZFCP_ERP_SUCCEEDED;
2087 int first_used;
2088 int used_count;
2089 struct zfcp_adapter *adapter = erp_action->adapter;
2090
2091 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) {
2092 ZFCP_LOG_DEBUG("error: attempt to shut down inactive QDIO "
2093 "queues on adapter %s\n",
2094 zfcp_get_busid_by_adapter(adapter));
2095 retval = ZFCP_ERP_FAILED;
2096 goto out;
2097 }
2098
2099 /*
2100 * Get queue_lock and clear QDIOUP flag. Thus it's guaranteed that
2101 * do_QDIO won't be called while qdio_shutdown is in progress.
2102 */
2103
2104 write_lock_irq(&adapter->request_queue.queue_lock);
2105 atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
2106 write_unlock_irq(&adapter->request_queue.queue_lock);
2107
2108 debug_text_event(adapter->erp_dbf, 3, "qdio_down2a");
2109 while (qdio_shutdown(adapter->ccw_device,
2110 QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS)
2111 msleep(1000);
2112 debug_text_event(adapter->erp_dbf, 3, "qdio_down2b");
2113
2114 /*
2115 * First we had to stop QDIO operation.
2116 * Now it is safe to take the following actions.
2117 */
2118
2119 /* Cleanup only necessary when there are unacknowledged buffers */
2120 if (atomic_read(&adapter->request_queue.free_count)
2121 < QDIO_MAX_BUFFERS_PER_Q) {
2122 first_used = (adapter->request_queue.free_index +
2123 atomic_read(&adapter->request_queue.free_count))
2124 % QDIO_MAX_BUFFERS_PER_Q;
2125 used_count = QDIO_MAX_BUFFERS_PER_Q -
2126 atomic_read(&adapter->request_queue.free_count);
2127 zfcp_qdio_zero_sbals(adapter->request_queue.buffer,
2128 first_used, used_count);
2129 }
2130 adapter->response_queue.free_index = 0;
2131 atomic_set(&adapter->response_queue.free_count, 0);
2132 adapter->request_queue.free_index = 0;
2133 atomic_set(&adapter->request_queue.free_count, 0);
2134 adapter->request_queue.distance_from_int = 0;
2135 out:
2136 return retval;
2137}
2138
Linus Torvalds1da177e2005-04-16 15:20:36 -07002139static int
2140zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action)
2141{
Andreas Herrmann2448c452005-12-01 02:50:36 +01002142 int retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143
Andreas Herrmann2448c452005-12-01 02:50:36 +01002144 retval = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action);
2145 if (retval == ZFCP_ERP_FAILED)
2146 return ZFCP_ERP_FAILED;
2147
2148 retval = zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);
2149 if (retval == ZFCP_ERP_FAILED)
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02002150 return ZFCP_ERP_FAILED;
2151
2152 return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002153}
2154
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155static int
2156zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
2157{
2158 int retval = ZFCP_ERP_SUCCEEDED;
2159 int retries;
Andreas Herrmann22753fa2005-06-13 13:15:15 +02002160 int sleep = ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161 struct zfcp_adapter *adapter = erp_action->adapter;
2162
2163 atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002164
Andreas Herrmann22753fa2005-06-13 13:15:15 +02002165 for (retries = ZFCP_EXCHANGE_CONFIG_DATA_RETRIES; retries; retries--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002166 atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
2167 &adapter->status);
2168 ZFCP_LOG_DEBUG("Doing exchange config data\n");
Heiko Carstens9f09c542006-07-03 17:32:20 -07002169 write_lock_irq(&adapter->erp_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002170 zfcp_erp_action_to_running(erp_action);
Heiko Carstens9f09c542006-07-03 17:32:20 -07002171 write_unlock_irq(&adapter->erp_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002172 zfcp_erp_timeout_init(erp_action);
2173 if (zfcp_fsf_exchange_config_data(erp_action)) {
2174 retval = ZFCP_ERP_FAILED;
2175 debug_text_event(adapter->erp_dbf, 5, "a_fstx_xf");
2176 ZFCP_LOG_INFO("error: initiation of exchange of "
2177 "configuration data failed for "
2178 "adapter %s\n",
2179 zfcp_get_busid_by_adapter(adapter));
2180 break;
2181 }
2182 debug_text_event(adapter->erp_dbf, 6, "a_fstx_xok");
2183 ZFCP_LOG_DEBUG("Xchange underway\n");
2184
2185 /*
2186 * Why this works:
2187 * Both the normal completion handler as well as the timeout
2188 * handler will do an 'up' when the 'exchange config data'
2189 * request completes or times out. Thus, the signal to go on
2190 * won't be lost utilizing this semaphore.
2191 * Furthermore, this 'adapter_reopen' action is
2192 * guaranteed to be the only action being there (highest action
2193 * which prevents other actions from being created).
2194 * Resulting from that, the wake signal recognized here
2195 * _must_ be the one belonging to the 'exchange config
2196 * data' request.
2197 */
2198 down(&adapter->erp_ready_sem);
2199 if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
2200 ZFCP_LOG_INFO("error: exchange of configuration data "
2201 "for adapter %s timed out\n",
2202 zfcp_get_busid_by_adapter(adapter));
2203 break;
2204 }
Andreas Herrmann22753fa2005-06-13 13:15:15 +02002205
2206 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
2207 &adapter->status))
2208 break;
2209
2210 ZFCP_LOG_DEBUG("host connection still initialising... "
2211 "waiting and retrying...\n");
2212 /* sleep a little bit before retry */
2213 msleep(jiffies_to_msecs(sleep));
2214 sleep *= 2;
2215 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002216
2217 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
2218 &adapter->status)) {
2219 ZFCP_LOG_INFO("error: exchange of configuration data for "
2220 "adapter %s failed\n",
2221 zfcp_get_busid_by_adapter(adapter));
2222 retval = ZFCP_ERP_FAILED;
2223 }
2224
2225 return retval;
2226}
2227
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02002228static int
2229zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)
2230{
Andreas Herrmann2448c452005-12-01 02:50:36 +01002231 int ret;
Andreas Herrmann2f8f3ed2006-02-11 01:41:50 +01002232 struct zfcp_adapter *adapter;
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02002233
Andreas Herrmann2f8f3ed2006-02-11 01:41:50 +01002234 adapter = erp_action->adapter;
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02002235 atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
2236
Heiko Carstens9f09c542006-07-03 17:32:20 -07002237 write_lock_irq(&adapter->erp_lock);
Andreas Herrmann2f8f3ed2006-02-11 01:41:50 +01002238 zfcp_erp_action_to_running(erp_action);
Heiko Carstens9f09c542006-07-03 17:32:20 -07002239 write_unlock_irq(&adapter->erp_lock);
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02002240
Andreas Herrmann2f8f3ed2006-02-11 01:41:50 +01002241 zfcp_erp_timeout_init(erp_action);
2242 ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL);
2243 if (ret == -EOPNOTSUPP) {
2244 debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp");
2245 return ZFCP_ERP_SUCCEEDED;
2246 } else if (ret) {
2247 debug_text_event(adapter->erp_dbf, 3, "a_xport_failed");
2248 return ZFCP_ERP_FAILED;
2249 }
2250 debug_text_event(adapter->erp_dbf, 6, "a_xport_ok");
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02002251
Andreas Herrmann2f8f3ed2006-02-11 01:41:50 +01002252 ret = ZFCP_ERP_SUCCEEDED;
2253 down(&adapter->erp_ready_sem);
2254 if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
2255 ZFCP_LOG_INFO("error: exchange port data timed out (adapter "
2256 "%s)\n", zfcp_get_busid_by_adapter(adapter));
2257 ret = ZFCP_ERP_FAILED;
2258 }
2259 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status)) {
2260 ZFCP_LOG_INFO("error: exchange port data failed (adapter "
2261 "%s\n", zfcp_get_busid_by_adapter(adapter));
2262 ret = ZFCP_ERP_FAILED;
2263 }
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02002264
Andreas Herrmann2f8f3ed2006-02-11 01:41:50 +01002265 return ret;
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02002266}
2267
Linus Torvalds1da177e2005-04-16 15:20:36 -07002268static int
2269zfcp_erp_adapter_strategy_open_fsf_statusread(struct zfcp_erp_action
2270 *erp_action)
2271{
2272 int retval = ZFCP_ERP_SUCCEEDED;
2273 int temp_ret;
2274 struct zfcp_adapter *adapter = erp_action->adapter;
2275 int i;
2276
2277 adapter->status_read_failed = 0;
2278 for (i = 0; i < ZFCP_STATUS_READS_RECOM; i++) {
2279 temp_ret = zfcp_fsf_status_read(adapter, ZFCP_WAIT_FOR_SBAL);
2280 if (temp_ret < 0) {
2281 ZFCP_LOG_INFO("error: set-up of unsolicited status "
2282 "notification failed on adapter %s\n",
2283 zfcp_get_busid_by_adapter(adapter));
2284 retval = ZFCP_ERP_FAILED;
2285 i--;
2286 break;
2287 }
2288 }
2289
2290 return retval;
2291}
2292
2293/*
2294 * function: zfcp_fsf_cleanup
2295 *
2296 * purpose: cleanup FSF operation for specified adapter
2297 *
2298 * returns: 0 - FSF operation successfully cleaned up
2299 * !0 - failed to cleanup FSF operation for this adapter
2300 */
2301static int
2302zfcp_erp_adapter_strategy_close_fsf(struct zfcp_erp_action *erp_action)
2303{
2304 int retval = ZFCP_ERP_SUCCEEDED;
2305 struct zfcp_adapter *adapter = erp_action->adapter;
2306
2307 /*
2308 * wake waiting initiators of requests,
2309 * return SCSI commands (with error status),
2310 * clean up all requests (synchronously)
2311 */
2312 zfcp_fsf_req_dismiss_all(adapter);
2313 /* reset FSF request sequence number */
2314 adapter->fsf_req_seq_no = 0;
2315 /* all ports and units are closed */
2316 zfcp_erp_modify_adapter_status(adapter,
2317 ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR);
2318
2319 return retval;
2320}
2321
2322/*
2323 * function:
2324 *
2325 * purpose: this routine executes the 'Reopen Physical Port' action
2326 *
2327 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2328 * ZFCP_ERP_SUCCEEDED - action finished successfully
2329 * ZFCP_ERP_FAILED - action finished unsuccessfully
2330 */
2331static int
2332zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action)
2333{
2334 int retval = ZFCP_ERP_FAILED;
2335 struct zfcp_port *port = erp_action->port;
2336 struct zfcp_adapter *adapter = erp_action->adapter;
2337
2338 switch (erp_action->step) {
2339
2340 /*
2341 * FIXME:
2342 * the ULP spec. begs for waiting for oustanding commands
2343 */
2344 case ZFCP_ERP_STEP_UNINITIALIZED:
2345 zfcp_erp_port_strategy_clearstati(port);
2346 /*
2347 * it would be sufficient to test only the normal open flag
2348 * since the phys. open flag cannot be set if the normal
2349 * open flag is unset - however, this is for readabilty ...
2350 */
2351 if (atomic_test_mask((ZFCP_STATUS_PORT_PHYS_OPEN |
2352 ZFCP_STATUS_COMMON_OPEN),
2353 &port->status)) {
2354 ZFCP_LOG_DEBUG("port 0x%016Lx is open -> trying "
2355 "close physical\n", port->wwpn);
2356 retval =
2357 zfcp_erp_port_forced_strategy_close(erp_action);
2358 } else
2359 retval = ZFCP_ERP_FAILED;
2360 break;
2361
2362 case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:
2363 if (atomic_test_mask(ZFCP_STATUS_PORT_PHYS_OPEN,
2364 &port->status)) {
2365 ZFCP_LOG_DEBUG("close physical failed for port "
2366 "0x%016Lx\n", port->wwpn);
2367 retval = ZFCP_ERP_FAILED;
2368 } else
2369 retval = ZFCP_ERP_SUCCEEDED;
2370 break;
2371 }
2372
2373 debug_text_event(adapter->erp_dbf, 3, "p_pfst/ret");
2374 debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof (wwn_t));
2375 debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int));
2376 debug_event(adapter->erp_dbf, 3, &retval, sizeof (int));
2377
2378 return retval;
2379}
2380
2381/*
2382 * function:
2383 *
2384 * purpose: this routine executes the 'Reopen Port' action
2385 *
2386 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2387 * ZFCP_ERP_SUCCEEDED - action finished successfully
2388 * ZFCP_ERP_FAILED - action finished unsuccessfully
2389 */
2390static int
2391zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
2392{
2393 int retval = ZFCP_ERP_FAILED;
2394 struct zfcp_port *port = erp_action->port;
2395 struct zfcp_adapter *adapter = erp_action->adapter;
2396
2397 switch (erp_action->step) {
2398
2399 /*
2400 * FIXME:
2401 * the ULP spec. begs for waiting for oustanding commands
2402 */
2403 case ZFCP_ERP_STEP_UNINITIALIZED:
2404 zfcp_erp_port_strategy_clearstati(port);
2405 if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &port->status)) {
2406 ZFCP_LOG_DEBUG("port 0x%016Lx is open -> trying "
2407 "close\n", port->wwpn);
2408 retval = zfcp_erp_port_strategy_close(erp_action);
2409 goto out;
2410 } /* else it's already closed, open it */
2411 break;
2412
2413 case ZFCP_ERP_STEP_PORT_CLOSING:
2414 if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &port->status)) {
2415 ZFCP_LOG_DEBUG("close failed for port 0x%016Lx\n",
2416 port->wwpn);
2417 retval = ZFCP_ERP_FAILED;
2418 goto out;
2419 } /* else it's closed now, open it */
2420 break;
2421 }
2422 if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
2423 retval = ZFCP_ERP_EXIT;
2424 else
2425 retval = zfcp_erp_port_strategy_open(erp_action);
2426
2427 out:
2428 debug_text_event(adapter->erp_dbf, 3, "p_pst/ret");
2429 debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof (wwn_t));
2430 debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int));
2431 debug_event(adapter->erp_dbf, 3, &retval, sizeof (int));
2432
2433 return retval;
2434}
2435
Linus Torvalds1da177e2005-04-16 15:20:36 -07002436static int
2437zfcp_erp_port_strategy_open(struct zfcp_erp_action *erp_action)
2438{
2439 int retval;
2440
2441 if (atomic_test_mask(ZFCP_STATUS_PORT_WKA,
2442 &erp_action->port->status))
2443 retval = zfcp_erp_port_strategy_open_nameserver(erp_action);
2444 else
2445 retval = zfcp_erp_port_strategy_open_common(erp_action);
2446
2447 return retval;
2448}
2449
Linus Torvalds1da177e2005-04-16 15:20:36 -07002450static int
2451zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action)
2452{
2453 int retval = 0;
2454 struct zfcp_adapter *adapter = erp_action->adapter;
2455 struct zfcp_port *port = erp_action->port;
2456
2457 switch (erp_action->step) {
2458
2459 case ZFCP_ERP_STEP_UNINITIALIZED:
2460 case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:
2461 case ZFCP_ERP_STEP_PORT_CLOSING:
Andreas Herrmannad757cd2006-01-13 02:26:11 +01002462 if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) {
6f71d9b2005-04-10 23:04:28 -05002463 if (port->wwpn != adapter->peer_wwpn) {
2464 ZFCP_LOG_NORMAL("Failed to open port 0x%016Lx "
2465 "on adapter %s.\nPeer WWPN "
2466 "0x%016Lx does not match\n",
2467 port->wwpn,
2468 zfcp_get_busid_by_adapter(adapter),
2469 adapter->peer_wwpn);
2470 zfcp_erp_port_failed(port);
2471 retval = ZFCP_ERP_FAILED;
2472 break;
2473 }
2474 port->d_id = adapter->peer_d_id;
2475 atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status);
2476 retval = zfcp_erp_port_strategy_open_port(erp_action);
2477 break;
2478 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002479 if (!(adapter->nameserver_port)) {
2480 retval = zfcp_nameserver_enqueue(adapter);
2481 if (retval != 0) {
2482 ZFCP_LOG_NORMAL("error: nameserver port "
2483 "unavailable for adapter %s\n",
2484 zfcp_get_busid_by_adapter(adapter));
2485 retval = ZFCP_ERP_FAILED;
2486 break;
2487 }
2488 }
2489 if (!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
2490 &adapter->nameserver_port->status)) {
2491 ZFCP_LOG_DEBUG("nameserver port is not open -> open "
2492 "nameserver port\n");
2493 /* nameserver port may live again */
2494 atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING,
2495 &adapter->nameserver_port->status);
2496 if (zfcp_erp_port_reopen(adapter->nameserver_port, 0)
2497 >= 0) {
2498 erp_action->step =
2499 ZFCP_ERP_STEP_NAMESERVER_OPEN;
2500 retval = ZFCP_ERP_CONTINUES;
2501 } else
2502 retval = ZFCP_ERP_FAILED;
2503 break;
2504 }
2505 /* else nameserver port is already open, fall through */
2506 case ZFCP_ERP_STEP_NAMESERVER_OPEN:
2507 if (!atomic_test_mask(ZFCP_STATUS_COMMON_OPEN,
2508 &adapter->nameserver_port->status)) {
2509 ZFCP_LOG_DEBUG("open failed for nameserver port\n");
2510 retval = ZFCP_ERP_FAILED;
2511 } else {
2512 ZFCP_LOG_DEBUG("nameserver port is open -> "
2513 "nameserver look-up for port 0x%016Lx\n",
2514 port->wwpn);
2515 retval = zfcp_erp_port_strategy_open_common_lookup
2516 (erp_action);
2517 }
2518 break;
2519
2520 case ZFCP_ERP_STEP_NAMESERVER_LOOKUP:
2521 if (!atomic_test_mask(ZFCP_STATUS_PORT_DID_DID, &port->status)) {
2522 if (atomic_test_mask
2523 (ZFCP_STATUS_PORT_INVALID_WWPN, &port->status)) {
2524 ZFCP_LOG_DEBUG("nameserver look-up failed "
2525 "for port 0x%016Lx "
2526 "(misconfigured WWPN?)\n",
2527 port->wwpn);
2528 zfcp_erp_port_failed(port);
2529 retval = ZFCP_ERP_EXIT;
2530 } else {
2531 ZFCP_LOG_DEBUG("nameserver look-up failed for "
2532 "port 0x%016Lx\n", port->wwpn);
2533 retval = ZFCP_ERP_FAILED;
2534 }
2535 } else {
2536 ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%08x -> "
2537 "trying open\n", port->wwpn, port->d_id);
2538 retval = zfcp_erp_port_strategy_open_port(erp_action);
2539 }
2540 break;
2541
2542 case ZFCP_ERP_STEP_PORT_OPENING:
2543 /* D_ID might have changed during open */
2544 if (atomic_test_mask((ZFCP_STATUS_COMMON_OPEN |
2545 ZFCP_STATUS_PORT_DID_DID),
2546 &port->status)) {
2547 ZFCP_LOG_DEBUG("port 0x%016Lx is open\n", port->wwpn);
2548 retval = ZFCP_ERP_SUCCEEDED;
2549 } else {
2550 ZFCP_LOG_DEBUG("open failed for port 0x%016Lx\n",
2551 port->wwpn);
2552 retval = ZFCP_ERP_FAILED;
2553 }
2554 break;
2555
2556 default:
2557 ZFCP_LOG_NORMAL("bug: unknown erp step 0x%08x\n",
2558 erp_action->step);
2559 retval = ZFCP_ERP_FAILED;
2560 }
2561
2562 return retval;
2563}
2564
Linus Torvalds1da177e2005-04-16 15:20:36 -07002565static int
2566zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *erp_action)
2567{
2568 int retval;
2569 struct zfcp_port *port = erp_action->port;
2570
2571 switch (erp_action->step) {
2572
2573 case ZFCP_ERP_STEP_UNINITIALIZED:
2574 case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:
2575 case ZFCP_ERP_STEP_PORT_CLOSING:
2576 ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%08x -> trying open\n",
2577 port->wwpn, port->d_id);
2578 retval = zfcp_erp_port_strategy_open_port(erp_action);
2579 break;
2580
2581 case ZFCP_ERP_STEP_PORT_OPENING:
2582 if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &port->status)) {
2583 ZFCP_LOG_DEBUG("WKA port is open\n");
2584 retval = ZFCP_ERP_SUCCEEDED;
2585 } else {
2586 ZFCP_LOG_DEBUG("open failed for WKA port\n");
2587 retval = ZFCP_ERP_FAILED;
2588 }
2589 /* this is needed anyway (dont care for retval of wakeup) */
2590 ZFCP_LOG_DEBUG("continue other open port operations\n");
2591 zfcp_erp_port_strategy_open_nameserver_wakeup(erp_action);
2592 break;
2593
2594 default:
2595 ZFCP_LOG_NORMAL("bug: unknown erp step 0x%08x\n",
2596 erp_action->step);
2597 retval = ZFCP_ERP_FAILED;
2598 }
2599
2600 return retval;
2601}
2602
2603/*
2604 * function:
2605 *
2606 * purpose: makes the erp thread continue with reopen (physical) port
2607 * actions which have been paused until the name server port
2608 * is opened (or failed)
2609 *
2610 * returns: 0 (a kind of void retval, its not used)
2611 */
2612static int
2613zfcp_erp_port_strategy_open_nameserver_wakeup(struct zfcp_erp_action
2614 *ns_erp_action)
2615{
2616 int retval = 0;
2617 unsigned long flags;
2618 struct zfcp_adapter *adapter = ns_erp_action->adapter;
2619 struct zfcp_erp_action *erp_action, *tmp;
2620
2621 read_lock_irqsave(&adapter->erp_lock, flags);
2622 list_for_each_entry_safe(erp_action, tmp, &adapter->erp_running_head,
2623 list) {
2624 debug_text_event(adapter->erp_dbf, 4, "p_pstnsw_n");
2625 debug_event(adapter->erp_dbf, 4, &erp_action->port->wwpn,
2626 sizeof (wwn_t));
2627 if (erp_action->step == ZFCP_ERP_STEP_NAMESERVER_OPEN) {
2628 debug_text_event(adapter->erp_dbf, 3, "p_pstnsw_w");
2629 debug_event(adapter->erp_dbf, 3,
2630 &erp_action->port->wwpn, sizeof (wwn_t));
2631 if (atomic_test_mask(
2632 ZFCP_STATUS_COMMON_ERP_FAILED,
2633 &adapter->nameserver_port->status))
2634 zfcp_erp_port_failed(erp_action->port);
2635 zfcp_erp_action_ready(erp_action);
2636 }
2637 }
2638 read_unlock_irqrestore(&adapter->erp_lock, flags);
2639
2640 return retval;
2641}
2642
2643/*
2644 * function:
2645 *
2646 * purpose:
2647 *
2648 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2649 * ZFCP_ERP_FAILED - action finished unsuccessfully
2650 */
2651static int
2652zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *erp_action)
2653{
2654 int retval;
2655 struct zfcp_adapter *adapter = erp_action->adapter;
2656 struct zfcp_port *port = erp_action->port;
2657
2658 zfcp_erp_timeout_init(erp_action);
2659 retval = zfcp_fsf_close_physical_port(erp_action);
2660 if (retval == -ENOMEM) {
2661 debug_text_event(adapter->erp_dbf, 5, "o_pfstc_nomem");
2662 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2663 retval = ZFCP_ERP_NOMEM;
2664 goto out;
2665 }
2666 erp_action->step = ZFCP_ERP_STEP_PHYS_PORT_CLOSING;
2667 if (retval != 0) {
2668 debug_text_event(adapter->erp_dbf, 5, "o_pfstc_cpf");
2669 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2670 /* could not send 'open', fail */
2671 retval = ZFCP_ERP_FAILED;
2672 goto out;
2673 }
2674 debug_text_event(adapter->erp_dbf, 6, "o_pfstc_cpok");
2675 debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));
2676 retval = ZFCP_ERP_CONTINUES;
2677 out:
2678 return retval;
2679}
2680
Linus Torvalds1da177e2005-04-16 15:20:36 -07002681static int
2682zfcp_erp_port_strategy_clearstati(struct zfcp_port *port)
2683{
2684 int retval = 0;
2685 struct zfcp_adapter *adapter = port->adapter;
2686
2687 debug_text_event(adapter->erp_dbf, 5, "p_pstclst");
2688 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2689
2690 atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING |
2691 ZFCP_STATUS_COMMON_CLOSING |
2692 ZFCP_STATUS_COMMON_ACCESS_DENIED |
2693 ZFCP_STATUS_PORT_DID_DID |
2694 ZFCP_STATUS_PORT_PHYS_CLOSING |
2695 ZFCP_STATUS_PORT_INVALID_WWPN,
2696 &port->status);
2697 return retval;
2698}
2699
2700/*
2701 * function:
2702 *
2703 * purpose:
2704 *
2705 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2706 * ZFCP_ERP_FAILED - action finished unsuccessfully
2707 */
2708static int
2709zfcp_erp_port_strategy_close(struct zfcp_erp_action *erp_action)
2710{
2711 int retval;
2712 struct zfcp_adapter *adapter = erp_action->adapter;
2713 struct zfcp_port *port = erp_action->port;
2714
2715 zfcp_erp_timeout_init(erp_action);
2716 retval = zfcp_fsf_close_port(erp_action);
2717 if (retval == -ENOMEM) {
2718 debug_text_event(adapter->erp_dbf, 5, "p_pstc_nomem");
2719 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2720 retval = ZFCP_ERP_NOMEM;
2721 goto out;
2722 }
2723 erp_action->step = ZFCP_ERP_STEP_PORT_CLOSING;
2724 if (retval != 0) {
2725 debug_text_event(adapter->erp_dbf, 5, "p_pstc_cpf");
2726 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2727 /* could not send 'close', fail */
2728 retval = ZFCP_ERP_FAILED;
2729 goto out;
2730 }
2731 debug_text_event(adapter->erp_dbf, 6, "p_pstc_cpok");
2732 debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));
2733 retval = ZFCP_ERP_CONTINUES;
2734 out:
2735 return retval;
2736}
2737
2738/*
2739 * function:
2740 *
2741 * purpose:
2742 *
2743 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2744 * ZFCP_ERP_FAILED - action finished unsuccessfully
2745 */
2746static int
2747zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action)
2748{
2749 int retval;
2750 struct zfcp_adapter *adapter = erp_action->adapter;
2751 struct zfcp_port *port = erp_action->port;
2752
2753 zfcp_erp_timeout_init(erp_action);
2754 retval = zfcp_fsf_open_port(erp_action);
2755 if (retval == -ENOMEM) {
2756 debug_text_event(adapter->erp_dbf, 5, "p_psto_nomem");
2757 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2758 retval = ZFCP_ERP_NOMEM;
2759 goto out;
2760 }
2761 erp_action->step = ZFCP_ERP_STEP_PORT_OPENING;
2762 if (retval != 0) {
2763 debug_text_event(adapter->erp_dbf, 5, "p_psto_opf");
2764 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2765 /* could not send 'open', fail */
2766 retval = ZFCP_ERP_FAILED;
2767 goto out;
2768 }
2769 debug_text_event(adapter->erp_dbf, 6, "p_psto_opok");
2770 debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));
2771 retval = ZFCP_ERP_CONTINUES;
2772 out:
2773 return retval;
2774}
2775
2776/*
2777 * function:
2778 *
2779 * purpose:
2780 *
2781 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2782 * ZFCP_ERP_FAILED - action finished unsuccessfully
2783 */
2784static int
2785zfcp_erp_port_strategy_open_common_lookup(struct zfcp_erp_action *erp_action)
2786{
2787 int retval;
2788 struct zfcp_adapter *adapter = erp_action->adapter;
2789 struct zfcp_port *port = erp_action->port;
2790
2791 zfcp_erp_timeout_init(erp_action);
2792 retval = zfcp_ns_gid_pn_request(erp_action);
2793 if (retval == -ENOMEM) {
2794 debug_text_event(adapter->erp_dbf, 5, "p_pstn_nomem");
2795 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2796 retval = ZFCP_ERP_NOMEM;
2797 goto out;
2798 }
2799 erp_action->step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP;
2800 if (retval != 0) {
2801 debug_text_event(adapter->erp_dbf, 5, "p_pstn_ref");
2802 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2803 /* could not send nameserver request, fail */
2804 retval = ZFCP_ERP_FAILED;
2805 goto out;
2806 }
2807 debug_text_event(adapter->erp_dbf, 6, "p_pstn_reok");
2808 debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));
2809 retval = ZFCP_ERP_CONTINUES;
2810 out:
2811 return retval;
2812}
2813
2814/*
2815 * function:
2816 *
2817 * purpose: this routine executes the 'Reopen Unit' action
2818 * currently no retries
2819 *
2820 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2821 * ZFCP_ERP_SUCCEEDED - action finished successfully
2822 * ZFCP_ERP_FAILED - action finished unsuccessfully
2823 */
2824static int
2825zfcp_erp_unit_strategy(struct zfcp_erp_action *erp_action)
2826{
2827 int retval = ZFCP_ERP_FAILED;
2828 struct zfcp_unit *unit = erp_action->unit;
2829 struct zfcp_adapter *adapter = erp_action->adapter;
2830
2831 switch (erp_action->step) {
2832
2833 /*
2834 * FIXME:
2835 * the ULP spec. begs for waiting for oustanding commands
2836 */
2837 case ZFCP_ERP_STEP_UNINITIALIZED:
2838 zfcp_erp_unit_strategy_clearstati(unit);
2839 if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status)) {
2840 ZFCP_LOG_DEBUG("unit 0x%016Lx is open -> "
2841 "trying close\n", unit->fcp_lun);
2842 retval = zfcp_erp_unit_strategy_close(erp_action);
2843 break;
2844 }
2845 /* else it's already closed, fall through */
2846 case ZFCP_ERP_STEP_UNIT_CLOSING:
2847 if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status)) {
2848 ZFCP_LOG_DEBUG("close failed for unit 0x%016Lx\n",
2849 unit->fcp_lun);
2850 retval = ZFCP_ERP_FAILED;
2851 } else {
2852 if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
2853 retval = ZFCP_ERP_EXIT;
2854 else {
2855 ZFCP_LOG_DEBUG("unit 0x%016Lx is not open -> "
2856 "trying open\n", unit->fcp_lun);
2857 retval =
2858 zfcp_erp_unit_strategy_open(erp_action);
2859 }
2860 }
2861 break;
2862
2863 case ZFCP_ERP_STEP_UNIT_OPENING:
2864 if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status)) {
2865 ZFCP_LOG_DEBUG("unit 0x%016Lx is open\n",
2866 unit->fcp_lun);
2867 retval = ZFCP_ERP_SUCCEEDED;
2868 } else {
2869 ZFCP_LOG_DEBUG("open failed for unit 0x%016Lx\n",
2870 unit->fcp_lun);
2871 retval = ZFCP_ERP_FAILED;
2872 }
2873 break;
2874 }
2875
2876 debug_text_event(adapter->erp_dbf, 3, "u_ust/ret");
2877 debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof (fcp_lun_t));
2878 debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int));
2879 debug_event(adapter->erp_dbf, 3, &retval, sizeof (int));
2880 return retval;
2881}
2882
Linus Torvalds1da177e2005-04-16 15:20:36 -07002883static int
2884zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit)
2885{
2886 int retval = 0;
2887 struct zfcp_adapter *adapter = unit->port->adapter;
2888
2889 debug_text_event(adapter->erp_dbf, 5, "u_ustclst");
2890 debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, sizeof (fcp_lun_t));
2891
2892 atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING |
2893 ZFCP_STATUS_COMMON_CLOSING |
2894 ZFCP_STATUS_COMMON_ACCESS_DENIED |
2895 ZFCP_STATUS_UNIT_SHARED |
2896 ZFCP_STATUS_UNIT_READONLY,
2897 &unit->status);
2898
2899 return retval;
2900}
2901
2902/*
2903 * function:
2904 *
2905 * purpose:
2906 *
2907 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2908 * ZFCP_ERP_FAILED - action finished unsuccessfully
2909 */
2910static int
2911zfcp_erp_unit_strategy_close(struct zfcp_erp_action *erp_action)
2912{
2913 int retval;
2914 struct zfcp_adapter *adapter = erp_action->adapter;
2915 struct zfcp_unit *unit = erp_action->unit;
2916
2917 zfcp_erp_timeout_init(erp_action);
2918 retval = zfcp_fsf_close_unit(erp_action);
2919 if (retval == -ENOMEM) {
2920 debug_text_event(adapter->erp_dbf, 5, "u_ustc_nomem");
2921 debug_event(adapter->erp_dbf, 5, &unit->fcp_lun,
2922 sizeof (fcp_lun_t));
2923 retval = ZFCP_ERP_NOMEM;
2924 goto out;
2925 }
2926 erp_action->step = ZFCP_ERP_STEP_UNIT_CLOSING;
2927 if (retval != 0) {
2928 debug_text_event(adapter->erp_dbf, 5, "u_ustc_cuf");
2929 debug_event(adapter->erp_dbf, 5, &unit->fcp_lun,
2930 sizeof (fcp_lun_t));
2931 /* could not send 'close', fail */
2932 retval = ZFCP_ERP_FAILED;
2933 goto out;
2934 }
2935 debug_text_event(adapter->erp_dbf, 6, "u_ustc_cuok");
2936 debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t));
2937 retval = ZFCP_ERP_CONTINUES;
2938
2939 out:
2940 return retval;
2941}
2942
2943/*
2944 * function:
2945 *
2946 * purpose:
2947 *
2948 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2949 * ZFCP_ERP_FAILED - action finished unsuccessfully
2950 */
2951static int
2952zfcp_erp_unit_strategy_open(struct zfcp_erp_action *erp_action)
2953{
2954 int retval;
2955 struct zfcp_adapter *adapter = erp_action->adapter;
2956 struct zfcp_unit *unit = erp_action->unit;
2957
2958 zfcp_erp_timeout_init(erp_action);
2959 retval = zfcp_fsf_open_unit(erp_action);
2960 if (retval == -ENOMEM) {
2961 debug_text_event(adapter->erp_dbf, 5, "u_usto_nomem");
2962 debug_event(adapter->erp_dbf, 5, &unit->fcp_lun,
2963 sizeof (fcp_lun_t));
2964 retval = ZFCP_ERP_NOMEM;
2965 goto out;
2966 }
2967 erp_action->step = ZFCP_ERP_STEP_UNIT_OPENING;
2968 if (retval != 0) {
2969 debug_text_event(adapter->erp_dbf, 5, "u_usto_ouf");
2970 debug_event(adapter->erp_dbf, 5, &unit->fcp_lun,
2971 sizeof (fcp_lun_t));
2972 /* could not send 'open', fail */
2973 retval = ZFCP_ERP_FAILED;
2974 goto out;
2975 }
2976 debug_text_event(adapter->erp_dbf, 6, "u_usto_ouok");
2977 debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t));
2978 retval = ZFCP_ERP_CONTINUES;
2979 out:
2980 return retval;
2981}
2982
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983static inline void
2984zfcp_erp_timeout_init(struct zfcp_erp_action *erp_action)
2985{
2986 init_timer(&erp_action->timer);
2987 erp_action->timer.function = zfcp_erp_timeout_handler;
2988 erp_action->timer.data = (unsigned long) erp_action;
2989 /* jiffies will be added in zfcp_fsf_req_send */
2990 erp_action->timer.expires = ZFCP_ERP_FSFREQ_TIMEOUT;
2991}
2992
2993/*
2994 * function:
2995 *
2996 * purpose: enqueue the specified error recovery action, if needed
2997 *
2998 * returns:
2999 */
3000static int
3001zfcp_erp_action_enqueue(int action,
3002 struct zfcp_adapter *adapter,
3003 struct zfcp_port *port, struct zfcp_unit *unit)
3004{
3005 int retval = 1;
3006 struct zfcp_erp_action *erp_action = NULL;
3007 int stronger_action = 0;
3008 u32 status = 0;
3009
3010 /*
3011 * We need some rules here which check whether we really need
3012 * this action or whether we should just drop it.
3013 * E.g. if there is a unfinished 'Reopen Port' request then we drop a
3014 * 'Reopen Unit' request for an associated unit since we can't
3015 * satisfy this request now. A 'Reopen Port' action will trigger
3016 * 'Reopen Unit' actions when it completes.
3017 * Thus, there are only actions in the queue which can immediately be
3018 * executed. This makes the processing of the action queue more
3019 * efficient.
3020 */
3021
3022 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP,
3023 &adapter->status))
3024 return -EIO;
3025
3026 debug_event(adapter->erp_dbf, 4, &action, sizeof (int));
3027 /* check whether we really need this */
3028 switch (action) {
3029 case ZFCP_ERP_ACTION_REOPEN_UNIT:
3030 if (atomic_test_mask
3031 (ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status)) {
3032 debug_text_event(adapter->erp_dbf, 4, "u_actenq_drp");
3033 debug_event(adapter->erp_dbf, 4, &port->wwpn,
3034 sizeof (wwn_t));
3035 debug_event(adapter->erp_dbf, 4, &unit->fcp_lun,
3036 sizeof (fcp_lun_t));
3037 goto out;
3038 }
3039 if (!atomic_test_mask
3040 (ZFCP_STATUS_COMMON_RUNNING, &port->status) ||
3041 atomic_test_mask
3042 (ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) {
3043 goto out;
3044 }
3045 if (!atomic_test_mask
3046 (ZFCP_STATUS_COMMON_UNBLOCKED, &port->status)) {
3047 stronger_action = ZFCP_ERP_ACTION_REOPEN_PORT;
3048 unit = NULL;
3049 }
3050 /* fall through !!! */
3051
3052 case ZFCP_ERP_ACTION_REOPEN_PORT:
3053 if (atomic_test_mask
3054 (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)) {
3055 debug_text_event(adapter->erp_dbf, 4, "p_actenq_drp");
3056 debug_event(adapter->erp_dbf, 4, &port->wwpn,
3057 sizeof (wwn_t));
3058 goto out;
3059 }
3060 /* fall through !!! */
3061
3062 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
Andreas Herrmann3734d242005-09-13 21:47:11 +02003063 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
3064 &port->status)) {
3065 if (port->erp_action.action !=
3066 ZFCP_ERP_ACTION_REOPEN_PORT_FORCED) {
3067 ZFCP_LOG_INFO("dropped erp action %i (port "
3068 "0x%016Lx, action in use: %i)\n",
3069 action, port->wwpn,
3070 port->erp_action.action);
3071 debug_text_event(adapter->erp_dbf, 4,
3072 "pf_actenq_drp");
3073 } else
3074 debug_text_event(adapter->erp_dbf, 4,
3075 "pf_actenq_drpcp");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003076 debug_event(adapter->erp_dbf, 4, &port->wwpn,
3077 sizeof (wwn_t));
3078 goto out;
3079 }
3080 if (!atomic_test_mask
3081 (ZFCP_STATUS_COMMON_RUNNING, &adapter->status) ||
3082 atomic_test_mask
3083 (ZFCP_STATUS_COMMON_ERP_FAILED, &adapter->status)) {
3084 goto out;
3085 }
3086 if (!atomic_test_mask
3087 (ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status)) {
3088 stronger_action = ZFCP_ERP_ACTION_REOPEN_ADAPTER;
3089 port = NULL;
3090 }
3091 /* fall through !!! */
3092
3093 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
3094 if (atomic_test_mask
3095 (ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status)) {
3096 debug_text_event(adapter->erp_dbf, 4, "a_actenq_drp");
3097 goto out;
3098 }
3099 break;
3100
3101 default:
3102 debug_text_exception(adapter->erp_dbf, 1, "a_actenq_bug");
3103 debug_event(adapter->erp_dbf, 1, &action, sizeof (int));
3104 ZFCP_LOG_NORMAL("bug: unknown erp action requested "
3105 "on adapter %s (action=%d)\n",
3106 zfcp_get_busid_by_adapter(adapter), action);
3107 goto out;
3108 }
3109
3110 /* check whether we need something stronger first */
3111 if (stronger_action) {
3112 debug_text_event(adapter->erp_dbf, 4, "a_actenq_str");
3113 debug_event(adapter->erp_dbf, 4, &stronger_action,
3114 sizeof (int));
3115 ZFCP_LOG_DEBUG("stronger erp action %d needed before "
3116 "erp action %d on adapter %s\n",
3117 stronger_action, action,
3118 zfcp_get_busid_by_adapter(adapter));
3119 action = stronger_action;
3120 }
3121
3122 /* mark adapter to have some error recovery pending */
3123 atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status);
3124
3125 /* setup error recovery action */
3126 switch (action) {
3127
3128 case ZFCP_ERP_ACTION_REOPEN_UNIT:
3129 zfcp_unit_get(unit);
3130 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status);
3131 erp_action = &unit->erp_action;
3132 if (!atomic_test_mask
3133 (ZFCP_STATUS_COMMON_RUNNING, &unit->status))
3134 status = ZFCP_STATUS_ERP_CLOSE_ONLY;
3135 break;
3136
3137 case ZFCP_ERP_ACTION_REOPEN_PORT:
3138 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
3139 zfcp_port_get(port);
3140 zfcp_erp_action_dismiss_port(port);
3141 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
3142 erp_action = &port->erp_action;
3143 if (!atomic_test_mask
3144 (ZFCP_STATUS_COMMON_RUNNING, &port->status))
3145 status = ZFCP_STATUS_ERP_CLOSE_ONLY;
3146 break;
3147
3148 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
3149 zfcp_adapter_get(adapter);
3150 zfcp_erp_action_dismiss_adapter(adapter);
3151 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status);
3152 erp_action = &adapter->erp_action;
3153 if (!atomic_test_mask
3154 (ZFCP_STATUS_COMMON_RUNNING, &adapter->status))
3155 status = ZFCP_STATUS_ERP_CLOSE_ONLY;
3156 break;
3157 }
3158
3159 debug_text_event(adapter->erp_dbf, 4, "a_actenq");
3160
3161 memset(erp_action, 0, sizeof (struct zfcp_erp_action));
3162 erp_action->adapter = adapter;
3163 erp_action->port = port;
3164 erp_action->unit = unit;
3165 erp_action->action = action;
3166 erp_action->status = status;
3167
3168 ++adapter->erp_total_count;
3169
3170 /* finally put it into 'ready' queue and kick erp thread */
3171 list_add(&erp_action->list, &adapter->erp_ready_head);
3172 up(&adapter->erp_ready_sem);
3173 retval = 0;
3174 out:
3175 return retval;
3176}
3177
Linus Torvalds1da177e2005-04-16 15:20:36 -07003178static int
3179zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action)
3180{
3181 int retval = 0;
3182 struct zfcp_adapter *adapter = erp_action->adapter;
3183
3184 --adapter->erp_total_count;
3185 if (erp_action->status & ZFCP_STATUS_ERP_LOWMEM) {
3186 --adapter->erp_low_mem_count;
3187 erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM;
3188 }
3189
3190 debug_text_event(adapter->erp_dbf, 4, "a_actdeq");
3191 debug_event(adapter->erp_dbf, 4, &erp_action->action, sizeof (int));
3192 list_del(&erp_action->list);
3193 switch (erp_action->action) {
3194 case ZFCP_ERP_ACTION_REOPEN_UNIT:
3195 atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
3196 &erp_action->unit->status);
3197 break;
3198 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
3199 case ZFCP_ERP_ACTION_REOPEN_PORT:
3200 atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
3201 &erp_action->port->status);
3202 break;
3203 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
3204 atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
3205 &erp_action->adapter->status);
3206 break;
3207 default:
3208 /* bug */
3209 break;
3210 }
3211 return retval;
3212}
3213
3214/**
3215 * zfcp_erp_action_cleanup
3216 *
Adrian Bunk575c9682006-01-15 02:00:17 +01003217 * Register unit with scsi stack if appropriate and fix reference counts.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003218 * Note: Temporary units are not registered with scsi stack.
3219 */
3220static void
3221zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
3222 struct zfcp_port *port, struct zfcp_unit *unit,
3223 int result)
3224{
3225 switch (action) {
3226 case ZFCP_ERP_ACTION_REOPEN_UNIT:
3227 if ((result == ZFCP_ERP_SUCCEEDED)
3228 && (!atomic_test_mask(ZFCP_STATUS_UNIT_TEMPORARY,
3229 &unit->status))
Andreas Herrmann3859f6a2005-08-27 11:07:54 -07003230 && !unit->device
Andreas Herrmannad58f7d2006-03-10 00:56:16 +01003231 && port->rport) {
3232 atomic_set_mask(ZFCP_STATUS_UNIT_REGISTERED,
3233 &unit->status);
3234 scsi_scan_target(&port->rport->dev, 0,
3235 port->rport->scsi_target_id,
3236 unit->scsi_lun, 0);
3237 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003238 zfcp_unit_put(unit);
3239 break;
3240 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
3241 case ZFCP_ERP_ACTION_REOPEN_PORT:
Andreas Herrmann338151e2006-05-22 18:25:56 +02003242 if (atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN,
3243 &port->status)) {
3244 zfcp_port_put(port);
3245 break;
3246 }
3247
Andreas Herrmann3859f6a2005-08-27 11:07:54 -07003248 if ((result == ZFCP_ERP_SUCCEEDED)
Andreas Herrmann3859f6a2005-08-27 11:07:54 -07003249 && !port->rport) {
3250 struct fc_rport_identifiers ids;
3251 ids.node_name = port->wwnn;
3252 ids.port_name = port->wwpn;
3253 ids.port_id = port->d_id;
3254 ids.roles = FC_RPORT_ROLE_FCP_TARGET;
3255 port->rport =
3256 fc_remote_port_add(adapter->scsi_host, 0, &ids);
3257 if (!port->rport)
3258 ZFCP_LOG_NORMAL("failed registration of rport"
3259 "(adapter %s, wwpn=0x%016Lx)\n",
3260 zfcp_get_busid_by_port(port),
3261 port->wwpn);
Ralph Wuerthner75bfc282006-05-22 18:24:33 +02003262 else {
Andreas Herrmann61c41822006-02-11 01:43:55 +01003263 scsi_flush_work(adapter->scsi_host);
Ralph Wuerthner75bfc282006-05-22 18:24:33 +02003264 port->rport->maxframe_size = port->maxframe_size;
3265 port->rport->supported_classes =
3266 port->supported_classes;
3267 }
Andreas Herrmann3859f6a2005-08-27 11:07:54 -07003268 }
Andreas Herrmann338151e2006-05-22 18:25:56 +02003269 if ((result != ZFCP_ERP_SUCCEEDED) && port->rport) {
3270 fc_remote_port_delete(port->rport);
3271 port->rport = NULL;
3272 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003273 zfcp_port_put(port);
3274 break;
3275 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
Andreas Herrmann338151e2006-05-22 18:25:56 +02003276 if (result != ZFCP_ERP_SUCCEEDED) {
3277 struct zfcp_port *port;
3278 list_for_each_entry(port, &adapter->port_list_head, list)
3279 if (port->rport &&
3280 !atomic_test_mask(ZFCP_STATUS_PORT_WKA,
3281 &port->status)) {
3282 fc_remote_port_delete(port->rport);
3283 port->rport = NULL;
3284 }
3285 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003286 zfcp_adapter_put(adapter);
3287 break;
3288 default:
3289 break;
3290 }
3291}
3292
3293
Linus Torvalds1da177e2005-04-16 15:20:36 -07003294static int
3295zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
3296{
3297 int retval = 0;
3298 struct zfcp_port *port;
3299
3300 debug_text_event(adapter->erp_dbf, 5, "a_actab");
3301 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status))
3302 zfcp_erp_action_dismiss(&adapter->erp_action);
3303 else
3304 list_for_each_entry(port, &adapter->port_list_head, list)
3305 zfcp_erp_action_dismiss_port(port);
3306
3307 return retval;
3308}
3309
Linus Torvalds1da177e2005-04-16 15:20:36 -07003310static int
3311zfcp_erp_action_dismiss_port(struct zfcp_port *port)
3312{
3313 int retval = 0;
3314 struct zfcp_unit *unit;
3315 struct zfcp_adapter *adapter = port->adapter;
3316
3317 debug_text_event(adapter->erp_dbf, 5, "p_actab");
3318 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
3319 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status))
3320 zfcp_erp_action_dismiss(&port->erp_action);
3321 else
3322 list_for_each_entry(unit, &port->unit_list_head, list)
3323 zfcp_erp_action_dismiss_unit(unit);
3324
3325 return retval;
3326}
3327
Linus Torvalds1da177e2005-04-16 15:20:36 -07003328static int
3329zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit)
3330{
3331 int retval = 0;
3332 struct zfcp_adapter *adapter = unit->port->adapter;
3333
3334 debug_text_event(adapter->erp_dbf, 5, "u_actab");
3335 debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, sizeof (fcp_lun_t));
3336 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status))
3337 zfcp_erp_action_dismiss(&unit->erp_action);
3338
3339 return retval;
3340}
3341
Linus Torvalds1da177e2005-04-16 15:20:36 -07003342static inline void
3343zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action)
3344{
3345 struct zfcp_adapter *adapter = erp_action->adapter;
3346
3347 debug_text_event(adapter->erp_dbf, 6, "a_toru");
3348 debug_event(adapter->erp_dbf, 6, &erp_action->action, sizeof (int));
3349 list_move(&erp_action->list, &erp_action->adapter->erp_running_head);
3350}
3351
Linus Torvalds1da177e2005-04-16 15:20:36 -07003352static inline void
3353zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action)
3354{
3355 struct zfcp_adapter *adapter = erp_action->adapter;
3356
3357 debug_text_event(adapter->erp_dbf, 6, "a_tore");
3358 debug_event(adapter->erp_dbf, 6, &erp_action->action, sizeof (int));
3359 list_move(&erp_action->list, &erp_action->adapter->erp_ready_head);
3360}
3361
Andreas Herrmannd736a27b2005-06-13 13:23:57 +02003362void
3363zfcp_erp_port_boxed(struct zfcp_port *port)
3364{
3365 struct zfcp_adapter *adapter = port->adapter;
3366 unsigned long flags;
3367
3368 debug_text_event(adapter->erp_dbf, 3, "p_access_boxed");
3369 debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
3370 read_lock_irqsave(&zfcp_data.config_lock, flags);
3371 zfcp_erp_modify_port_status(port,
3372 ZFCP_STATUS_COMMON_ACCESS_BOXED,
3373 ZFCP_SET);
3374 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
3375 zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED);
3376}
3377
Andreas Herrmannd736a27b2005-06-13 13:23:57 +02003378void
3379zfcp_erp_unit_boxed(struct zfcp_unit *unit)
3380{
3381 struct zfcp_adapter *adapter = unit->port->adapter;
3382
3383 debug_text_event(adapter->erp_dbf, 3, "u_access_boxed");
3384 debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
3385 zfcp_erp_modify_unit_status(unit,
3386 ZFCP_STATUS_COMMON_ACCESS_BOXED,
3387 ZFCP_SET);
3388 zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED);
3389}
3390
Linus Torvalds1da177e2005-04-16 15:20:36 -07003391void
3392zfcp_erp_port_access_denied(struct zfcp_port *port)
3393{
3394 struct zfcp_adapter *adapter = port->adapter;
3395 unsigned long flags;
3396
Andreas Herrmannd736a27b2005-06-13 13:23:57 +02003397 debug_text_event(adapter->erp_dbf, 3, "p_access_denied");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003398 debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
3399 read_lock_irqsave(&zfcp_data.config_lock, flags);
Andreas Herrmannd736a27b2005-06-13 13:23:57 +02003400 zfcp_erp_modify_port_status(port,
3401 ZFCP_STATUS_COMMON_ERP_FAILED |
3402 ZFCP_STATUS_COMMON_ACCESS_DENIED,
3403 ZFCP_SET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003404 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
3405}
3406
Linus Torvalds1da177e2005-04-16 15:20:36 -07003407void
3408zfcp_erp_unit_access_denied(struct zfcp_unit *unit)
3409{
3410 struct zfcp_adapter *adapter = unit->port->adapter;
3411
Andreas Herrmannd736a27b2005-06-13 13:23:57 +02003412 debug_text_event(adapter->erp_dbf, 3, "u_access_denied");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003413 debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
Andreas Herrmannd736a27b2005-06-13 13:23:57 +02003414 zfcp_erp_modify_unit_status(unit,
3415 ZFCP_STATUS_COMMON_ERP_FAILED |
3416 ZFCP_STATUS_COMMON_ACCESS_DENIED,
3417 ZFCP_SET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003418}
3419
Linus Torvalds1da177e2005-04-16 15:20:36 -07003420void
3421zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter)
3422{
3423 struct zfcp_port *port;
3424 unsigned long flags;
3425
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02003426 if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
3427 return;
3428
Andreas Herrmannd736a27b2005-06-13 13:23:57 +02003429 debug_text_event(adapter->erp_dbf, 3, "a_access_recover");
Andreas Herrmann06506d02006-05-22 18:18:19 +02003430 debug_event(adapter->erp_dbf, 3, zfcp_get_busid_by_adapter(adapter), 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003431
Linus Torvalds1da177e2005-04-16 15:20:36 -07003432 read_lock_irqsave(&zfcp_data.config_lock, flags);
6f71d9b2005-04-10 23:04:28 -05003433 if (adapter->nameserver_port)
3434 zfcp_erp_port_access_changed(adapter->nameserver_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003435 list_for_each_entry(port, &adapter->port_list_head, list)
3436 if (port != adapter->nameserver_port)
3437 zfcp_erp_port_access_changed(port);
3438 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
3439}
3440
Linus Torvalds1da177e2005-04-16 15:20:36 -07003441void
3442zfcp_erp_port_access_changed(struct zfcp_port *port)
3443{
3444 struct zfcp_adapter *adapter = port->adapter;
3445 struct zfcp_unit *unit;
3446
Andreas Herrmannd736a27b2005-06-13 13:23:57 +02003447 debug_text_event(adapter->erp_dbf, 3, "p_access_recover");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003448 debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
3449
3450 if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED,
Andreas Herrmannd736a27b2005-06-13 13:23:57 +02003451 &port->status) &&
3452 !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003453 &port->status)) {
3454 if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
3455 list_for_each_entry(unit, &port->unit_list_head, list)
3456 zfcp_erp_unit_access_changed(unit);
3457 return;
3458 }
3459
3460 ZFCP_LOG_NORMAL("reopen of port 0x%016Lx on adapter %s "
3461 "(due to ACT update)\n",
3462 port->wwpn, zfcp_get_busid_by_adapter(adapter));
3463 if (zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED) != 0)
3464 ZFCP_LOG_NORMAL("failed reopen of port"
3465 "(adapter %s, wwpn=0x%016Lx)\n",
3466 zfcp_get_busid_by_adapter(adapter), port->wwpn);
3467}
3468
Linus Torvalds1da177e2005-04-16 15:20:36 -07003469void
3470zfcp_erp_unit_access_changed(struct zfcp_unit *unit)
3471{
3472 struct zfcp_adapter *adapter = unit->port->adapter;
3473
Andreas Herrmannd736a27b2005-06-13 13:23:57 +02003474 debug_text_event(adapter->erp_dbf, 3, "u_access_recover");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003475 debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
3476
Andreas Herrmannd736a27b2005-06-13 13:23:57 +02003477 if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED,
3478 &unit->status) &&
3479 !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED,
3480 &unit->status))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003481 return;
3482
3483 ZFCP_LOG_NORMAL("reopen of unit 0x%016Lx on port 0x%016Lx "
3484 " on adapter %s (due to ACT update)\n",
3485 unit->fcp_lun, unit->port->wwpn,
3486 zfcp_get_busid_by_adapter(adapter));
3487 if (zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED) != 0)
3488 ZFCP_LOG_NORMAL("failed reopen of unit (adapter %s, "
3489 "wwpn=0x%016Lx, fcp_lun=0x%016Lx)\n",
3490 zfcp_get_busid_by_adapter(adapter),
3491 unit->port->wwpn, unit->fcp_lun);
3492}
3493
3494#undef ZFCP_LOG_AREA