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
60static int32_t ocs_els_send(ocs_io_t *els, uint32_t reqlen, uint32_t timeout_sec, ocs_hw_srrs_cb_t cb);
61static int32_t ocs_els_send_rsp(ocs_io_t *els, uint32_t rsplen);
62static 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);
63static ocs_io_t *ocs_bls_send_acc(ocs_io_t *io, uint32_t s_id, uint16_t ox_id, uint16_t rx_id);
64static 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);
66static void ocs_io_transition(ocs_io_t *els, ocs_sm_function_t state, void *data);
67static ocs_io_t *ocs_els_abort_io(ocs_io_t *els, int send_abts);
68static void _ocs_els_io_free(void *arg);
69static 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 */
90static void
91ocs_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 */
114void
115ocs_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
143ocs_io_t *
144ocs_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
164ocs_io_t *
165ocs_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
269void
270ocs_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
287static 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
345static void
346ocs_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
394static int32_t
395ocs_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
423static int32_t
424ocs_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
455static int32_t
456ocs_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
549static int32_t
550ocs_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
616ocs_io_t *
617ocs_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
671ocs_io_t *
672ocs_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
731ocs_io_t *
732ocs_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
787ocs_io_t *
788ocs_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
850ocs_io_t *
851ocs_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
903ocs_io_t *
904ocs_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
963ocs_io_t *
964ocs_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
1026ocs_io_t *
1027ocs_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
1076ocs_io_t *
1077ocs_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
1125ocs_io_t *
1126ocs_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 */
1175ocs_io_t *
1176ocs_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
1233ocs_io_t *
1234ocs_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 */
1283ocs_io_t *
1284ocs_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 */
1345ocs_io_t *
1346ocs_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
1384ocs_io_t *
1385ocs_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
1449ocs_io_t *
1450ocs_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
1506ocs_io_t *
1507ocs_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 */
1558ocs_io_t *
1559ocs_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 */
1605ocs_io_t *
1606ocs_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
1654ocs_io_t *
1655ocs_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 */
1713ocs_io_t *
1714ocs_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 */
1766ocs_io_t *
1767ocs_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
1828ocs_io_t *
1829ocs_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
1880ocs_io_t *
1881ocs_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
1906static ocs_io_t *
1907ocs_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
1970static int32_t
1971ocs_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
1997static int32_t
1998ocs_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
2049static ocs_io_t *
2050ocs_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
2145void
2146ocs_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
2178void *
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
2219void *
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
2263void *
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
2342void *
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 */
2408void *
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 */
2445void *
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
2491void *
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
2534static void
2535ocs_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
2563void *
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
2606void *
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
2641void
2642ocs_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
2665int32_t
2666ocs_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 */
2689static int32_t
2690ocs_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 */
2713int32_t
2714ocs_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 */
2757static void
2758ocs_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