xref: /freebsd/sys/dev/ocs_fc/ocs_els.c (revision 076b94438c7d42c1b4661ed1e12e3b12ca69361a)
1 /*-
2  * Copyright (c) 2017 Broadcom. All rights reserved.
3  * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  *    this list of conditions and the following disclaimer in the documentation
13  *    and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  * $FreeBSD$
32  */
33 
34 /**
35  * @file
36  * Functions to build and send ELS/CT/BLS commands and responses.
37  */
38 
39 /*!
40 @defgroup els_api ELS/BLS/CT Command and Response Functions
41 */
42 
43 #include "ocs.h"
44 #include "ocs_els.h"
45 #include "ocs_scsi.h"
46 #include "ocs_device.h"
47 
48 #define ELS_IOFMT "[i:%04x t:%04x h:%04x]"
49 #define ELS_IOFMT_ARGS(els) els->init_task_tag, els->tgt_task_tag, els->hw_tag
50 
51 #define node_els_trace()  \
52 	do { \
53 		if (OCS_LOG_ENABLE_ELS_TRACE(ocs)) \
54 			ocs_log_info(ocs, "[%s] %-20s\n", node->display_name, __func__); \
55 	} while (0)
56 
57 #define els_io_printf(els, fmt, ...) \
58 	ocs_log_debug(els->node->ocs, "[%s]" ELS_IOFMT " %-8s " fmt, els->node->display_name, ELS_IOFMT_ARGS(els), els->display_name, ##__VA_ARGS__);
59 
60 static int32_t ocs_els_send(ocs_io_t *els, uint32_t reqlen, uint32_t timeout_sec, ocs_hw_srrs_cb_t cb);
61 static int32_t ocs_els_send_rsp(ocs_io_t *els, uint32_t rsplen);
62 static int32_t ocs_els_acc_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *arg);
63 static ocs_io_t *ocs_bls_send_acc(ocs_io_t *io, uint32_t s_id, uint16_t ox_id, uint16_t rx_id);
64 static int32_t ocs_bls_send_acc_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length,
65 	int32_t status, uint32_t ext_status, void *app);
66 static void ocs_io_transition(ocs_io_t *els, ocs_sm_function_t state, void *data);
67 static ocs_io_t *ocs_els_abort_io(ocs_io_t *els, int send_abts);
68 static void _ocs_els_io_free(void *arg);
69 static void ocs_els_delay_timer_cb(void *arg);
70 
71 
72 /**
73  * @ingroup els_api
74  * @brief ELS state machine transition wrapper.
75  *
76  * <h3 class="desc">Description</h3>
77  * This function is the transition wrapper for the ELS state machine. It grabs
78  * the node lock prior to making the transition to protect
79  * against multiple threads accessing a particular ELS. For example,
80  * one thread transitioning from __els_init to
81  * __ocs_els_wait_resp and another thread (tasklet) handling the
82  * completion of that ELS request.
83  *
84  * @param els Pointer to the IO context.
85  * @param state State to transition to.
86  * @param data Data to pass in with the transition.
87  *
88  * @return None.
89  */
90 static void
91 ocs_io_transition(ocs_io_t *els, ocs_sm_function_t state, void *data)
92 {
93 	/* protect ELS events with node lock */
94 	ocs_node_t *node = els->node;
95 	ocs_node_lock(node);
96 		ocs_sm_transition(&els->els_sm, state, data);
97 	ocs_node_unlock(node);
98 }
99 
100 /**
101  * @ingroup els_api
102  * @brief ELS state machine post event wrapper.
103  *
104  * <h3 class="desc">Description</h3>
105  * Post an event wrapper for the ELS state machine. This function grabs
106  * the node lock prior to posting the event.
107  *
108  * @param els Pointer to the IO context.
109  * @param evt Event to process.
110  * @param data Data to pass in with the transition.
111  *
112  * @return None.
113  */
114 void
115 ocs_els_post_event(ocs_io_t *els, ocs_sm_event_t evt, void *data)
116 {
117 	/* protect ELS events with node lock */
118 	ocs_node_t *node = els->node;
119 	ocs_node_lock(node);
120 		els->els_evtdepth ++;
121 		ocs_sm_post_event(&els->els_sm, evt, data);
122 		els->els_evtdepth --;
123 	ocs_node_unlock(node);
124 	if (els->els_evtdepth == 0 && els->els_req_free) {
125 		ocs_els_io_free(els);
126 	}
127 }
128 
129 /**
130  * @ingroup els_api
131  * @brief Allocate an IO structure for an ELS IO context.
132  *
133  * <h3 class="desc">Description</h3>
134  * Allocate an IO for an ELS context.  Uses OCS_ELS_RSP_LEN as response size.
135  *
136  * @param node node to associate ELS IO with
137  * @param reqlen Length of ELS request
138  * @param role Role of ELS (originator/responder)
139  *
140  * @return pointer to IO structure allocated
141  */
142 
143 ocs_io_t *
144 ocs_els_io_alloc(ocs_node_t *node, uint32_t reqlen, ocs_els_role_e role)
145 {
146 	return ocs_els_io_alloc_size(node, reqlen, OCS_ELS_RSP_LEN, role);
147 }
148 
149 /**
150  * @ingroup els_api
151  * @brief Allocate an IO structure for an ELS IO context.
152  *
153  * <h3 class="desc">Description</h3>
154  * Allocate an IO for an ELS context, allowing the caller to specify the size of the response.
155  *
156  * @param node node to associate ELS IO with
157  * @param reqlen Length of ELS request
158  * @param rsplen Length of ELS response
159  * @param role Role of ELS (originator/responder)
160  *
161  * @return pointer to IO structure allocated
162  */
163 
164 ocs_io_t *
165 ocs_els_io_alloc_size(ocs_node_t *node, uint32_t reqlen, uint32_t rsplen, ocs_els_role_e role)
166 {
167 
168 	ocs_t *ocs;
169 	ocs_xport_t *xport;
170 	ocs_io_t *els;
171 	ocs_assert(node, NULL);
172 	ocs_assert(node->ocs, NULL);
173 	ocs = node->ocs;
174 	ocs_assert(ocs->xport, NULL);
175 	xport = ocs->xport;
176 
177 	ocs_lock(&node->active_ios_lock);
178 		if (!node->io_alloc_enabled) {
179 			ocs_log_debug(ocs, "called with io_alloc_enabled = FALSE\n");
180 			ocs_unlock(&node->active_ios_lock);
181 			return NULL;
182 		}
183 
184 		els = ocs_io_alloc(ocs);
185 		if (els == NULL) {
186 			ocs_atomic_add_return(&xport->io_alloc_failed_count, 1);
187 			ocs_unlock(&node->active_ios_lock);
188 			return NULL;
189 		}
190 
191 		/* initialize refcount */
192 		ocs_ref_init(&els->ref, _ocs_els_io_free, els);
193 
194 		switch (role) {
195 		case OCS_ELS_ROLE_ORIGINATOR:
196 			els->cmd_ini = TRUE;
197 			els->cmd_tgt = FALSE;
198 			break;
199 		case OCS_ELS_ROLE_RESPONDER:
200 			els->cmd_ini = FALSE;
201 			els->cmd_tgt = TRUE;
202 			break;
203 		}
204 
205 		/* IO should not have an associated HW IO yet.  Assigned below. */
206 		if (els->hio != NULL) {
207 			ocs_log_err(ocs, "assertion failed.  HIO is not null\n");
208 			ocs_io_free(ocs, els);
209 			ocs_unlock(&node->active_ios_lock);
210 			return NULL;
211 		}
212 
213 		/* populate generic io fields */
214 		els->ocs = ocs;
215 		els->node = node;
216 
217 		/* set type and ELS-specific fields */
218 		els->io_type = OCS_IO_TYPE_ELS;
219 		els->display_name = "pending";
220 
221 		if (reqlen > OCS_ELS_REQ_LEN) {
222 			ocs_log_err(ocs, "ELS command request len greater than allocated\n");
223 			ocs_io_free(ocs, els);
224 			ocs_unlock(&node->active_ios_lock);
225 			return NULL;
226 		}
227 
228 		if (rsplen > OCS_ELS_GID_PT_RSP_LEN) {
229 			ocs_log_err(ocs, "ELS command response len: %d "
230 				"greater than allocated\n", rsplen);
231 			ocs_io_free(ocs, els);
232 			ocs_unlock(&node->active_ios_lock);
233 			return NULL;
234 		}
235 
236 		els->els_req.size = reqlen;
237 		els->els_rsp.size = rsplen;
238 
239 		if (els != NULL) {
240 			ocs_memset(&els->els_sm, 0, sizeof(els->els_sm));
241 			els->els_sm.app = els;
242 
243 			/* initialize fields */
244 			els->els_retries_remaining = OCS_FC_ELS_DEFAULT_RETRIES;
245 			els->els_evtdepth = 0;
246 			els->els_pend = 0;
247 			els->els_active = 0;
248 
249 			/* add els structure to ELS IO list */
250 			ocs_list_add_tail(&node->els_io_pend_list, els);
251 			els->els_pend = 1;
252 		}
253 	ocs_unlock(&node->active_ios_lock);
254 	return els;
255 }
256 
257 /**
258  * @ingroup els_api
259  * @brief Free IO structure for an ELS IO context.
260  *
261  * <h3 class="desc">Description</h3> Free IO for an ELS
262  * IO context
263  *
264  * @param els ELS IO structure for which IO is allocated
265  *
266  * @return None
267  */
268 
269 void
270 ocs_els_io_free(ocs_io_t *els)
271 {
272 	ocs_ref_put(&els->ref);
273 }
274 
275 /**
276  * @ingroup els_api
277  * @brief Free IO structure for an ELS IO context.
278  *
279  * <h3 class="desc">Description</h3> Free IO for an ELS
280  * IO context
281  *
282  * @param arg ELS IO structure for which IO is allocated
283  *
284  * @return None
285  */
286 
287 static void
288 _ocs_els_io_free(void *arg)
289 {
290 	ocs_io_t *els = (ocs_io_t *)arg;
291 	ocs_t *ocs;
292 	ocs_node_t *node;
293 	int send_empty_event = FALSE;
294 
295 	ocs_assert(els);
296 	ocs_assert(els->node);
297 	ocs_assert(els->node->ocs);
298 	ocs = els->node->ocs;
299 
300 	node = els->node;
301 	ocs = node->ocs;
302 
303 	ocs_lock(&node->active_ios_lock);
304 		if (els->els_active) {
305 			/* if active, remove from active list and check empty */
306 			ocs_list_remove(&node->els_io_active_list, els);
307 			/* Send list empty event if the IO allocator is disabled, and the list is empty
308 			 * If node->io_alloc_enabled was not checked, the event would be posted continually
309 			 */
310 			send_empty_event = (!node->io_alloc_enabled) && ocs_list_empty(&node->els_io_active_list);
311 			els->els_active = 0;
312 		} else if (els->els_pend) {
313 			/* if pending, remove from pending list; node shutdown isn't
314 			 * gated off the pending list (only the active list), so no
315 			 * need to check if pending list is empty
316 			 */
317 			ocs_list_remove(&node->els_io_pend_list, els);
318 			els->els_pend = 0;
319 		} else {
320 			ocs_log_err(ocs, "assertion failed: niether els->els_pend nor els->active set\n");
321 			ocs_unlock(&node->active_ios_lock);
322 			return;
323 		}
324 
325 	ocs_unlock(&node->active_ios_lock);
326 
327 	ocs_io_free(ocs, els);
328 
329 	if (send_empty_event) {
330 		ocs_node_post_event(node, OCS_EVT_ALL_CHILD_NODES_FREE, NULL);
331 	}
332 
333 	ocs_scsi_check_pending(ocs);
334 }
335 
336 /**
337  * @ingroup els_api
338  * @brief Make ELS IO active
339  *
340  * @param els Pointer to the IO context to make active.
341  *
342  * @return Returns 0 on success; or a negative error code value on failure.
343  */
344 
345 static void
346 ocs_els_make_active(ocs_io_t *els)
347 {
348 	ocs_node_t *node = els->node;
349 
350 	/* move ELS from pending list to active list */
351 	ocs_lock(&node->active_ios_lock);
352 		if (els->els_pend) {
353 			if (els->els_active) {
354 				ocs_log_err(node->ocs, "assertion failed: both els->els_pend and els->active set\n");
355 				ocs_unlock(&node->active_ios_lock);
356 				return;
357 			} else {
358 
359 				/* remove from pending list */
360 				ocs_list_remove(&node->els_io_pend_list, els);
361 				els->els_pend = 0;
362 
363 				/* add els structure to ELS IO list */
364 				ocs_list_add_tail(&node->els_io_active_list, els);
365 				els->els_active = 1;
366 			}
367 		} else {
368 			/* must be retrying; make sure it's already active */
369 			if (!els->els_active) {
370 				ocs_log_err(node->ocs, "assertion failed: niether els->els_pend nor els->active set\n");
371 			}
372 		}
373 	ocs_unlock(&node->active_ios_lock);
374 }
375 
376 /**
377  * @ingroup els_api
378  * @brief Send the ELS command.
379  *
380  * <h3 class="desc">Description</h3>
381  * The command, given by the \c els IO context, is sent to the node that the IO was
382  * configured with, using ocs_hw_srrs_send(). Upon completion,
383  * the \c cb callback is invoked,
384  * with the application-specific argument set to the \c els IO context.
385  *
386  * @param els Pointer to the IO context.
387  * @param reqlen Byte count in the payload to send.
388  * @param timeout_sec Command timeout, in seconds (0 -> 2*R_A_TOV).
389  * @param cb Completion callback.
390  *
391  * @return Returns 0 on success; or a negative error code value on failure.
392  */
393 
394 static int32_t
395 ocs_els_send(ocs_io_t *els, uint32_t reqlen, uint32_t timeout_sec, ocs_hw_srrs_cb_t cb)
396 {
397 	ocs_node_t *node = els->node;
398 
399 	/* update ELS request counter */
400 	node->els_req_cnt++;
401 
402 	/* move ELS from pending list to active list */
403 	ocs_els_make_active(els);
404 
405 	els->wire_len = reqlen;
406 	return ocs_scsi_io_dispatch(els, cb);
407 }
408 
409 /**
410  * @ingroup els_api
411  * @brief Send the ELS response.
412  *
413  * <h3 class="desc">Description</h3>
414  * The ELS response, given by the \c els IO context, is sent to the node
415  * that the IO was configured with, using ocs_hw_srrs_send().
416  *
417  * @param els Pointer to the IO context.
418  * @param rsplen Byte count in the payload to send.
419  *
420  * @return Returns 0 on success; or a negative error value on failure.
421  */
422 
423 static int32_t
424 ocs_els_send_rsp(ocs_io_t *els, uint32_t rsplen)
425 {
426 	ocs_node_t *node = els->node;
427 
428 	/* increment ELS completion counter */
429 	node->els_cmpl_cnt++;
430 
431 	/* move ELS from pending list to active list */
432 	ocs_els_make_active(els);
433 
434 	els->wire_len = rsplen;
435 	return ocs_scsi_io_dispatch(els, ocs_els_acc_cb);
436 }
437 
438 /**
439  * @ingroup els_api
440  * @brief Handle ELS IO request completions.
441  *
442  * <h3 class="desc">Description</h3>
443  * This callback is used for several ELS send operations.
444  *
445  * @param hio Pointer to the HW IO context that completed.
446  * @param rnode Pointer to the remote node.
447  * @param length Length of the returned payload data.
448  * @param status Status of the completion.
449  * @param ext_status Extended status of the completion.
450  * @param arg Application-specific argument (generally a pointer to the ELS IO context).
451  *
452  * @return Returns 0 on success; or a negative error value on failure.
453  */
454 
455 static int32_t
456 ocs_els_req_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *arg)
457 {
458 	ocs_io_t *els;
459 	ocs_node_t *node;
460 	ocs_t *ocs;
461 	ocs_node_cb_t cbdata;
462 	ocs_io_t *io;
463 
464 	ocs_assert(arg, -1);
465 	io = arg;
466 	els = io;
467 	ocs_assert(els, -1);
468 	ocs_assert(els->node, -1);
469 	node = els->node;
470 	ocs_assert(node->ocs, -1);
471 	ocs = node->ocs;
472 
473 	ocs_assert(io->hio, -1);
474 	ocs_assert(hio == io->hio, -1);
475 
476 	if (status != 0) {
477 		els_io_printf(els, "status x%x ext x%x\n", status, ext_status);
478 	}
479 
480 	/* set the response len element of els->rsp */
481 	els->els_rsp.len = length;
482 
483 	cbdata.status = status;
484 	cbdata.ext_status = ext_status;
485 	cbdata.header = NULL;
486 	cbdata.els = els;
487 
488 	/* FW returns the number of bytes received on the link in
489 	 * the WCQE, not the amount placed in the buffer; use this info to
490 	 * check if there was an overrun.
491 	 */
492 	if (length > els->els_rsp.size) {
493 		ocs_log_warn(ocs, "ELS response returned len=%d > buflen=%zu\n",
494 				length, els->els_rsp.size);
495 		ocs_els_post_event(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &cbdata);
496 		return 0;
497 	}
498 
499 	/* Post event to ELS IO object */
500 	switch (status) {
501 	case SLI4_FC_WCQE_STATUS_SUCCESS:
502 		ocs_els_post_event(els, OCS_EVT_SRRS_ELS_REQ_OK, &cbdata);
503 		break;
504 
505 	case SLI4_FC_WCQE_STATUS_LS_RJT:
506 		ocs_els_post_event(els, OCS_EVT_SRRS_ELS_REQ_RJT, &cbdata);
507 		break;
508 
509 
510 	case SLI4_FC_WCQE_STATUS_LOCAL_REJECT:
511 		switch (ext_status) {
512 		case SLI4_FC_LOCAL_REJECT_SEQUENCE_TIMEOUT:
513 			ocs_els_post_event(els, OCS_EVT_ELS_REQ_TIMEOUT, &cbdata);
514 			break;
515 		case SLI4_FC_LOCAL_REJECT_ABORT_REQUESTED:
516 			ocs_els_post_event(els, OCS_EVT_ELS_REQ_ABORTED, &cbdata);
517 			break;
518 		default:
519 			ocs_els_post_event(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &cbdata);
520 			break;
521 		}
522 		break;
523 	default:
524 		ocs_log_warn(ocs, "els req complete: failed status x%x, ext_status, x%x\n", status, ext_status);
525 		ocs_els_post_event(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &cbdata);
526 		break;
527 	}
528 
529 	return 0;
530 }
531 
532 /**
533  * @ingroup els_api
534  * @brief Handle ELS IO accept/response completions.
535  *
536  * <h3 class="desc">Description</h3>
537  * This callback is used for several ELS send operations.
538  *
539  * @param hio Pointer to the HW IO context that completed.
540  * @param rnode Pointer to the remote node.
541  * @param length Length of the returned payload data.
542  * @param status Status of the completion.
543  * @param ext_status Extended status of the completion.
544  * @param arg Application-specific argument (generally a pointer to the ELS IO context).
545  *
546  * @return Returns 0 on success; or a negative error value on failure.
547  */
548 
549 static int32_t
550 ocs_els_acc_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *arg)
551 {
552 	ocs_io_t *els;
553 	ocs_node_t *node;
554 	ocs_t *ocs;
555 	ocs_node_cb_t cbdata;
556 	ocs_io_t *io;
557 
558 	ocs_assert(arg, -1);
559 	io = arg;
560 	els = io;
561 	ocs_assert(els, -1);
562 	ocs_assert(els->node, -1);
563 	node = els->node;
564 	ocs_assert(node->ocs, -1);
565 	ocs = node->ocs;
566 
567 	ocs_assert(io->hio, -1);
568 	ocs_assert(hio == io->hio, -1);
569 
570 	cbdata.status = status;
571 	cbdata.ext_status = ext_status;
572 	cbdata.header = NULL;
573 	cbdata.els = els;
574 
575 	/* Post node event */
576 	switch (status) {
577 	case SLI4_FC_WCQE_STATUS_SUCCESS:
578 		ocs_node_post_event(node, OCS_EVT_SRRS_ELS_CMPL_OK, &cbdata);
579 		break;
580 
581 	default:
582 		ocs_log_warn(ocs, "[%s] %-8s failed status x%x, ext_status x%x\n",
583 			node->display_name, els->display_name, status, ext_status);
584 		ocs_log_warn(ocs, "els acc complete: failed status x%x, ext_status, x%x\n", status, ext_status);
585 		ocs_node_post_event(node, OCS_EVT_SRRS_ELS_CMPL_FAIL, &cbdata);
586 		break;
587 	}
588 
589 	/* If this IO has a callback, invoke it */
590 	if (els->els_callback) {
591 		(*els->els_callback)(node, &cbdata, els->els_callback_arg);
592 	}
593 
594 	ocs_els_io_free(els);
595 
596 	return 0;
597 }
598 
599 /**
600  * @ingroup els_api
601  * @brief Format and send a PLOGI ELS command.
602  *
603  * <h3 class="desc">Description</h3>
604  * Construct a PLOGI payload using the domain SLI port service parameters,
605  * and send to the \c node.
606  *
607  * @param node Node to which the PLOGI is sent.
608  * @param timeout_sec Command timeout, in seconds.
609  * @param retries Number of times to retry errors before reporting a failure.
610  * @param cb Callback function.
611  * @param cbarg Callback function argument.
612  *
613  * @return Returns pointer to IO object, or NULL if error.
614  */
615 
616 ocs_io_t *
617 ocs_send_plogi(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
618 	void (*cb)(ocs_node_t *node, ocs_node_cb_t *cbdata, void *arg), void *cbarg)
619 {
620 	ocs_io_t *els;
621 	ocs_t *ocs = node->ocs;
622 	fc_plogi_payload_t *plogi;
623 
624 	node_els_trace();
625 
626 	els = ocs_els_io_alloc(node, sizeof(*plogi), OCS_ELS_ROLE_ORIGINATOR);
627 	if (els == NULL) {
628 		ocs_log_err(ocs, "IO alloc failed\n");
629 	} else {
630 		els->els_timeout_sec = timeout_sec;
631 		els->els_retries_remaining = retries;
632 		els->els_callback = cb;
633 		els->els_callback_arg = cbarg;
634 		els->display_name = "plogi";
635 
636 		/* Build PLOGI request */
637 		plogi = els->els_req.virt;
638 
639 		ocs_memcpy(plogi, node->sport->service_params, sizeof(*plogi));
640 
641 		plogi->command_code = FC_ELS_CMD_PLOGI;
642 		plogi->resv1 = 0;
643 
644 		ocs_display_sparams(node->display_name, "plogi send req", 0, NULL, plogi->common_service_parameters);
645 
646 		els->hio_type = OCS_HW_ELS_REQ;
647 		els->iparam.els.timeout = timeout_sec;
648 
649 		ocs_io_transition(els, __ocs_els_init, NULL);
650 
651 	}
652 	return els;
653 }
654 
655 /**
656  * @ingroup els_api
657  * @brief Format and send a FLOGI ELS command.
658  *
659  * <h3 class="desc">Description</h3>
660  * Construct an FLOGI payload, and send to the \c node.
661  *
662  * @param node Node to which the FLOGI is sent.
663  * @param timeout_sec Command timeout, in seconds.
664  * @param retries Number of times to retry errors before reporting a failure.
665  * @param cb Callback function.
666  * @param cbarg Callback function argument.
667  *
668  * @return Returns pointer to IO object, or NULL if error.
669  */
670 
671 ocs_io_t *
672 ocs_send_flogi(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
673 	els_cb_t cb, void *cbarg)
674 {
675 	ocs_io_t *els;
676 	ocs_t *ocs;
677 	fc_plogi_payload_t *flogi;
678 
679 	ocs_assert(node, NULL);
680 	ocs_assert(node->ocs, NULL);
681 	ocs_assert(node->sport, NULL);
682 	ocs = node->ocs;
683 
684 	node_els_trace();
685 
686 	els = ocs_els_io_alloc(node, sizeof(*flogi), OCS_ELS_ROLE_ORIGINATOR);
687 	if (els == NULL) {
688 		ocs_log_err(ocs, "IO alloc failed\n");
689 	} else {
690 		els->els_timeout_sec = timeout_sec;
691 		els->els_retries_remaining = retries;
692 		els->els_callback = cb;
693 		els->els_callback_arg = cbarg;
694 		els->display_name = "flogi";
695 
696 		/* Build FLOGI request */
697 		flogi = els->els_req.virt;
698 
699 		ocs_memcpy(flogi, node->sport->service_params, sizeof(*flogi));
700 		flogi->command_code = FC_ELS_CMD_FLOGI;
701 		flogi->resv1 = 0;
702 
703 		/* Priority tagging support */
704 		flogi->common_service_parameters[1] |= ocs_htobe32(1U << 23);
705 
706 		ocs_display_sparams(node->display_name, "flogi send req", 0, NULL, flogi->common_service_parameters);
707 
708 		els->hio_type = OCS_HW_ELS_REQ;
709 		els->iparam.els.timeout = timeout_sec;
710 		ocs_io_transition(els, __ocs_els_init, NULL);
711 	}
712 	return els;
713 }
714 
715 /**
716  * @ingroup els_api
717  * @brief Format and send a FDISC ELS command.
718  *
719  * <h3 class="desc">Description</h3>
720  * Construct an FDISC payload, and send to the \c node.
721  *
722  * @param node Node to which the FDISC is sent.
723  * @param timeout_sec Command timeout, in seconds.
724  * @param retries Number of times to retry errors before reporting a failure.
725  * @param cb Callback function.
726  * @param cbarg Callback function argument.
727  *
728  * @return Returns pointer to IO object, or NULL if error.
729  */
730 
731 ocs_io_t *
732 ocs_send_fdisc(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
733 	els_cb_t cb, void *cbarg)
734 {
735 	ocs_io_t *els;
736 	ocs_t *ocs;
737 	fc_plogi_payload_t *fdisc;
738 
739 	ocs_assert(node, NULL);
740 	ocs_assert(node->ocs, NULL);
741 	ocs = node->ocs;
742 
743 	node_els_trace();
744 
745 	els = ocs_els_io_alloc(node, sizeof(*fdisc), OCS_ELS_ROLE_ORIGINATOR);
746 	if (els == NULL) {
747 		ocs_log_err(ocs, "IO alloc failed\n");
748 	} else {
749 		els->els_timeout_sec = timeout_sec;
750 		els->els_retries_remaining = retries;
751 		els->els_callback = cb;
752 		els->els_callback_arg = cbarg;
753 		els->display_name = "fdisc";
754 
755 		/* Build FDISC request */
756 		fdisc = els->els_req.virt;
757 
758 		ocs_memcpy(fdisc, node->sport->service_params, sizeof(*fdisc));
759 		fdisc->command_code = FC_ELS_CMD_FDISC;
760 		fdisc->resv1 = 0;
761 
762 		ocs_display_sparams(node->display_name, "fdisc send req", 0, NULL, fdisc->common_service_parameters);
763 
764 		els->hio_type = OCS_HW_ELS_REQ;
765 		els->iparam.els.timeout = timeout_sec;
766 		ocs_io_transition(els, __ocs_els_init, NULL);
767 	}
768 	return els;
769 }
770 
771 /**
772  * @ingroup els_api
773  * @brief Send a PRLI ELS command.
774  *
775  * <h3 class="desc">Description</h3>
776  * Construct a PRLI ELS command, and send to the \c node.
777  *
778  * @param node Node to which the PRLI is sent.
779  * @param timeout_sec Command timeout, in seconds.
780  * @param retries Number of times to retry errors before reporting a failure.
781  * @param cb Callback function.
782  * @param cbarg Callback function argument.
783  *
784  * @return Returns pointer to IO object, or NULL if error.
785  */
786 
787 ocs_io_t *
788 ocs_send_prli(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
789 	els_cb_t cb, void *cbarg)
790 {
791 	ocs_t *ocs = node->ocs;
792 	ocs_io_t *els;
793 	fc_prli_payload_t *prli;
794 
795 	node_els_trace();
796 
797 	els = ocs_els_io_alloc(node, sizeof(*prli), OCS_ELS_ROLE_ORIGINATOR);
798 	if (els == NULL) {
799 		ocs_log_err(ocs, "IO alloc failed\n");
800 	} else {
801 		els->els_timeout_sec = timeout_sec;
802 		els->els_retries_remaining = retries;
803 		els->els_callback = cb;
804 		els->els_callback_arg = cbarg;
805 		els->display_name = "prli";
806 
807 		/* Build PRLI request */
808 		prli = els->els_req.virt;
809 
810 		ocs_memset(prli, 0, sizeof(*prli));
811 
812 		prli->command_code = FC_ELS_CMD_PRLI;
813 		prli->page_length = 16;
814 		prli->payload_length = ocs_htobe16(sizeof(fc_prli_payload_t));
815 		prli->type = FC_TYPE_FCP;
816 		prli->type_ext = 0;
817 		prli->flags = ocs_htobe16(FC_PRLI_ESTABLISH_IMAGE_PAIR);
818 		prli->service_params = ocs_htobe16(FC_PRLI_READ_XRDY_DISABLED |
819 			(node->sport->enable_ini ? FC_PRLI_INITIATOR_FUNCTION : 0) |
820 			(node->sport->enable_tgt ? FC_PRLI_TARGET_FUNCTION : 0));
821 
822 		/* For Tape Drive support */
823 		prli->service_params |= ocs_htobe16(FC_PRLI_CONFIRMED_COMPLETION | FC_PRLI_RETRY |
824 				 FC_PRLI_TASK_RETRY_ID_REQ| FC_PRLI_REC_SUPPORT);
825 
826 		els->hio_type = OCS_HW_ELS_REQ;
827 		els->iparam.els.timeout = timeout_sec;
828 		ocs_io_transition(els, __ocs_els_init, NULL);
829 	}
830 
831 	return els;
832 }
833 
834 /**
835  * @ingroup els_api
836  * @brief Send a PRLO ELS command.
837  *
838  * <h3 class="desc">Description</h3>
839  * Construct a PRLO ELS command, and send to the \c node.
840  *
841  * @param node Node to which the PRLO is sent.
842  * @param timeout_sec Command timeout, in seconds.
843  * @param retries Number of times to retry errors before reporting a failure.
844  * @param cb Callback function.
845  * @param cbarg Callback function argument.
846  *
847  * @return Returns pointer to IO object, or NULL if error.
848  */
849 
850 ocs_io_t *
851 ocs_send_prlo(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
852 	els_cb_t cb, void *cbarg)
853 {
854 	ocs_t *ocs = node->ocs;
855 	ocs_io_t *els;
856 	fc_prlo_payload_t *prlo;
857 
858 	node_els_trace();
859 
860 	els = ocs_els_io_alloc(node, sizeof(*prlo), OCS_ELS_ROLE_ORIGINATOR);
861 	if (els == NULL) {
862 		ocs_log_err(ocs, "IO alloc failed\n");
863 	} else {
864 		els->els_timeout_sec = timeout_sec;
865 		els->els_retries_remaining = retries;
866 		els->els_callback = cb;
867 		els->els_callback_arg = cbarg;
868 		els->display_name = "prlo";
869 
870 		/* Build PRLO request */
871 		prlo = els->els_req.virt;
872 
873 		ocs_memset(prlo, 0, sizeof(*prlo));
874 		prlo->command_code = FC_ELS_CMD_PRLO;
875 		prlo->page_length = 16;
876 		prlo->payload_length = ocs_htobe16(sizeof(fc_prlo_payload_t));
877 		prlo->type = FC_TYPE_FCP;
878 		prlo->type_ext = 0;
879 
880 		els->hio_type = OCS_HW_ELS_REQ;
881 		els->iparam.els.timeout = timeout_sec;
882 		ocs_io_transition(els, __ocs_els_init, NULL);
883 	}
884 	return els;
885 }
886 
887 /**
888  * @ingroup els_api
889  * @brief Send a LOGO ELS command.
890  *
891  * <h3 class="desc">Description</h3>
892  * Format a LOGO, and send to the \c node.
893  *
894  * @param node Node to which the LOGO is sent.
895  * @param timeout_sec Command timeout, in seconds.
896  * @param retries Number of times to retry errors before reporting a failure.
897  * @param cb Callback function.
898  * @param cbarg Callback function argument.
899  *
900  * @return Returns pointer to IO object, or NULL if error.
901  */
902 
903 ocs_io_t *
904 ocs_send_logo(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
905 	els_cb_t cb, void *cbarg)
906 {
907 	ocs_io_t *els;
908 	ocs_t *ocs;
909 	fc_logo_payload_t *logo;
910 	fc_plogi_payload_t *sparams;
911 
912 
913 	ocs = node->ocs;
914 
915 	node_els_trace();
916 
917 	sparams = (fc_plogi_payload_t*) node->sport->service_params;
918 
919 	els = ocs_els_io_alloc(node, sizeof(*logo), OCS_ELS_ROLE_ORIGINATOR);
920 	if (els == NULL) {
921 		ocs_log_err(ocs, "IO alloc failed\n");
922 	} else {
923 		els->els_timeout_sec = timeout_sec;
924 		els->els_retries_remaining = retries;
925 		els->els_callback = cb;
926 		els->els_callback_arg = cbarg;
927 		els->display_name = "logo";
928 
929 		/* Build LOGO request */
930 
931 		logo = els->els_req.virt;
932 
933 		ocs_memset(logo, 0, sizeof(*logo));
934 		logo->command_code = FC_ELS_CMD_LOGO;
935 		logo->resv1 = 0;
936 		logo->port_id = fc_htobe24(node->rnode.sport->fc_id);
937 		logo->port_name_hi = sparams->port_name_hi;
938 		logo->port_name_lo = sparams->port_name_lo;
939 
940 		els->hio_type = OCS_HW_ELS_REQ;
941 		els->iparam.els.timeout = timeout_sec;
942 		ocs_io_transition(els, __ocs_els_init, NULL);
943 	}
944 	return els;
945 }
946 
947 /**
948  * @ingroup els_api
949  * @brief Send an ADISC ELS command.
950  *
951  * <h3 class="desc">Description</h3>
952  * Construct an ADISC ELS command, and send to the \c node.
953  *
954  * @param node Node to which the ADISC is sent.
955  * @param timeout_sec Command timeout, in seconds.
956  * @param retries Number of times to retry errors before reporting a failure.
957  * @param cb Callback function.
958  * @param cbarg Callback function argument.
959  *
960  * @return Returns pointer to IO object, or NULL if error.
961  */
962 
963 ocs_io_t *
964 ocs_send_adisc(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
965 	els_cb_t cb, void *cbarg)
966 {
967 	ocs_io_t *els;
968 	ocs_t *ocs;
969 	fc_adisc_payload_t *adisc;
970 	fc_plogi_payload_t *sparams;
971 	ocs_sport_t *sport = node->sport;
972 
973 	ocs = node->ocs;
974 
975 	node_els_trace();
976 
977 	sparams = (fc_plogi_payload_t*) node->sport->service_params;
978 
979 	els = ocs_els_io_alloc(node, sizeof(*adisc), OCS_ELS_ROLE_ORIGINATOR);
980 	if (els == NULL) {
981 		ocs_log_err(ocs, "IO alloc failed\n");
982 	} else {
983 		els->els_timeout_sec = timeout_sec;
984 		els->els_retries_remaining = retries;
985 		els->els_callback = cb;
986 		els->els_callback_arg = cbarg;
987 		els->display_name = "adisc";
988 
989 		/* Build ADISC request */
990 
991 		adisc = els->els_req.virt;
992 		sparams = (fc_plogi_payload_t*) node->sport->service_params;
993 
994 		ocs_memset(adisc, 0, sizeof(*adisc));
995 		adisc->command_code = FC_ELS_CMD_ADISC;
996 		adisc->hard_address = fc_htobe24(sport->fc_id);
997 		adisc->port_name_hi = sparams->port_name_hi;
998 		adisc->port_name_lo = sparams->port_name_lo;
999 		adisc->node_name_hi = sparams->node_name_hi;
1000 		adisc->node_name_lo = sparams->node_name_lo;
1001 		adisc->port_id = fc_htobe24(node->rnode.sport->fc_id);
1002 
1003 		els->hio_type = OCS_HW_ELS_REQ;
1004 		els->iparam.els.timeout = timeout_sec;
1005 		ocs_io_transition(els, __ocs_els_init, NULL);
1006 	}
1007 	return els;
1008 }
1009 
1010 /**
1011  * @ingroup els_api
1012  * @brief Send a PDISC ELS command.
1013  *
1014  * <h3 class="desc">Description</h3>
1015  * Construct a PDISC ELS command, and send to the \c node.
1016  *
1017  * @param node Node to which the PDISC is sent.
1018  * @param timeout_sec Command timeout, in seconds.
1019  * @param retries Number of times to retry errors before reporting a failure.
1020  * @param cb Callback function.
1021  * @param cbarg Callback function argument.
1022  *
1023  * @return Returns pointer to IO object, or NULL if error.
1024  */
1025 
1026 ocs_io_t *
1027 ocs_send_pdisc(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
1028 	els_cb_t cb, void *cbarg)
1029 {
1030 	ocs_io_t *els;
1031 	ocs_t *ocs = node->ocs;
1032 	fc_plogi_payload_t *pdisc;
1033 
1034 	node_els_trace();
1035 
1036 	els = ocs_els_io_alloc(node, sizeof(*pdisc), OCS_ELS_ROLE_ORIGINATOR);
1037 	if (els == NULL) {
1038 		ocs_log_err(ocs, "IO alloc failed\n");
1039 	} else {
1040 		els->els_timeout_sec = timeout_sec;
1041 		els->els_retries_remaining = retries;
1042 		els->els_callback = cb;
1043 		els->els_callback_arg = cbarg;
1044 		els->display_name = "pdisc";
1045 
1046 		pdisc = els->els_req.virt;
1047 
1048 		ocs_memcpy(pdisc, node->sport->service_params, sizeof(*pdisc));
1049 
1050 		pdisc->command_code = FC_ELS_CMD_PDISC;
1051 		pdisc->resv1 = 0;
1052 
1053 		els->hio_type = OCS_HW_ELS_REQ;
1054 		els->iparam.els.timeout = timeout_sec;
1055 		ocs_io_transition(els, __ocs_els_init, NULL);
1056 	}
1057 	return els;
1058 }
1059 
1060 /**
1061  * @ingroup els_api
1062  * @brief Send an SCR ELS command.
1063  *
1064  * <h3 class="desc">Description</h3>
1065  * Format an SCR, and send to the \c node.
1066  *
1067  * @param node Node to which the SCR is sent.
1068  * @param timeout_sec Command timeout, in seconds.
1069  * @param retries Number of times to retry errors before reporting a failure.
1070  * @param cb Callback function
1071  * @param cbarg Callback function arg
1072  *
1073  * @return Returns pointer to IO object, or NULL if error.
1074  */
1075 
1076 ocs_io_t *
1077 ocs_send_scr(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
1078 	els_cb_t cb, void *cbarg)
1079 {
1080 	ocs_io_t *els;
1081 	ocs_t *ocs = node->ocs;
1082 	fc_scr_payload_t *req;
1083 
1084 	node_els_trace();
1085 
1086 	els = ocs_els_io_alloc(node, sizeof(*req), OCS_ELS_ROLE_ORIGINATOR);
1087 	if (els == NULL) {
1088 		ocs_log_err(ocs, "IO alloc failed\n");
1089 	} else {
1090 		els->els_timeout_sec = timeout_sec;
1091 		els->els_retries_remaining = retries;
1092 		els->els_callback = cb;
1093 		els->els_callback_arg = cbarg;
1094 		els->display_name = "scr";
1095 
1096 		req = els->els_req.virt;
1097 
1098 		ocs_memset(req, 0, sizeof(*req));
1099 		req->command_code = FC_ELS_CMD_SCR;
1100 		req->function = FC_SCR_REG_FULL;
1101 
1102 		els->hio_type = OCS_HW_ELS_REQ;
1103 		els->iparam.els.timeout = timeout_sec;
1104 		ocs_io_transition(els, __ocs_els_init, NULL);
1105 	}
1106 	return els;
1107 }
1108 
1109 /**
1110  * @ingroup els_api
1111  * @brief Send an RRQ ELS command.
1112  *
1113  * <h3 class="desc">Description</h3>
1114  * Format an RRQ, and send to the \c node.
1115  *
1116  * @param node Node to which the RRQ is sent.
1117  * @param timeout_sec Command timeout, in seconds.
1118  * @param retries Number of times to retry errors before reporting a failure.
1119  * @param cb Callback function
1120  * @param cbarg Callback function arg
1121  *
1122  * @return Returns pointer to IO object, or NULL if error.
1123  */
1124 
1125 ocs_io_t *
1126 ocs_send_rrq(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
1127 	els_cb_t cb, void *cbarg)
1128 {
1129 	ocs_io_t *els;
1130 	ocs_t *ocs = node->ocs;
1131 	fc_scr_payload_t *req;
1132 
1133 	node_els_trace();
1134 
1135 	els = ocs_els_io_alloc(node, sizeof(*req), OCS_ELS_ROLE_ORIGINATOR);
1136 	if (els == NULL) {
1137 		ocs_log_err(ocs, "IO alloc failed\n");
1138 	} else {
1139 		els->els_timeout_sec = timeout_sec;
1140 		els->els_retries_remaining = retries;
1141 		els->els_callback = cb;
1142 		els->els_callback_arg = cbarg;
1143 		els->display_name = "scr";
1144 
1145 		req = els->els_req.virt;
1146 
1147 		ocs_memset(req, 0, sizeof(*req));
1148 		req->command_code = FC_ELS_CMD_RRQ;
1149 		req->function = FC_SCR_REG_FULL;
1150 
1151 		els->hio_type = OCS_HW_ELS_REQ;
1152 		els->iparam.els.timeout = timeout_sec;
1153 		ocs_io_transition(els, __ocs_els_init, NULL);
1154 	}
1155 	return els;
1156 }
1157 
1158 /**
1159  * @ingroup els_api
1160  * @brief Send an RSCN ELS command.
1161  *
1162  * <h3 class="desc">Description</h3>
1163  * Format an RSCN, and send to the \c node.
1164  *
1165  * @param node Node to which the RRQ is sent.
1166  * @param timeout_sec Command timeout, in seconds.
1167  * @param retries Number of times to retry errors before reporting a failure.
1168  * @param port_ids Pointer to port IDs
1169  * @param port_ids_count Count of port IDs
1170  * @param cb Callback function
1171  * @param cbarg Callback function arg
1172  *
1173  * @return Returns pointer to IO object, or NULL if error.
1174  */
1175 ocs_io_t *
1176 ocs_send_rscn(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
1177 	void *port_ids, uint32_t port_ids_count, els_cb_t cb, void *cbarg)
1178 {
1179 	ocs_io_t *els;
1180 	ocs_t *ocs = node->ocs;
1181 	fc_rscn_payload_t *req;
1182 	uint32_t payload_length = sizeof(fc_rscn_affected_port_id_page_t)*(port_ids_count - 1) +
1183 		sizeof(fc_rscn_payload_t);
1184 
1185 	node_els_trace();
1186 
1187 	els = ocs_els_io_alloc(node, payload_length, OCS_ELS_ROLE_ORIGINATOR);
1188 	if (els == NULL) {
1189 		ocs_log_err(ocs, "IO alloc failed\n");
1190 	} else {
1191 		els->els_timeout_sec = timeout_sec;
1192 		els->els_retries_remaining = retries;
1193 		els->els_callback = cb;
1194 		els->els_callback_arg = cbarg;
1195 		els->display_name = "rscn";
1196 
1197 		req = els->els_req.virt;
1198 
1199 		req->command_code = FC_ELS_CMD_RSCN;
1200 		req->page_length = sizeof(fc_rscn_affected_port_id_page_t);
1201 		req->payload_length = ocs_htobe16(sizeof(*req) +
1202 			sizeof(fc_rscn_affected_port_id_page_t)*(port_ids_count-1));
1203 
1204 		els->hio_type = OCS_HW_ELS_REQ;
1205 		els->iparam.els.timeout = timeout_sec;
1206 
1207 		/* copy in the payload */
1208 		ocs_memcpy(req->port_list, port_ids, port_ids_count*sizeof(fc_rscn_affected_port_id_page_t));
1209 
1210 		/* Submit the request */
1211 		ocs_io_transition(els, __ocs_els_init, NULL);
1212 	}
1213 	return els;
1214 }
1215 
1216 /**
1217  * @brief Send an LS_RJT ELS response.
1218  *
1219  * <h3 class="desc">Description</h3>
1220  * Send an LS_RJT ELS response.
1221  *
1222  * @param io Pointer to a SCSI IO object.
1223  * @param ox_id Originator exchange ID being responded to.
1224  * @param reason_code Reason code value for LS_RJT.
1225  * @param reason_code_expl Reason code explanation value for LS_RJT.
1226  * @param vendor_unique Vendor-unique value for LS_RJT.
1227  * @param cb Callback function.
1228  * @param cbarg Callback function argument.
1229  *
1230  * @return Returns pointer to IO object, or NULL if error.
1231  */
1232 
1233 ocs_io_t *
1234 ocs_send_ls_rjt(ocs_io_t *io, uint32_t ox_id, uint32_t reason_code, uint32_t reason_code_expl,
1235 		uint32_t vendor_unique, els_cb_t cb, void *cbarg)
1236 {
1237 	ocs_node_t *node = io->node;
1238 	int32_t rc;
1239 	ocs_t *ocs = node->ocs;
1240 	fc_ls_rjt_payload_t *rjt;
1241 
1242 	node_els_trace();
1243 
1244 	io->els_callback = cb;
1245 	io->els_callback_arg = cbarg;
1246 	io->display_name = "ls_rjt";
1247 	io->init_task_tag = ox_id;
1248 
1249 	ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1250 	io->iparam.els.ox_id = ox_id;
1251 
1252 	rjt = io->els_req.virt;
1253 	ocs_memset(rjt, 0, sizeof(*rjt));
1254 
1255 	rjt->command_code = FC_ELS_CMD_RJT;
1256 	rjt->reason_code = reason_code;
1257 	rjt->reason_code_exp = reason_code_expl;
1258 
1259 	io->hio_type = OCS_HW_ELS_RSP;
1260 	if ((rc = ocs_els_send_rsp(io, sizeof(*rjt)))) {
1261 		ocs_els_io_free(io);
1262 		io = NULL;
1263 	}
1264 
1265 	return io;
1266 }
1267 
1268 /**
1269  * @ingroup els_api
1270  * @brief Send a PLOGI accept response.
1271  *
1272  * <h3 class="desc">Description</h3>
1273  * Construct a PLOGI LS_ACC, and send to the \c node, using the originator exchange ID
1274  * \c ox_id.
1275  *
1276  * @param io Pointer to a SCSI IO object.
1277  * @param ox_id Originator exchange ID being responsed to.
1278  * @param cb Callback function.
1279  * @param cbarg Callback function argument.
1280  *
1281  * @return Returns pointer to IO object, or NULL if error.
1282  */
1283 ocs_io_t *
1284 ocs_send_plogi_acc(ocs_io_t *io, uint32_t ox_id, els_cb_t cb, void *cbarg)
1285 {
1286 	ocs_node_t *node = io->node;
1287 	int32_t rc;
1288 	ocs_t *ocs = node->ocs;
1289 	fc_plogi_payload_t *plogi;
1290 	fc_plogi_payload_t *req = (fc_plogi_payload_t *)node->service_params;
1291 
1292 	node_els_trace();
1293 
1294 	io->els_callback = cb;
1295 	io->els_callback_arg = cbarg;
1296 	io->display_name = "plog_acc";
1297 	io->init_task_tag = ox_id;
1298 
1299 	ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1300 	io->iparam.els.ox_id = ox_id;
1301 
1302 	plogi = io->els_req.virt;
1303 
1304 	/* copy our port's service parameters to payload */
1305 	ocs_memcpy(plogi, node->sport->service_params, sizeof(*plogi));
1306 	plogi->command_code = FC_ELS_CMD_ACC;
1307 	plogi->resv1 = 0;
1308 
1309 	/* Set Application header support bit if requested */
1310 	if (req->common_service_parameters[1] & ocs_htobe32(1U << 24)) {
1311 		plogi->common_service_parameters[1] |= ocs_htobe32(1U << 24);
1312 	}
1313 
1314 	/* Priority tagging support. */
1315 	if (req->common_service_parameters[1] & ocs_htobe32(1U << 23)) {
1316 		plogi->common_service_parameters[1] |= ocs_htobe32(1U << 23);
1317 	}
1318 
1319 	ocs_display_sparams(node->display_name, "plogi send resp", 0, NULL, plogi->common_service_parameters);
1320 
1321 	io->hio_type = OCS_HW_ELS_RSP;
1322 	if ((rc = ocs_els_send_rsp(io, sizeof(*plogi)))) {
1323 		ocs_els_io_free(io);
1324 		io = NULL;
1325 	}
1326 	return io;
1327 }
1328 
1329 /**
1330  * @ingroup els_api
1331  * @brief Send an FLOGI accept response for point-to-point negotiation.
1332  *
1333  * <h3 class="desc">Description</h3>
1334  * Construct an FLOGI accept response, and send to the \c node using the originator
1335  * exchange id \c ox_id. The \c s_id is used for the response frame source FC ID.
1336  *
1337  * @param io Pointer to a SCSI IO object.
1338  * @param ox_id Originator exchange ID for the response.
1339  * @param s_id Source FC ID to be used in the response frame.
1340  * @param cb Callback function.
1341  * @param cbarg Callback function argument.
1342  *
1343  * @return Returns pointer to IO object, or NULL if error.
1344  */
1345 ocs_io_t *
1346 ocs_send_flogi_p2p_acc(ocs_io_t *io, uint32_t ox_id, uint32_t s_id, els_cb_t cb, void *cbarg)
1347 {
1348 	ocs_node_t *node = io->node;
1349 	int32_t rc;
1350 	ocs_t *ocs = node->ocs;
1351 	fc_plogi_payload_t *flogi;
1352 
1353 	node_els_trace();
1354 
1355 	io->els_callback = cb;
1356 	io->els_callback_arg = cbarg;
1357 	io->display_name = "flogi_p2p_acc";
1358 	io->init_task_tag = ox_id;
1359 
1360 	ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1361 	io->iparam.els_sid.ox_id = ox_id;
1362 	io->iparam.els_sid.s_id = s_id;
1363 
1364 	flogi = io->els_req.virt;
1365 
1366 	/* copy our port's service parameters to payload */
1367 	ocs_memcpy(flogi, node->sport->service_params, sizeof(*flogi));
1368 	flogi->command_code = FC_ELS_CMD_ACC;
1369 	flogi->resv1 = 0;
1370 	ocs_memset(flogi->class1_service_parameters, 0, sizeof(flogi->class1_service_parameters));
1371 	ocs_memset(flogi->class2_service_parameters, 0, sizeof(flogi->class1_service_parameters));
1372 	ocs_memset(flogi->class3_service_parameters, 0, sizeof(flogi->class1_service_parameters));
1373 	ocs_memset(flogi->class4_service_parameters, 0, sizeof(flogi->class1_service_parameters));
1374 
1375 	io->hio_type = OCS_HW_ELS_RSP_SID;
1376 	if ((rc = ocs_els_send_rsp(io, sizeof(*flogi)))) {
1377 		ocs_els_io_free(io);
1378 		io = NULL;
1379 	}
1380 
1381 	return io;
1382 }
1383 
1384 ocs_io_t *
1385 ocs_send_flogi_acc(ocs_io_t *io, uint32_t ox_id, uint32_t is_fport, els_cb_t cb, void *cbarg)
1386 {
1387 	ocs_node_t *node = io->node;
1388 	int32_t rc;
1389 	ocs_t *ocs = node->ocs;
1390 	fc_plogi_payload_t *flogi;
1391 
1392 	node_els_trace();
1393 
1394 	io->els_callback = cb;
1395 	io->els_callback_arg = cbarg;
1396 	io->display_name = "flogi_acc";
1397 	io->init_task_tag = ox_id;
1398 
1399 	ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1400 	io->iparam.els_sid.ox_id = ox_id;
1401 	io->iparam.els_sid.s_id = io->node->sport->fc_id;
1402 
1403 	flogi = io->els_req.virt;
1404 
1405 	/* copy our port's service parameters to payload */
1406 	ocs_memcpy(flogi, node->sport->service_params, sizeof(*flogi));
1407 
1408 	/* Set F_port */
1409 	if (is_fport) {
1410 		/* Set F_PORT and Multiple N_PORT_ID Assignment */
1411 		flogi->common_service_parameters[1] |= ocs_be32toh(3U << 28);
1412 	}
1413 
1414 	flogi->command_code = FC_ELS_CMD_ACC;
1415 	flogi->resv1 = 0;
1416 
1417 	ocs_display_sparams(node->display_name, "flogi send resp", 0, NULL, flogi->common_service_parameters);
1418 
1419 	ocs_memset(flogi->class1_service_parameters, 0, sizeof(flogi->class1_service_parameters));
1420 	ocs_memset(flogi->class2_service_parameters, 0, sizeof(flogi->class1_service_parameters));
1421 	ocs_memset(flogi->class3_service_parameters, 0, sizeof(flogi->class1_service_parameters));
1422 	ocs_memset(flogi->class4_service_parameters, 0, sizeof(flogi->class1_service_parameters));
1423 
1424 	io->hio_type = OCS_HW_ELS_RSP_SID;
1425 	if ((rc = ocs_els_send_rsp(io, sizeof(*flogi)))) {
1426 		ocs_els_io_free(io);
1427 		io = NULL;
1428 	}
1429 
1430 	return io;
1431 }
1432 
1433 /**
1434  * @ingroup els_api
1435  * @brief Send a PRLI accept response
1436  *
1437  * <h3 class="desc">Description</h3>
1438  * Construct a PRLI LS_ACC response, and send to the \c node, using the originator
1439  * \c ox_id exchange ID.
1440  *
1441  * @param io Pointer to a SCSI IO object.
1442  * @param ox_id Originator exchange ID.
1443  * @param cb Callback function.
1444  * @param cbarg Callback function argument.
1445  *
1446  * @return Returns pointer to IO object, or NULL if error.
1447  */
1448 
1449 ocs_io_t *
1450 ocs_send_prli_acc(ocs_io_t *io, uint32_t ox_id, uint8_t fc_type, els_cb_t cb, void *cbarg)
1451 {
1452 	ocs_node_t *node = io->node;
1453 	int32_t rc;
1454 	ocs_t *ocs = node->ocs;
1455 	fc_prli_payload_t *prli;
1456 
1457 	node_els_trace();
1458 
1459 	io->els_callback = cb;
1460 	io->els_callback_arg = cbarg;
1461 	io->display_name = "prli_acc";
1462 	io->init_task_tag = ox_id;
1463 
1464 	ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1465 	io->iparam.els.ox_id = ox_id;
1466 
1467 	prli = io->els_req.virt;
1468 	ocs_memset(prli, 0, sizeof(*prli));
1469 
1470 	prli->command_code = FC_ELS_CMD_ACC;
1471 	prli->page_length = 16;
1472 	prli->payload_length = ocs_htobe16(sizeof(fc_prli_payload_t));
1473 	prli->type = fc_type;
1474 	prli->type_ext = 0;
1475 	prli->flags = ocs_htobe16(FC_PRLI_ESTABLISH_IMAGE_PAIR | FC_PRLI_REQUEST_EXECUTED);
1476 
1477 	prli->service_params = ocs_htobe16(FC_PRLI_READ_XRDY_DISABLED |
1478 				(node->sport->enable_ini ? FC_PRLI_INITIATOR_FUNCTION : 0) |
1479 				(node->sport->enable_tgt ? FC_PRLI_TARGET_FUNCTION : 0));
1480 
1481 	io->hio_type = OCS_HW_ELS_RSP;
1482 	if ((rc = ocs_els_send_rsp(io, sizeof(*prli)))) {
1483 		ocs_els_io_free(io);
1484 		io = NULL;
1485 	}
1486 
1487 	return io;
1488 }
1489 
1490 /**
1491  * @ingroup els_api
1492  * @brief Send a PRLO accept response.
1493  *
1494  * <h3 class="desc">Description</h3>
1495  * Construct a PRLO LS_ACC response, and send to the \c node, using the originator
1496  * exchange ID \c ox_id.
1497  *
1498  * @param io Pointer to a SCSI IO object.
1499  * @param ox_id Originator exchange ID.
1500  * @param cb Callback function.
1501  * @param cbarg Callback function argument.
1502  *
1503  * @return Returns pointer to IO object, or NULL if error.
1504  */
1505 
1506 ocs_io_t *
1507 ocs_send_prlo_acc(ocs_io_t *io, uint32_t ox_id, uint8_t fc_type, els_cb_t cb, void *cbarg)
1508 {
1509 	ocs_node_t *node = io->node;
1510 	int32_t rc;
1511 	ocs_t *ocs = node->ocs;
1512 	fc_prlo_acc_payload_t *prlo_acc;
1513 
1514 	node_els_trace();
1515 
1516 	io->els_callback = cb;
1517 	io->els_callback_arg = cbarg;
1518 	io->display_name = "prlo_acc";
1519 	io->init_task_tag = ox_id;
1520 
1521 	ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1522 	io->iparam.els.ox_id = ox_id;
1523 
1524 	prlo_acc = io->els_req.virt;
1525 	ocs_memset(prlo_acc, 0, sizeof(*prlo_acc));
1526 
1527 	prlo_acc->command_code = FC_ELS_CMD_ACC;
1528 	prlo_acc->page_length = 16;
1529 	prlo_acc->payload_length = ocs_htobe16(sizeof(fc_prlo_acc_payload_t));
1530 	prlo_acc->type = fc_type;
1531 	prlo_acc->type_ext = 0;
1532 	prlo_acc->response_code = FC_PRLO_REQUEST_EXECUTED;
1533 
1534 	io->hio_type = OCS_HW_ELS_RSP;
1535 	if ((rc = ocs_els_send_rsp(io, sizeof(*prlo_acc)))) {
1536 		ocs_els_io_free(io);
1537 		io = NULL;
1538 	}
1539 
1540 	return io;
1541 }
1542 
1543 /**
1544  * @ingroup els_api
1545  * @brief Send a generic LS_ACC response without a payload.
1546  *
1547  * <h3 class="desc">Description</h3>
1548  * A generic LS_ACC response is sent to the \c node using the originator exchange ID
1549  * \c ox_id.
1550  *
1551  * @param io Pointer to a SCSI IO object.
1552  * @param ox_id Originator exchange id.
1553  * @param cb Callback function.
1554  * @param cbarg Callback function argument.
1555  *
1556  * @return Returns pointer to IO object, or NULL if error.
1557  */
1558 ocs_io_t *
1559 ocs_send_ls_acc(ocs_io_t *io, uint32_t ox_id, els_cb_t cb, void *cbarg)
1560 {
1561 	ocs_node_t *node = io->node;
1562 	int32_t rc;
1563 	ocs_t *ocs = node->ocs;
1564 	fc_acc_payload_t *acc;
1565 
1566 	node_els_trace();
1567 
1568 	io->els_callback = cb;
1569 	io->els_callback_arg = cbarg;
1570 	io->display_name = "ls_acc";
1571 	io->init_task_tag = ox_id;
1572 
1573 	ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1574 	io->iparam.els.ox_id = ox_id;
1575 
1576 	acc = io->els_req.virt;
1577 	ocs_memset(acc, 0, sizeof(*acc));
1578 
1579 	acc->command_code = FC_ELS_CMD_ACC;
1580 
1581 	io->hio_type = OCS_HW_ELS_RSP;
1582 	if ((rc = ocs_els_send_rsp(io, sizeof(*acc)))) {
1583 		ocs_els_io_free(io);
1584 		io = NULL;
1585 	}
1586 
1587 	return io;
1588 }
1589 
1590 /**
1591  * @ingroup els_api
1592  * @brief Send a LOGO accept response.
1593  *
1594  * <h3 class="desc">Description</h3>
1595  * Construct a LOGO LS_ACC response, and send to the \c node, using the originator
1596  * exchange ID \c ox_id.
1597  *
1598  * @param io Pointer to a SCSI IO object.
1599  * @param ox_id Originator exchange ID.
1600  * @param cb Callback function.
1601  * @param cbarg Callback function argument.
1602  *
1603  * @return Returns pointer to IO object, or NULL if error.
1604  */
1605 ocs_io_t *
1606 ocs_send_logo_acc(ocs_io_t *io, uint32_t ox_id, els_cb_t cb, void *cbarg)
1607 {
1608 	ocs_node_t *node = io->node;
1609 	int32_t rc;
1610 	ocs_t *ocs = node->ocs;
1611 	fc_acc_payload_t *logo;
1612 
1613 	node_els_trace();
1614 
1615 	io->els_callback = cb;
1616 	io->els_callback_arg = cbarg;
1617 	io->display_name = "logo_acc";
1618 	io->init_task_tag = ox_id;
1619 
1620 	ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1621 	io->iparam.els.ox_id = ox_id;
1622 
1623 	logo = io->els_req.virt;
1624 	ocs_memset(logo, 0, sizeof(*logo));
1625 
1626 	logo->command_code = FC_ELS_CMD_ACC;
1627 	logo->resv1 = 0;
1628 
1629 	io->hio_type = OCS_HW_ELS_RSP;
1630 	if ((rc = ocs_els_send_rsp(io, sizeof(*logo)))) {
1631 		ocs_els_io_free(io);
1632 		io = NULL;
1633 	}
1634 
1635 	return io;
1636 }
1637 
1638 /**
1639  * @ingroup els_api
1640  * @brief Send an ADISC accept response.
1641  *
1642  * <h3 class="desc">Description</h3>
1643  * Construct an ADISC LS__ACC, and send to the \c node, using the originator
1644  * exchange id \c ox_id.
1645  *
1646  * @param io Pointer to a SCSI IO object.
1647  * @param ox_id Originator exchange ID.
1648  * @param cb Callback function.
1649  * @param cbarg Callback function argument.
1650  *
1651  * @return Returns pointer to IO object, or NULL if error.
1652  */
1653 
1654 ocs_io_t *
1655 ocs_send_adisc_acc(ocs_io_t *io, uint32_t ox_id, els_cb_t cb, void *cbarg)
1656 {
1657 	ocs_node_t *node = io->node;
1658 	int32_t rc;
1659 	fc_adisc_payload_t *adisc;
1660 	fc_plogi_payload_t *sparams;
1661 	ocs_t *ocs;
1662 
1663 	ocs_assert(node, NULL);
1664 	ocs_assert(node->ocs, NULL);
1665 	ocs = node->ocs;
1666 
1667 	node_els_trace();
1668 
1669 	io->els_callback = cb;
1670 	io->els_callback_arg = cbarg;
1671 	io->display_name = "adisc_acc";
1672 	io->init_task_tag = ox_id;
1673 
1674 	/* Go ahead and send the ELS_ACC */
1675 	ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1676 	io->iparam.els.ox_id = ox_id;
1677 
1678 	sparams = (fc_plogi_payload_t*) node->sport->service_params;
1679 	adisc = io->els_req.virt;
1680 	ocs_memset(adisc, 0, sizeof(fc_adisc_payload_t));
1681 	adisc->command_code = FC_ELS_CMD_ACC;
1682 	adisc->hard_address = 0;
1683 	adisc->port_name_hi = sparams->port_name_hi;
1684 	adisc->port_name_lo = sparams->port_name_lo;
1685 	adisc->node_name_hi = sparams->node_name_hi;
1686 	adisc->node_name_lo = sparams->node_name_lo;
1687 	adisc->port_id = fc_htobe24(node->rnode.sport->fc_id);
1688 
1689 	io->hio_type = OCS_HW_ELS_RSP;
1690 	if ((rc = ocs_els_send_rsp(io, sizeof(*adisc)))) {
1691 		ocs_els_io_free(io);
1692 		io = NULL;
1693 	}
1694 
1695 	return io;
1696 }
1697 
1698 /**
1699  * @ingroup els_api
1700  * @brief Send a RFTID CT request.
1701  *
1702  * <h3 class="desc">Description</h3>
1703  * Construct an RFTID CT request, and send to the \c node.
1704  *
1705  * @param node Node to which the RFTID request is sent.
1706  * @param timeout_sec Time, in seconds, to wait before timing out the ELS.
1707  * @param retries Number of times to retry errors before reporting a failure.
1708  * @param cb Callback function.
1709  * @param cbarg Callback function argument.
1710  *
1711  * @return Returns pointer to IO object, or NULL if error.
1712  */
1713 ocs_io_t *
1714 ocs_ns_send_rftid(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
1715 	els_cb_t cb, void *cbarg)
1716 {
1717 	ocs_io_t *els;
1718 	ocs_t *ocs = node->ocs;
1719 	fcct_rftid_req_t *rftid;
1720 
1721 	node_els_trace();
1722 
1723 	els = ocs_els_io_alloc(node, sizeof(*rftid), OCS_ELS_ROLE_ORIGINATOR);
1724 	if (els == NULL) {
1725 		ocs_log_err(ocs, "IO alloc failed\n");
1726 	} else {
1727 
1728 		els->iparam.fc_ct.r_ctl = FC_RCTL_ELS;
1729 		els->iparam.fc_ct.type = FC_TYPE_GS;
1730 		els->iparam.fc_ct.df_ctl = 0;
1731 		els->iparam.fc_ct.timeout = timeout_sec;
1732 
1733 		els->els_callback = cb;
1734 		els->els_callback_arg = cbarg;
1735 		els->display_name = "rftid";
1736 
1737 		rftid = els->els_req.virt;
1738 
1739 		ocs_memset(rftid, 0, sizeof(*rftid));
1740 		fcct_build_req_header(&rftid->hdr, FC_GS_NAMESERVER_RFT_ID, (OCS_ELS_RSP_LEN - sizeof(rftid->hdr)));
1741 		rftid->port_id = ocs_htobe32(node->rnode.sport->fc_id);
1742 		rftid->fc4_types[FC_GS_TYPE_WORD(FC_TYPE_FCP)] = ocs_htobe32(1 << FC_GS_TYPE_BIT(FC_TYPE_FCP));
1743 
1744 		els->hio_type = OCS_HW_FC_CT;
1745 
1746 		ocs_io_transition(els, __ocs_els_init, NULL);
1747 	}
1748 	return els;
1749 }
1750 
1751 /**
1752  * @ingroup els_api
1753  * @brief Send a RFFID CT request.
1754  *
1755  * <h3 class="desc">Description</h3>
1756  * Construct an RFFID CT request, and send to the \c node.
1757  *
1758  * @param node Node to which the RFFID request is sent.
1759  * @param timeout_sec Time, in seconds, to wait before timing out the ELS.
1760  * @param retries Number of times to retry errors before reporting a failure.
1761  * @param cb Callback function
1762  * @param cbarg Callback function argument.
1763  *
1764  * @return Returns pointer to IO object, or NULL if error.
1765  */
1766 ocs_io_t *
1767 ocs_ns_send_rffid(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
1768 	els_cb_t cb, void *cbarg)
1769 {
1770 	ocs_io_t *els;
1771 	ocs_t *ocs = node->ocs;
1772 	fcct_rffid_req_t *rffid;
1773 
1774 	node_els_trace();
1775 
1776 	els = ocs_els_io_alloc(node, sizeof(*rffid), OCS_ELS_ROLE_ORIGINATOR);
1777 	if (els == NULL) {
1778 		ocs_log_err(ocs, "IO alloc failed\n");
1779 	} else {
1780 
1781 		els->iparam.fc_ct.r_ctl = FC_RCTL_ELS;
1782 		els->iparam.fc_ct.type = FC_TYPE_GS;
1783 		els->iparam.fc_ct.df_ctl = 0;
1784 		els->iparam.fc_ct.timeout = timeout_sec;
1785 
1786 		els->els_callback = cb;
1787 		els->els_callback_arg = cbarg;
1788 		els->display_name = "rffid";
1789 
1790 		rffid = els->els_req.virt;
1791 
1792 		ocs_memset(rffid, 0, sizeof(*rffid));
1793 
1794 		fcct_build_req_header(&rffid->hdr, FC_GS_NAMESERVER_RFF_ID, (OCS_ELS_RSP_LEN - sizeof(rffid->hdr)));
1795 		rffid->port_id = ocs_htobe32(node->rnode.sport->fc_id);
1796 		if (node->sport->enable_ini) {
1797 			rffid->fc4_feature_bits |= FC4_FEATURE_INITIATOR;
1798 		}
1799 		if (node->sport->enable_tgt) {
1800 			rffid->fc4_feature_bits |= FC4_FEATURE_TARGET;
1801 		}
1802 		rffid->type = FC_TYPE_FCP;
1803 
1804 		els->hio_type = OCS_HW_FC_CT;
1805 
1806 		ocs_io_transition(els, __ocs_els_init, NULL);
1807 	}
1808 	return els;
1809 }
1810 
1811 
1812 /**
1813  * @ingroup els_api
1814  * @brief Send a GIDPT CT request.
1815  *
1816  * <h3 class="desc">Description</h3>
1817  * Construct a GIDPT CT request, and send to the \c node.
1818  *
1819  * @param node Node to which the GIDPT request is sent.
1820  * @param timeout_sec Time, in seconds, to wait before timing out the ELS.
1821  * @param retries Number of times to retry errors before reporting a failure.
1822  * @param cb Callback function.
1823  * @param cbarg Callback function argument.
1824  *
1825  * @return Returns pointer to IO object, or NULL if error.
1826  */
1827 
1828 ocs_io_t *
1829 ocs_ns_send_gidpt(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
1830 	els_cb_t cb, void *cbarg)
1831 {
1832 	ocs_io_t *els;
1833 	ocs_t *ocs = node->ocs;
1834 	fcct_gidpt_req_t *gidpt;
1835 
1836 	node_els_trace();
1837 
1838 	els = ocs_els_io_alloc_size(node, sizeof(*gidpt), OCS_ELS_GID_PT_RSP_LEN, OCS_ELS_ROLE_ORIGINATOR);
1839 	if (els == NULL) {
1840 		ocs_log_err(ocs, "IO alloc failed\n");
1841 	} else {
1842 
1843 		els->iparam.fc_ct.r_ctl = FC_RCTL_ELS;
1844 		els->iparam.fc_ct.type = FC_TYPE_GS;
1845 		els->iparam.fc_ct.df_ctl = 0;
1846 		els->iparam.fc_ct.timeout = timeout_sec;
1847 
1848 		els->els_callback = cb;
1849 		els->els_callback_arg = cbarg;
1850 		els->display_name = "gidpt";
1851 
1852 		gidpt = els->els_req.virt;
1853 
1854 		ocs_memset(gidpt, 0, sizeof(*gidpt));
1855 		fcct_build_req_header(&gidpt->hdr, FC_GS_NAMESERVER_GID_PT, (OCS_ELS_GID_PT_RSP_LEN - sizeof(gidpt->hdr)) );
1856 		gidpt->domain_id_scope = 0;
1857 		gidpt->area_id_scope = 0;
1858 		gidpt->port_type = 0x7f;
1859 
1860 		els->hio_type = OCS_HW_FC_CT;
1861 
1862 		ocs_io_transition(els, __ocs_els_init, NULL);
1863 	}
1864 	return els;
1865 }
1866 
1867 /**
1868  * @ingroup els_api
1869  * @brief Send a BA_ACC given the request's FC header
1870  *
1871  * <h3 class="desc">Description</h3>
1872  * Using the S_ID/D_ID from the request's FC header, generate a BA_ACC.
1873  *
1874  * @param io Pointer to a SCSI IO object.
1875  * @param hdr Pointer to the FC header.
1876  *
1877  * @return Returns pointer to IO object, or NULL if error.
1878  */
1879 
1880 ocs_io_t *
1881 ocs_bls_send_acc_hdr(ocs_io_t *io, fc_header_t *hdr)
1882 {
1883 	uint16_t ox_id = ocs_be16toh(hdr->ox_id);
1884 	uint16_t rx_id = ocs_be16toh(hdr->rx_id);
1885 	uint32_t d_id = fc_be24toh(hdr->d_id);
1886 
1887 	return ocs_bls_send_acc(io, d_id, ox_id, rx_id);
1888 }
1889 
1890 /**
1891  * @ingroup els_api
1892  * @brief Send a BLS BA_ACC response.
1893  *
1894  * <h3 class="desc">Description</h3>
1895  * Construct a BLS BA_ACC response, and send to the \c node.
1896  *
1897  * @param io Pointer to a SCSI IO object.
1898  * @param s_id S_ID to use for the response. If UINT32_MAX, then use our SLI port
1899  * (sport) S_ID.
1900  * @param ox_id Originator exchange ID.
1901  * @param rx_id Responder exchange ID.
1902  *
1903  * @return Returns pointer to IO object, or NULL if error.
1904  */
1905 
1906 static ocs_io_t *
1907 ocs_bls_send_acc(ocs_io_t *io, uint32_t s_id, uint16_t ox_id, uint16_t rx_id)
1908 {
1909 	ocs_node_t *node = io->node;
1910 	int32_t rc;
1911 	fc_ba_acc_payload_t *acc;
1912 	ocs_t *ocs;
1913 
1914 	ocs_assert(node, NULL);
1915 	ocs_assert(node->ocs, NULL);
1916 	ocs = node->ocs;
1917 
1918 	if (node->rnode.sport->fc_id == s_id) {
1919 		s_id = UINT32_MAX;
1920 	}
1921 
1922 	/* fill out generic fields */
1923 	io->ocs = ocs;
1924 	io->node = node;
1925 	io->cmd_tgt = TRUE;
1926 
1927 	/* fill out BLS Response-specific fields */
1928 	io->io_type = OCS_IO_TYPE_BLS_RESP;
1929 	io->display_name = "ba_acc";
1930 	io->hio_type = OCS_HW_BLS_ACC_SID;
1931 	io->init_task_tag = ox_id;
1932 
1933 	/* fill out iparam fields */
1934 	ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1935 	io->iparam.bls_sid.s_id = s_id;
1936 	io->iparam.bls_sid.ox_id = ox_id;
1937 	io->iparam.bls_sid.rx_id = rx_id;
1938 
1939 	acc = (void *)io->iparam.bls_sid.payload;
1940 
1941 	ocs_memset(io->iparam.bls_sid.payload, 0, sizeof(io->iparam.bls_sid.payload));
1942 	acc->ox_id = io->iparam.bls_sid.ox_id;
1943 	acc->rx_id = io->iparam.bls_sid.rx_id;
1944 	acc->high_seq_cnt = UINT16_MAX;
1945 
1946 	if ((rc = ocs_scsi_io_dispatch(io, ocs_bls_send_acc_cb))) {
1947 		ocs_log_err(ocs, "ocs_scsi_io_dispatch() failed: %d\n", rc);
1948 		ocs_scsi_io_free(io);
1949 		io = NULL;
1950 	}
1951 	return io;
1952 }
1953 
1954 /**
1955  * @brief Handle the BLS accept completion.
1956  *
1957  * <h3 class="desc">Description</h3>
1958  * Upon completion of sending a BA_ACC, this callback is invoked by the HW.
1959  *
1960  * @param hio Pointer to the HW IO object.
1961  * @param rnode Pointer to the HW remote node.
1962  * @param length Length of the response payload, in bytes.
1963  * @param status Completion status.
1964  * @param ext_status Extended completion status.
1965  * @param app Callback private argument.
1966  *
1967  * @return Returns 0 on success; or a negative error value on failure.
1968  */
1969 
1970 static int32_t
1971 ocs_bls_send_acc_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *app)
1972 {
1973 	ocs_io_t *io = app;
1974 
1975 	ocs_assert(io, -1);
1976 
1977 	ocs_scsi_io_free(io);
1978 	return 0;
1979 }
1980 
1981 /**
1982  * @brief ELS abort callback.
1983  *
1984  * <h3 class="desc">Description</h3>
1985  * This callback is invoked by the HW when an ELS IO is aborted.
1986  *
1987  * @param hio Pointer to the HW IO object.
1988  * @param rnode Pointer to the HW remote node.
1989  * @param length Length of the response payload, in bytes.
1990  * @param status Completion status.
1991  * @param ext_status Extended completion status.
1992  * @param app Callback private argument.
1993  *
1994  * @return Returns 0 on success; or a negative error value on failure.
1995  */
1996 
1997 static int32_t
1998 ocs_els_abort_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *app)
1999 {
2000 	ocs_io_t *els;
2001 	ocs_io_t *abort_io = NULL; /* IO structure used to abort ELS */
2002 	ocs_t *ocs;
2003 
2004 	ocs_assert(app, -1);
2005 	abort_io = app;
2006 	els = abort_io->io_to_abort;
2007 	ocs_assert(els->node, -1);
2008 	ocs_assert(els->node->ocs, -1);
2009 
2010 	ocs = els->node->ocs;
2011 
2012 	if (status != 0) {
2013 		ocs_log_warn(ocs, "status x%x ext x%x\n", status, ext_status);
2014 	}
2015 
2016 	/* now free the abort IO */
2017 	ocs_io_free(ocs, abort_io);
2018 
2019 	/* send completion event to indicate abort process is complete
2020 	 * Note: The ELS SM will already be receiving ELS_REQ_OK/FAIL/RJT/ABORTED
2021 	 */
2022 	ocs_els_post_event(els, OCS_EVT_ELS_ABORT_CMPL, NULL);
2023 
2024 	/* done with ELS IO to abort */
2025 	ocs_ref_put(&els->ref); /* ocs_ref_get(): ocs_els_abort_io() */
2026 	return 0;
2027 }
2028 
2029 /**
2030  * @brief Abort an ELS IO.
2031  *
2032  * <h3 class="desc">Description</h3>
2033  * The ELS IO is aborted by making a HW abort IO request,
2034  * optionally requesting that an ABTS is sent.
2035  *
2036  * \b Note: This function allocates a HW IO, and associates the HW IO
2037  * with the ELS IO that it is aborting. It does not associate
2038  * the HW IO with the node directly, like for ELS requests. The
2039  * abort completion is propagated up to the node once the
2040  * original WQE and the abort WQE are complete (the original WQE
2041  * completion is not propagated up to node).
2042  *
2043  * @param els Pointer to the ELS IO.
2044  * @param send_abts Boolean to indicate if hardware will automatically generate an ABTS.
2045  *
2046  * @return Returns pointer to Abort IO object, or NULL if error.
2047  */
2048 
2049 static ocs_io_t *
2050 ocs_els_abort_io(ocs_io_t *els, int send_abts)
2051 {
2052 	ocs_t *ocs;
2053 	ocs_xport_t *xport;
2054 	int32_t rc;
2055 	ocs_io_t *abort_io = NULL;
2056 
2057 	ocs_assert(els, NULL);
2058 	ocs_assert(els->node, NULL);
2059 	ocs_assert(els->node->ocs, NULL);
2060 
2061 	ocs = els->node->ocs;
2062 	ocs_assert(ocs->xport, NULL);
2063 	xport = ocs->xport;
2064 
2065 	/* take a reference on IO being aborted */
2066 	if ((ocs_ref_get_unless_zero(&els->ref) == 0)) {
2067 		/* command no longer active */
2068 		ocs_log_debug(ocs, "els no longer active\n");
2069 		return NULL;
2070 	}
2071 
2072 	/* allocate IO structure to send abort */
2073 	abort_io = ocs_io_alloc(ocs);
2074 	if (abort_io == NULL) {
2075 		ocs_atomic_add_return(&xport->io_alloc_failed_count, 1);
2076 	} else {
2077 		ocs_assert(abort_io->hio == NULL, NULL);
2078 
2079 		/* set generic fields */
2080 		abort_io->ocs = ocs;
2081 		abort_io->node = els->node;
2082 		abort_io->cmd_ini = TRUE;
2083 
2084 		/* set type and ABORT-specific fields */
2085 		abort_io->io_type = OCS_IO_TYPE_ABORT;
2086 		abort_io->display_name = "abort_els";
2087 		abort_io->io_to_abort = els;
2088 		abort_io->send_abts = send_abts;
2089 
2090 		/* now dispatch IO */
2091 		if ((rc = ocs_scsi_io_dispatch_abort(abort_io, ocs_els_abort_cb))) {
2092 			ocs_log_err(ocs, "ocs_scsi_io_dispatch failed: %d\n", rc);
2093 			ocs_io_free(ocs, abort_io);
2094 			abort_io = NULL;
2095 		}
2096 	}
2097 
2098 	/* if something failed, put reference on ELS to abort */
2099 	if (abort_io == NULL) {
2100 		ocs_ref_put(&els->ref); /* ocs_ref_get(): same function */
2101 	}
2102 	return abort_io;
2103 }
2104 
2105 
2106 /*
2107  * ELS IO State Machine
2108  */
2109 
2110 #define std_els_state_decl(...) \
2111 	ocs_io_t *els = NULL; \
2112 	ocs_node_t *node = NULL; \
2113 	ocs_t *ocs = NULL; \
2114 	ocs_assert(ctx != NULL, NULL); \
2115 	els = ctx->app; \
2116 	ocs_assert(els != NULL, NULL); \
2117 	node = els->node; \
2118 	ocs_assert(node != NULL, NULL); \
2119 	ocs = node->ocs; \
2120 	ocs_assert(ocs != NULL, NULL);
2121 
2122 #define els_sm_trace(...) \
2123 	do { \
2124 		if (OCS_LOG_ENABLE_ELS_TRACE(ocs)) \
2125 			ocs_log_info(ocs, "[%s] %-8s %-20s %-20s\n", node->display_name, els->display_name, \
2126 				__func__, ocs_sm_event_name(evt)); \
2127 	} while (0)
2128 
2129 
2130 /**
2131  * @brief Cleanup an ELS IO
2132  *
2133  * <h3 class="desc">Description</h3>
2134  * Cleans up an ELS IO by posting the requested event to the owning node object;
2135  * invoking the callback, if one is provided; and then freeing the
2136  * ELS IO object.
2137  *
2138  * @param els Pointer to the ELS IO.
2139  * @param node_evt Node SM event to post.
2140  * @param arg Node SM event argument.
2141  *
2142  * @return None.
2143  */
2144 
2145 void
2146 ocs_els_io_cleanup(ocs_io_t *els, ocs_sm_event_t node_evt, void *arg)
2147 {
2148 	ocs_assert(els);
2149 
2150 	/* don't want further events that could come; e.g. abort requests
2151 	 * from the node state machine; thus, disable state machine
2152 	 */
2153 	ocs_sm_disable(&els->els_sm);
2154 	ocs_node_post_event(els->node, node_evt, arg);
2155 
2156 	/* If this IO has a callback, invoke it */
2157 	if (els->els_callback) {
2158 		(*els->els_callback)(els->node, arg, els->els_callback_arg);
2159 	}
2160 	els->els_req_free = 1;
2161 }
2162 
2163 
2164 /**
2165  * @brief Common event handler for the ELS IO state machine.
2166  *
2167  * <h3 class="desc">Description</h3>
2168  * Provide handler for events for which default actions are desired.
2169  *
2170  * @param funcname Name of the calling function (for logging).
2171  * @param ctx Remote node SM context.
2172  * @param evt Event to process.
2173  * @param arg Per event optional argument.
2174  *
2175  * @return Returns NULL.
2176  */
2177 
2178 void *
2179 __ocs_els_common(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2180 {
2181 	std_els_state_decl();
2182 
2183 	switch(evt) {
2184 	case OCS_EVT_ENTER:
2185 	case OCS_EVT_REENTER:
2186 	case OCS_EVT_EXIT:
2187 		break;
2188 
2189 	/* If ELS_REQ_FAIL is not handled in state, then we'll terminate this ELS and
2190 	 * pass the event to the node
2191 	 */
2192 	case OCS_EVT_SRRS_ELS_REQ_FAIL:
2193 		ocs_log_warn(els->node->ocs, "[%s] %-20s %-20s not handled - terminating ELS\n", node->display_name, funcname,
2194 			ocs_sm_event_name(evt));
2195 		ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, arg);
2196 		break;
2197 	default:
2198 		ocs_log_warn(els->node->ocs, "[%s] %-20s %-20s not handled\n", node->display_name, funcname,
2199 			ocs_sm_event_name(evt));
2200 		break;
2201 	}
2202 	return NULL;
2203 }
2204 
2205 /**
2206  * @brief Initial ELS IO state
2207  *
2208  * <h3 class="desc">Description</h3>
2209  * This is the initial ELS IO state. Upon entry, the requested ELS/CT is submitted to
2210  * the hardware.
2211  *
2212  * @param ctx Remote node SM context.
2213  * @param evt Event to process.
2214  * @param arg Per event optional argument.
2215  *
2216  * @return Returns NULL.
2217  */
2218 
2219 void *
2220 __ocs_els_init(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2221 {
2222 	int32_t rc = 0;
2223 	std_els_state_decl();
2224 
2225 	els_sm_trace();
2226 
2227 	switch(evt) {
2228 	case OCS_EVT_ENTER: {
2229 		rc = ocs_els_send(els, els->els_req.size, els->els_timeout_sec, ocs_els_req_cb);
2230 		if (rc) {
2231 			ocs_node_cb_t cbdata;
2232 			cbdata.status = cbdata.ext_status = (~0);
2233 			cbdata.els = els;
2234 			ocs_log_err(ocs, "ocs_els_send failed: %d\n", rc);
2235 			ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &cbdata);
2236 		} else {
2237 			ocs_io_transition(els, __ocs_els_wait_resp, NULL);
2238 		}
2239 		break;
2240 	}
2241 	default:
2242 		__ocs_els_common(__func__, ctx, evt, arg);
2243 		break;
2244 	}
2245 
2246 	return NULL;
2247 }
2248 
2249 /**
2250  * @brief Wait for the ELS request to complete.
2251  *
2252  * <h3 class="desc">Description</h3>
2253  * This is the ELS IO state that waits for the submitted ELS event to complete.
2254  * If an error completion event is received, the requested ELS is aborted.
2255  *
2256  * @param ctx Remote node SM context.
2257  * @param evt Event to process.
2258  * @param arg Per event optional argument.
2259  *
2260  * @return Returns NULL.
2261  */
2262 
2263 void *
2264 __ocs_els_wait_resp(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2265 {
2266 	ocs_io_t *io;
2267 	std_els_state_decl();
2268 
2269 	els_sm_trace();
2270 
2271 	switch(evt) {
2272 	case OCS_EVT_SRRS_ELS_REQ_OK: {
2273 		ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_OK, arg);
2274 		break;
2275 	}
2276 
2277 	case OCS_EVT_SRRS_ELS_REQ_FAIL: {
2278 		ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, arg);
2279 		break;
2280 	}
2281 
2282 	case OCS_EVT_ELS_REQ_TIMEOUT: {
2283 		els_io_printf(els, "Timed out, retry (%d tries remaining)\n",
2284 				els->els_retries_remaining-1);
2285 		ocs_io_transition(els, __ocs_els_retry, NULL);
2286 		break;
2287 	}
2288 
2289 	case OCS_EVT_SRRS_ELS_REQ_RJT: {
2290 		ocs_node_cb_t *cbdata = arg;
2291 		uint32_t reason_code = (cbdata->ext_status >> 16) & 0xff;
2292 
2293 		/* delay and retry if reason code is Logical Busy */
2294 		switch (reason_code) {
2295 		case FC_REASON_LOGICAL_BUSY:
2296 			els->node->els_req_cnt--;
2297 			els_io_printf(els, "LS_RJT Logical Busy response, delay and retry\n");
2298 			ocs_io_transition(els, __ocs_els_delay_retry, NULL);
2299 			break;
2300 		default:
2301 			ocs_els_io_cleanup(els, evt, arg);
2302 			break;
2303 		}
2304 		break;
2305 	}
2306 
2307 	case OCS_EVT_ABORT_ELS: {
2308 		/* request to abort this ELS without an ABTS */
2309 		els_io_printf(els, "ELS abort requested\n");
2310 		els->els_retries_remaining = 0;		/* Set retries to zero, we are done */
2311 		io = ocs_els_abort_io(els, FALSE);
2312 		if (io == NULL) {
2313 			ocs_log_err(ocs, "ocs_els_send failed\n");
2314 			ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, arg);
2315 		} else {
2316 			ocs_io_transition(els, __ocs_els_aborting, NULL);
2317 		}
2318 		break;
2319 	}
2320 
2321 	default:
2322 		__ocs_els_common(__func__, ctx, evt, arg);
2323 		break;
2324 	}
2325 	return NULL;
2326 }
2327 
2328 /**
2329  * @brief Wait for the ELS IO abort request to complete, and retry the ELS.
2330  *
2331  * <h3 class="desc">Description</h3>
2332  * This state is entered when waiting for an abort of an ELS
2333  * request to complete so the request can be retried.
2334  *
2335  * @param ctx Remote node SM context.
2336  * @param evt Event to process.
2337  * @param arg Per event optional argument.
2338  *
2339  * @return Returns NULL.
2340  */
2341 
2342 void *
2343 __ocs_els_retry(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2344 {
2345 	int32_t rc = 0;
2346 	std_els_state_decl();
2347 
2348 	els_sm_trace();
2349 
2350 	switch(evt) {
2351 	case OCS_EVT_ENTER: {
2352 		/* handle event for ABORT_XRI WQE
2353 		 * once abort is complete, retry if retries left;
2354 		 * don't need to wait for OCS_EVT_SRRS_ELS_REQ_* event because we got
2355 		 * by receiving OCS_EVT_ELS_REQ_TIMEOUT
2356 		 */
2357 		ocs_node_cb_t node_cbdata;
2358 		node_cbdata.status = node_cbdata.ext_status = (~0);
2359 		node_cbdata.els = els;
2360 		if (els->els_retries_remaining && --els->els_retries_remaining) {
2361 			/* Use a different XRI for the retry (would like a new oxid),
2362 			 * so free the HW IO (dispatch will allocate a new one). It's an
2363 			 * optimization to only free the HW IO here and not the ocs_io_t;
2364 			 * Freeing the ocs_io_t object would require copying all the necessary
2365 			 * info from the old ocs_io_t object to the * new one; and allocating
2366 			 * a new ocs_io_t could fail.
2367 			 */
2368 			ocs_assert(els->hio, NULL);
2369 			ocs_hw_io_free(&ocs->hw, els->hio);
2370 			els->hio = NULL;
2371 
2372 			/* result isn't propagated up to node sm, need to decrement req cnt */
2373 			ocs_assert(els->node->els_req_cnt, NULL);
2374 			els->node->els_req_cnt--;
2375 			rc = ocs_els_send(els, els->els_req.size, els->els_timeout_sec, ocs_els_req_cb);
2376 			if (rc) {
2377 				ocs_log_err(ocs, "ocs_els_send failed: %d\n", rc);
2378 				ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &node_cbdata);
2379 			}
2380 			ocs_io_transition(els, __ocs_els_wait_resp, NULL);
2381 		} else {
2382 			els_io_printf(els, "Retries exhausted\n");
2383 			ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &node_cbdata);
2384 		}
2385 		break;
2386 	}
2387 
2388 	default:
2389 		__ocs_els_common(__func__, ctx, evt, arg);
2390 		break;
2391 	}
2392 	return NULL;
2393 }
2394 
2395 /**
2396  * @brief Wait for a retry timer to expire having received an abort request
2397  *
2398  * <h3 class="desc">Description</h3>
2399  * This state is entered when waiting for a timer event, after having received
2400  * an abort request, to avoid a race condition with the timer handler
2401  *
2402  * @param ctx Remote node SM context.
2403  * @param evt Event to process.
2404  * @param arg Per event optional argument.
2405  *
2406  * @return Returns NULL.
2407  */
2408 void *
2409 __ocs_els_aborted_delay_retry(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2410 {
2411 	std_els_state_decl();
2412 
2413 	els_sm_trace();
2414 
2415 	switch(evt) {
2416 	case OCS_EVT_ENTER:
2417 		/* mod/resched the timer for a short duration */
2418 		ocs_mod_timer(&els->delay_timer, 1);
2419 		break;
2420 	case OCS_EVT_TIMER_EXPIRED:
2421 		/* Cancel the timer, skip post node event, and free the io */
2422 		node->els_req_cnt++;
2423 		ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, arg);
2424 		break;
2425 	default:
2426 		__ocs_els_common(__func__, ctx, evt, arg);
2427 		break;
2428 	}
2429 	return NULL;
2430 }
2431 
2432 /**
2433  * @brief Wait for a retry timer to expire
2434  *
2435  * <h3 class="desc">Description</h3>
2436  * This state is entered when waiting for a timer event, so that
2437  * the ELS request can be retried.
2438  *
2439  * @param ctx Remote node SM context.
2440  * @param evt Event to process.
2441  * @param arg Per event optional argument.
2442  *
2443  * @return Returns NULL.
2444  */
2445 void *
2446 __ocs_els_delay_retry(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2447 {
2448 	std_els_state_decl();
2449 
2450 	els_sm_trace();
2451 
2452 	switch(evt) {
2453 	case OCS_EVT_ENTER:
2454 		ocs_setup_timer(ocs, &els->delay_timer, ocs_els_delay_timer_cb, els, 5000);
2455 		break;
2456 	case OCS_EVT_TIMER_EXPIRED:
2457 		/* Retry delay timer expired, retry the ELS request, Free the HW IO so
2458 		 * that a new oxid is used.
2459 		 */
2460 		if (els->hio != NULL) {
2461 			ocs_hw_io_free(&ocs->hw, els->hio);
2462 			els->hio = NULL;
2463 		}
2464 		ocs_io_transition(els, __ocs_els_init, NULL);
2465 		break;
2466 	case OCS_EVT_ABORT_ELS:
2467 		ocs_io_transition(els, __ocs_els_aborted_delay_retry, NULL);
2468 		break;
2469 	default:
2470 		__ocs_els_common(__func__, ctx, evt, arg);
2471 		break;
2472 	}
2473 	return NULL;
2474 }
2475 
2476 /**
2477  * @brief Wait for the ELS IO abort request to complete.
2478  *
2479  * <h3 class="desc">Description</h3>
2480  * This state is entered after we abort an ELS WQE and are
2481  * waiting for either the original ELS WQE request or the abort
2482  * to complete.
2483  *
2484  * @param ctx Remote node SM context.
2485  * @param evt Event to process.
2486  * @param arg Per event optional argument.
2487  *
2488  * @return Returns NULL.
2489  */
2490 
2491 void *
2492 __ocs_els_aborting(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2493 {
2494 	std_els_state_decl();
2495 
2496 	els_sm_trace();
2497 
2498 	switch(evt) {
2499 	case OCS_EVT_SRRS_ELS_REQ_OK:
2500 	case OCS_EVT_SRRS_ELS_REQ_FAIL:
2501 	case OCS_EVT_SRRS_ELS_REQ_RJT:
2502 	case OCS_EVT_ELS_REQ_TIMEOUT:
2503 	case OCS_EVT_ELS_REQ_ABORTED: {
2504 		/* completion for ELS received first, transition to wait for abort cmpl */
2505 		els_io_printf(els, "request cmpl evt=%s\n", ocs_sm_event_name(evt));
2506 		ocs_io_transition(els, __ocs_els_aborting_wait_abort_cmpl, NULL);
2507 		break;
2508 	}
2509 	case OCS_EVT_ELS_ABORT_CMPL: {
2510 		/* completion for abort was received first, transition to wait for req cmpl */
2511 		els_io_printf(els, "abort cmpl evt=%s\n", ocs_sm_event_name(evt));
2512 		ocs_io_transition(els, __ocs_els_aborting_wait_req_cmpl, NULL);
2513 		break;
2514 	}
2515 	case OCS_EVT_ABORT_ELS:
2516 		/* nothing we can do but wait */
2517 		break;
2518 
2519 	default:
2520 		__ocs_els_common(__func__, ctx, evt, arg);
2521 		break;
2522 	}
2523 	return NULL;
2524 }
2525 
2526 /**
2527  * @brief cleanup ELS after abort
2528  *
2529  * @param els ELS IO to cleanup
2530  *
2531  * @return Returns None.
2532  */
2533 
2534 static void
2535 ocs_els_abort_cleanup(ocs_io_t *els)
2536 {
2537 	/* handle event for ABORT_WQE
2538 	 * whatever state ELS happened to be in, propagate aborted event up
2539 	 * to node state machine in lieu of OCS_EVT_SRRS_ELS_* event
2540 	 */
2541 	ocs_node_cb_t cbdata;
2542 	cbdata.status = cbdata.ext_status = 0;
2543 	cbdata.els = els;
2544 	els_io_printf(els, "Request aborted\n");
2545 	ocs_els_io_cleanup(els, OCS_EVT_ELS_REQ_ABORTED, &cbdata);
2546 }
2547 
2548 /**
2549  * @brief Wait for the ELS IO abort request to complete.
2550  *
2551  * <h3 class="desc">Description</h3>
2552  * This state is entered after we abort an ELS WQE, we received
2553  * the abort completion first and are waiting for the original
2554  * ELS WQE request to complete.
2555  *
2556  * @param ctx Remote node SM context.
2557  * @param evt Event to process.
2558  * @param arg Per event optional argument.
2559  *
2560  * @return Returns NULL.
2561  */
2562 
2563 void *
2564 __ocs_els_aborting_wait_req_cmpl(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2565 {
2566 	std_els_state_decl();
2567 
2568 	els_sm_trace();
2569 
2570 	switch(evt) {
2571 	case OCS_EVT_SRRS_ELS_REQ_OK:
2572 	case OCS_EVT_SRRS_ELS_REQ_FAIL:
2573 	case OCS_EVT_SRRS_ELS_REQ_RJT:
2574 	case OCS_EVT_ELS_REQ_TIMEOUT:
2575 	case OCS_EVT_ELS_REQ_ABORTED: {
2576 		/* completion for ELS that was aborted */
2577 		ocs_els_abort_cleanup(els);
2578 		break;
2579 	}
2580 	case OCS_EVT_ABORT_ELS:
2581 		/* nothing we can do but wait */
2582 		break;
2583 
2584 	default:
2585 		__ocs_els_common(__func__, ctx, evt, arg);
2586 		break;
2587 	}
2588 	return NULL;
2589 }
2590 
2591 /**
2592  * @brief Wait for the ELS IO abort request to complete.
2593  *
2594  * <h3 class="desc">Description</h3>
2595  * This state is entered after we abort an ELS WQE, we received
2596  * the original ELS WQE request completion first and are waiting
2597  * for the abort to complete.
2598  *
2599  * @param ctx Remote node SM context.
2600  * @param evt Event to process.
2601  * @param arg Per event optional argument.
2602  *
2603  * @return Returns NULL.
2604  */
2605 
2606 void *
2607 __ocs_els_aborting_wait_abort_cmpl(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2608 {
2609 	std_els_state_decl();
2610 
2611 	els_sm_trace();
2612 
2613 	switch(evt) {
2614 	case OCS_EVT_ELS_ABORT_CMPL: {
2615 		ocs_els_abort_cleanup(els);
2616 		break;
2617 	}
2618 	case OCS_EVT_ABORT_ELS:
2619 		/* nothing we can do but wait */
2620 		break;
2621 
2622 	default:
2623 		__ocs_els_common(__func__, ctx, evt, arg);
2624 		break;
2625 	}
2626 	return NULL;
2627 }
2628 
2629 /**
2630  * @brief Generate ELS context ddump data.
2631  *
2632  * <h3 class="desc">Description</h3>
2633  * Generate the ddump data for an ELS context.
2634  *
2635  * @param textbuf Pointer to the text buffer.
2636  * @param els Pointer to the ELS context.
2637  *
2638  * @return None.
2639  */
2640 
2641 void
2642 ocs_ddump_els(ocs_textbuf_t *textbuf, ocs_io_t *els)
2643 {
2644 	ocs_ddump_section(textbuf, "els", -1);
2645 	ocs_ddump_value(textbuf, "req_free", "%d", els->els_req_free);
2646 	ocs_ddump_value(textbuf, "evtdepth", "%d", els->els_evtdepth);
2647 	ocs_ddump_value(textbuf, "pend", "%d", els->els_pend);
2648 	ocs_ddump_value(textbuf, "active", "%d", els->els_active);
2649 	ocs_ddump_io(textbuf, els);
2650 	ocs_ddump_endsection(textbuf, "els", -1);
2651 }
2652 
2653 
2654 /**
2655  * @brief return TRUE if given ELS list is empty (while taking proper locks)
2656  *
2657  * Test if given ELS list is empty while holding the node->active_ios_lock.
2658  *
2659  * @param node pointer to node object
2660  * @param list pointer to list
2661  *
2662  * @return TRUE if els_io_list is empty
2663  */
2664 
2665 int32_t
2666 ocs_els_io_list_empty(ocs_node_t *node, ocs_list_t *list)
2667 {
2668 	int empty;
2669 	ocs_lock(&node->active_ios_lock);
2670 		empty = ocs_list_empty(list);
2671 	ocs_unlock(&node->active_ios_lock);
2672 	return empty;
2673 }
2674 
2675 /**
2676  * @brief Handle CT send response completion
2677  *
2678  * Called when CT response completes, free IO
2679  *
2680  * @param hio Pointer to the HW IO context that completed.
2681  * @param rnode Pointer to the remote node.
2682  * @param length Length of the returned payload data.
2683  * @param status Status of the completion.
2684  * @param ext_status Extended status of the completion.
2685  * @param arg Application-specific argument (generally a pointer to the ELS IO context).
2686  *
2687  * @return returns 0
2688  */
2689 static int32_t
2690 ocs_ct_acc_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *arg)
2691 {
2692 	ocs_io_t *io = arg;
2693 
2694 	ocs_els_io_free(io);
2695 
2696 	return 0;
2697 }
2698 
2699 /**
2700  * @brief Send CT response
2701  *
2702  * Sends a CT response frame with payload
2703  *
2704  * @param io Pointer to the IO context.
2705  * @param ox_id Originator exchange ID
2706  * @param ct_hdr Pointer to the CT IU
2707  * @param cmd_rsp_code CT response code
2708  * @param reason_code Reason code
2709  * @param reason_code_explanation Reason code explanation
2710  *
2711  * @return returns 0 for success, a negative error code value for failure.
2712  */
2713 int32_t
2714 ocs_send_ct_rsp(ocs_io_t *io, uint32_t ox_id, fcct_iu_header_t *ct_hdr, uint32_t cmd_rsp_code, uint32_t reason_code, uint32_t reason_code_explanation)
2715 {
2716 	fcct_iu_header_t *rsp = io->els_rsp.virt;
2717 
2718 	io->io_type = OCS_IO_TYPE_CT_RESP;
2719 
2720 	*rsp = *ct_hdr;
2721 
2722 	fcct_build_req_header(rsp, cmd_rsp_code, 0);
2723 	rsp->reason_code = reason_code;
2724 	rsp->reason_code_explanation = reason_code_explanation;
2725 
2726 	io->display_name = "ct response";
2727 	io->init_task_tag = ox_id;
2728 	io->wire_len += sizeof(*rsp);
2729 
2730 	ocs_memset(&io->iparam, 0, sizeof(io->iparam));
2731 
2732 	io->io_type = OCS_IO_TYPE_CT_RESP;
2733 	io->hio_type = OCS_HW_FC_CT_RSP;
2734 	io->iparam.fc_ct_rsp.ox_id = ocs_htobe16(ox_id);
2735 	io->iparam.fc_ct_rsp.r_ctl = 3;
2736 	io->iparam.fc_ct_rsp.type = FC_TYPE_GS;
2737 	io->iparam.fc_ct_rsp.df_ctl = 0;
2738 	io->iparam.fc_ct_rsp.timeout = 5;
2739 
2740 	if (ocs_scsi_io_dispatch(io, ocs_ct_acc_cb) < 0) {
2741 		ocs_els_io_free(io);
2742 		return -1;
2743 	}
2744 	return 0;
2745 }
2746 
2747 
2748 /**
2749  * @brief Handle delay retry timeout
2750  *
2751  * Callback is invoked when the delay retry timer expires.
2752  *
2753  * @param arg pointer to the ELS IO object
2754  *
2755  * @return none
2756  */
2757 static void
2758 ocs_els_delay_timer_cb(void *arg)
2759 {
2760 	ocs_io_t *els = arg;
2761 	ocs_node_t *node = els->node;
2762 
2763 	/*
2764 	 * There is a potential deadlock here since is Linux executes timers
2765 	 * in a soft IRQ context. The lock may be aready locked by the interrupt
2766 	 * thread. Handle this case by attempting to take the node lock and reset the
2767 	 * timer if we fail to acquire the lock.
2768 	 *
2769 	 * Note: This code relies on the fact that the node lock is recursive.
2770 	 */
2771 	if (ocs_node_lock_try(node)) {
2772 		ocs_els_post_event(els, OCS_EVT_TIMER_EXPIRED, NULL);
2773 		ocs_node_unlock(node);
2774 	} else {
2775 		ocs_setup_timer(els->ocs, &els->delay_timer, ocs_els_delay_timer_cb, els, 1);
2776 	}
2777 }
2778