blob: 909731b99d2671e9d54dc51ab21ca1399ce882a4 [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) {
851 /* take lock to ensure that request is not being deleted meanwhile */
Andreas Herrmann1db2c9c2005-06-13 13:20:35 +0200852 spin_lock(&adapter->fsf_req_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853 /* check whether fsf req does still exist */
854 list_for_each_entry(fsf_req, &adapter->fsf_req_list_head, list)
855 if (fsf_req == erp_action->fsf_req)
856 break;
Andreas Herrmann3734d242005-09-13 21:47:11 +0200857 if (fsf_req && (fsf_req->erp_action == erp_action)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858 /* fsf_req still exists */
859 debug_text_event(adapter->erp_dbf, 3, "a_ca_req");
860 debug_event(adapter->erp_dbf, 3, &fsf_req,
861 sizeof (unsigned long));
862 /* dismiss fsf_req of timed out or dismissed erp_action */
863 if (erp_action->status & (ZFCP_STATUS_ERP_DISMISSED |
864 ZFCP_STATUS_ERP_TIMEDOUT)) {
865 debug_text_event(adapter->erp_dbf, 3,
866 "a_ca_disreq");
867 fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
868 }
869 if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
870 ZFCP_LOG_NORMAL("error: erp step timed out "
871 "(action=%d, fsf_req=%p)\n ",
872 erp_action->action,
873 erp_action->fsf_req);
874 }
875 /*
876 * If fsf_req is neither dismissed nor completed
877 * then keep it running asynchronously and don't mess
878 * with the association of erp_action and fsf_req.
879 */
880 if (fsf_req->status & (ZFCP_STATUS_FSFREQ_COMPLETED |
881 ZFCP_STATUS_FSFREQ_DISMISSED)) {
882 /* forget about association between fsf_req
883 and erp_action */
884 fsf_req->erp_action = NULL;
885 erp_action->fsf_req = NULL;
886 }
887 } else {
888 debug_text_event(adapter->erp_dbf, 3, "a_ca_gonereq");
889 /*
890 * even if this fsf_req has gone, forget about
891 * association between erp_action and fsf_req
892 */
893 erp_action->fsf_req = NULL;
894 }
Andreas Herrmann1db2c9c2005-06-13 13:20:35 +0200895 spin_unlock(&adapter->fsf_req_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896 } else
897 debug_text_event(adapter->erp_dbf, 3, "a_ca_noreq");
898
899 return retval;
900}
901
902/*
903 * purpose: generic handler for asynchronous events related to erp_action events
904 * (normal completion, time-out, dismissing, retry after
905 * low memory condition)
906 *
907 * note: deletion of timer is not required (e.g. in case of a time-out),
908 * but a second try does no harm,
909 * we leave it in here to allow for greater simplification
910 *
911 * returns: 0 - there was an action to handle
912 * !0 - otherwise
913 */
914static int
915zfcp_erp_async_handler_nolock(struct zfcp_erp_action *erp_action,
916 unsigned long set_mask)
917{
918 int retval;
919 struct zfcp_adapter *adapter = erp_action->adapter;
920
921 if (zfcp_erp_action_exists(erp_action) == ZFCP_ERP_ACTION_RUNNING) {
922 debug_text_event(adapter->erp_dbf, 2, "a_asyh_ex");
923 debug_event(adapter->erp_dbf, 2, &erp_action->action,
924 sizeof (int));
925 if (!(set_mask & ZFCP_STATUS_ERP_TIMEDOUT))
926 del_timer(&erp_action->timer);
927 erp_action->status |= set_mask;
928 zfcp_erp_action_ready(erp_action);
929 retval = 0;
930 } else {
931 /* action is ready or gone - nothing to do */
932 debug_text_event(adapter->erp_dbf, 3, "a_asyh_gone");
933 debug_event(adapter->erp_dbf, 3, &erp_action->action,
934 sizeof (int));
935 retval = 1;
936 }
937
938 return retval;
939}
940
941/*
942 * purpose: generic handler for asynchronous events related to erp_action
943 * events (normal completion, time-out, dismissing, retry after
944 * low memory condition)
945 *
946 * note: deletion of timer is not required (e.g. in case of a time-out),
947 * but a second try does no harm,
948 * we leave it in here to allow for greater simplification
949 *
950 * returns: 0 - there was an action to handle
951 * !0 - otherwise
952 */
953int
954zfcp_erp_async_handler(struct zfcp_erp_action *erp_action,
955 unsigned long set_mask)
956{
957 struct zfcp_adapter *adapter = erp_action->adapter;
958 unsigned long flags;
959 int retval;
960
961 write_lock_irqsave(&adapter->erp_lock, flags);
962 retval = zfcp_erp_async_handler_nolock(erp_action, set_mask);
963 write_unlock_irqrestore(&adapter->erp_lock, flags);
964
965 return retval;
966}
967
968/*
969 * purpose: is called for erp_action which was slept waiting for
970 * memory becoming avaliable,
971 * will trigger that this action will be continued
972 */
973static void
974zfcp_erp_memwait_handler(unsigned long data)
975{
976 struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data;
977 struct zfcp_adapter *adapter = erp_action->adapter;
978
979 debug_text_event(adapter->erp_dbf, 2, "a_mwh");
980 debug_event(adapter->erp_dbf, 2, &erp_action->action, sizeof (int));
981
982 zfcp_erp_async_handler(erp_action, 0);
983}
984
985/*
986 * purpose: is called if an asynchronous erp step timed out,
987 * action gets an appropriate flag and will be processed
988 * accordingly
989 */
990static void
991zfcp_erp_timeout_handler(unsigned long data)
992{
993 struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data;
994 struct zfcp_adapter *adapter = erp_action->adapter;
995
996 debug_text_event(adapter->erp_dbf, 2, "a_th");
997 debug_event(adapter->erp_dbf, 2, &erp_action->action, sizeof (int));
998
999 zfcp_erp_async_handler(erp_action, ZFCP_STATUS_ERP_TIMEDOUT);
1000}
1001
1002/*
1003 * purpose: is called for an erp_action which needs to be ended
1004 * though not being done,
1005 * this is usually required if an higher is generated,
1006 * action gets an appropriate flag and will be processed
1007 * accordingly
1008 *
1009 * locks: erp_lock held (thus we need to call another handler variant)
1010 */
1011static int
1012zfcp_erp_action_dismiss(struct zfcp_erp_action *erp_action)
1013{
1014 struct zfcp_adapter *adapter = erp_action->adapter;
1015
1016 debug_text_event(adapter->erp_dbf, 2, "a_adis");
1017 debug_event(adapter->erp_dbf, 2, &erp_action->action, sizeof (int));
1018
1019 zfcp_erp_async_handler_nolock(erp_action, ZFCP_STATUS_ERP_DISMISSED);
1020
1021 return 0;
1022}
1023
1024int
1025zfcp_erp_thread_setup(struct zfcp_adapter *adapter)
1026{
1027 int retval = 0;
1028
1029 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
1030
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD);
1032 if (retval < 0) {
1033 ZFCP_LOG_NORMAL("error: creation of erp thread failed for "
1034 "adapter %s\n",
1035 zfcp_get_busid_by_adapter(adapter));
1036 debug_text_event(adapter->erp_dbf, 5, "a_thset_fail");
1037 } else {
1038 wait_event(adapter->erp_thread_wqh,
1039 atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP,
1040 &adapter->status));
1041 debug_text_event(adapter->erp_dbf, 5, "a_thset_ok");
1042 }
1043
1044 return (retval < 0);
1045}
1046
1047/*
1048 * function:
1049 *
1050 * purpose:
1051 *
1052 * returns:
1053 *
1054 * context: process (i.e. proc-fs or rmmod/insmod)
1055 *
1056 * note: The caller of this routine ensures that the specified
1057 * adapter has been shut down and that this operation
1058 * has been completed. Thus, there are no pending erp_actions
1059 * which would need to be handled here.
1060 */
1061int
1062zfcp_erp_thread_kill(struct zfcp_adapter *adapter)
1063{
1064 int retval = 0;
1065
1066 atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status);
1067 up(&adapter->erp_ready_sem);
1068
1069 wait_event(adapter->erp_thread_wqh,
1070 !atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP,
1071 &adapter->status));
1072
1073 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL,
1074 &adapter->status);
1075
1076 debug_text_event(adapter->erp_dbf, 5, "a_thki_ok");
1077
1078 return retval;
1079}
1080
1081/*
1082 * purpose: is run as a kernel thread,
1083 * goes through list of error recovery actions of associated adapter
1084 * and delegates single action to execution
1085 *
1086 * returns: 0
1087 */
1088static int
1089zfcp_erp_thread(void *data)
1090{
1091 struct zfcp_adapter *adapter = (struct zfcp_adapter *) data;
1092 struct list_head *next;
1093 struct zfcp_erp_action *erp_action;
1094 unsigned long flags;
1095
1096 daemonize("zfcperp%s", zfcp_get_busid_by_adapter(adapter));
1097 /* Block all signals */
1098 siginitsetinv(&current->blocked, 0);
1099 atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
1100 debug_text_event(adapter->erp_dbf, 5, "a_th_run");
1101 wake_up(&adapter->erp_thread_wqh);
1102
1103 while (!atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL,
1104 &adapter->status)) {
1105
1106 write_lock_irqsave(&adapter->erp_lock, flags);
1107 next = adapter->erp_ready_head.prev;
1108 write_unlock_irqrestore(&adapter->erp_lock, flags);
1109
1110 if (next != &adapter->erp_ready_head) {
1111 erp_action =
1112 list_entry(next, struct zfcp_erp_action, list);
1113 /*
1114 * process action (incl. [re]moving it
1115 * from 'ready' queue)
1116 */
1117 zfcp_erp_strategy(erp_action);
1118 }
1119
1120 /*
1121 * sleep as long as there is nothing to do, i.e.
1122 * no action in 'ready' queue to be processed and
1123 * thread is not to be killed
1124 */
1125 down_interruptible(&adapter->erp_ready_sem);
1126 debug_text_event(adapter->erp_dbf, 5, "a_th_woken");
1127 }
1128
1129 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
1130 debug_text_event(adapter->erp_dbf, 5, "a_th_stop");
1131 wake_up(&adapter->erp_thread_wqh);
1132
1133 return 0;
1134}
1135
1136/*
1137 * function:
1138 *
1139 * purpose: drives single error recovery action and schedules higher and
1140 * subordinate actions, if necessary
1141 *
1142 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
1143 * ZFCP_ERP_SUCCEEDED - action finished successfully (deqd)
1144 * ZFCP_ERP_FAILED - action finished unsuccessfully (deqd)
1145 * ZFCP_ERP_EXIT - action finished (dequeued), offline
1146 * ZFCP_ERP_DISMISSED - action canceled (dequeued)
1147 */
1148static int
1149zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
1150{
1151 int retval = 0;
1152 struct zfcp_adapter *adapter = erp_action->adapter;
1153 struct zfcp_port *port = erp_action->port;
1154 struct zfcp_unit *unit = erp_action->unit;
1155 int action = erp_action->action;
1156 u32 status = erp_action->status;
1157 unsigned long flags;
1158
1159 /* serialise dismissing, timing out, moving, enqueueing */
1160 read_lock_irqsave(&zfcp_data.config_lock, flags);
1161 write_lock(&adapter->erp_lock);
1162
1163 /* dequeue dismissed action and leave, if required */
1164 retval = zfcp_erp_strategy_check_action(erp_action, retval);
1165 if (retval == ZFCP_ERP_DISMISSED) {
1166 debug_text_event(adapter->erp_dbf, 4, "a_st_dis1");
1167 goto unlock;
1168 }
1169
1170 /*
1171 * move action to 'running' queue before processing it
1172 * (to avoid a race condition regarding moving the
1173 * action to the 'running' queue and back)
1174 */
1175 zfcp_erp_action_to_running(erp_action);
1176
1177 /*
1178 * try to process action as far as possible,
1179 * no lock to allow for blocking operations (kmalloc, qdio, ...),
1180 * afterwards the lock is required again for the following reasons:
1181 * - dequeueing of finished action and enqueueing of
1182 * follow-up actions must be atomic so that any other
1183 * reopen-routine does not believe there is nothing to do
1184 * and that it is safe to enqueue something else,
1185 * - we want to force any control thread which is dismissing
1186 * actions to finish this before we decide about
1187 * necessary steps to be taken here further
1188 */
1189 write_unlock(&adapter->erp_lock);
1190 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
1191 retval = zfcp_erp_strategy_do_action(erp_action);
1192 read_lock_irqsave(&zfcp_data.config_lock, flags);
1193 write_lock(&adapter->erp_lock);
1194
1195 /*
1196 * check for dismissed status again to avoid follow-up actions,
1197 * failing of targets and so on for dismissed actions
1198 */
1199 retval = zfcp_erp_strategy_check_action(erp_action, retval);
1200
1201 switch (retval) {
1202 case ZFCP_ERP_DISMISSED:
1203 /* leave since this action has ridden to its ancestors */
1204 debug_text_event(adapter->erp_dbf, 6, "a_st_dis2");
1205 goto unlock;
1206 case ZFCP_ERP_NOMEM:
1207 /* no memory to continue immediately, let it sleep */
1208 if (!(erp_action->status & ZFCP_STATUS_ERP_LOWMEM)) {
1209 ++adapter->erp_low_mem_count;
1210 erp_action->status |= ZFCP_STATUS_ERP_LOWMEM;
1211 }
1212 /* This condition is true if there is no memory available
1213 for any erp_action on this adapter. This implies that there
1214 are no elements in the memory pool(s) left for erp_actions.
1215 This might happen if an erp_action that used a memory pool
1216 element was timed out.
1217 */
1218 if (adapter->erp_total_count == adapter->erp_low_mem_count) {
1219 debug_text_event(adapter->erp_dbf, 3, "a_st_lowmem");
1220 ZFCP_LOG_NORMAL("error: no mempool elements available, "
1221 "restarting I/O on adapter %s "
1222 "to free mempool\n",
1223 zfcp_get_busid_by_adapter(adapter));
1224 zfcp_erp_adapter_reopen_internal(adapter, 0);
1225 } else {
1226 debug_text_event(adapter->erp_dbf, 2, "a_st_memw");
1227 retval = zfcp_erp_strategy_memwait(erp_action);
1228 }
1229 goto unlock;
1230 case ZFCP_ERP_CONTINUES:
1231 /* leave since this action runs asynchronously */
1232 debug_text_event(adapter->erp_dbf, 6, "a_st_cont");
1233 if (erp_action->status & ZFCP_STATUS_ERP_LOWMEM) {
1234 --adapter->erp_low_mem_count;
1235 erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM;
1236 }
1237 goto unlock;
1238 }
1239 /* ok, finished action (whatever its result is) */
1240
1241 /* check for unrecoverable targets */
1242 retval = zfcp_erp_strategy_check_target(erp_action, retval);
1243
1244 /* action must be dequeued (here to allow for further ones) */
1245 zfcp_erp_action_dequeue(erp_action);
1246
1247 /*
1248 * put this target through the erp mill again if someone has
1249 * requested to change the status of a target being online
1250 * to offline or the other way around
1251 * (old retval is preserved if nothing has to be done here)
1252 */
1253 retval = zfcp_erp_strategy_statechange(action, status, adapter,
1254 port, unit, retval);
1255
1256 /*
1257 * leave if target is in permanent error state or if
1258 * action is repeated in order to process state change
1259 */
1260 if (retval == ZFCP_ERP_EXIT) {
1261 debug_text_event(adapter->erp_dbf, 2, "a_st_exit");
1262 goto unlock;
1263 }
1264
1265 /* trigger follow up actions */
1266 zfcp_erp_strategy_followup_actions(action, adapter, port, unit, retval);
1267
1268 unlock:
1269 write_unlock(&adapter->erp_lock);
1270 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
1271
1272 if (retval != ZFCP_ERP_CONTINUES)
1273 zfcp_erp_action_cleanup(action, adapter, port, unit, retval);
1274
1275 /*
1276 * a few tasks remain when the erp queues are empty
1277 * (don't do that if the last action evaluated was dismissed
1278 * since this clearly indicates that there is more to come) :
1279 * - close the name server port if it is open yet
1280 * (enqueues another [probably] final action)
1281 * - otherwise, wake up whoever wants to be woken when we are
1282 * done with erp
1283 */
1284 if (retval != ZFCP_ERP_DISMISSED)
1285 zfcp_erp_strategy_check_queues(adapter);
1286
1287 debug_text_event(adapter->erp_dbf, 6, "a_st_done");
1288
1289 return retval;
1290}
1291
1292/*
1293 * function:
1294 *
1295 * purpose:
1296 *
1297 * returns: ZFCP_ERP_DISMISSED - if action has been dismissed
1298 * retval - otherwise
1299 */
1300static int
1301zfcp_erp_strategy_check_action(struct zfcp_erp_action *erp_action, int retval)
1302{
1303 struct zfcp_adapter *adapter = erp_action->adapter;
1304
1305 zfcp_erp_strategy_check_fsfreq(erp_action);
1306
1307 debug_event(adapter->erp_dbf, 5, &erp_action->action, sizeof (int));
1308 if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) {
1309 debug_text_event(adapter->erp_dbf, 3, "a_stcd_dis");
1310 zfcp_erp_action_dequeue(erp_action);
1311 retval = ZFCP_ERP_DISMISSED;
1312 } else
1313 debug_text_event(adapter->erp_dbf, 5, "a_stcd_nodis");
1314
1315 return retval;
1316}
1317
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318static int
1319zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action)
1320{
1321 int retval = ZFCP_ERP_FAILED;
1322 struct zfcp_adapter *adapter = erp_action->adapter;
1323
1324 /*
1325 * try to execute/continue action as far as possible,
1326 * note: no lock in subsequent strategy routines
1327 * (this allows these routine to call schedule, e.g.
1328 * kmalloc with such flags or qdio_initialize & friends)
1329 * Note: in case of timeout, the seperate strategies will fail
1330 * anyhow. No need for a special action. Even worse, a nameserver
1331 * failure would not wake up waiting ports without the call.
1332 */
1333 switch (erp_action->action) {
1334
1335 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
1336 retval = zfcp_erp_adapter_strategy(erp_action);
1337 break;
1338
1339 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
1340 retval = zfcp_erp_port_forced_strategy(erp_action);
1341 break;
1342
1343 case ZFCP_ERP_ACTION_REOPEN_PORT:
1344 retval = zfcp_erp_port_strategy(erp_action);
1345 break;
1346
1347 case ZFCP_ERP_ACTION_REOPEN_UNIT:
1348 retval = zfcp_erp_unit_strategy(erp_action);
1349 break;
1350
1351 default:
1352 debug_text_exception(adapter->erp_dbf, 1, "a_stda_bug");
1353 debug_event(adapter->erp_dbf, 1, &erp_action->action,
1354 sizeof (int));
1355 ZFCP_LOG_NORMAL("bug: unknown erp action requested on "
1356 "adapter %s (action=%d)\n",
1357 zfcp_get_busid_by_adapter(erp_action->adapter),
1358 erp_action->action);
1359 }
1360
1361 return retval;
1362}
1363
1364/*
1365 * function:
1366 *
1367 * purpose: triggers retry of this action after a certain amount of time
1368 * by means of timer provided by erp_action
1369 *
1370 * returns: ZFCP_ERP_CONTINUES - erp_action sleeps in erp running queue
1371 */
1372static int
1373zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action)
1374{
1375 int retval = ZFCP_ERP_CONTINUES;
1376 struct zfcp_adapter *adapter = erp_action->adapter;
1377
1378 debug_text_event(adapter->erp_dbf, 6, "a_mwinit");
1379 debug_event(adapter->erp_dbf, 6, &erp_action->action, sizeof (int));
1380 init_timer(&erp_action->timer);
1381 erp_action->timer.function = zfcp_erp_memwait_handler;
1382 erp_action->timer.data = (unsigned long) erp_action;
1383 erp_action->timer.expires = jiffies + ZFCP_ERP_MEMWAIT_TIMEOUT;
1384 add_timer(&erp_action->timer);
1385
1386 return retval;
1387}
1388
1389/*
1390 * function: zfcp_erp_adapter_failed
1391 *
1392 * purpose: sets the adapter and all underlying devices to ERP_FAILED
1393 *
1394 */
1395void
1396zfcp_erp_adapter_failed(struct zfcp_adapter *adapter)
1397{
1398 zfcp_erp_modify_adapter_status(adapter,
1399 ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
1400 ZFCP_LOG_NORMAL("adapter erp failed on adapter %s\n",
1401 zfcp_get_busid_by_adapter(adapter));
1402 debug_text_event(adapter->erp_dbf, 2, "a_afail");
1403}
1404
1405/*
1406 * function: zfcp_erp_port_failed
1407 *
1408 * purpose: sets the port and all underlying devices to ERP_FAILED
1409 *
1410 */
1411void
1412zfcp_erp_port_failed(struct zfcp_port *port)
1413{
1414 zfcp_erp_modify_port_status(port,
1415 ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
1416
1417 if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
1418 ZFCP_LOG_NORMAL("port erp failed (adapter %s, "
1419 "port d_id=0x%08x)\n",
1420 zfcp_get_busid_by_port(port), port->d_id);
1421 else
1422 ZFCP_LOG_NORMAL("port erp failed (adapter %s, wwpn=0x%016Lx)\n",
1423 zfcp_get_busid_by_port(port), port->wwpn);
1424
1425 debug_text_event(port->adapter->erp_dbf, 2, "p_pfail");
1426 debug_event(port->adapter->erp_dbf, 2, &port->wwpn, sizeof (wwn_t));
1427}
1428
1429/*
1430 * function: zfcp_erp_unit_failed
1431 *
1432 * purpose: sets the unit to ERP_FAILED
1433 *
1434 */
1435void
1436zfcp_erp_unit_failed(struct zfcp_unit *unit)
1437{
1438 zfcp_erp_modify_unit_status(unit,
1439 ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
1440
1441 ZFCP_LOG_NORMAL("unit erp failed on unit 0x%016Lx on port 0x%016Lx "
1442 " on adapter %s\n", unit->fcp_lun,
1443 unit->port->wwpn, zfcp_get_busid_by_unit(unit));
1444 debug_text_event(unit->port->adapter->erp_dbf, 2, "u_ufail");
1445 debug_event(unit->port->adapter->erp_dbf, 2,
1446 &unit->fcp_lun, sizeof (fcp_lun_t));
1447}
1448
1449/*
1450 * function: zfcp_erp_strategy_check_target
1451 *
1452 * purpose: increments the erp action count on the device currently in
1453 * recovery if the action failed or resets the count in case of
1454 * success. If a maximum count is exceeded the device is marked
1455 * as ERP_FAILED.
1456 * The 'blocked' state of a target which has been recovered
1457 * successfully is reset.
1458 *
1459 * returns: ZFCP_ERP_CONTINUES - action continues (not considered)
1460 * ZFCP_ERP_SUCCEEDED - action finished successfully
1461 * ZFCP_ERP_EXIT - action failed and will not continue
1462 */
1463static int
1464zfcp_erp_strategy_check_target(struct zfcp_erp_action *erp_action, int result)
1465{
1466 struct zfcp_adapter *adapter = erp_action->adapter;
1467 struct zfcp_port *port = erp_action->port;
1468 struct zfcp_unit *unit = erp_action->unit;
1469
1470 debug_text_event(adapter->erp_dbf, 5, "a_stct_norm");
1471 debug_event(adapter->erp_dbf, 5, &erp_action->action, sizeof (int));
1472 debug_event(adapter->erp_dbf, 5, &result, sizeof (int));
1473
1474 switch (erp_action->action) {
1475
1476 case ZFCP_ERP_ACTION_REOPEN_UNIT:
1477 result = zfcp_erp_strategy_check_unit(unit, result);
1478 break;
1479
1480 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
1481 case ZFCP_ERP_ACTION_REOPEN_PORT:
1482 result = zfcp_erp_strategy_check_port(port, result);
1483 break;
1484
1485 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
1486 result = zfcp_erp_strategy_check_adapter(adapter, result);
1487 break;
1488 }
1489
1490 return result;
1491}
1492
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493static int
1494zfcp_erp_strategy_statechange(int action,
1495 u32 status,
1496 struct zfcp_adapter *adapter,
1497 struct zfcp_port *port,
1498 struct zfcp_unit *unit, int retval)
1499{
1500 debug_text_event(adapter->erp_dbf, 3, "a_stsc");
1501 debug_event(adapter->erp_dbf, 3, &action, sizeof (int));
1502
1503 switch (action) {
1504
1505 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
1506 if (zfcp_erp_strategy_statechange_detected(&adapter->status,
1507 status)) {
1508 zfcp_erp_adapter_reopen_internal(adapter, ZFCP_STATUS_COMMON_ERP_FAILED);
1509 retval = ZFCP_ERP_EXIT;
1510 }
1511 break;
1512
1513 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
1514 case ZFCP_ERP_ACTION_REOPEN_PORT:
1515 if (zfcp_erp_strategy_statechange_detected(&port->status,
1516 status)) {
1517 zfcp_erp_port_reopen_internal(port, ZFCP_STATUS_COMMON_ERP_FAILED);
1518 retval = ZFCP_ERP_EXIT;
1519 }
1520 break;
1521
1522 case ZFCP_ERP_ACTION_REOPEN_UNIT:
1523 if (zfcp_erp_strategy_statechange_detected(&unit->status,
1524 status)) {
1525 zfcp_erp_unit_reopen_internal(unit, ZFCP_STATUS_COMMON_ERP_FAILED);
1526 retval = ZFCP_ERP_EXIT;
1527 }
1528 break;
1529 }
1530
1531 return retval;
1532}
1533
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534static inline int
1535zfcp_erp_strategy_statechange_detected(atomic_t * target_status, u32 erp_status)
1536{
1537 return
1538 /* take it online */
1539 (atomic_test_mask(ZFCP_STATUS_COMMON_RUNNING, target_status) &&
1540 (ZFCP_STATUS_ERP_CLOSE_ONLY & erp_status)) ||
1541 /* take it offline */
1542 (!atomic_test_mask(ZFCP_STATUS_COMMON_RUNNING, target_status) &&
1543 !(ZFCP_STATUS_ERP_CLOSE_ONLY & erp_status));
1544}
1545
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546static int
1547zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result)
1548{
1549 debug_text_event(unit->port->adapter->erp_dbf, 5, "u_stct");
1550 debug_event(unit->port->adapter->erp_dbf, 5, &unit->fcp_lun,
1551 sizeof (fcp_lun_t));
1552
1553 switch (result) {
1554 case ZFCP_ERP_SUCCEEDED :
1555 atomic_set(&unit->erp_counter, 0);
1556 zfcp_erp_unit_unblock(unit);
1557 break;
1558 case ZFCP_ERP_FAILED :
1559 atomic_inc(&unit->erp_counter);
1560 if (atomic_read(&unit->erp_counter) > ZFCP_MAX_ERPS)
1561 zfcp_erp_unit_failed(unit);
1562 break;
1563 case ZFCP_ERP_EXIT :
1564 /* nothing */
1565 break;
1566 }
1567
1568 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &unit->status)) {
1569 zfcp_erp_unit_block(unit, 0); /* for ZFCP_ERP_SUCCEEDED */
1570 result = ZFCP_ERP_EXIT;
1571 }
1572
1573 return result;
1574}
1575
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576static int
1577zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
1578{
1579 debug_text_event(port->adapter->erp_dbf, 5, "p_stct");
1580 debug_event(port->adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
1581
1582 switch (result) {
1583 case ZFCP_ERP_SUCCEEDED :
1584 atomic_set(&port->erp_counter, 0);
1585 zfcp_erp_port_unblock(port);
1586 break;
1587 case ZFCP_ERP_FAILED :
1588 atomic_inc(&port->erp_counter);
1589 if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS)
1590 zfcp_erp_port_failed(port);
1591 break;
1592 case ZFCP_ERP_EXIT :
1593 /* nothing */
1594 break;
1595 }
1596
1597 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) {
1598 zfcp_erp_port_block(port, 0); /* for ZFCP_ERP_SUCCEEDED */
1599 result = ZFCP_ERP_EXIT;
1600 }
1601
1602 return result;
1603}
1604
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605static int
1606zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, int result)
1607{
1608 debug_text_event(adapter->erp_dbf, 5, "a_stct");
1609
1610 switch (result) {
1611 case ZFCP_ERP_SUCCEEDED :
1612 atomic_set(&adapter->erp_counter, 0);
1613 zfcp_erp_adapter_unblock(adapter);
1614 break;
1615 case ZFCP_ERP_FAILED :
1616 atomic_inc(&adapter->erp_counter);
1617 if (atomic_read(&adapter->erp_counter) > ZFCP_MAX_ERPS)
1618 zfcp_erp_adapter_failed(adapter);
1619 break;
1620 case ZFCP_ERP_EXIT :
1621 /* nothing */
1622 break;
1623 }
1624
1625 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &adapter->status)) {
1626 zfcp_erp_adapter_block(adapter, 0); /* for ZFCP_ERP_SUCCEEDED */
1627 result = ZFCP_ERP_EXIT;
1628 }
1629
1630 return result;
1631}
1632
1633/*
1634 * function:
1635 *
1636 * purpose: remaining things in good cases,
1637 * escalation in bad cases
1638 *
1639 * returns:
1640 */
1641static int
1642zfcp_erp_strategy_followup_actions(int action,
1643 struct zfcp_adapter *adapter,
1644 struct zfcp_port *port,
1645 struct zfcp_unit *unit, int status)
1646{
1647 debug_text_event(adapter->erp_dbf, 5, "a_stfol");
1648 debug_event(adapter->erp_dbf, 5, &action, sizeof (int));
1649
1650 /* initiate follow-up actions depending on success of finished action */
1651 switch (action) {
1652
1653 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
1654 if (status == ZFCP_ERP_SUCCEEDED)
1655 zfcp_erp_port_reopen_all_internal(adapter, 0);
1656 else
1657 zfcp_erp_adapter_reopen_internal(adapter, 0);
1658 break;
1659
1660 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
1661 if (status == ZFCP_ERP_SUCCEEDED)
1662 zfcp_erp_port_reopen_internal(port, 0);
1663 else
1664 zfcp_erp_adapter_reopen_internal(adapter, 0);
1665 break;
1666
1667 case ZFCP_ERP_ACTION_REOPEN_PORT:
1668 if (status == ZFCP_ERP_SUCCEEDED)
1669 zfcp_erp_unit_reopen_all_internal(port, 0);
1670 else
1671 zfcp_erp_port_forced_reopen_internal(port, 0);
1672 break;
1673
1674 case ZFCP_ERP_ACTION_REOPEN_UNIT:
1675 if (status == ZFCP_ERP_SUCCEEDED) ; /* no further action */
1676 else
1677 zfcp_erp_port_reopen_internal(unit->port, 0);
1678 break;
1679 }
1680
1681 return 0;
1682}
1683
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684static int
1685zfcp_erp_strategy_check_queues(struct zfcp_adapter *adapter)
1686{
1687 unsigned long flags;
1688
1689 read_lock_irqsave(&zfcp_data.config_lock, flags);
1690 read_lock(&adapter->erp_lock);
1691 if (list_empty(&adapter->erp_ready_head) &&
1692 list_empty(&adapter->erp_running_head)) {
1693 debug_text_event(adapter->erp_dbf, 4, "a_cq_wake");
1694 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING,
1695 &adapter->status);
1696 wake_up(&adapter->erp_done_wqh);
1697 } else
1698 debug_text_event(adapter->erp_dbf, 5, "a_cq_notempty");
1699 read_unlock(&adapter->erp_lock);
1700 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
1701
1702 return 0;
1703}
1704
1705/**
1706 * zfcp_erp_wait - wait for completion of error recovery on an adapter
1707 * @adapter: adapter for which to wait for completion of its error recovery
1708 * Return: 0
1709 */
1710int
1711zfcp_erp_wait(struct zfcp_adapter *adapter)
1712{
1713 int retval = 0;
1714
1715 wait_event(adapter->erp_done_wqh,
1716 !atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING,
1717 &adapter->status));
1718
1719 return retval;
1720}
1721
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722void
1723zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter,
1724 u32 mask, int set_or_clear)
1725{
1726 struct zfcp_port *port;
1727 u32 common_mask = mask & ZFCP_COMMON_FLAGS;
1728
1729 if (set_or_clear == ZFCP_SET) {
1730 atomic_set_mask(mask, &adapter->status);
1731 debug_text_event(adapter->erp_dbf, 3, "a_mod_as_s");
1732 } else {
1733 atomic_clear_mask(mask, &adapter->status);
1734 if (mask & ZFCP_STATUS_COMMON_ERP_FAILED)
1735 atomic_set(&adapter->erp_counter, 0);
1736 debug_text_event(adapter->erp_dbf, 3, "a_mod_as_c");
1737 }
1738 debug_event(adapter->erp_dbf, 3, &mask, sizeof (u32));
1739
1740 /* Deal with all underlying devices, only pass common_mask */
1741 if (common_mask)
1742 list_for_each_entry(port, &adapter->port_list_head, list)
1743 zfcp_erp_modify_port_status(port, common_mask,
1744 set_or_clear);
1745}
1746
1747/*
1748 * function: zfcp_erp_modify_port_status
1749 *
1750 * purpose: sets the port and all underlying devices to ERP_FAILED
1751 *
1752 */
1753void
1754zfcp_erp_modify_port_status(struct zfcp_port *port, u32 mask, int set_or_clear)
1755{
1756 struct zfcp_unit *unit;
1757 u32 common_mask = mask & ZFCP_COMMON_FLAGS;
1758
1759 if (set_or_clear == ZFCP_SET) {
1760 atomic_set_mask(mask, &port->status);
1761 debug_text_event(port->adapter->erp_dbf, 3, "p_mod_ps_s");
1762 } else {
1763 atomic_clear_mask(mask, &port->status);
1764 if (mask & ZFCP_STATUS_COMMON_ERP_FAILED)
1765 atomic_set(&port->erp_counter, 0);
1766 debug_text_event(port->adapter->erp_dbf, 3, "p_mod_ps_c");
1767 }
1768 debug_event(port->adapter->erp_dbf, 3, &port->wwpn, sizeof (wwn_t));
1769 debug_event(port->adapter->erp_dbf, 3, &mask, sizeof (u32));
1770
1771 /* Modify status of all underlying devices, only pass common mask */
1772 if (common_mask)
1773 list_for_each_entry(unit, &port->unit_list_head, list)
1774 zfcp_erp_modify_unit_status(unit, common_mask,
1775 set_or_clear);
1776}
1777
1778/*
1779 * function: zfcp_erp_modify_unit_status
1780 *
1781 * purpose: sets the unit to ERP_FAILED
1782 *
1783 */
1784void
1785zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u32 mask, int set_or_clear)
1786{
1787 if (set_or_clear == ZFCP_SET) {
1788 atomic_set_mask(mask, &unit->status);
1789 debug_text_event(unit->port->adapter->erp_dbf, 3, "u_mod_us_s");
1790 } else {
1791 atomic_clear_mask(mask, &unit->status);
1792 if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) {
1793 atomic_set(&unit->erp_counter, 0);
1794 }
1795 debug_text_event(unit->port->adapter->erp_dbf, 3, "u_mod_us_c");
1796 }
1797 debug_event(unit->port->adapter->erp_dbf, 3, &unit->fcp_lun,
1798 sizeof (fcp_lun_t));
1799 debug_event(unit->port->adapter->erp_dbf, 3, &mask, sizeof (u32));
1800}
1801
1802/*
1803 * function:
1804 *
1805 * purpose: Wrappper for zfcp_erp_port_reopen_all_internal
1806 * used to ensure the correct locking
1807 *
Andreas Mohrd6e05ed2006-06-26 18:35:02 +02001808 * returns: 0 - initiated action successfully
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 * <0 - failed to initiate action
1810 */
1811int
1812zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, int clear_mask)
1813{
1814 int retval;
1815 unsigned long flags;
1816
1817 read_lock_irqsave(&zfcp_data.config_lock, flags);
1818 write_lock(&adapter->erp_lock);
1819 retval = zfcp_erp_port_reopen_all_internal(adapter, clear_mask);
1820 write_unlock(&adapter->erp_lock);
1821 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
1822
1823 return retval;
1824}
1825
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826static int
1827zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *adapter, int clear_mask)
1828{
1829 int retval = 0;
1830 struct zfcp_port *port;
1831
1832 list_for_each_entry(port, &adapter->port_list_head, list)
1833 if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
1834 zfcp_erp_port_reopen_internal(port, clear_mask);
1835
1836 return retval;
1837}
1838
1839/*
1840 * function:
1841 *
1842 * purpose:
1843 *
1844 * returns: FIXME
1845 */
1846static int
1847zfcp_erp_unit_reopen_all_internal(struct zfcp_port *port, int clear_mask)
1848{
1849 int retval = 0;
1850 struct zfcp_unit *unit;
1851
1852 list_for_each_entry(unit, &port->unit_list_head, list)
1853 zfcp_erp_unit_reopen_internal(unit, clear_mask);
1854
1855 return retval;
1856}
1857
1858/*
1859 * function:
1860 *
1861 * purpose: this routine executes the 'Reopen Adapter' action
1862 * (the entire action is processed synchronously, since
1863 * there are no actions which might be run concurrently
1864 * per definition)
1865 *
1866 * returns: ZFCP_ERP_SUCCEEDED - action finished successfully
1867 * ZFCP_ERP_FAILED - action finished unsuccessfully
1868 */
1869static int
1870zfcp_erp_adapter_strategy(struct zfcp_erp_action *erp_action)
1871{
1872 int retval;
1873 struct zfcp_adapter *adapter = erp_action->adapter;
1874
1875 retval = zfcp_erp_adapter_strategy_close(erp_action);
1876 if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
1877 retval = ZFCP_ERP_EXIT;
1878 else
1879 retval = zfcp_erp_adapter_strategy_open(erp_action);
1880
1881 debug_text_event(adapter->erp_dbf, 3, "a_ast/ret");
1882 debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int));
1883 debug_event(adapter->erp_dbf, 3, &retval, sizeof (int));
1884
1885 if (retval == ZFCP_ERP_FAILED) {
1886 ZFCP_LOG_INFO("Waiting to allow the adapter %s "
1887 "to recover itself\n",
1888 zfcp_get_busid_by_adapter(adapter));
1889 msleep(jiffies_to_msecs(ZFCP_TYPE2_RECOVERY_TIME));
1890 }
1891
1892 return retval;
1893}
1894
1895/*
1896 * function:
1897 *
1898 * purpose:
1899 *
1900 * returns: ZFCP_ERP_SUCCEEDED - action finished successfully
1901 * ZFCP_ERP_FAILED - action finished unsuccessfully
1902 */
1903static int
1904zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *erp_action)
1905{
1906 int retval;
1907
1908 atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING,
1909 &erp_action->adapter->status);
1910 retval = zfcp_erp_adapter_strategy_generic(erp_action, 1);
1911 atomic_clear_mask(ZFCP_STATUS_COMMON_CLOSING,
1912 &erp_action->adapter->status);
1913
1914 return retval;
1915}
1916
1917/*
1918 * function:
1919 *
1920 * purpose:
1921 *
1922 * returns: ZFCP_ERP_SUCCEEDED - action finished successfully
1923 * ZFCP_ERP_FAILED - action finished unsuccessfully
1924 */
1925static int
1926zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *erp_action)
1927{
1928 int retval;
1929
1930 atomic_set_mask(ZFCP_STATUS_COMMON_OPENING,
1931 &erp_action->adapter->status);
1932 retval = zfcp_erp_adapter_strategy_generic(erp_action, 0);
1933 atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING,
1934 &erp_action->adapter->status);
1935
1936 return retval;
1937}
1938
1939/*
1940 * function: zfcp_register_adapter
1941 *
1942 * purpose: allocate the irq associated with this devno and register
1943 * the FSF adapter with the SCSI stack
1944 *
1945 * returns:
1946 */
1947static int
1948zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *erp_action, int close)
1949{
1950 int retval = ZFCP_ERP_SUCCEEDED;
1951
1952 if (close)
1953 goto close_only;
1954
1955 retval = zfcp_erp_adapter_strategy_open_qdio(erp_action);
1956 if (retval != ZFCP_ERP_SUCCEEDED)
1957 goto failed_qdio;
1958
1959 retval = zfcp_erp_adapter_strategy_open_fsf(erp_action);
1960 if (retval != ZFCP_ERP_SUCCEEDED)
1961 goto failed_openfcp;
1962
1963 atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &erp_action->adapter->status);
1964 goto out;
1965
1966 close_only:
1967 atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN,
1968 &erp_action->adapter->status);
1969
1970 failed_openfcp:
1971 zfcp_erp_adapter_strategy_close_qdio(erp_action);
1972 zfcp_erp_adapter_strategy_close_fsf(erp_action);
1973 failed_qdio:
1974 out:
1975 return retval;
1976}
1977
1978/*
1979 * function: zfcp_qdio_init
1980 *
1981 * purpose: setup QDIO operation for specified adapter
1982 *
1983 * returns: 0 - successful setup
1984 * !0 - failed setup
1985 */
1986int
1987zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
1988{
1989 int retval;
1990 int i;
1991 volatile struct qdio_buffer_element *sbale;
1992 struct zfcp_adapter *adapter = erp_action->adapter;
1993
1994 if (atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) {
1995 ZFCP_LOG_NORMAL("bug: second attempt to set up QDIO on "
1996 "adapter %s\n",
1997 zfcp_get_busid_by_adapter(adapter));
1998 goto failed_sanity;
1999 }
2000
2001 if (qdio_establish(&adapter->qdio_init_data) != 0) {
2002 ZFCP_LOG_INFO("error: establishment of QDIO queues failed "
2003 "on adapter %s\n",
2004 zfcp_get_busid_by_adapter(adapter));
2005 goto failed_qdio_establish;
2006 }
2007 debug_text_event(adapter->erp_dbf, 3, "qdio_est");
2008
2009 if (qdio_activate(adapter->ccw_device, 0) != 0) {
2010 ZFCP_LOG_INFO("error: activation of QDIO queues failed "
2011 "on adapter %s\n",
2012 zfcp_get_busid_by_adapter(adapter));
2013 goto failed_qdio_activate;
2014 }
2015 debug_text_event(adapter->erp_dbf, 3, "qdio_act");
2016
2017 /*
2018 * put buffers into response queue,
2019 */
2020 for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) {
2021 sbale = &(adapter->response_queue.buffer[i]->element[0]);
2022 sbale->length = 0;
2023 sbale->flags = SBAL_FLAGS_LAST_ENTRY;
2024 sbale->addr = 0;
2025 }
2026
2027 ZFCP_LOG_TRACE("calling do_QDIO on adapter %s (flags=0x%x, "
2028 "queue_no=%i, index_in_queue=%i, count=%i)\n",
2029 zfcp_get_busid_by_adapter(adapter),
2030 QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q);
2031
2032 retval = do_QDIO(adapter->ccw_device,
2033 QDIO_FLAG_SYNC_INPUT,
2034 0, 0, QDIO_MAX_BUFFERS_PER_Q, NULL);
2035
2036 if (retval) {
2037 ZFCP_LOG_NORMAL("bug: setup of QDIO failed (retval=%d)\n",
2038 retval);
2039 goto failed_do_qdio;
2040 } else {
2041 adapter->response_queue.free_index = 0;
2042 atomic_set(&adapter->response_queue.free_count, 0);
2043 ZFCP_LOG_DEBUG("%i buffers successfully enqueued to "
2044 "response queue\n", QDIO_MAX_BUFFERS_PER_Q);
2045 }
2046 /* set index of first avalable SBALS / number of available SBALS */
2047 adapter->request_queue.free_index = 0;
2048 atomic_set(&adapter->request_queue.free_count, QDIO_MAX_BUFFERS_PER_Q);
2049 adapter->request_queue.distance_from_int = 0;
2050
2051 /* initialize waitqueue used to wait for free SBALs in requests queue */
2052 init_waitqueue_head(&adapter->request_wq);
2053
2054 /* ok, we did it - skip all cleanups for different failures */
2055 atomic_set_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
2056 retval = ZFCP_ERP_SUCCEEDED;
2057 goto out;
2058
2059 failed_do_qdio:
2060 /* NOP */
2061
2062 failed_qdio_activate:
2063 debug_text_event(adapter->erp_dbf, 3, "qdio_down1a");
2064 while (qdio_shutdown(adapter->ccw_device,
2065 QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS)
2066 msleep(1000);
2067 debug_text_event(adapter->erp_dbf, 3, "qdio_down1b");
2068
2069 failed_qdio_establish:
2070 failed_sanity:
2071 retval = ZFCP_ERP_FAILED;
2072
2073 out:
2074 return retval;
2075}
2076
2077/*
2078 * function: zfcp_qdio_cleanup
2079 *
2080 * purpose: cleans up QDIO operation for the specified adapter
2081 *
2082 * returns: 0 - successful cleanup
2083 * !0 - failed cleanup
2084 */
2085int
2086zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action)
2087{
2088 int retval = ZFCP_ERP_SUCCEEDED;
2089 int first_used;
2090 int used_count;
2091 struct zfcp_adapter *adapter = erp_action->adapter;
2092
2093 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) {
2094 ZFCP_LOG_DEBUG("error: attempt to shut down inactive QDIO "
2095 "queues on adapter %s\n",
2096 zfcp_get_busid_by_adapter(adapter));
2097 retval = ZFCP_ERP_FAILED;
2098 goto out;
2099 }
2100
2101 /*
2102 * Get queue_lock and clear QDIOUP flag. Thus it's guaranteed that
2103 * do_QDIO won't be called while qdio_shutdown is in progress.
2104 */
2105
2106 write_lock_irq(&adapter->request_queue.queue_lock);
2107 atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
2108 write_unlock_irq(&adapter->request_queue.queue_lock);
2109
2110 debug_text_event(adapter->erp_dbf, 3, "qdio_down2a");
2111 while (qdio_shutdown(adapter->ccw_device,
2112 QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS)
2113 msleep(1000);
2114 debug_text_event(adapter->erp_dbf, 3, "qdio_down2b");
2115
2116 /*
2117 * First we had to stop QDIO operation.
2118 * Now it is safe to take the following actions.
2119 */
2120
2121 /* Cleanup only necessary when there are unacknowledged buffers */
2122 if (atomic_read(&adapter->request_queue.free_count)
2123 < QDIO_MAX_BUFFERS_PER_Q) {
2124 first_used = (adapter->request_queue.free_index +
2125 atomic_read(&adapter->request_queue.free_count))
2126 % QDIO_MAX_BUFFERS_PER_Q;
2127 used_count = QDIO_MAX_BUFFERS_PER_Q -
2128 atomic_read(&adapter->request_queue.free_count);
2129 zfcp_qdio_zero_sbals(adapter->request_queue.buffer,
2130 first_used, used_count);
2131 }
2132 adapter->response_queue.free_index = 0;
2133 atomic_set(&adapter->response_queue.free_count, 0);
2134 adapter->request_queue.free_index = 0;
2135 atomic_set(&adapter->request_queue.free_count, 0);
2136 adapter->request_queue.distance_from_int = 0;
2137 out:
2138 return retval;
2139}
2140
Linus Torvalds1da177e2005-04-16 15:20:36 -07002141static int
2142zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action)
2143{
Andreas Herrmann2448c452005-12-01 02:50:36 +01002144 int retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145
Andreas Herrmann2448c452005-12-01 02:50:36 +01002146 retval = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action);
2147 if (retval == ZFCP_ERP_FAILED)
2148 return ZFCP_ERP_FAILED;
2149
2150 retval = zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);
2151 if (retval == ZFCP_ERP_FAILED)
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02002152 return ZFCP_ERP_FAILED;
2153
2154 return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155}
2156
Linus Torvalds1da177e2005-04-16 15:20:36 -07002157static int
2158zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
2159{
2160 int retval = ZFCP_ERP_SUCCEEDED;
2161 int retries;
Andreas Herrmann22753fa2005-06-13 13:15:15 +02002162 int sleep = ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163 struct zfcp_adapter *adapter = erp_action->adapter;
2164
2165 atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002166
Andreas Herrmann22753fa2005-06-13 13:15:15 +02002167 for (retries = ZFCP_EXCHANGE_CONFIG_DATA_RETRIES; retries; retries--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002168 atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
2169 &adapter->status);
2170 ZFCP_LOG_DEBUG("Doing exchange config data\n");
Andreas Herrmann3734d242005-09-13 21:47:11 +02002171 write_lock(&adapter->erp_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002172 zfcp_erp_action_to_running(erp_action);
Andreas Herrmann3734d242005-09-13 21:47:11 +02002173 write_unlock(&adapter->erp_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174 zfcp_erp_timeout_init(erp_action);
2175 if (zfcp_fsf_exchange_config_data(erp_action)) {
2176 retval = ZFCP_ERP_FAILED;
2177 debug_text_event(adapter->erp_dbf, 5, "a_fstx_xf");
2178 ZFCP_LOG_INFO("error: initiation of exchange of "
2179 "configuration data failed for "
2180 "adapter %s\n",
2181 zfcp_get_busid_by_adapter(adapter));
2182 break;
2183 }
2184 debug_text_event(adapter->erp_dbf, 6, "a_fstx_xok");
2185 ZFCP_LOG_DEBUG("Xchange underway\n");
2186
2187 /*
2188 * Why this works:
2189 * Both the normal completion handler as well as the timeout
2190 * handler will do an 'up' when the 'exchange config data'
2191 * request completes or times out. Thus, the signal to go on
2192 * won't be lost utilizing this semaphore.
2193 * Furthermore, this 'adapter_reopen' action is
2194 * guaranteed to be the only action being there (highest action
2195 * which prevents other actions from being created).
2196 * Resulting from that, the wake signal recognized here
2197 * _must_ be the one belonging to the 'exchange config
2198 * data' request.
2199 */
2200 down(&adapter->erp_ready_sem);
2201 if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
2202 ZFCP_LOG_INFO("error: exchange of configuration data "
2203 "for adapter %s timed out\n",
2204 zfcp_get_busid_by_adapter(adapter));
2205 break;
2206 }
Andreas Herrmann22753fa2005-06-13 13:15:15 +02002207
2208 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
2209 &adapter->status))
2210 break;
2211
2212 ZFCP_LOG_DEBUG("host connection still initialising... "
2213 "waiting and retrying...\n");
2214 /* sleep a little bit before retry */
2215 msleep(jiffies_to_msecs(sleep));
2216 sleep *= 2;
2217 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002218
2219 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
2220 &adapter->status)) {
2221 ZFCP_LOG_INFO("error: exchange of configuration data for "
2222 "adapter %s failed\n",
2223 zfcp_get_busid_by_adapter(adapter));
2224 retval = ZFCP_ERP_FAILED;
2225 }
2226
2227 return retval;
2228}
2229
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02002230static int
2231zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)
2232{
Andreas Herrmann2448c452005-12-01 02:50:36 +01002233 int ret;
Andreas Herrmann2f8f3ed2006-02-11 01:41:50 +01002234 struct zfcp_adapter *adapter;
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02002235
Andreas Herrmann2f8f3ed2006-02-11 01:41:50 +01002236 adapter = erp_action->adapter;
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02002237 atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
2238
Andreas Herrmann2f8f3ed2006-02-11 01:41:50 +01002239 write_lock(&adapter->erp_lock);
2240 zfcp_erp_action_to_running(erp_action);
2241 write_unlock(&adapter->erp_lock);
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02002242
Andreas Herrmann2f8f3ed2006-02-11 01:41:50 +01002243 zfcp_erp_timeout_init(erp_action);
2244 ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL);
2245 if (ret == -EOPNOTSUPP) {
2246 debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp");
2247 return ZFCP_ERP_SUCCEEDED;
2248 } else if (ret) {
2249 debug_text_event(adapter->erp_dbf, 3, "a_xport_failed");
2250 return ZFCP_ERP_FAILED;
2251 }
2252 debug_text_event(adapter->erp_dbf, 6, "a_xport_ok");
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02002253
Andreas Herrmann2f8f3ed2006-02-11 01:41:50 +01002254 ret = ZFCP_ERP_SUCCEEDED;
2255 down(&adapter->erp_ready_sem);
2256 if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
2257 ZFCP_LOG_INFO("error: exchange port data timed out (adapter "
2258 "%s)\n", zfcp_get_busid_by_adapter(adapter));
2259 ret = ZFCP_ERP_FAILED;
2260 }
2261 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status)) {
2262 ZFCP_LOG_INFO("error: exchange port data failed (adapter "
2263 "%s\n", zfcp_get_busid_by_adapter(adapter));
2264 ret = ZFCP_ERP_FAILED;
2265 }
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02002266
Andreas Herrmann2f8f3ed2006-02-11 01:41:50 +01002267 return ret;
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02002268}
2269
Linus Torvalds1da177e2005-04-16 15:20:36 -07002270static int
2271zfcp_erp_adapter_strategy_open_fsf_statusread(struct zfcp_erp_action
2272 *erp_action)
2273{
2274 int retval = ZFCP_ERP_SUCCEEDED;
2275 int temp_ret;
2276 struct zfcp_adapter *adapter = erp_action->adapter;
2277 int i;
2278
2279 adapter->status_read_failed = 0;
2280 for (i = 0; i < ZFCP_STATUS_READS_RECOM; i++) {
2281 temp_ret = zfcp_fsf_status_read(adapter, ZFCP_WAIT_FOR_SBAL);
2282 if (temp_ret < 0) {
2283 ZFCP_LOG_INFO("error: set-up of unsolicited status "
2284 "notification failed on adapter %s\n",
2285 zfcp_get_busid_by_adapter(adapter));
2286 retval = ZFCP_ERP_FAILED;
2287 i--;
2288 break;
2289 }
2290 }
2291
2292 return retval;
2293}
2294
2295/*
2296 * function: zfcp_fsf_cleanup
2297 *
2298 * purpose: cleanup FSF operation for specified adapter
2299 *
2300 * returns: 0 - FSF operation successfully cleaned up
2301 * !0 - failed to cleanup FSF operation for this adapter
2302 */
2303static int
2304zfcp_erp_adapter_strategy_close_fsf(struct zfcp_erp_action *erp_action)
2305{
2306 int retval = ZFCP_ERP_SUCCEEDED;
2307 struct zfcp_adapter *adapter = erp_action->adapter;
2308
2309 /*
2310 * wake waiting initiators of requests,
2311 * return SCSI commands (with error status),
2312 * clean up all requests (synchronously)
2313 */
2314 zfcp_fsf_req_dismiss_all(adapter);
2315 /* reset FSF request sequence number */
2316 adapter->fsf_req_seq_no = 0;
2317 /* all ports and units are closed */
2318 zfcp_erp_modify_adapter_status(adapter,
2319 ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR);
2320
2321 return retval;
2322}
2323
2324/*
2325 * function:
2326 *
2327 * purpose: this routine executes the 'Reopen Physical Port' action
2328 *
2329 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2330 * ZFCP_ERP_SUCCEEDED - action finished successfully
2331 * ZFCP_ERP_FAILED - action finished unsuccessfully
2332 */
2333static int
2334zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action)
2335{
2336 int retval = ZFCP_ERP_FAILED;
2337 struct zfcp_port *port = erp_action->port;
2338 struct zfcp_adapter *adapter = erp_action->adapter;
2339
2340 switch (erp_action->step) {
2341
2342 /*
2343 * FIXME:
2344 * the ULP spec. begs for waiting for oustanding commands
2345 */
2346 case ZFCP_ERP_STEP_UNINITIALIZED:
2347 zfcp_erp_port_strategy_clearstati(port);
2348 /*
2349 * it would be sufficient to test only the normal open flag
2350 * since the phys. open flag cannot be set if the normal
2351 * open flag is unset - however, this is for readabilty ...
2352 */
2353 if (atomic_test_mask((ZFCP_STATUS_PORT_PHYS_OPEN |
2354 ZFCP_STATUS_COMMON_OPEN),
2355 &port->status)) {
2356 ZFCP_LOG_DEBUG("port 0x%016Lx is open -> trying "
2357 "close physical\n", port->wwpn);
2358 retval =
2359 zfcp_erp_port_forced_strategy_close(erp_action);
2360 } else
2361 retval = ZFCP_ERP_FAILED;
2362 break;
2363
2364 case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:
2365 if (atomic_test_mask(ZFCP_STATUS_PORT_PHYS_OPEN,
2366 &port->status)) {
2367 ZFCP_LOG_DEBUG("close physical failed for port "
2368 "0x%016Lx\n", port->wwpn);
2369 retval = ZFCP_ERP_FAILED;
2370 } else
2371 retval = ZFCP_ERP_SUCCEEDED;
2372 break;
2373 }
2374
2375 debug_text_event(adapter->erp_dbf, 3, "p_pfst/ret");
2376 debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof (wwn_t));
2377 debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int));
2378 debug_event(adapter->erp_dbf, 3, &retval, sizeof (int));
2379
2380 return retval;
2381}
2382
2383/*
2384 * function:
2385 *
2386 * purpose: this routine executes the 'Reopen Port' action
2387 *
2388 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2389 * ZFCP_ERP_SUCCEEDED - action finished successfully
2390 * ZFCP_ERP_FAILED - action finished unsuccessfully
2391 */
2392static int
2393zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
2394{
2395 int retval = ZFCP_ERP_FAILED;
2396 struct zfcp_port *port = erp_action->port;
2397 struct zfcp_adapter *adapter = erp_action->adapter;
2398
2399 switch (erp_action->step) {
2400
2401 /*
2402 * FIXME:
2403 * the ULP spec. begs for waiting for oustanding commands
2404 */
2405 case ZFCP_ERP_STEP_UNINITIALIZED:
2406 zfcp_erp_port_strategy_clearstati(port);
2407 if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &port->status)) {
2408 ZFCP_LOG_DEBUG("port 0x%016Lx is open -> trying "
2409 "close\n", port->wwpn);
2410 retval = zfcp_erp_port_strategy_close(erp_action);
2411 goto out;
2412 } /* else it's already closed, open it */
2413 break;
2414
2415 case ZFCP_ERP_STEP_PORT_CLOSING:
2416 if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &port->status)) {
2417 ZFCP_LOG_DEBUG("close failed for port 0x%016Lx\n",
2418 port->wwpn);
2419 retval = ZFCP_ERP_FAILED;
2420 goto out;
2421 } /* else it's closed now, open it */
2422 break;
2423 }
2424 if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
2425 retval = ZFCP_ERP_EXIT;
2426 else
2427 retval = zfcp_erp_port_strategy_open(erp_action);
2428
2429 out:
2430 debug_text_event(adapter->erp_dbf, 3, "p_pst/ret");
2431 debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof (wwn_t));
2432 debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int));
2433 debug_event(adapter->erp_dbf, 3, &retval, sizeof (int));
2434
2435 return retval;
2436}
2437
Linus Torvalds1da177e2005-04-16 15:20:36 -07002438static int
2439zfcp_erp_port_strategy_open(struct zfcp_erp_action *erp_action)
2440{
2441 int retval;
2442
2443 if (atomic_test_mask(ZFCP_STATUS_PORT_WKA,
2444 &erp_action->port->status))
2445 retval = zfcp_erp_port_strategy_open_nameserver(erp_action);
2446 else
2447 retval = zfcp_erp_port_strategy_open_common(erp_action);
2448
2449 return retval;
2450}
2451
Linus Torvalds1da177e2005-04-16 15:20:36 -07002452static int
2453zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action)
2454{
2455 int retval = 0;
2456 struct zfcp_adapter *adapter = erp_action->adapter;
2457 struct zfcp_port *port = erp_action->port;
2458
2459 switch (erp_action->step) {
2460
2461 case ZFCP_ERP_STEP_UNINITIALIZED:
2462 case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:
2463 case ZFCP_ERP_STEP_PORT_CLOSING:
Andreas Herrmannad757cd2006-01-13 02:26:11 +01002464 if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) {
6f71d9b2005-04-10 23:04:28 -05002465 if (port->wwpn != adapter->peer_wwpn) {
2466 ZFCP_LOG_NORMAL("Failed to open port 0x%016Lx "
2467 "on adapter %s.\nPeer WWPN "
2468 "0x%016Lx does not match\n",
2469 port->wwpn,
2470 zfcp_get_busid_by_adapter(adapter),
2471 adapter->peer_wwpn);
2472 zfcp_erp_port_failed(port);
2473 retval = ZFCP_ERP_FAILED;
2474 break;
2475 }
2476 port->d_id = adapter->peer_d_id;
2477 atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status);
2478 retval = zfcp_erp_port_strategy_open_port(erp_action);
2479 break;
2480 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002481 if (!(adapter->nameserver_port)) {
2482 retval = zfcp_nameserver_enqueue(adapter);
2483 if (retval != 0) {
2484 ZFCP_LOG_NORMAL("error: nameserver port "
2485 "unavailable for adapter %s\n",
2486 zfcp_get_busid_by_adapter(adapter));
2487 retval = ZFCP_ERP_FAILED;
2488 break;
2489 }
2490 }
2491 if (!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
2492 &adapter->nameserver_port->status)) {
2493 ZFCP_LOG_DEBUG("nameserver port is not open -> open "
2494 "nameserver port\n");
2495 /* nameserver port may live again */
2496 atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING,
2497 &adapter->nameserver_port->status);
2498 if (zfcp_erp_port_reopen(adapter->nameserver_port, 0)
2499 >= 0) {
2500 erp_action->step =
2501 ZFCP_ERP_STEP_NAMESERVER_OPEN;
2502 retval = ZFCP_ERP_CONTINUES;
2503 } else
2504 retval = ZFCP_ERP_FAILED;
2505 break;
2506 }
2507 /* else nameserver port is already open, fall through */
2508 case ZFCP_ERP_STEP_NAMESERVER_OPEN:
2509 if (!atomic_test_mask(ZFCP_STATUS_COMMON_OPEN,
2510 &adapter->nameserver_port->status)) {
2511 ZFCP_LOG_DEBUG("open failed for nameserver port\n");
2512 retval = ZFCP_ERP_FAILED;
2513 } else {
2514 ZFCP_LOG_DEBUG("nameserver port is open -> "
2515 "nameserver look-up for port 0x%016Lx\n",
2516 port->wwpn);
2517 retval = zfcp_erp_port_strategy_open_common_lookup
2518 (erp_action);
2519 }
2520 break;
2521
2522 case ZFCP_ERP_STEP_NAMESERVER_LOOKUP:
2523 if (!atomic_test_mask(ZFCP_STATUS_PORT_DID_DID, &port->status)) {
2524 if (atomic_test_mask
2525 (ZFCP_STATUS_PORT_INVALID_WWPN, &port->status)) {
2526 ZFCP_LOG_DEBUG("nameserver look-up failed "
2527 "for port 0x%016Lx "
2528 "(misconfigured WWPN?)\n",
2529 port->wwpn);
2530 zfcp_erp_port_failed(port);
2531 retval = ZFCP_ERP_EXIT;
2532 } else {
2533 ZFCP_LOG_DEBUG("nameserver look-up failed for "
2534 "port 0x%016Lx\n", port->wwpn);
2535 retval = ZFCP_ERP_FAILED;
2536 }
2537 } else {
2538 ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%08x -> "
2539 "trying open\n", port->wwpn, port->d_id);
2540 retval = zfcp_erp_port_strategy_open_port(erp_action);
2541 }
2542 break;
2543
2544 case ZFCP_ERP_STEP_PORT_OPENING:
2545 /* D_ID might have changed during open */
2546 if (atomic_test_mask((ZFCP_STATUS_COMMON_OPEN |
2547 ZFCP_STATUS_PORT_DID_DID),
2548 &port->status)) {
2549 ZFCP_LOG_DEBUG("port 0x%016Lx is open\n", port->wwpn);
2550 retval = ZFCP_ERP_SUCCEEDED;
2551 } else {
2552 ZFCP_LOG_DEBUG("open failed for port 0x%016Lx\n",
2553 port->wwpn);
2554 retval = ZFCP_ERP_FAILED;
2555 }
2556 break;
2557
2558 default:
2559 ZFCP_LOG_NORMAL("bug: unknown erp step 0x%08x\n",
2560 erp_action->step);
2561 retval = ZFCP_ERP_FAILED;
2562 }
2563
2564 return retval;
2565}
2566
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567static int
2568zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *erp_action)
2569{
2570 int retval;
2571 struct zfcp_port *port = erp_action->port;
2572
2573 switch (erp_action->step) {
2574
2575 case ZFCP_ERP_STEP_UNINITIALIZED:
2576 case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:
2577 case ZFCP_ERP_STEP_PORT_CLOSING:
2578 ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%08x -> trying open\n",
2579 port->wwpn, port->d_id);
2580 retval = zfcp_erp_port_strategy_open_port(erp_action);
2581 break;
2582
2583 case ZFCP_ERP_STEP_PORT_OPENING:
2584 if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &port->status)) {
2585 ZFCP_LOG_DEBUG("WKA port is open\n");
2586 retval = ZFCP_ERP_SUCCEEDED;
2587 } else {
2588 ZFCP_LOG_DEBUG("open failed for WKA port\n");
2589 retval = ZFCP_ERP_FAILED;
2590 }
2591 /* this is needed anyway (dont care for retval of wakeup) */
2592 ZFCP_LOG_DEBUG("continue other open port operations\n");
2593 zfcp_erp_port_strategy_open_nameserver_wakeup(erp_action);
2594 break;
2595
2596 default:
2597 ZFCP_LOG_NORMAL("bug: unknown erp step 0x%08x\n",
2598 erp_action->step);
2599 retval = ZFCP_ERP_FAILED;
2600 }
2601
2602 return retval;
2603}
2604
2605/*
2606 * function:
2607 *
2608 * purpose: makes the erp thread continue with reopen (physical) port
2609 * actions which have been paused until the name server port
2610 * is opened (or failed)
2611 *
2612 * returns: 0 (a kind of void retval, its not used)
2613 */
2614static int
2615zfcp_erp_port_strategy_open_nameserver_wakeup(struct zfcp_erp_action
2616 *ns_erp_action)
2617{
2618 int retval = 0;
2619 unsigned long flags;
2620 struct zfcp_adapter *adapter = ns_erp_action->adapter;
2621 struct zfcp_erp_action *erp_action, *tmp;
2622
2623 read_lock_irqsave(&adapter->erp_lock, flags);
2624 list_for_each_entry_safe(erp_action, tmp, &adapter->erp_running_head,
2625 list) {
2626 debug_text_event(adapter->erp_dbf, 4, "p_pstnsw_n");
2627 debug_event(adapter->erp_dbf, 4, &erp_action->port->wwpn,
2628 sizeof (wwn_t));
2629 if (erp_action->step == ZFCP_ERP_STEP_NAMESERVER_OPEN) {
2630 debug_text_event(adapter->erp_dbf, 3, "p_pstnsw_w");
2631 debug_event(adapter->erp_dbf, 3,
2632 &erp_action->port->wwpn, sizeof (wwn_t));
2633 if (atomic_test_mask(
2634 ZFCP_STATUS_COMMON_ERP_FAILED,
2635 &adapter->nameserver_port->status))
2636 zfcp_erp_port_failed(erp_action->port);
2637 zfcp_erp_action_ready(erp_action);
2638 }
2639 }
2640 read_unlock_irqrestore(&adapter->erp_lock, flags);
2641
2642 return retval;
2643}
2644
2645/*
2646 * function:
2647 *
2648 * purpose:
2649 *
2650 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2651 * ZFCP_ERP_FAILED - action finished unsuccessfully
2652 */
2653static int
2654zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *erp_action)
2655{
2656 int retval;
2657 struct zfcp_adapter *adapter = erp_action->adapter;
2658 struct zfcp_port *port = erp_action->port;
2659
2660 zfcp_erp_timeout_init(erp_action);
2661 retval = zfcp_fsf_close_physical_port(erp_action);
2662 if (retval == -ENOMEM) {
2663 debug_text_event(adapter->erp_dbf, 5, "o_pfstc_nomem");
2664 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2665 retval = ZFCP_ERP_NOMEM;
2666 goto out;
2667 }
2668 erp_action->step = ZFCP_ERP_STEP_PHYS_PORT_CLOSING;
2669 if (retval != 0) {
2670 debug_text_event(adapter->erp_dbf, 5, "o_pfstc_cpf");
2671 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2672 /* could not send 'open', fail */
2673 retval = ZFCP_ERP_FAILED;
2674 goto out;
2675 }
2676 debug_text_event(adapter->erp_dbf, 6, "o_pfstc_cpok");
2677 debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));
2678 retval = ZFCP_ERP_CONTINUES;
2679 out:
2680 return retval;
2681}
2682
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683static int
2684zfcp_erp_port_strategy_clearstati(struct zfcp_port *port)
2685{
2686 int retval = 0;
2687 struct zfcp_adapter *adapter = port->adapter;
2688
2689 debug_text_event(adapter->erp_dbf, 5, "p_pstclst");
2690 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2691
2692 atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING |
2693 ZFCP_STATUS_COMMON_CLOSING |
2694 ZFCP_STATUS_COMMON_ACCESS_DENIED |
2695 ZFCP_STATUS_PORT_DID_DID |
2696 ZFCP_STATUS_PORT_PHYS_CLOSING |
2697 ZFCP_STATUS_PORT_INVALID_WWPN,
2698 &port->status);
2699 return retval;
2700}
2701
2702/*
2703 * function:
2704 *
2705 * purpose:
2706 *
2707 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2708 * ZFCP_ERP_FAILED - action finished unsuccessfully
2709 */
2710static int
2711zfcp_erp_port_strategy_close(struct zfcp_erp_action *erp_action)
2712{
2713 int retval;
2714 struct zfcp_adapter *adapter = erp_action->adapter;
2715 struct zfcp_port *port = erp_action->port;
2716
2717 zfcp_erp_timeout_init(erp_action);
2718 retval = zfcp_fsf_close_port(erp_action);
2719 if (retval == -ENOMEM) {
2720 debug_text_event(adapter->erp_dbf, 5, "p_pstc_nomem");
2721 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2722 retval = ZFCP_ERP_NOMEM;
2723 goto out;
2724 }
2725 erp_action->step = ZFCP_ERP_STEP_PORT_CLOSING;
2726 if (retval != 0) {
2727 debug_text_event(adapter->erp_dbf, 5, "p_pstc_cpf");
2728 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2729 /* could not send 'close', fail */
2730 retval = ZFCP_ERP_FAILED;
2731 goto out;
2732 }
2733 debug_text_event(adapter->erp_dbf, 6, "p_pstc_cpok");
2734 debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));
2735 retval = ZFCP_ERP_CONTINUES;
2736 out:
2737 return retval;
2738}
2739
2740/*
2741 * function:
2742 *
2743 * purpose:
2744 *
2745 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2746 * ZFCP_ERP_FAILED - action finished unsuccessfully
2747 */
2748static int
2749zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action)
2750{
2751 int retval;
2752 struct zfcp_adapter *adapter = erp_action->adapter;
2753 struct zfcp_port *port = erp_action->port;
2754
2755 zfcp_erp_timeout_init(erp_action);
2756 retval = zfcp_fsf_open_port(erp_action);
2757 if (retval == -ENOMEM) {
2758 debug_text_event(adapter->erp_dbf, 5, "p_psto_nomem");
2759 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2760 retval = ZFCP_ERP_NOMEM;
2761 goto out;
2762 }
2763 erp_action->step = ZFCP_ERP_STEP_PORT_OPENING;
2764 if (retval != 0) {
2765 debug_text_event(adapter->erp_dbf, 5, "p_psto_opf");
2766 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2767 /* could not send 'open', fail */
2768 retval = ZFCP_ERP_FAILED;
2769 goto out;
2770 }
2771 debug_text_event(adapter->erp_dbf, 6, "p_psto_opok");
2772 debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));
2773 retval = ZFCP_ERP_CONTINUES;
2774 out:
2775 return retval;
2776}
2777
2778/*
2779 * function:
2780 *
2781 * purpose:
2782 *
2783 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2784 * ZFCP_ERP_FAILED - action finished unsuccessfully
2785 */
2786static int
2787zfcp_erp_port_strategy_open_common_lookup(struct zfcp_erp_action *erp_action)
2788{
2789 int retval;
2790 struct zfcp_adapter *adapter = erp_action->adapter;
2791 struct zfcp_port *port = erp_action->port;
2792
2793 zfcp_erp_timeout_init(erp_action);
2794 retval = zfcp_ns_gid_pn_request(erp_action);
2795 if (retval == -ENOMEM) {
2796 debug_text_event(adapter->erp_dbf, 5, "p_pstn_nomem");
2797 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2798 retval = ZFCP_ERP_NOMEM;
2799 goto out;
2800 }
2801 erp_action->step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP;
2802 if (retval != 0) {
2803 debug_text_event(adapter->erp_dbf, 5, "p_pstn_ref");
2804 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
2805 /* could not send nameserver request, fail */
2806 retval = ZFCP_ERP_FAILED;
2807 goto out;
2808 }
2809 debug_text_event(adapter->erp_dbf, 6, "p_pstn_reok");
2810 debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));
2811 retval = ZFCP_ERP_CONTINUES;
2812 out:
2813 return retval;
2814}
2815
2816/*
2817 * function:
2818 *
2819 * purpose: this routine executes the 'Reopen Unit' action
2820 * currently no retries
2821 *
2822 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2823 * ZFCP_ERP_SUCCEEDED - action finished successfully
2824 * ZFCP_ERP_FAILED - action finished unsuccessfully
2825 */
2826static int
2827zfcp_erp_unit_strategy(struct zfcp_erp_action *erp_action)
2828{
2829 int retval = ZFCP_ERP_FAILED;
2830 struct zfcp_unit *unit = erp_action->unit;
2831 struct zfcp_adapter *adapter = erp_action->adapter;
2832
2833 switch (erp_action->step) {
2834
2835 /*
2836 * FIXME:
2837 * the ULP spec. begs for waiting for oustanding commands
2838 */
2839 case ZFCP_ERP_STEP_UNINITIALIZED:
2840 zfcp_erp_unit_strategy_clearstati(unit);
2841 if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status)) {
2842 ZFCP_LOG_DEBUG("unit 0x%016Lx is open -> "
2843 "trying close\n", unit->fcp_lun);
2844 retval = zfcp_erp_unit_strategy_close(erp_action);
2845 break;
2846 }
2847 /* else it's already closed, fall through */
2848 case ZFCP_ERP_STEP_UNIT_CLOSING:
2849 if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status)) {
2850 ZFCP_LOG_DEBUG("close failed for unit 0x%016Lx\n",
2851 unit->fcp_lun);
2852 retval = ZFCP_ERP_FAILED;
2853 } else {
2854 if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
2855 retval = ZFCP_ERP_EXIT;
2856 else {
2857 ZFCP_LOG_DEBUG("unit 0x%016Lx is not open -> "
2858 "trying open\n", unit->fcp_lun);
2859 retval =
2860 zfcp_erp_unit_strategy_open(erp_action);
2861 }
2862 }
2863 break;
2864
2865 case ZFCP_ERP_STEP_UNIT_OPENING:
2866 if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status)) {
2867 ZFCP_LOG_DEBUG("unit 0x%016Lx is open\n",
2868 unit->fcp_lun);
2869 retval = ZFCP_ERP_SUCCEEDED;
2870 } else {
2871 ZFCP_LOG_DEBUG("open failed for unit 0x%016Lx\n",
2872 unit->fcp_lun);
2873 retval = ZFCP_ERP_FAILED;
2874 }
2875 break;
2876 }
2877
2878 debug_text_event(adapter->erp_dbf, 3, "u_ust/ret");
2879 debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof (fcp_lun_t));
2880 debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int));
2881 debug_event(adapter->erp_dbf, 3, &retval, sizeof (int));
2882 return retval;
2883}
2884
Linus Torvalds1da177e2005-04-16 15:20:36 -07002885static int
2886zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit)
2887{
2888 int retval = 0;
2889 struct zfcp_adapter *adapter = unit->port->adapter;
2890
2891 debug_text_event(adapter->erp_dbf, 5, "u_ustclst");
2892 debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, sizeof (fcp_lun_t));
2893
2894 atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING |
2895 ZFCP_STATUS_COMMON_CLOSING |
2896 ZFCP_STATUS_COMMON_ACCESS_DENIED |
2897 ZFCP_STATUS_UNIT_SHARED |
2898 ZFCP_STATUS_UNIT_READONLY,
2899 &unit->status);
2900
2901 return retval;
2902}
2903
2904/*
2905 * function:
2906 *
2907 * purpose:
2908 *
2909 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2910 * ZFCP_ERP_FAILED - action finished unsuccessfully
2911 */
2912static int
2913zfcp_erp_unit_strategy_close(struct zfcp_erp_action *erp_action)
2914{
2915 int retval;
2916 struct zfcp_adapter *adapter = erp_action->adapter;
2917 struct zfcp_unit *unit = erp_action->unit;
2918
2919 zfcp_erp_timeout_init(erp_action);
2920 retval = zfcp_fsf_close_unit(erp_action);
2921 if (retval == -ENOMEM) {
2922 debug_text_event(adapter->erp_dbf, 5, "u_ustc_nomem");
2923 debug_event(adapter->erp_dbf, 5, &unit->fcp_lun,
2924 sizeof (fcp_lun_t));
2925 retval = ZFCP_ERP_NOMEM;
2926 goto out;
2927 }
2928 erp_action->step = ZFCP_ERP_STEP_UNIT_CLOSING;
2929 if (retval != 0) {
2930 debug_text_event(adapter->erp_dbf, 5, "u_ustc_cuf");
2931 debug_event(adapter->erp_dbf, 5, &unit->fcp_lun,
2932 sizeof (fcp_lun_t));
2933 /* could not send 'close', fail */
2934 retval = ZFCP_ERP_FAILED;
2935 goto out;
2936 }
2937 debug_text_event(adapter->erp_dbf, 6, "u_ustc_cuok");
2938 debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t));
2939 retval = ZFCP_ERP_CONTINUES;
2940
2941 out:
2942 return retval;
2943}
2944
2945/*
2946 * function:
2947 *
2948 * purpose:
2949 *
2950 * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
2951 * ZFCP_ERP_FAILED - action finished unsuccessfully
2952 */
2953static int
2954zfcp_erp_unit_strategy_open(struct zfcp_erp_action *erp_action)
2955{
2956 int retval;
2957 struct zfcp_adapter *adapter = erp_action->adapter;
2958 struct zfcp_unit *unit = erp_action->unit;
2959
2960 zfcp_erp_timeout_init(erp_action);
2961 retval = zfcp_fsf_open_unit(erp_action);
2962 if (retval == -ENOMEM) {
2963 debug_text_event(adapter->erp_dbf, 5, "u_usto_nomem");
2964 debug_event(adapter->erp_dbf, 5, &unit->fcp_lun,
2965 sizeof (fcp_lun_t));
2966 retval = ZFCP_ERP_NOMEM;
2967 goto out;
2968 }
2969 erp_action->step = ZFCP_ERP_STEP_UNIT_OPENING;
2970 if (retval != 0) {
2971 debug_text_event(adapter->erp_dbf, 5, "u_usto_ouf");
2972 debug_event(adapter->erp_dbf, 5, &unit->fcp_lun,
2973 sizeof (fcp_lun_t));
2974 /* could not send 'open', fail */
2975 retval = ZFCP_ERP_FAILED;
2976 goto out;
2977 }
2978 debug_text_event(adapter->erp_dbf, 6, "u_usto_ouok");
2979 debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t));
2980 retval = ZFCP_ERP_CONTINUES;
2981 out:
2982 return retval;
2983}
2984
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985static inline void
2986zfcp_erp_timeout_init(struct zfcp_erp_action *erp_action)
2987{
2988 init_timer(&erp_action->timer);
2989 erp_action->timer.function = zfcp_erp_timeout_handler;
2990 erp_action->timer.data = (unsigned long) erp_action;
2991 /* jiffies will be added in zfcp_fsf_req_send */
2992 erp_action->timer.expires = ZFCP_ERP_FSFREQ_TIMEOUT;
2993}
2994
2995/*
2996 * function:
2997 *
2998 * purpose: enqueue the specified error recovery action, if needed
2999 *
3000 * returns:
3001 */
3002static int
3003zfcp_erp_action_enqueue(int action,
3004 struct zfcp_adapter *adapter,
3005 struct zfcp_port *port, struct zfcp_unit *unit)
3006{
3007 int retval = 1;
3008 struct zfcp_erp_action *erp_action = NULL;
3009 int stronger_action = 0;
3010 u32 status = 0;
3011
3012 /*
3013 * We need some rules here which check whether we really need
3014 * this action or whether we should just drop it.
3015 * E.g. if there is a unfinished 'Reopen Port' request then we drop a
3016 * 'Reopen Unit' request for an associated unit since we can't
3017 * satisfy this request now. A 'Reopen Port' action will trigger
3018 * 'Reopen Unit' actions when it completes.
3019 * Thus, there are only actions in the queue which can immediately be
3020 * executed. This makes the processing of the action queue more
3021 * efficient.
3022 */
3023
3024 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP,
3025 &adapter->status))
3026 return -EIO;
3027
3028 debug_event(adapter->erp_dbf, 4, &action, sizeof (int));
3029 /* check whether we really need this */
3030 switch (action) {
3031 case ZFCP_ERP_ACTION_REOPEN_UNIT:
3032 if (atomic_test_mask
3033 (ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status)) {
3034 debug_text_event(adapter->erp_dbf, 4, "u_actenq_drp");
3035 debug_event(adapter->erp_dbf, 4, &port->wwpn,
3036 sizeof (wwn_t));
3037 debug_event(adapter->erp_dbf, 4, &unit->fcp_lun,
3038 sizeof (fcp_lun_t));
3039 goto out;
3040 }
3041 if (!atomic_test_mask
3042 (ZFCP_STATUS_COMMON_RUNNING, &port->status) ||
3043 atomic_test_mask
3044 (ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) {
3045 goto out;
3046 }
3047 if (!atomic_test_mask
3048 (ZFCP_STATUS_COMMON_UNBLOCKED, &port->status)) {
3049 stronger_action = ZFCP_ERP_ACTION_REOPEN_PORT;
3050 unit = NULL;
3051 }
3052 /* fall through !!! */
3053
3054 case ZFCP_ERP_ACTION_REOPEN_PORT:
3055 if (atomic_test_mask
3056 (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)) {
3057 debug_text_event(adapter->erp_dbf, 4, "p_actenq_drp");
3058 debug_event(adapter->erp_dbf, 4, &port->wwpn,
3059 sizeof (wwn_t));
3060 goto out;
3061 }
3062 /* fall through !!! */
3063
3064 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
Andreas Herrmann3734d242005-09-13 21:47:11 +02003065 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
3066 &port->status)) {
3067 if (port->erp_action.action !=
3068 ZFCP_ERP_ACTION_REOPEN_PORT_FORCED) {
3069 ZFCP_LOG_INFO("dropped erp action %i (port "
3070 "0x%016Lx, action in use: %i)\n",
3071 action, port->wwpn,
3072 port->erp_action.action);
3073 debug_text_event(adapter->erp_dbf, 4,
3074 "pf_actenq_drp");
3075 } else
3076 debug_text_event(adapter->erp_dbf, 4,
3077 "pf_actenq_drpcp");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003078 debug_event(adapter->erp_dbf, 4, &port->wwpn,
3079 sizeof (wwn_t));
3080 goto out;
3081 }
3082 if (!atomic_test_mask
3083 (ZFCP_STATUS_COMMON_RUNNING, &adapter->status) ||
3084 atomic_test_mask
3085 (ZFCP_STATUS_COMMON_ERP_FAILED, &adapter->status)) {
3086 goto out;
3087 }
3088 if (!atomic_test_mask
3089 (ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status)) {
3090 stronger_action = ZFCP_ERP_ACTION_REOPEN_ADAPTER;
3091 port = NULL;
3092 }
3093 /* fall through !!! */
3094
3095 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
3096 if (atomic_test_mask
3097 (ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status)) {
3098 debug_text_event(adapter->erp_dbf, 4, "a_actenq_drp");
3099 goto out;
3100 }
3101 break;
3102
3103 default:
3104 debug_text_exception(adapter->erp_dbf, 1, "a_actenq_bug");
3105 debug_event(adapter->erp_dbf, 1, &action, sizeof (int));
3106 ZFCP_LOG_NORMAL("bug: unknown erp action requested "
3107 "on adapter %s (action=%d)\n",
3108 zfcp_get_busid_by_adapter(adapter), action);
3109 goto out;
3110 }
3111
3112 /* check whether we need something stronger first */
3113 if (stronger_action) {
3114 debug_text_event(adapter->erp_dbf, 4, "a_actenq_str");
3115 debug_event(adapter->erp_dbf, 4, &stronger_action,
3116 sizeof (int));
3117 ZFCP_LOG_DEBUG("stronger erp action %d needed before "
3118 "erp action %d on adapter %s\n",
3119 stronger_action, action,
3120 zfcp_get_busid_by_adapter(adapter));
3121 action = stronger_action;
3122 }
3123
3124 /* mark adapter to have some error recovery pending */
3125 atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status);
3126
3127 /* setup error recovery action */
3128 switch (action) {
3129
3130 case ZFCP_ERP_ACTION_REOPEN_UNIT:
3131 zfcp_unit_get(unit);
3132 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status);
3133 erp_action = &unit->erp_action;
3134 if (!atomic_test_mask
3135 (ZFCP_STATUS_COMMON_RUNNING, &unit->status))
3136 status = ZFCP_STATUS_ERP_CLOSE_ONLY;
3137 break;
3138
3139 case ZFCP_ERP_ACTION_REOPEN_PORT:
3140 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
3141 zfcp_port_get(port);
3142 zfcp_erp_action_dismiss_port(port);
3143 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
3144 erp_action = &port->erp_action;
3145 if (!atomic_test_mask
3146 (ZFCP_STATUS_COMMON_RUNNING, &port->status))
3147 status = ZFCP_STATUS_ERP_CLOSE_ONLY;
3148 break;
3149
3150 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
3151 zfcp_adapter_get(adapter);
3152 zfcp_erp_action_dismiss_adapter(adapter);
3153 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status);
3154 erp_action = &adapter->erp_action;
3155 if (!atomic_test_mask
3156 (ZFCP_STATUS_COMMON_RUNNING, &adapter->status))
3157 status = ZFCP_STATUS_ERP_CLOSE_ONLY;
3158 break;
3159 }
3160
3161 debug_text_event(adapter->erp_dbf, 4, "a_actenq");
3162
3163 memset(erp_action, 0, sizeof (struct zfcp_erp_action));
3164 erp_action->adapter = adapter;
3165 erp_action->port = port;
3166 erp_action->unit = unit;
3167 erp_action->action = action;
3168 erp_action->status = status;
3169
3170 ++adapter->erp_total_count;
3171
3172 /* finally put it into 'ready' queue and kick erp thread */
3173 list_add(&erp_action->list, &adapter->erp_ready_head);
3174 up(&adapter->erp_ready_sem);
3175 retval = 0;
3176 out:
3177 return retval;
3178}
3179
Linus Torvalds1da177e2005-04-16 15:20:36 -07003180static int
3181zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action)
3182{
3183 int retval = 0;
3184 struct zfcp_adapter *adapter = erp_action->adapter;
3185
3186 --adapter->erp_total_count;
3187 if (erp_action->status & ZFCP_STATUS_ERP_LOWMEM) {
3188 --adapter->erp_low_mem_count;
3189 erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM;
3190 }
3191
3192 debug_text_event(adapter->erp_dbf, 4, "a_actdeq");
3193 debug_event(adapter->erp_dbf, 4, &erp_action->action, sizeof (int));
3194 list_del(&erp_action->list);
3195 switch (erp_action->action) {
3196 case ZFCP_ERP_ACTION_REOPEN_UNIT:
3197 atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
3198 &erp_action->unit->status);
3199 break;
3200 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
3201 case ZFCP_ERP_ACTION_REOPEN_PORT:
3202 atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
3203 &erp_action->port->status);
3204 break;
3205 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
3206 atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
3207 &erp_action->adapter->status);
3208 break;
3209 default:
3210 /* bug */
3211 break;
3212 }
3213 return retval;
3214}
3215
3216/**
3217 * zfcp_erp_action_cleanup
3218 *
Adrian Bunk575c9682006-01-15 02:00:17 +01003219 * Register unit with scsi stack if appropriate and fix reference counts.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003220 * Note: Temporary units are not registered with scsi stack.
3221 */
3222static void
3223zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
3224 struct zfcp_port *port, struct zfcp_unit *unit,
3225 int result)
3226{
3227 switch (action) {
3228 case ZFCP_ERP_ACTION_REOPEN_UNIT:
3229 if ((result == ZFCP_ERP_SUCCEEDED)
3230 && (!atomic_test_mask(ZFCP_STATUS_UNIT_TEMPORARY,
3231 &unit->status))
Andreas Herrmann3859f6a2005-08-27 11:07:54 -07003232 && !unit->device
Andreas Herrmannad58f7d2006-03-10 00:56:16 +01003233 && port->rport) {
3234 atomic_set_mask(ZFCP_STATUS_UNIT_REGISTERED,
3235 &unit->status);
3236 scsi_scan_target(&port->rport->dev, 0,
3237 port->rport->scsi_target_id,
3238 unit->scsi_lun, 0);
3239 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003240 zfcp_unit_put(unit);
3241 break;
3242 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
3243 case ZFCP_ERP_ACTION_REOPEN_PORT:
Andreas Herrmann338151e2006-05-22 18:25:56 +02003244 if (atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN,
3245 &port->status)) {
3246 zfcp_port_put(port);
3247 break;
3248 }
3249
Andreas Herrmann3859f6a2005-08-27 11:07:54 -07003250 if ((result == ZFCP_ERP_SUCCEEDED)
Andreas Herrmann3859f6a2005-08-27 11:07:54 -07003251 && !port->rport) {
3252 struct fc_rport_identifiers ids;
3253 ids.node_name = port->wwnn;
3254 ids.port_name = port->wwpn;
3255 ids.port_id = port->d_id;
3256 ids.roles = FC_RPORT_ROLE_FCP_TARGET;
3257 port->rport =
3258 fc_remote_port_add(adapter->scsi_host, 0, &ids);
3259 if (!port->rport)
3260 ZFCP_LOG_NORMAL("failed registration of rport"
3261 "(adapter %s, wwpn=0x%016Lx)\n",
3262 zfcp_get_busid_by_port(port),
3263 port->wwpn);
Ralph Wuerthner75bfc282006-05-22 18:24:33 +02003264 else {
Andreas Herrmann61c41822006-02-11 01:43:55 +01003265 scsi_flush_work(adapter->scsi_host);
Ralph Wuerthner75bfc282006-05-22 18:24:33 +02003266 port->rport->maxframe_size = port->maxframe_size;
3267 port->rport->supported_classes =
3268 port->supported_classes;
3269 }
Andreas Herrmann3859f6a2005-08-27 11:07:54 -07003270 }
Andreas Herrmann338151e2006-05-22 18:25:56 +02003271 if ((result != ZFCP_ERP_SUCCEEDED) && port->rport) {
3272 fc_remote_port_delete(port->rport);
3273 port->rport = NULL;
3274 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003275 zfcp_port_put(port);
3276 break;
3277 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
Andreas Herrmann338151e2006-05-22 18:25:56 +02003278 if (result != ZFCP_ERP_SUCCEEDED) {
3279 struct zfcp_port *port;
3280 list_for_each_entry(port, &adapter->port_list_head, list)
3281 if (port->rport &&
3282 !atomic_test_mask(ZFCP_STATUS_PORT_WKA,
3283 &port->status)) {
3284 fc_remote_port_delete(port->rport);
3285 port->rport = NULL;
3286 }
3287 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003288 zfcp_adapter_put(adapter);
3289 break;
3290 default:
3291 break;
3292 }
3293}
3294
3295
Linus Torvalds1da177e2005-04-16 15:20:36 -07003296static int
3297zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
3298{
3299 int retval = 0;
3300 struct zfcp_port *port;
3301
3302 debug_text_event(adapter->erp_dbf, 5, "a_actab");
3303 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status))
3304 zfcp_erp_action_dismiss(&adapter->erp_action);
3305 else
3306 list_for_each_entry(port, &adapter->port_list_head, list)
3307 zfcp_erp_action_dismiss_port(port);
3308
3309 return retval;
3310}
3311
Linus Torvalds1da177e2005-04-16 15:20:36 -07003312static int
3313zfcp_erp_action_dismiss_port(struct zfcp_port *port)
3314{
3315 int retval = 0;
3316 struct zfcp_unit *unit;
3317 struct zfcp_adapter *adapter = port->adapter;
3318
3319 debug_text_event(adapter->erp_dbf, 5, "p_actab");
3320 debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
3321 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status))
3322 zfcp_erp_action_dismiss(&port->erp_action);
3323 else
3324 list_for_each_entry(unit, &port->unit_list_head, list)
3325 zfcp_erp_action_dismiss_unit(unit);
3326
3327 return retval;
3328}
3329
Linus Torvalds1da177e2005-04-16 15:20:36 -07003330static int
3331zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit)
3332{
3333 int retval = 0;
3334 struct zfcp_adapter *adapter = unit->port->adapter;
3335
3336 debug_text_event(adapter->erp_dbf, 5, "u_actab");
3337 debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, sizeof (fcp_lun_t));
3338 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status))
3339 zfcp_erp_action_dismiss(&unit->erp_action);
3340
3341 return retval;
3342}
3343
Linus Torvalds1da177e2005-04-16 15:20:36 -07003344static inline void
3345zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action)
3346{
3347 struct zfcp_adapter *adapter = erp_action->adapter;
3348
3349 debug_text_event(adapter->erp_dbf, 6, "a_toru");
3350 debug_event(adapter->erp_dbf, 6, &erp_action->action, sizeof (int));
3351 list_move(&erp_action->list, &erp_action->adapter->erp_running_head);
3352}
3353
Linus Torvalds1da177e2005-04-16 15:20:36 -07003354static inline void
3355zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action)
3356{
3357 struct zfcp_adapter *adapter = erp_action->adapter;
3358
3359 debug_text_event(adapter->erp_dbf, 6, "a_tore");
3360 debug_event(adapter->erp_dbf, 6, &erp_action->action, sizeof (int));
3361 list_move(&erp_action->list, &erp_action->adapter->erp_ready_head);
3362}
3363
Andreas Herrmannd736a272005-06-13 13:23:57 +02003364void
3365zfcp_erp_port_boxed(struct zfcp_port *port)
3366{
3367 struct zfcp_adapter *adapter = port->adapter;
3368 unsigned long flags;
3369
3370 debug_text_event(adapter->erp_dbf, 3, "p_access_boxed");
3371 debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
3372 read_lock_irqsave(&zfcp_data.config_lock, flags);
3373 zfcp_erp_modify_port_status(port,
3374 ZFCP_STATUS_COMMON_ACCESS_BOXED,
3375 ZFCP_SET);
3376 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
3377 zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED);
3378}
3379
Andreas Herrmannd736a272005-06-13 13:23:57 +02003380void
3381zfcp_erp_unit_boxed(struct zfcp_unit *unit)
3382{
3383 struct zfcp_adapter *adapter = unit->port->adapter;
3384
3385 debug_text_event(adapter->erp_dbf, 3, "u_access_boxed");
3386 debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
3387 zfcp_erp_modify_unit_status(unit,
3388 ZFCP_STATUS_COMMON_ACCESS_BOXED,
3389 ZFCP_SET);
3390 zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED);
3391}
3392
Linus Torvalds1da177e2005-04-16 15:20:36 -07003393void
3394zfcp_erp_port_access_denied(struct zfcp_port *port)
3395{
3396 struct zfcp_adapter *adapter = port->adapter;
3397 unsigned long flags;
3398
Andreas Herrmannd736a272005-06-13 13:23:57 +02003399 debug_text_event(adapter->erp_dbf, 3, "p_access_denied");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003400 debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
3401 read_lock_irqsave(&zfcp_data.config_lock, flags);
Andreas Herrmannd736a272005-06-13 13:23:57 +02003402 zfcp_erp_modify_port_status(port,
3403 ZFCP_STATUS_COMMON_ERP_FAILED |
3404 ZFCP_STATUS_COMMON_ACCESS_DENIED,
3405 ZFCP_SET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003406 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
3407}
3408
Linus Torvalds1da177e2005-04-16 15:20:36 -07003409void
3410zfcp_erp_unit_access_denied(struct zfcp_unit *unit)
3411{
3412 struct zfcp_adapter *adapter = unit->port->adapter;
3413
Andreas Herrmannd736a272005-06-13 13:23:57 +02003414 debug_text_event(adapter->erp_dbf, 3, "u_access_denied");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003415 debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
Andreas Herrmannd736a272005-06-13 13:23:57 +02003416 zfcp_erp_modify_unit_status(unit,
3417 ZFCP_STATUS_COMMON_ERP_FAILED |
3418 ZFCP_STATUS_COMMON_ACCESS_DENIED,
3419 ZFCP_SET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003420}
3421
Linus Torvalds1da177e2005-04-16 15:20:36 -07003422void
3423zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter)
3424{
3425 struct zfcp_port *port;
3426 unsigned long flags;
3427
Maxim Shchetyninaef4a982005-09-13 21:51:16 +02003428 if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
3429 return;
3430
Andreas Herrmannd736a272005-06-13 13:23:57 +02003431 debug_text_event(adapter->erp_dbf, 3, "a_access_recover");
Andreas Herrmann06506d02006-05-22 18:18:19 +02003432 debug_event(adapter->erp_dbf, 3, zfcp_get_busid_by_adapter(adapter), 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003433
Linus Torvalds1da177e2005-04-16 15:20:36 -07003434 read_lock_irqsave(&zfcp_data.config_lock, flags);
6f71d9b2005-04-10 23:04:28 -05003435 if (adapter->nameserver_port)
3436 zfcp_erp_port_access_changed(adapter->nameserver_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003437 list_for_each_entry(port, &adapter->port_list_head, list)
3438 if (port != adapter->nameserver_port)
3439 zfcp_erp_port_access_changed(port);
3440 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
3441}
3442
Linus Torvalds1da177e2005-04-16 15:20:36 -07003443void
3444zfcp_erp_port_access_changed(struct zfcp_port *port)
3445{
3446 struct zfcp_adapter *adapter = port->adapter;
3447 struct zfcp_unit *unit;
3448
Andreas Herrmannd736a272005-06-13 13:23:57 +02003449 debug_text_event(adapter->erp_dbf, 3, "p_access_recover");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003450 debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
3451
3452 if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED,
Andreas Herrmannd736a272005-06-13 13:23:57 +02003453 &port->status) &&
3454 !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003455 &port->status)) {
3456 if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
3457 list_for_each_entry(unit, &port->unit_list_head, list)
3458 zfcp_erp_unit_access_changed(unit);
3459 return;
3460 }
3461
3462 ZFCP_LOG_NORMAL("reopen of port 0x%016Lx on adapter %s "
3463 "(due to ACT update)\n",
3464 port->wwpn, zfcp_get_busid_by_adapter(adapter));
3465 if (zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED) != 0)
3466 ZFCP_LOG_NORMAL("failed reopen of port"
3467 "(adapter %s, wwpn=0x%016Lx)\n",
3468 zfcp_get_busid_by_adapter(adapter), port->wwpn);
3469}
3470
Linus Torvalds1da177e2005-04-16 15:20:36 -07003471void
3472zfcp_erp_unit_access_changed(struct zfcp_unit *unit)
3473{
3474 struct zfcp_adapter *adapter = unit->port->adapter;
3475
Andreas Herrmannd736a272005-06-13 13:23:57 +02003476 debug_text_event(adapter->erp_dbf, 3, "u_access_recover");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003477 debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
3478
Andreas Herrmannd736a272005-06-13 13:23:57 +02003479 if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED,
3480 &unit->status) &&
3481 !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED,
3482 &unit->status))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003483 return;
3484
3485 ZFCP_LOG_NORMAL("reopen of unit 0x%016Lx on port 0x%016Lx "
3486 " on adapter %s (due to ACT update)\n",
3487 unit->fcp_lun, unit->port->wwpn,
3488 zfcp_get_busid_by_adapter(adapter));
3489 if (zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED) != 0)
3490 ZFCP_LOG_NORMAL("failed reopen of unit (adapter %s, "
3491 "wwpn=0x%016Lx, fcp_lun=0x%016Lx)\n",
3492 zfcp_get_busid_by_adapter(adapter),
3493 unit->port->wwpn, unit->fcp_lun);
3494}
3495
3496#undef ZFCP_LOG_AREA