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 * OCS driver remote node handler.  This file contains code that is shared
37 * between fabric (ocs_fabric.c) and device (ocs_device.c) nodes.
38 */
39
40/*!
41 * @defgroup node_common Node common support
42 * @defgroup node_alloc Node allocation
43 */
44
45#include "ocs.h"
46#include "ocs_els.h"
47#include "ocs_device.h"
48
49#define SCSI_IOFMT "[%04x][i:%0*x t:%0*x h:%04x]"
50#define SCSI_ITT_SIZE(ocs)	((ocs->ocs_xport == OCS_XPORT_FC) ? 4 : 8)
51
52#define SCSI_IOFMT_ARGS(io) io->instance_index, SCSI_ITT_SIZE(io->ocs), io->init_task_tag, SCSI_ITT_SIZE(io->ocs), io->tgt_task_tag, io->hw_tag
53
54#define scsi_io_printf(io, fmt, ...) ocs_log_debug(io->ocs, "[%s]" SCSI_IOFMT fmt, \
55	io->node->display_name, SCSI_IOFMT_ARGS(io), ##__VA_ARGS__)
56
57void ocs_mgmt_node_list(ocs_textbuf_t *textbuf, void *node);
58void ocs_mgmt_node_get_all(ocs_textbuf_t *textbuf, void *node);
59int ocs_mgmt_node_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *node);
60int ocs_mgmt_node_set(char *parent, char *name, char *value, void *node);
61int ocs_mgmt_node_exec(char *parent, char *action, void *arg_in, uint32_t arg_in_length,
62		void *arg_out, uint32_t arg_out_length, void *node);
63static ocs_mgmt_functions_t node_mgmt_functions = {
64	.get_list_handler	=	ocs_mgmt_node_list,
65	.get_handler		=	ocs_mgmt_node_get,
66	.get_all_handler	=	ocs_mgmt_node_get_all,
67	.set_handler		=	ocs_mgmt_node_set,
68	.exec_handler		=	ocs_mgmt_node_exec,
69};
70
71/**
72 * @ingroup node_common
73 * @brief Device node state machine wait for all ELS's to
74 *        complete
75 *
76 * Abort all ELS's for given node.
77 *
78 * @param node node for which ELS's will be aborted
79 */
80
81void
82ocs_node_abort_all_els(ocs_node_t *node)
83{
84	ocs_io_t *els;
85	ocs_io_t *els_next;
86	ocs_node_cb_t cbdata = {0};
87
88	ocs_node_hold_frames(node);
89	ocs_lock(&node->active_ios_lock);
90		ocs_list_foreach_safe(&node->els_io_active_list, els, els_next) {
91			ocs_log_debug(node->ocs, "[%s] initiate ELS abort %s\n", node->display_name, els->display_name);
92			ocs_unlock(&node->active_ios_lock);
93			cbdata.els = els;
94			ocs_els_post_event(els, OCS_EVT_ABORT_ELS, &cbdata);
95			ocs_lock(&node->active_ios_lock);
96		}
97	ocs_unlock(&node->active_ios_lock);
98}
99
100/**
101 * @ingroup node_common
102 * @brief Handle remote node events from HW
103 *
104 * Handle remote node events from HW.   Essentially the HW event is translated into
105 * a node state machine event that is posted to the affected node.
106 *
107 * @param arg pointer to ocs
108 * @param event HW event to proceoss
109 * @param data application specific data (pointer to the affected node)
110 *
111 * @return returns 0 for success, a negative error code value for failure.
112 */
113int32_t
114ocs_remote_node_cb(void *arg, ocs_hw_remote_node_event_e event, void *data)
115{
116	ocs_t *ocs = arg;
117	ocs_sm_event_t	sm_event = OCS_EVT_LAST;
118	ocs_remote_node_t *rnode = data;
119	ocs_node_t *node = rnode->node;
120
121	switch (event) {
122	case OCS_HW_NODE_ATTACH_OK:
123		sm_event = OCS_EVT_NODE_ATTACH_OK;
124		break;
125
126	case OCS_HW_NODE_ATTACH_FAIL:
127		sm_event = OCS_EVT_NODE_ATTACH_FAIL;
128		break;
129
130	case OCS_HW_NODE_FREE_OK:
131		sm_event = OCS_EVT_NODE_FREE_OK;
132		break;
133
134	case OCS_HW_NODE_FREE_FAIL:
135		sm_event = OCS_EVT_NODE_FREE_FAIL;
136		break;
137
138	default:
139		ocs_log_test(ocs, "unhandled event %#x\n", event);
140		return -1;
141	}
142
143	/* If we're using HLM, forward the NODE_ATTACH_OK/FAIL event to all nodes in the node group */
144	if ((node->node_group != NULL) &&
145			((sm_event == OCS_EVT_NODE_ATTACH_OK) || (sm_event == OCS_EVT_NODE_ATTACH_FAIL))) {
146		ocs_node_t *n = NULL;
147		uint8_t		attach_ok = sm_event == OCS_EVT_NODE_ATTACH_OK;
148
149		ocs_sport_lock(node->sport);
150		{
151			ocs_list_foreach(&node->sport->node_list, n) {
152				if (node == n) {
153					continue;
154				}
155				ocs_node_lock(n);
156					if ((!n->rnode.attached) && (node->node_group == n->node_group)) {
157						n->rnode.attached = attach_ok;
158						node_printf(n, "rpi[%d] deferred HLM node attach %s posted\n",
159								n->rnode.index, attach_ok ? "ok" : "fail");
160						ocs_node_post_event(n, sm_event, NULL);
161					}
162				ocs_node_unlock(n);
163			}
164		}
165
166		ocs_sport_unlock(node->sport);
167	}
168
169	ocs_node_post_event(node, sm_event, NULL);
170
171	return 0;
172}
173
174/**
175 * @ingroup node_alloc
176 * @brief Find an FC node structure given the FC port ID
177 *
178 * @param sport the SPORT to search
179 * @param port_id FC port ID
180 *
181 * @return pointer to the object or NULL if not found
182 */
183ocs_node_t *
184ocs_node_find(ocs_sport_t *sport, uint32_t port_id)
185{
186	ocs_node_t *node;
187
188	ocs_assert(sport->lookup, NULL);
189	ocs_sport_lock(sport);
190		node = spv_get(sport->lookup, port_id);
191	ocs_sport_unlock(sport);
192	return node;
193}
194
195/**
196 * @ingroup node_alloc
197 * @brief Find an FC node structure given the WWPN
198 *
199 * @param sport the SPORT to search
200 * @param wwpn the WWPN to search for (host endian)
201 *
202 * @return pointer to the object or NULL if not found
203 */
204ocs_node_t *
205ocs_node_find_wwpn(ocs_sport_t *sport, uint64_t wwpn)
206{
207	ocs_node_t *node = NULL;
208
209	ocs_assert(sport, NULL);
210
211	ocs_sport_lock(sport);
212		ocs_list_foreach(&sport->node_list, node) {
213			if (ocs_node_get_wwpn(node) == wwpn) {
214				ocs_sport_unlock(sport);
215				return node;
216			}
217		}
218	ocs_sport_unlock(sport);
219	return NULL;
220}
221
222/**
223 * @ingroup node_alloc
224 * @brief allocate node object pool
225 *
226 * A pool of ocs_node_t objects is allocated.
227 *
228 * @param ocs pointer to driver instance context
229 * @param node_count count of nodes to allocate
230 *
231 * @return returns 0 for success, a negative error code value for failure.
232 */
233
234int32_t
235ocs_node_create_pool(ocs_t *ocs, uint32_t node_count)
236{
237	ocs_xport_t *xport = ocs->xport;
238	uint32_t i;
239	ocs_node_t *node;
240	uint32_t max_sge;
241	uint32_t num_sgl;
242	uint64_t max_xfer_size;
243	int32_t rc;
244
245	xport->nodes_count = node_count;
246
247	xport->nodes = ocs_malloc(ocs, node_count * sizeof(ocs_node_t *), OCS_M_ZERO | OCS_M_NOWAIT);
248	if (xport->nodes == NULL) {
249		ocs_log_err(ocs, "node ptrs allocation failed");
250		return -1;
251	}
252
253	if (0 == ocs_hw_get(&ocs->hw, OCS_HW_MAX_SGE, &max_sge) &&
254	    0 == ocs_hw_get(&ocs->hw, OCS_HW_N_SGL, &num_sgl)) {
255		max_xfer_size = (max_sge * (uint64_t)num_sgl);
256	} else {
257		max_xfer_size = 65536;
258	}
259
260	if (max_xfer_size > 65536)
261		max_xfer_size = 65536;
262
263	ocs_list_init(&xport->nodes_free_list, ocs_node_t, link);
264
265	for (i = 0; i < node_count; i ++) {
266		node = ocs_malloc(ocs, sizeof(ocs_node_t), OCS_M_ZERO | OCS_M_NOWAIT);
267		if (node == NULL) {
268			ocs_log_err(ocs, "node allocation failed");
269			goto error;
270		}
271
272		/* Assign any persistent field values */
273		node->instance_index = i;
274		node->max_wr_xfer_size = max_xfer_size;
275		node->rnode.indicator = UINT32_MAX;
276
277		rc = ocs_dma_alloc(ocs, &node->sparm_dma_buf, 256, 16);
278		if (rc) {
279			ocs_free(ocs, node, sizeof(ocs_node_t));
280			ocs_log_err(ocs, "ocs_dma_alloc failed: %d\n", rc);
281			goto error;
282		}
283
284		xport->nodes[i] = node;
285		ocs_list_add_tail(&xport->nodes_free_list, node);
286	}
287	return 0;
288
289error:
290	ocs_node_free_pool(ocs);
291	return -1;
292}
293
294/**
295 * @ingroup node_alloc
296 * @brief free node object pool
297 *
298 * The pool of previously allocated node objects is freed
299 *
300 * @param ocs pointer to driver instance context
301 *
302 * @return none
303 */
304
305void
306ocs_node_free_pool(ocs_t *ocs)
307{
308	ocs_xport_t *xport = ocs->xport;
309	ocs_node_t *node;
310	uint32_t i;
311
312	if (!xport->nodes)
313		return;
314
315	ocs_device_lock(ocs);
316
317	for (i = 0; i < xport->nodes_count; i ++) {
318		node = xport->nodes[i];
319		if (node) {
320			/* free sparam_dma_buf */
321			ocs_dma_free(ocs, &node->sparm_dma_buf);
322			ocs_free(ocs, node, sizeof(ocs_node_t));
323		}
324		xport->nodes[i] = NULL;
325	}
326
327	ocs_free(ocs, xport->nodes, (xport->nodes_count * sizeof(ocs_node_t *)));
328
329	ocs_device_unlock(ocs);
330}
331
332/**
333 * @ingroup node_alloc
334 * @brief return pointer to node object given instance index
335 *
336 * A pointer to the node object given by an instance index is returned.
337 *
338 * @param ocs pointer to driver instance context
339 * @param index instance index
340 *
341 * @return returns pointer to node object, or NULL
342 */
343
344ocs_node_t *
345ocs_node_get_instance(ocs_t *ocs, uint32_t index)
346{
347	ocs_xport_t *xport = ocs->xport;
348	ocs_node_t *node = NULL;
349
350	if (index >= (xport->nodes_count)) {
351		ocs_log_test(ocs, "invalid index: %d\n", index);
352		return NULL;
353	}
354	node = xport->nodes[index];
355	return node->attached ? node : NULL;
356}
357
358/**
359 * @ingroup node_alloc
360 * @brief Allocate an fc node structure and add to node list
361 *
362 * @param sport pointer to the SPORT from which this node is allocated
363 * @param port_id FC port ID of new node
364 * @param init Port is an inititiator (sent a plogi)
365 * @param targ Port is potentially a target
366 *
367 * @return pointer to the object or NULL if none available
368 */
369
370ocs_node_t *
371ocs_node_alloc(ocs_sport_t *sport, uint32_t port_id, uint8_t init, uint8_t targ)
372{
373	int32_t rc;
374	ocs_node_t *node = NULL;
375	uint32_t instance_index;
376	uint32_t max_wr_xfer_size;
377	ocs_t *ocs = sport->ocs;
378	ocs_xport_t *xport = ocs->xport;
379	ocs_dma_t sparm_dma_buf;
380
381	ocs_assert(sport, NULL);
382
383	if (sport->shutting_down) {
384		ocs_log_debug(ocs, "node allocation when shutting down %06x", port_id);
385		return NULL;
386	}
387
388	ocs_device_lock(ocs);
389		node = ocs_list_remove_head(&xport->nodes_free_list);
390	ocs_device_unlock(ocs);
391	if (node == NULL) {
392		ocs_log_err(ocs, "node allocation failed %06x", port_id);
393		return NULL;
394	}
395
396	/* Save persistent values across memset zero */
397	instance_index = node->instance_index;
398	max_wr_xfer_size = node->max_wr_xfer_size;
399	sparm_dma_buf = node->sparm_dma_buf;
400
401	ocs_memset(node, 0, sizeof(*node));
402	node->instance_index = instance_index;
403	node->max_wr_xfer_size = max_wr_xfer_size;
404	node->sparm_dma_buf = sparm_dma_buf;
405	node->rnode.indicator = UINT32_MAX;
406
407	node->sport = sport;
408	ocs_sport_lock(sport);
409
410		node->ocs = ocs;
411		node->init = init;
412		node->targ = targ;
413
414		rc = ocs_hw_node_alloc(&ocs->hw, &node->rnode, port_id, sport);
415		if (rc) {
416			ocs_log_err(ocs, "ocs_hw_node_alloc failed: %d\n", rc);
417			ocs_sport_unlock(sport);
418
419			/* Return back to pool. */
420			ocs_device_lock(ocs);
421			ocs_list_add_tail(&xport->nodes_free_list, node);
422			ocs_device_unlock(ocs);
423
424			return NULL;
425		}
426		ocs_list_add_tail(&sport->node_list, node);
427
428		ocs_node_lock_init(node);
429		ocs_lock_init(ocs, &node->pend_frames_lock, "pend_frames_lock[%d]", node->instance_index);
430		ocs_list_init(&node->pend_frames, ocs_hw_sequence_t, link);
431		ocs_lock_init(ocs, &node->active_ios_lock, "active_ios[%d]", node->instance_index);
432		ocs_list_init(&node->active_ios, ocs_io_t, link);
433		ocs_list_init(&node->els_io_pend_list, ocs_io_t, link);
434		ocs_list_init(&node->els_io_active_list, ocs_io_t, link);
435		ocs_scsi_io_alloc_enable(node);
436
437		/* zero the service parameters */
438		ocs_memset(node->sparm_dma_buf.virt, 0, node->sparm_dma_buf.size);
439
440		node->rnode.node = node;
441		node->sm.app = node;
442		node->evtdepth = 0;
443
444		ocs_node_update_display_name(node);
445
446		spv_set(sport->lookup, port_id, node);
447	ocs_sport_unlock(sport);
448	node->mgmt_functions = &node_mgmt_functions;
449
450	return node;
451}
452
453/**
454 * @ingroup node_alloc
455 * @brief free a node structure
456 *
457 * The node structure given by 'node' is free'd
458 *
459 * @param node the node to free
460 *
461 * @return returns 0 for success, a negative error code value for failure.
462 */
463
464int32_t
465ocs_node_free(ocs_node_t *node)
466{
467	ocs_sport_t *sport;
468	ocs_t *ocs;
469	ocs_xport_t *xport;
470	ocs_hw_rtn_e rc = 0;
471	ocs_node_t *ns = NULL;
472	int post_all_free = FALSE;
473
474	ocs_assert(node, -1);
475	ocs_assert(node->sport, -1);
476	ocs_assert(node->ocs, -1);
477	sport = node->sport;
478	ocs_assert(sport, -1);
479	ocs = node->ocs;
480	ocs_assert(ocs->xport, -1);
481	xport = ocs->xport;
482
483	node_printf(node, "Free'd\n");
484
485	if(node->refound) {
486		/*
487		 * Save the name server node. We will send fake RSCN event at
488		 * the end to handle ignored RSCN event during node deletion
489		 */
490		ns = ocs_node_find(node->sport, FC_ADDR_NAMESERVER);
491	}
492
493	/* Remove from node list */
494	ocs_sport_lock(sport);
495		ocs_list_remove(&sport->node_list, node);
496
497		/* Free HW resources */
498		if (OCS_HW_RTN_IS_ERROR((rc = ocs_hw_node_free_resources(&ocs->hw, &node->rnode)))) {
499			ocs_log_test(ocs, "ocs_hw_node_free failed: %d\n", rc);
500			rc = -1;
501		}
502
503		/* if the gidpt_delay_timer is still running, then delete it */
504		if (ocs_timer_pending(&node->gidpt_delay_timer)) {
505			ocs_del_timer(&node->gidpt_delay_timer);
506		}
507
508		if (node->fcp2device) {
509			ocs_del_crn(node);
510		}
511
512		/* remove entry from sparse vector list */
513		if (sport->lookup == NULL) {
514			ocs_log_test(node->ocs, "assertion failed: sport lookup is NULL\n");
515			ocs_sport_unlock(sport);
516			return -1;
517		}
518
519		spv_set(sport->lookup, node->rnode.fc_id, NULL);
520
521		/*
522		 * If the node_list is empty, then post a ALL_CHILD_NODES_FREE event to the sport,
523		 * after the lock is released.  The sport may be free'd as a result of the event.
524		 */
525		if (ocs_list_empty(&sport->node_list)) {
526			post_all_free = TRUE;
527		}
528
529	ocs_sport_unlock(sport);
530
531	if (post_all_free) {
532		ocs_sm_post_event(&sport->sm, OCS_EVT_ALL_CHILD_NODES_FREE, NULL);
533	}
534
535	node->sport = NULL;
536	node->sm.current_state = NULL;
537
538	ocs_node_lock_free(node);
539	ocs_lock_free(&node->pend_frames_lock);
540	ocs_lock_free(&node->active_ios_lock);
541
542	/* return to free list */
543	ocs_device_lock(ocs);
544		ocs_list_add_tail(&xport->nodes_free_list, node);
545	ocs_device_unlock(ocs);
546
547	if(ns != NULL) {
548		/* sending fake RSCN event to name server node */
549		ocs_node_post_event(ns, OCS_EVT_RSCN_RCVD, NULL);
550	}
551
552	return rc;
553}
554
555/**
556 * @brief free memory resources of a node object
557 *
558 * The node object's child objects are freed after which the
559 * node object is freed.
560 *
561 * @param node pointer to a node object
562 *
563 * @return none
564 */
565
566void
567ocs_node_force_free(ocs_node_t *node)
568{
569	ocs_io_t *io;
570	ocs_io_t *next;
571	ocs_io_t *els;
572	ocs_io_t *els_next;
573
574	/* shutdown sm processing */
575	ocs_sm_disable(&node->sm);
576	ocs_strncpy(node->prev_state_name, node->current_state_name, sizeof(node->prev_state_name));
577	ocs_strncpy(node->current_state_name, "disabled", sizeof(node->current_state_name));
578
579	/* Let the backend cleanup if needed */
580	ocs_scsi_notify_node_force_free(node);
581
582	ocs_lock(&node->active_ios_lock);
583		ocs_list_foreach_safe(&node->active_ios, io, next) {
584			ocs_list_remove(&io->node->active_ios, io);
585			ocs_io_free(node->ocs, io);
586		}
587	ocs_unlock(&node->active_ios_lock);
588
589	/* free all pending ELS IOs */
590	ocs_lock(&node->active_ios_lock);
591		ocs_list_foreach_safe(&node->els_io_pend_list, els, els_next) {
592			/* can't call ocs_els_io_free() because lock is held; cleanup manually */
593			ocs_list_remove(&node->els_io_pend_list, els);
594
595			ocs_io_free(node->ocs, els);
596		}
597	ocs_unlock(&node->active_ios_lock);
598
599	/* free all active ELS IOs */
600	ocs_lock(&node->active_ios_lock);
601		ocs_list_foreach_safe(&node->els_io_active_list, els, els_next) {
602			/* can't call ocs_els_io_free() because lock is held; cleanup manually */
603			ocs_list_remove(&node->els_io_active_list, els);
604
605			ocs_io_free(node->ocs, els);
606		}
607	ocs_unlock(&node->active_ios_lock);
608
609	/* manually purge pending frames (if any) */
610	ocs_node_purge_pending(node);
611
612	ocs_node_free(node);
613}
614
615/**
616 * @ingroup node_common
617 * @brief Perform HW call to attach a remote node
618 *
619 * @param node pointer to node object
620 *
621 * @return 0 on success, non-zero otherwise
622 */
623int32_t
624ocs_node_attach(ocs_node_t *node)
625{
626	int32_t rc = 0;
627	ocs_sport_t *sport = node->sport;
628	ocs_domain_t *domain = sport->domain;
629	ocs_t *ocs = node->ocs;
630
631	if (!domain->attached) {
632		ocs_log_test(ocs, "Warning: ocs_node_attach with unattached domain\n");
633		return -1;
634	}
635	/* Update node->wwpn/wwnn */
636
637	ocs_node_build_eui_name(node->wwpn, sizeof(node->wwpn), ocs_node_get_wwpn(node));
638	ocs_node_build_eui_name(node->wwnn, sizeof(node->wwnn), ocs_node_get_wwnn(node));
639
640	if (ocs->enable_hlm) {
641		ocs_node_group_init(node);
642	}
643
644	ocs_dma_copy_in(&node->sparm_dma_buf, node->service_params+4, sizeof(node->service_params)-4);
645
646	/* take lock to protect node->rnode.attached */
647	ocs_node_lock(node);
648		rc = ocs_hw_node_attach(&ocs->hw, &node->rnode, &node->sparm_dma_buf);
649		if (OCS_HW_RTN_IS_ERROR(rc)) {
650			ocs_log_test(ocs, "ocs_hw_node_attach failed: %d\n", rc);
651		}
652	ocs_node_unlock(node);
653
654	return rc;
655}
656
657/**
658 * @ingroup node_common
659 * @brief Generate text for a node's fc_id
660 *
661 * The text for a nodes fc_id is generated, either as a well known name, or a 6 digit
662 * hex value.
663 *
664 * @param fc_id fc_id
665 * @param buffer text buffer
666 * @param buffer_length text buffer length in bytes
667 *
668 * @return none
669 */
670
671void
672ocs_node_fcid_display(uint32_t fc_id, char *buffer, uint32_t buffer_length)
673{
674	switch (fc_id) {
675	case FC_ADDR_FABRIC:
676		ocs_snprintf(buffer, buffer_length, "fabric");
677		break;
678	case FC_ADDR_CONTROLLER:
679		ocs_snprintf(buffer, buffer_length, "fabctl");
680		break;
681	case FC_ADDR_NAMESERVER:
682		ocs_snprintf(buffer, buffer_length, "nserve");
683		break;
684	default:
685		if (FC_ADDR_IS_DOMAIN_CTRL(fc_id)) {
686			ocs_snprintf(buffer, buffer_length, "dctl%02x",
687				FC_ADDR_GET_DOMAIN_CTRL(fc_id));
688		} else {
689			ocs_snprintf(buffer, buffer_length, "%06x", fc_id);
690		}
691		break;
692	}
693
694}
695
696/**
697 * @brief update the node's display name
698 *
699 * The node's display name is updated, sometimes needed because the sport part
700 * is updated after the node is allocated.
701 *
702 * @param node pointer to the node object
703 *
704 * @return none
705 */
706
707void
708ocs_node_update_display_name(ocs_node_t *node)
709{
710	uint32_t port_id = node->rnode.fc_id;
711	ocs_sport_t *sport = node->sport;
712	char portid_display[16];
713
714	ocs_assert(sport);
715
716	ocs_node_fcid_display(port_id, portid_display, sizeof(portid_display));
717
718	ocs_snprintf(node->display_name, sizeof(node->display_name), "%s.%s", sport->display_name, portid_display);
719}
720
721/**
722 * @brief cleans up an XRI for the pending link services accept by aborting the
723 *         XRI if required.
724 *
725 * <h3 class="desc">Description</h3>
726 * This function is called when the LS accept is not sent.
727 *
728 * @param node Node for which should be cleaned up
729 */
730
731void
732ocs_node_send_ls_io_cleanup(ocs_node_t *node)
733{
734	ocs_t *ocs = node->ocs;
735
736	if (node->send_ls_acc != OCS_NODE_SEND_LS_ACC_NONE) {
737		ocs_assert(node->ls_acc_io);
738		ocs_log_debug(ocs, "[%s] cleaning up LS_ACC oxid=0x%x\n",
739			node->display_name, node->ls_acc_oxid);
740
741		node->ls_acc_io->hio = NULL;
742		ocs_els_io_free(node->ls_acc_io);
743		node->send_ls_acc = OCS_NODE_SEND_LS_ACC_NONE;
744		node->ls_acc_io = NULL;
745	}
746}
747
748/**
749 * @ingroup node_common
750 * @brief state: shutdown a node
751 *
752 * A node is shutdown,
753 *
754 * @param ctx remote node sm context
755 * @param evt event to process
756 * @param arg per event optional argument
757 *
758 * @return returns NULL
759 *
760 * @note
761 */
762
763void *
764__ocs_node_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
765{
766	int32_t rc;
767	std_node_state_decl();
768
769	node_sm_trace();
770
771	switch(evt) {
772	case OCS_EVT_ENTER: {
773		ocs_node_hold_frames(node);
774		ocs_assert(ocs_node_active_ios_empty(node), NULL);
775		ocs_assert(ocs_els_io_list_empty(node, &node->els_io_active_list), NULL);
776
777		/* by default, we will be freeing node after we unwind */
778		node->req_free = 1;
779
780		switch (node->shutdown_reason) {
781		case OCS_NODE_SHUTDOWN_IMPLICIT_LOGO:
782			/* sm: if shutdown reason is implicit logout / ocs_node_attach
783			 * Node shutdown b/c of PLOGI received when node already
784			 * logged in. We have PLOGI service parameters, so submit
785			 * node attach; we won't be freeing this node
786			 */
787
788			/* currently, only case for implicit logo is PLOGI recvd. Thus,
789			 * node's ELS IO pending list won't be empty (PLOGI will be on it)
790			 */
791			ocs_assert(node->send_ls_acc == OCS_NODE_SEND_LS_ACC_PLOGI, NULL);
792			node_printf(node, "Shutdown reason: implicit logout, re-authenticate\n");
793
794			ocs_scsi_io_alloc_enable(node);
795
796			/* Re-attach node with the same HW node resources */
797			node->req_free = 0;
798			rc = ocs_node_attach(node);
799			ocs_node_transition(node, __ocs_d_wait_node_attach, NULL);
800			if (rc == OCS_HW_RTN_SUCCESS_SYNC) {
801				ocs_node_post_event(node, OCS_EVT_NODE_ATTACH_OK, NULL);
802			}
803			break;
804		case OCS_NODE_SHUTDOWN_EXPLICIT_LOGO: {
805			int8_t pend_frames_empty;
806
807			/* cleanup any pending LS_ACC ELSs */
808			ocs_node_send_ls_io_cleanup(node);
809			ocs_assert(ocs_els_io_list_empty(node, &node->els_io_pend_list), NULL);
810
811			ocs_lock(&node->pend_frames_lock);
812				pend_frames_empty = ocs_list_empty(&node->pend_frames);
813			ocs_unlock(&node->pend_frames_lock);
814
815			/* there are two scenarios where we want to keep this node alive:
816			 * 1. there are pending frames that need to be processed or
817			 * 2. we're an initiator and the remote node is a target and we
818			 *    need to re-authenticate
819			 */
820			node_printf(node, "Shutdown: explicit logo pend=%d sport.ini=%d node.tgt=%d\n",
821				    !pend_frames_empty, node->sport->enable_ini, node->targ);
822
823			if((!pend_frames_empty) || (node->sport->enable_ini && node->targ)) {
824				uint8_t send_plogi = FALSE;
825				if (node->sport->enable_ini && node->targ) {
826					/* we're an initiator and node shutting down is a target; we'll
827					 * need to re-authenticate in initial state
828					 */
829					send_plogi = TRUE;
830				}
831
832				/* transition to __ocs_d_init (will retain HW node resources) */
833				ocs_scsi_io_alloc_enable(node);
834				node->req_free = 0;
835
836				/* either pending frames exist, or we're re-authenticating with PLOGI
837				 * (or both); in either case, return to initial state
838				 */
839				ocs_node_init_device(node, send_plogi);
840			}
841			/* else: let node shutdown occur */
842			break;
843		}
844		case OCS_NODE_SHUTDOWN_DEFAULT:
845		default:
846			/* shutdown due to link down, node going away (xport event) or
847			 * sport shutdown, purge pending and proceed to cleanup node
848			 */
849
850			/* cleanup any pending LS_ACC ELSs */
851			ocs_node_send_ls_io_cleanup(node);
852			ocs_assert(ocs_els_io_list_empty(node, &node->els_io_pend_list), NULL);
853
854			node_printf(node, "Shutdown reason: default, purge pending\n");
855			ocs_node_purge_pending(node);
856			break;
857		}
858
859		break;
860	}
861	case OCS_EVT_EXIT:
862		ocs_node_accept_frames(node);
863		break;
864
865	default:
866		__ocs_node_common(__func__, ctx, evt, arg);
867		return NULL;
868	}
869
870	return NULL;
871}
872
873/**
874 * @ingroup common_node
875 * @brief Checks to see if ELS's have been quiesced
876 *
877 * Check if ELS's have been quiesced. If so, transition to the
878 * next state in the shutdown process.
879 *
880 * @param node Node for which ELS's are checked
881 *
882 * @return Returns 1 if ELS's have been quiesced, 0 otherwise.
883 */
884static int
885ocs_node_check_els_quiesced(ocs_node_t *node)
886{
887	ocs_assert(node, -1);
888
889	/* check to see if ELS requests, completions are quiesced */
890	if ((node->els_req_cnt == 0) && (node->els_cmpl_cnt == 0) &&
891	    ocs_els_io_list_empty(node, &node->els_io_active_list)) {
892		if (!node->attached) {
893			/* hw node detach already completed, proceed */
894			node_printf(node, "HW node not attached\n");
895			ocs_node_transition(node, __ocs_node_wait_ios_shutdown, NULL);
896		} else {
897			/* hw node detach hasn't completed, transition and wait */
898			node_printf(node, "HW node still attached\n");
899			ocs_node_transition(node, __ocs_node_wait_node_free, NULL);
900		}
901		return 1;
902	}
903	return 0;
904}
905
906/**
907 * @ingroup common_node
908 * @brief Initiate node IO cleanup.
909 *
910 * Note: this function must be called with a non-attached node
911 * or a node for which the node detach (ocs_hw_node_detach())
912 * has already been initiated.
913 *
914 * @param node Node for which shutdown is initiated
915 *
916 * @return Returns None.
917 */
918
919void
920ocs_node_initiate_cleanup(ocs_node_t *node)
921{
922	ocs_io_t *els;
923	ocs_io_t *els_next;
924	ocs_t *ocs;
925	ocs_assert(node);
926	ocs = node->ocs;
927
928	/* first cleanup ELS's that are pending (not yet active) */
929	ocs_lock(&node->active_ios_lock);
930		ocs_list_foreach_safe(&node->els_io_pend_list, els, els_next) {
931			/* skip the ELS IO for which a response will be sent after shutdown */
932			if ((node->send_ls_acc != OCS_NODE_SEND_LS_ACC_NONE) &&
933			    (els == node->ls_acc_io)) {
934				continue;
935			}
936			/* can't call ocs_els_io_free() because lock is held; cleanup manually */
937                        node_printf(node, "Freeing pending els %s\n", els->display_name);
938			ocs_list_remove(&node->els_io_pend_list, els);
939
940			ocs_io_free(node->ocs, els);
941		}
942	ocs_unlock(&node->active_ios_lock);
943
944	if (node->ls_acc_io && node->ls_acc_io->hio != NULL) {
945		/*
946		 * if there's an IO that will result in an LS_ACC after
947		 * shutdown and its HW IO is non-NULL, it better be an
948		 * implicit logout in vanilla sequence coalescing. In this
949		 * case, force the LS_ACC to go out on another XRI (hio)
950		 * since the previous will have been aborted by the UNREG_RPI
951		 */
952		ocs_assert(node->shutdown_reason == OCS_NODE_SHUTDOWN_IMPLICIT_LOGO);
953		ocs_assert(node->send_ls_acc == OCS_NODE_SEND_LS_ACC_PLOGI);
954		node_printf(node, "invalidating ls_acc_io due to implicit logo\n");
955
956		/* No need to abort because the unreg_rpi takes care of it, just free */
957		ocs_hw_io_free(&ocs->hw, node->ls_acc_io->hio);
958
959		/* NULL out hio to force the LS_ACC to grab a new XRI */
960		node->ls_acc_io->hio = NULL;
961	}
962
963	/*
964	 * if ELS's have already been quiesced, will move to next state
965	 * if ELS's have not been quiesced, abort them
966	 */
967	if (ocs_node_check_els_quiesced(node) == 0) {
968		/*
969		 * Abort all ELS's since ELS's won't be aborted by HW
970		 * node free.
971		 */
972		ocs_node_abort_all_els(node);
973		ocs_node_transition(node, __ocs_node_wait_els_shutdown, NULL);
974	}
975}
976
977/**
978 * @ingroup node_common
979 * @brief Node state machine: Wait for all ELSs to complete.
980 *
981 * <h3 class="desc">Description</h3>
982 * State waits for all ELSs to complete after aborting all
983 * outstanding .
984 *
985 * @param ctx Remote node state machine context.
986 * @param evt Event to process.
987 * @param arg Per event optional argument.
988 *
989 * @return Returns NULL.
990 */
991
992void *
993__ocs_node_wait_els_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
994{
995	uint8_t check_quiesce = FALSE;
996	std_node_state_decl();
997
998	node_sm_trace();
999
1000	switch(evt) {
1001	case OCS_EVT_ENTER: {
1002		ocs_node_hold_frames(node);
1003		if (ocs_els_io_list_empty(node, &node->els_io_active_list)) {
1004			node_printf(node, "All ELS IOs complete\n");
1005			check_quiesce = TRUE;
1006		}
1007		break;
1008	}
1009	case OCS_EVT_EXIT:
1010		ocs_node_accept_frames(node);
1011		break;
1012
1013	case OCS_EVT_SRRS_ELS_REQ_OK:
1014	case OCS_EVT_SRRS_ELS_REQ_FAIL:
1015	case OCS_EVT_SRRS_ELS_REQ_RJT:
1016	case OCS_EVT_ELS_REQ_ABORTED:
1017		ocs_assert(node->els_req_cnt, NULL);
1018		node->els_req_cnt--;
1019		check_quiesce = TRUE;
1020		break;
1021
1022	case OCS_EVT_SRRS_ELS_CMPL_OK:
1023	case OCS_EVT_SRRS_ELS_CMPL_FAIL:
1024		ocs_assert(node->els_cmpl_cnt, NULL);
1025		node->els_cmpl_cnt--;
1026		check_quiesce = TRUE;
1027		break;
1028
1029	case OCS_EVT_ALL_CHILD_NODES_FREE:
1030		/* all ELS IO's complete */
1031		node_printf(node, "All ELS IOs complete\n");
1032		ocs_assert(ocs_els_io_list_empty(node, &node->els_io_active_list), NULL);
1033		check_quiesce = TRUE;
1034		break;
1035
1036	case OCS_EVT_NODE_ACTIVE_IO_LIST_EMPTY:
1037		break;
1038
1039	case OCS_EVT_DOMAIN_ATTACH_OK:
1040		/* don't care about domain_attach_ok */
1041		break;
1042
1043	/* ignore shutdown events as we're already in shutdown path */
1044	case OCS_EVT_SHUTDOWN:
1045		/* have default shutdown event take precedence */
1046		node->shutdown_reason = OCS_NODE_SHUTDOWN_DEFAULT;
1047		/* fall through */
1048	case OCS_EVT_SHUTDOWN_EXPLICIT_LOGO:
1049	case OCS_EVT_SHUTDOWN_IMPLICIT_LOGO:
1050		node_printf(node, "%s received\n", ocs_sm_event_name(evt));
1051		break;
1052
1053	default:
1054		__ocs_node_common(__func__, ctx, evt, arg);
1055		return NULL;
1056	}
1057
1058	if (check_quiesce) {
1059		ocs_node_check_els_quiesced(node);
1060	}
1061	return NULL;
1062}
1063
1064/**
1065 * @ingroup node_command
1066 * @brief Node state machine: Wait for a HW node free event to
1067 * complete.
1068 *
1069 * <h3 class="desc">Description</h3>
1070 * State waits for the node free event to be received from the HW.
1071 *
1072 * @param ctx Remote node state machine context.
1073 * @param evt Event to process.
1074 * @param arg Per event optional argument.
1075 *
1076 * @return Returns NULL.
1077 */
1078
1079void *
1080__ocs_node_wait_node_free(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
1081{
1082	std_node_state_decl();
1083
1084	node_sm_trace();
1085
1086	switch(evt) {
1087	case OCS_EVT_ENTER:
1088		ocs_node_hold_frames(node);
1089		break;
1090
1091	case OCS_EVT_EXIT:
1092		ocs_node_accept_frames(node);
1093		break;
1094
1095	case OCS_EVT_NODE_FREE_OK:
1096		/* node is officially no longer attached */
1097		node->attached = FALSE;
1098		ocs_node_transition(node, __ocs_node_wait_ios_shutdown, NULL);
1099		break;
1100
1101	case OCS_EVT_ALL_CHILD_NODES_FREE:
1102	case OCS_EVT_NODE_ACTIVE_IO_LIST_EMPTY:
1103		/* As IOs and ELS IO's complete we expect to get these events */
1104		break;
1105
1106	case OCS_EVT_DOMAIN_ATTACH_OK:
1107		/* don't care about domain_attach_ok */
1108		break;
1109
1110	/* ignore shutdown events as we're already in shutdown path */
1111	case OCS_EVT_SHUTDOWN:
1112		/* have default shutdown event take precedence */
1113		node->shutdown_reason = OCS_NODE_SHUTDOWN_DEFAULT;
1114		/* Fall through */
1115	case OCS_EVT_SHUTDOWN_EXPLICIT_LOGO:
1116	case OCS_EVT_SHUTDOWN_IMPLICIT_LOGO:
1117		node_printf(node, "%s received\n", ocs_sm_event_name(evt));
1118		break;
1119	default:
1120		__ocs_node_common(__func__, ctx, evt, arg);
1121		return NULL;
1122	}
1123
1124	return NULL;
1125}
1126
1127/**
1128 * @ingroup node_common
1129 * @brief state: initiate node shutdown
1130 *
1131 * State is entered when a node receives a shutdown event, and it's waiting
1132 * for all the active IOs and ELS IOs associated with the node to complete.
1133 *
1134 * @param ctx remote node sm context
1135 * @param evt event to process
1136 * @param arg per event optional argument
1137 *
1138 * @return returns NULL
1139 */
1140
1141void *
1142__ocs_node_wait_ios_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
1143{
1144	ocs_io_t *io;
1145	ocs_io_t *next;
1146	std_node_state_decl();
1147
1148	node_sm_trace();
1149
1150	switch(evt) {
1151	case OCS_EVT_ENTER:
1152		ocs_node_hold_frames(node);
1153
1154		/* first check to see if no ELS IOs are outstanding */
1155		if (ocs_els_io_list_empty(node, &node->els_io_active_list)) {
1156			/* If there are any active IOS, Free them. */
1157			if (!ocs_node_active_ios_empty(node)) {
1158				ocs_lock(&node->active_ios_lock);
1159				ocs_list_foreach_safe(&node->active_ios, io, next) {
1160					ocs_list_remove(&io->node->active_ios, io);
1161					ocs_io_free(node->ocs, io);
1162				}
1163				ocs_unlock(&node->active_ios_lock);
1164			}
1165			ocs_node_transition(node, __ocs_node_shutdown, NULL);
1166		}
1167		break;
1168
1169	case OCS_EVT_NODE_ACTIVE_IO_LIST_EMPTY:
1170	case OCS_EVT_ALL_CHILD_NODES_FREE: {
1171		if (ocs_node_active_ios_empty(node) &&
1172		    ocs_els_io_list_empty(node, &node->els_io_active_list)) {
1173			ocs_node_transition(node, __ocs_node_shutdown, NULL);
1174		}
1175		break;
1176	}
1177
1178	case OCS_EVT_EXIT:
1179		ocs_node_accept_frames(node);
1180		break;
1181
1182	case OCS_EVT_SRRS_ELS_REQ_FAIL:
1183		/* Can happen as ELS IO IO's complete */
1184		ocs_assert(node->els_req_cnt, NULL);
1185		node->els_req_cnt--;
1186		break;
1187
1188	/* ignore shutdown events as we're already in shutdown path */
1189	case OCS_EVT_SHUTDOWN:
1190		/* have default shutdown event take precedence */
1191		node->shutdown_reason = OCS_NODE_SHUTDOWN_DEFAULT;
1192		/* fall through */
1193	case OCS_EVT_SHUTDOWN_EXPLICIT_LOGO:
1194	case OCS_EVT_SHUTDOWN_IMPLICIT_LOGO:
1195		ocs_log_debug(ocs, "[%s] %-20s\n", node->display_name, ocs_sm_event_name(evt));
1196		break;
1197	case OCS_EVT_DOMAIN_ATTACH_OK:
1198		/* don't care about domain_attach_ok */
1199		break;
1200	default:
1201		__ocs_node_common(__func__, ctx, evt, arg);
1202		return NULL;
1203	}
1204
1205	return NULL;
1206}
1207
1208/**
1209 * @ingroup node_common
1210 * @brief state: common node event handler
1211 *
1212 * Handle common/shared node events
1213 *
1214 * @param funcname calling function's name
1215 * @param ctx remote node sm context
1216 * @param evt event to process
1217 * @param arg per event optional argument
1218 *
1219 * @return returns NULL
1220 */
1221
1222void *
1223__ocs_node_common(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
1224{
1225	ocs_node_t *node = NULL;
1226	ocs_t *ocs = NULL;
1227	ocs_node_cb_t *cbdata = arg;
1228	ocs_assert(ctx, NULL);
1229	ocs_assert(ctx->app, NULL);
1230	node = ctx->app;
1231	ocs_assert(node->ocs, NULL);
1232	ocs = node->ocs;
1233
1234	switch(evt) {
1235	case OCS_EVT_ENTER:
1236	case OCS_EVT_REENTER:
1237	case OCS_EVT_EXIT:
1238	case OCS_EVT_SPORT_TOPOLOGY_NOTIFY:
1239	case OCS_EVT_NODE_MISSING:
1240	case OCS_EVT_FCP_CMD_RCVD:
1241		break;
1242
1243	case OCS_EVT_NODE_REFOUND:
1244		node->refound = 1;
1245		break;
1246
1247	/* node->attached must be set appropriately for all node attach/detach events */
1248	case OCS_EVT_NODE_ATTACH_OK:
1249		node->attached = TRUE;
1250		break;
1251
1252	case OCS_EVT_NODE_FREE_OK:
1253	case OCS_EVT_NODE_ATTACH_FAIL:
1254		node->attached = FALSE;
1255		break;
1256
1257	/* handle any ELS completions that other states either didn't care about
1258	 * or forgot about
1259	 */
1260	case OCS_EVT_SRRS_ELS_CMPL_OK:
1261	case OCS_EVT_SRRS_ELS_CMPL_FAIL:
1262		ocs_assert(node->els_cmpl_cnt, NULL);
1263		node->els_cmpl_cnt--;
1264		break;
1265
1266	/* handle any ELS request completions that other states either didn't care about
1267	 * or forgot about
1268	 */
1269	case OCS_EVT_SRRS_ELS_REQ_OK:
1270	case OCS_EVT_SRRS_ELS_REQ_FAIL:
1271	case OCS_EVT_SRRS_ELS_REQ_RJT:
1272	case OCS_EVT_ELS_REQ_ABORTED:
1273		ocs_assert(node->els_req_cnt, NULL);
1274		node->els_req_cnt--;
1275		break;
1276
1277	case OCS_EVT_ELS_RCVD: {
1278		fc_header_t *hdr = cbdata->header->dma.virt;
1279
1280		/* Unsupported ELS was received, send LS_RJT, command not supported */
1281		ocs_log_debug(ocs, "[%s] (%s) ELS x%02x, LS_RJT not supported\n",
1282			      node->display_name, funcname, ((uint8_t*)cbdata->payload->dma.virt)[0]);
1283		ocs_send_ls_rjt(cbdata->io, ocs_be16toh(hdr->ox_id),
1284			FC_REASON_COMMAND_NOT_SUPPORTED, FC_EXPL_NO_ADDITIONAL, 0,
1285			NULL, NULL);
1286		break;
1287	}
1288
1289	case OCS_EVT_PLOGI_RCVD:
1290	case OCS_EVT_FLOGI_RCVD:
1291	case OCS_EVT_LOGO_RCVD:
1292	case OCS_EVT_PRLI_RCVD:
1293	case OCS_EVT_PRLO_RCVD:
1294	case OCS_EVT_PDISC_RCVD:
1295	case OCS_EVT_FDISC_RCVD:
1296	case OCS_EVT_ADISC_RCVD:
1297	case OCS_EVT_RSCN_RCVD:
1298	case OCS_EVT_SCR_RCVD: {
1299		fc_header_t *hdr = cbdata->header->dma.virt;
1300		/* sm: / send ELS_RJT */
1301		ocs_log_debug(ocs, "[%s] (%s) %s sending ELS_RJT\n",
1302			      node->display_name, funcname, ocs_sm_event_name(evt));
1303		/* if we didn't catch this in a state, send generic LS_RJT */
1304		ocs_send_ls_rjt(cbdata->io, ocs_be16toh(hdr->ox_id),
1305			FC_REASON_UNABLE_TO_PERFORM, FC_EXPL_NO_ADDITIONAL, 0,
1306			NULL, NULL);
1307
1308		break;
1309	}
1310	case OCS_EVT_GID_PT_RCVD:
1311	case OCS_EVT_RFT_ID_RCVD:
1312	case OCS_EVT_RFF_ID_RCVD: {
1313		fc_header_t *hdr = cbdata->header->dma.virt;
1314		ocs_log_debug(ocs, "[%s] (%s) %s sending CT_REJECT\n",
1315			      node->display_name, funcname, ocs_sm_event_name(evt));
1316		ocs_send_ct_rsp(cbdata->io, hdr->ox_id, cbdata->payload->dma.virt, FCCT_HDR_CMDRSP_REJECT, FCCT_COMMAND_NOT_SUPPORTED, 0);
1317		break;
1318	}
1319
1320	case OCS_EVT_ABTS_RCVD: {
1321		fc_header_t *hdr = cbdata->header->dma.virt;
1322		ocs_log_debug(ocs, "[%s] (%s) %s sending BA_ACC\n",
1323			      node->display_name, funcname, ocs_sm_event_name(evt));
1324
1325		/* sm: send BA_ACC */
1326		ocs_bls_send_acc_hdr(cbdata->io, hdr);
1327		break;
1328	}
1329
1330	default:
1331		ocs_log_test(node->ocs, "[%s] %-20s %-20s not handled\n", node->display_name, funcname,
1332			ocs_sm_event_name(evt));
1333		break;
1334	}
1335	return NULL;
1336}
1337
1338/**
1339 * @ingroup node_common
1340 * @brief save node service parameters
1341 *
1342 * Service parameters are copyed into the node structure
1343 *
1344 * @param node pointer to node structure
1345 * @param payload pointer to service parameters to save
1346 *
1347 * @return none
1348 */
1349
1350void
1351ocs_node_save_sparms(ocs_node_t *node, void *payload)
1352{
1353	ocs_memcpy(node->service_params, payload, sizeof(node->service_params));
1354}
1355
1356/**
1357 * @ingroup node_common
1358 * @brief Post event to node state machine context
1359 *
1360 * This is used by the node state machine code to post events to the nodes.  Upon
1361 * completion of the event posting, if the nesting depth is zero and we're not holding
1362 * inbound frames, then the pending frames are processed.
1363 *
1364 * @param node pointer to node
1365 * @param evt event to post
1366 * @param arg event posting argument
1367 *
1368 * @return none
1369 */
1370
1371void
1372ocs_node_post_event(ocs_node_t *node, ocs_sm_event_t evt, void *arg)
1373{
1374	int free_node = FALSE;
1375	ocs_assert(node);
1376
1377	ocs_node_lock(node);
1378		node->evtdepth ++;
1379
1380		ocs_sm_post_event(&node->sm, evt, arg);
1381
1382		/* If our event call depth is one and we're not holding frames
1383		 * then we can dispatch any pending frames.   We don't want to allow
1384		 * the ocs_process_node_pending() call to recurse.
1385		 */
1386		if (!node->hold_frames && (node->evtdepth == 1)) {
1387			ocs_process_node_pending(node);
1388		}
1389		node->evtdepth --;
1390
1391		/* Free the node object if so requested, and we're at an event
1392		 * call depth of zero
1393		 */
1394		if ((node->evtdepth == 0) && node->req_free) {
1395			free_node = TRUE;
1396		}
1397	ocs_node_unlock(node);
1398
1399	if (free_node) {
1400		ocs_node_free(node);
1401	}
1402
1403	return;
1404}
1405
1406/**
1407 * @ingroup node_common
1408 * @brief transition state of a node
1409 *
1410 * The node's state is transitioned to the requested state.  Entry/Exit
1411 * events are posted as needed.
1412 *
1413 * @param node pointer to node
1414 * @param state state to transition to
1415 * @param data transition data
1416 *
1417 * @return none
1418 */
1419
1420void
1421ocs_node_transition(ocs_node_t *node, ocs_sm_function_t state, void *data)
1422{
1423	ocs_sm_ctx_t *ctx = &node->sm;
1424
1425	ocs_node_lock(node);
1426		if (ctx->current_state == state) {
1427			ocs_node_post_event(node, OCS_EVT_REENTER, data);
1428		} else {
1429			ocs_node_post_event(node, OCS_EVT_EXIT, data);
1430			ctx->current_state = state;
1431			ocs_node_post_event(node, OCS_EVT_ENTER, data);
1432		}
1433	ocs_node_unlock(node);
1434}
1435
1436/**
1437 * @ingroup node_common
1438 * @brief build EUI formatted WWN
1439 *
1440 * Build a WWN given the somewhat transport agnostic iScsi naming specification, for FC
1441 * use the eui. format, an ascii string such as: "eui.10000000C9A19501"
1442 *
1443 * @param buffer buffer to place formatted name into
1444 * @param buffer_len length in bytes of the buffer
1445 * @param eui_name cpu endian 64 bit WWN value
1446 *
1447 * @return none
1448 */
1449
1450void
1451ocs_node_build_eui_name(char *buffer, uint32_t buffer_len, uint64_t eui_name)
1452{
1453	ocs_memset(buffer, 0, buffer_len);
1454
1455	ocs_snprintf(buffer, buffer_len, "eui.%016llx", (unsigned long long)eui_name);
1456}
1457
1458/**
1459 * @ingroup node_common
1460 * @brief return nodes' WWPN as a uint64_t
1461 *
1462 * The WWPN is computed from service parameters and returned as a uint64_t
1463 *
1464 * @param node pointer to node structure
1465 *
1466 * @return WWPN
1467 *
1468 */
1469
1470uint64_t
1471ocs_node_get_wwpn(ocs_node_t *node)
1472{
1473	fc_plogi_payload_t *sp = (fc_plogi_payload_t*) node->service_params;
1474
1475	return (((uint64_t)ocs_be32toh(sp->port_name_hi) << 32ll) | (ocs_be32toh(sp->port_name_lo)));
1476}
1477
1478/**
1479 * @ingroup node_common
1480 * @brief return nodes' WWNN as a uint64_t
1481 *
1482 * The WWNN is computed from service parameters and returned as a uint64_t
1483 *
1484 * @param node pointer to node structure
1485 *
1486 * @return WWNN
1487 *
1488 */
1489
1490uint64_t
1491ocs_node_get_wwnn(ocs_node_t *node)
1492{
1493	fc_plogi_payload_t *sp = (fc_plogi_payload_t*) node->service_params;
1494
1495	return (((uint64_t)ocs_be32toh(sp->node_name_hi) << 32ll) | (ocs_be32toh(sp->node_name_lo)));
1496}
1497
1498/**
1499 * @brief Generate node ddump data
1500 *
1501 * Generates the node ddumpdata
1502 *
1503 * @param textbuf pointer to text buffer
1504 * @param node pointer to node context
1505 *
1506 * @return Returns 0 on success, or a negative value on failure.
1507 */
1508
1509int
1510ocs_ddump_node(ocs_textbuf_t *textbuf, ocs_node_t *node)
1511{
1512	ocs_io_t *io;
1513	ocs_io_t *els;
1514	int retval = 0;
1515
1516	ocs_ddump_section(textbuf, "node", node->instance_index);
1517	ocs_ddump_value(textbuf, "display_name", "%s", node->display_name);
1518	ocs_ddump_value(textbuf, "current_state", "%s", node->current_state_name);
1519	ocs_ddump_value(textbuf, "prev_state", "%s", node->prev_state_name);
1520	ocs_ddump_value(textbuf, "current_evt", "%s", ocs_sm_event_name(node->current_evt));
1521	ocs_ddump_value(textbuf, "prev_evt", "%s", ocs_sm_event_name(node->prev_evt));
1522
1523	ocs_ddump_value(textbuf, "indicator", "%#x", node->rnode.indicator);
1524	ocs_ddump_value(textbuf, "fc_id", "%#06x", node->rnode.fc_id);
1525	ocs_ddump_value(textbuf, "attached", "%d", node->rnode.attached);
1526
1527	ocs_ddump_value(textbuf, "hold_frames", "%d", node->hold_frames);
1528	ocs_ddump_value(textbuf, "io_alloc_enabled", "%d", node->io_alloc_enabled);
1529	ocs_ddump_value(textbuf, "shutdown_reason", "%d", node->shutdown_reason);
1530	ocs_ddump_value(textbuf, "send_ls_acc", "%d", node->send_ls_acc);
1531	ocs_ddump_value(textbuf, "ls_acc_did", "%d", node->ls_acc_did);
1532	ocs_ddump_value(textbuf, "ls_acc_oxid", "%#04x", node->ls_acc_oxid);
1533	ocs_ddump_value(textbuf, "req_free", "%d", node->req_free);
1534	ocs_ddump_value(textbuf, "els_req_cnt", "%d", node->els_req_cnt);
1535	ocs_ddump_value(textbuf, "els_cmpl_cnt", "%d", node->els_cmpl_cnt);
1536
1537	ocs_ddump_value(textbuf, "targ", "%d", node->targ);
1538	ocs_ddump_value(textbuf, "init", "%d", node->init);
1539	ocs_ddump_value(textbuf, "wwnn", "%s", node->wwnn);
1540	ocs_ddump_value(textbuf, "wwpn", "%s", node->wwpn);
1541	ocs_ddump_value(textbuf, "login_state", "%d", (node->sm.current_state == __ocs_d_device_ready) ? 1 : 0);
1542	ocs_ddump_value(textbuf, "chained_io_count", "%d", node->chained_io_count);
1543	ocs_ddump_value(textbuf, "abort_cnt", "%d", node->abort_cnt);
1544
1545	ocs_display_sparams(NULL, "node_sparams", 1, textbuf, node->service_params+4);
1546
1547	ocs_lock(&node->pend_frames_lock);
1548		if (!ocs_list_empty(&node->pend_frames)) {
1549			ocs_hw_sequence_t *frame;
1550			ocs_ddump_section(textbuf, "pending_frames", 0);
1551			ocs_list_foreach(&node->pend_frames, frame) {
1552				fc_header_t *hdr;
1553				char buf[128];
1554
1555				hdr = frame->header->dma.virt;
1556				ocs_snprintf(buf, sizeof(buf), "%02x/%04x/%04x len %zu",
1557				 hdr->r_ctl, ocs_be16toh(hdr->ox_id), ocs_be16toh(hdr->rx_id),
1558				 frame->payload->dma.len);
1559				ocs_ddump_value(textbuf, "frame", "%s", buf);
1560			}
1561			ocs_ddump_endsection(textbuf, "pending_frames", 0);
1562		}
1563	ocs_unlock(&node->pend_frames_lock);
1564
1565	ocs_scsi_ini_ddump(textbuf, OCS_SCSI_DDUMP_NODE, node);
1566	ocs_scsi_tgt_ddump(textbuf, OCS_SCSI_DDUMP_NODE, node);
1567
1568	ocs_lock(&node->active_ios_lock);
1569		ocs_ddump_section(textbuf, "active_ios", 0);
1570		ocs_list_foreach(&node->active_ios, io) {
1571			ocs_ddump_io(textbuf, io);
1572		}
1573		ocs_ddump_endsection(textbuf, "active_ios", 0);
1574
1575		ocs_ddump_section(textbuf, "els_io_pend_list", 0);
1576		ocs_list_foreach(&node->els_io_pend_list, els) {
1577			ocs_ddump_els(textbuf, els);
1578		}
1579		ocs_ddump_endsection(textbuf, "els_io_pend_list", 0);
1580
1581		ocs_ddump_section(textbuf, "els_io_active_list", 0);
1582		ocs_list_foreach(&node->els_io_active_list, els) {
1583			ocs_ddump_els(textbuf, els);
1584		}
1585		ocs_ddump_endsection(textbuf, "els_io_active_list", 0);
1586	ocs_unlock(&node->active_ios_lock);
1587
1588	ocs_ddump_endsection(textbuf, "node", node->instance_index);
1589
1590	return retval;
1591}
1592
1593/**
1594 * @brief check ELS request completion
1595 *
1596 * Check ELS request completion event to make sure it's for the
1597 * ELS request we expect. If not, invoke given common event
1598 * handler and return an error.
1599 *
1600 * @param ctx state machine context
1601 * @param evt ELS request event
1602 * @param arg event argument
1603 * @param cmd ELS command expected
1604 * @param node_common_func common event handler to call if ELS
1605 *      		   doesn't match
1606 * @param funcname function name that called this
1607 *
1608 * @return zero if ELS command matches, -1 otherwise
1609 */
1610int32_t
1611node_check_els_req(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg, uint8_t cmd, ocs_node_common_func_t node_common_func, const char *funcname)
1612{
1613	ocs_node_t *node = NULL;
1614	ocs_t *ocs = NULL;
1615	ocs_node_cb_t *cbdata = arg;
1616	fc_els_gen_t *els_gen = NULL;
1617	ocs_assert(ctx, -1);
1618	node = ctx->app;
1619	ocs_assert(node, -1);
1620	ocs = node->ocs;
1621	ocs_assert(ocs, -1);
1622	cbdata = arg;
1623	ocs_assert(cbdata, -1);
1624	ocs_assert(cbdata->els, -1);
1625	els_gen = (fc_els_gen_t *)cbdata->els->els_req.virt;
1626	ocs_assert(els_gen, -1);
1627
1628	if ((cbdata->els->hio_type != OCS_HW_ELS_REQ) || (els_gen->command_code != cmd)) {
1629		if (cbdata->els->hio_type != OCS_HW_ELS_REQ) {
1630			ocs_log_debug(node->ocs, "[%s] %-20s expecting ELS cmd=x%x received type=%d\n",
1631				node->display_name, funcname, cmd, cbdata->els->hio_type);
1632		} else {
1633			ocs_log_debug(node->ocs, "[%s] %-20s expecting ELS cmd=x%x received cmd=x%x\n",
1634				node->display_name, funcname, cmd, els_gen->command_code);
1635		}
1636		/* send event to common handler */
1637		node_common_func(funcname, ctx, evt, arg);
1638		return -1;
1639	}
1640	return 0;
1641}
1642
1643/**
1644 * @brief check NS request completion
1645 *
1646 * Check ELS request completion event to make sure it's for the
1647 * nameserver request we expect. If not, invoke given common
1648 * event handler and return an error.
1649 *
1650 * @param ctx state machine context
1651 * @param evt ELS request event
1652 * @param arg event argument
1653 * @param cmd nameserver command expected
1654 * @param node_common_func common event handler to call if
1655 *      		   nameserver cmd doesn't match
1656 * @param funcname function name that called this
1657 *
1658 * @return zero if NS command matches, -1 otherwise
1659 */
1660int32_t
1661node_check_ns_req(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg, uint32_t cmd, ocs_node_common_func_t node_common_func, const char *funcname)
1662{
1663	ocs_node_t *node = NULL;
1664	ocs_t *ocs = NULL;
1665	ocs_node_cb_t *cbdata = arg;
1666	fcct_iu_header_t *fcct = NULL;
1667	ocs_assert(ctx, -1);
1668	node = ctx->app;
1669	ocs_assert(node, -1);
1670	ocs = node->ocs;
1671	ocs_assert(ocs, -1);
1672	cbdata = arg;
1673	ocs_assert(cbdata, -1);
1674	ocs_assert(cbdata->els, -1);
1675	fcct = (fcct_iu_header_t *)cbdata->els->els_req.virt;
1676	ocs_assert(fcct, -1);
1677
1678	if ((cbdata->els->hio_type != OCS_HW_FC_CT) || fcct->cmd_rsp_code != ocs_htobe16(cmd)) {
1679		if (cbdata->els->hio_type != OCS_HW_FC_CT) {
1680			ocs_log_debug(node->ocs, "[%s] %-20s expecting NS cmd=x%x received type=%d\n",
1681				node->display_name, funcname, cmd, cbdata->els->hio_type);
1682		} else {
1683			ocs_log_debug(node->ocs, "[%s] %-20s expecting NS cmd=x%x received cmd=x%x\n",
1684				node->display_name, funcname, cmd, fcct->cmd_rsp_code);
1685		}
1686		/* send event to common handler */
1687		node_common_func(funcname, ctx, evt, arg);
1688		return -1;
1689	}
1690	return 0;
1691}
1692
1693void
1694ocs_mgmt_node_list(ocs_textbuf_t *textbuf, void *object)
1695{
1696	ocs_io_t *io;
1697	ocs_node_t *node = (ocs_node_t *)object;
1698
1699	ocs_mgmt_start_section(textbuf, "node", node->instance_index);
1700
1701	/* Readonly values */
1702	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "display_name");
1703	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "indicator");
1704	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "fc_id");
1705	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "attached");
1706	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "hold_frames");
1707	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "shutting_down");
1708	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "req_free");
1709	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "ox_id");
1710	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "ox_id_in_use");
1711	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "abort_cnt");
1712	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "targ");
1713	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "init");
1714	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "wwpn");
1715	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "wwnn");
1716	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "pend_frames");
1717	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "chained_io_count");
1718
1719	/* Actions */
1720	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_EX, "resume");
1721
1722	ocs_lock(&node->active_ios_lock);
1723	ocs_list_foreach(&node->active_ios, io) {
1724		if ((io->mgmt_functions) && (io->mgmt_functions->get_list_handler)) {
1725			io->mgmt_functions->get_list_handler(textbuf, io);
1726		}
1727	}
1728	ocs_unlock(&node->active_ios_lock);
1729
1730	ocs_mgmt_end_section(textbuf, "node", node->instance_index);
1731}
1732
1733int
1734ocs_mgmt_node_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *object)
1735{
1736	ocs_io_t *io;
1737	ocs_node_t *node = (ocs_node_t *)object;
1738	char qualifier[80];
1739	int retval = -1;
1740
1741	ocs_mgmt_start_section(textbuf, "node", node->instance_index);
1742
1743	ocs_snprintf(qualifier, sizeof(qualifier), "%s/node[%d]", parent, node->instance_index);
1744
1745	/* If it doesn't start with my qualifier I don't know what to do with it */
1746	if (ocs_strncmp(name, qualifier, strlen(qualifier)) == 0) {
1747		char *unqualified_name = name + strlen(qualifier) +1;
1748
1749		/* See if it's a value I can supply */
1750		if (ocs_strcmp(unqualified_name, "display_name") == 0) {
1751			ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "display_name", node->display_name);
1752			retval = 0;
1753		} else if (ocs_strcmp(unqualified_name, "indicator") == 0) {
1754			ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "indicator", "0x%x", node->rnode.indicator);
1755			retval = 0;
1756		} else if (ocs_strcmp(unqualified_name, "fc_id") == 0) {
1757			ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "fc_id", "0x%06x", node->rnode.fc_id);
1758			retval = 0;
1759		} else if (ocs_strcmp(unqualified_name, "attached") == 0) {
1760			ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "attached", node->rnode.attached);
1761			retval = 0;
1762		} else if (ocs_strcmp(unqualified_name, "hold_frames") == 0) {
1763			ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "hold_frames", node->hold_frames);
1764			retval = 0;
1765		} else if (ocs_strcmp(unqualified_name, "io_alloc_enabled") == 0) {
1766			ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "io_alloc_enabled", node->io_alloc_enabled);
1767			retval = 0;
1768		} else if (ocs_strcmp(unqualified_name, "req_free") == 0) {
1769			ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "req_free", node->req_free);
1770			retval = 0;
1771		} else if (ocs_strcmp(unqualified_name, "ls_acc_oxid") == 0) {
1772			ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "ls_acc_oxid", "0x%#04x", node->ls_acc_oxid);
1773			retval = 0;
1774		} else if (ocs_strcmp(unqualified_name, "ls_acc_did") == 0) {
1775			ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "ls_acc_did", "0x%#04x", node->ls_acc_did);
1776			retval = 0;
1777		} else if (ocs_strcmp(unqualified_name, "abort_cnt") == 0) {
1778			ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "abort_cnt", "%d", node->abort_cnt);
1779			retval = 0;
1780		} else if (ocs_strcmp(unqualified_name, "targ") == 0) {
1781			ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "targ",  node->targ);
1782			retval = 0;
1783		} else if (ocs_strcmp(unqualified_name, "init") == 0) {
1784			ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "init",  node->init);
1785			retval = 0;
1786		} else if (ocs_strcmp(unqualified_name, "wwpn") == 0) {
1787			ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "wwpn", "%s", node->wwpn);
1788			retval = 0;
1789		} else if (ocs_strcmp(unqualified_name, "wwnn") == 0) {
1790			ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "wwnn", "%s", node->wwnn);
1791			retval = 0;
1792		} else if (ocs_strcmp(unqualified_name, "current_state") == 0) {
1793			ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "current_state", node->current_state_name);
1794			retval = 0;
1795		} else if (ocs_strcmp(unqualified_name, "login_state") == 0) {
1796			ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "login_state", "%d", (node->sm.current_state == __ocs_d_device_ready) ? 1 : 0);
1797			retval = 0;
1798		} else if (ocs_strcmp(unqualified_name, "pend_frames") == 0) {
1799			ocs_hw_sequence_t *frame;
1800			ocs_lock(&node->pend_frames_lock);
1801				ocs_list_foreach(&node->pend_frames, frame) {
1802					fc_header_t *hdr;
1803					char buf[128];
1804
1805					hdr = frame->header->dma.virt;
1806					ocs_snprintf(buf, sizeof(buf), "%02x/%04x/%04x len %zu", hdr->r_ctl,
1807						 ocs_be16toh(hdr->ox_id), ocs_be16toh(hdr->rx_id),
1808						 frame->payload->dma.len);
1809					ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "pend_frames", buf);
1810				}
1811			ocs_unlock(&node->pend_frames_lock);
1812			retval = 0;
1813		} else if (ocs_strcmp(unqualified_name, "chained_io_count") == 0) {
1814			ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "chained_io_count", "%d", node->chained_io_count);
1815			retval = 0;
1816		} else {
1817			/* If I didn't know the value of this status pass the request to each of my children */
1818			ocs_lock(&node->active_ios_lock);
1819				ocs_list_foreach(&node->active_ios, io) {
1820					if ((io->mgmt_functions) && (io->mgmt_functions->get_handler)) {
1821						retval = io->mgmt_functions->get_handler(textbuf, qualifier, name, io);
1822					}
1823
1824					if (retval == 0) {
1825						break;
1826					}
1827				}
1828			ocs_unlock(&node->active_ios_lock);
1829		}
1830	}
1831
1832	ocs_mgmt_end_section(textbuf, "node", node->instance_index);
1833
1834	return retval;
1835}
1836
1837void
1838ocs_mgmt_node_get_all(ocs_textbuf_t *textbuf, void *object)
1839{
1840	ocs_io_t *io;
1841	ocs_node_t *node = (ocs_node_t *)object;
1842	ocs_hw_sequence_t *frame;
1843
1844	ocs_mgmt_start_section(textbuf, "node", node->instance_index);
1845
1846	ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "display_name", node->display_name);
1847	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "indicator", "0x%x", node->rnode.indicator);
1848	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "fc_id", "0x%06x", node->rnode.fc_id);
1849	ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "attached", node->rnode.attached);
1850	ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "hold_frames", node->hold_frames);
1851	ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "io_alloc_enabled", node->io_alloc_enabled);
1852	ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "req_free", node->req_free);
1853	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "ls_acc_oxid", "0x%#04x", node->ls_acc_oxid);
1854	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "ls_acc_did", "0x%#04x", node->ls_acc_did);
1855	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "abort_cnt", "%d", node->abort_cnt);
1856	ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "targ",  node->targ);
1857	ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "init",  node->init);
1858	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "wwpn", "%s", node->wwpn);
1859	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "wwnn", "%s", node->wwnn);
1860
1861	ocs_lock(&node->pend_frames_lock);
1862	ocs_list_foreach(&node->pend_frames, frame) {
1863		fc_header_t *hdr;
1864		char buf[128];
1865
1866		hdr = frame->header->dma.virt;
1867		ocs_snprintf(buf, sizeof(buf), "%02x/%04x/%04x len %zu", hdr->r_ctl,
1868			     ocs_be16toh(hdr->ox_id), ocs_be16toh(hdr->rx_id),
1869			     frame->payload->dma.len);
1870		ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "pend_frames", buf);
1871	}
1872	ocs_unlock(&node->pend_frames_lock);
1873
1874	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "chained_io_count", "%d", node->chained_io_count);
1875	ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_EX, "resume");
1876	ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "current_state", node->current_state_name);
1877	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "login_state", "%d", (node->sm.current_state == __ocs_d_device_ready) ? 1 : 0);
1878
1879	ocs_lock(&node->active_ios_lock);
1880	ocs_list_foreach(&node->active_ios, io) {
1881		if ((io->mgmt_functions) && (io->mgmt_functions->get_all_handler)) {
1882			io->mgmt_functions->get_all_handler(textbuf,io);
1883		}
1884	}
1885	ocs_unlock(&node->active_ios_lock);
1886
1887	ocs_mgmt_end_section(textbuf, "node", node->instance_index);
1888}
1889
1890int
1891ocs_mgmt_node_set(char *parent, char *name, char *value, void *object)
1892{
1893	ocs_io_t *io;
1894	ocs_node_t *node = (ocs_node_t *)object;
1895	char qualifier[80];
1896	int retval = -1;
1897
1898	ocs_snprintf(qualifier, sizeof(qualifier), "%s/node[%d]", parent, node->instance_index);
1899
1900	/* If it doesn't start with my qualifier I don't know what to do with it */
1901	if (ocs_strncmp(name, qualifier, strlen(qualifier)) == 0) {
1902		ocs_lock(&node->active_ios_lock);
1903		ocs_list_foreach(&node->active_ios, io) {
1904			if ((io->mgmt_functions) && (io->mgmt_functions->set_handler)) {
1905				retval = io->mgmt_functions->set_handler(qualifier, name, value, io);
1906			}
1907
1908			if (retval == 0) {
1909				break;
1910			}
1911		}
1912		ocs_unlock(&node->active_ios_lock);
1913	}
1914
1915	return retval;
1916}
1917
1918int
1919ocs_mgmt_node_exec(char *parent, char *action, void *arg_in, uint32_t arg_in_length,
1920		   void *arg_out, uint32_t arg_out_length, void *object)
1921{
1922	ocs_io_t *io;
1923	ocs_node_t *node = (ocs_node_t *)object;
1924	char qualifier[80];
1925	int retval = -1;
1926
1927	ocs_snprintf(qualifier, sizeof(qualifier), "%s.node%d", parent, node->instance_index);
1928
1929	/* If it doesn't start with my qualifier I don't know what to do with it */
1930	if (ocs_strncmp(action, qualifier, strlen(qualifier)) == 0) {
1931		char *unqualified_name = action + strlen(qualifier) +1;
1932
1933		if (ocs_strcmp(unqualified_name, "resume") == 0) {
1934			ocs_node_post_event(node, OCS_EVT_RESUME, NULL);
1935		}
1936
1937		{
1938			/* If I didn't know how to do this action pass the request to each of my children */
1939			ocs_lock(&node->active_ios_lock);
1940				ocs_list_foreach(&node->active_ios, io) {
1941					if ((io->mgmt_functions) && (io->mgmt_functions->exec_handler)) {
1942						retval = io->mgmt_functions->exec_handler(qualifier, action, arg_in, arg_in_length,
1943							arg_out, arg_out_length, io);
1944					}
1945
1946					if (retval == 0) {
1947						break;
1948					}
1949				}
1950			ocs_unlock(&node->active_ios_lock);
1951		}
1952	}
1953
1954	return retval;
1955}
1956
1957/**
1958 * @brief Return TRUE if active ios list is empty
1959 *
1960 * Test if node->active_ios list is empty while holding the node->active_ios_lock.
1961 *
1962 * @param node pointer to node object
1963 *
1964 * @return TRUE if node active ios list is empty
1965 */
1966
1967int
1968ocs_node_active_ios_empty(ocs_node_t *node)
1969{
1970	int empty;
1971
1972	ocs_lock(&node->active_ios_lock);
1973		empty = ocs_list_empty(&node->active_ios);
1974	ocs_unlock(&node->active_ios_lock);
1975	return empty;
1976}
1977
1978/**
1979 * @brief Pause a node
1980 *
1981 * The node is placed in the __ocs_node_paused state after saving the state
1982 * to return to
1983 *
1984 * @param node Pointer to node object
1985 * @param state State to resume to
1986 *
1987 * @return none
1988 */
1989
1990void
1991ocs_node_pause(ocs_node_t *node, ocs_sm_function_t state)
1992{
1993	node->nodedb_state = state;
1994	ocs_node_transition(node, __ocs_node_paused, NULL);
1995}
1996
1997/**
1998 * @brief Paused node state
1999 *
2000 * This state is entered when a state is "paused". When resumed, the node
2001 * is transitioned to a previously saved state (node->ndoedb_state)
2002 *
2003 * @param ctx Remote node state machine context.
2004 * @param evt Event to process.
2005 * @param arg Per event optional argument.
2006 *
2007 * @return returns NULL
2008 */
2009
2010void *
2011__ocs_node_paused(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2012{
2013	std_node_state_decl();
2014
2015	node_sm_trace();
2016
2017	switch(evt) {
2018	case OCS_EVT_ENTER:
2019		node_printf(node, "Paused\n");
2020		break;
2021
2022	case OCS_EVT_RESUME: {
2023		ocs_sm_function_t pf = node->nodedb_state;
2024
2025		node->nodedb_state = NULL;
2026		ocs_node_transition(node, pf, NULL);
2027		break;
2028	}
2029
2030	case OCS_EVT_DOMAIN_ATTACH_OK:
2031		break;
2032
2033	case OCS_EVT_SHUTDOWN:
2034		node->req_free = 1;
2035		break;
2036
2037	default:
2038		__ocs_node_common(__func__, ctx, evt, arg);
2039		break;
2040	}
2041	return NULL;
2042}
2043
2044/**
2045 * @brief Resume a paused state
2046 *
2047 * Posts a resume event to the paused node.
2048 *
2049 * @param node Pointer to node object
2050 *
2051 * @return returns 0 for success, a negative error code value for failure.
2052 */
2053
2054int32_t
2055ocs_node_resume(ocs_node_t *node)
2056{
2057	ocs_assert(node != NULL, -1);
2058
2059	ocs_node_post_event(node, OCS_EVT_RESUME, NULL);
2060
2061	return 0;
2062}
2063
2064/**
2065 * @ingroup node_common
2066 * @brief Dispatch a ELS frame.
2067 *
2068 * <h3 class="desc">Description</h3>
2069 * An ELS frame is dispatched to the \c node state machine.
2070 * RQ Pair mode: this function is always called with a NULL hw
2071 * io.
2072 *
2073 * @param node Node that originated the frame.
2074 * @param seq header/payload sequence buffers
2075 *
2076 * @return Returns 0 if frame processed and RX buffers cleaned
2077 * up appropriately, -1 if frame not handled and RX buffers need
2078 * to be returned.
2079 */
2080
2081int32_t
2082ocs_node_recv_els_frame(ocs_node_t *node, ocs_hw_sequence_t *seq)
2083{
2084	struct {
2085		uint32_t cmd;
2086		ocs_sm_event_t evt;
2087		uint32_t payload_size;
2088	} els_cmd_list[] = {
2089		{FC_ELS_CMD_PLOGI,	OCS_EVT_PLOGI_RCVD, 	sizeof(fc_plogi_payload_t)},
2090		{FC_ELS_CMD_FLOGI,	OCS_EVT_FLOGI_RCVD, 	sizeof(fc_plogi_payload_t)},
2091		{FC_ELS_CMD_LOGO,	OCS_EVT_LOGO_RCVD, 	sizeof(fc_acc_payload_t)},
2092		{FC_ELS_CMD_RRQ,	OCS_EVT_RRQ_RCVD, 	sizeof(fc_acc_payload_t)},
2093		{FC_ELS_CMD_PRLI, 	OCS_EVT_PRLI_RCVD, 	sizeof(fc_prli_payload_t)},
2094		{FC_ELS_CMD_PRLO, 	OCS_EVT_PRLO_RCVD, 	sizeof(fc_prlo_payload_t)},
2095		{FC_ELS_CMD_PDISC, 	OCS_EVT_PDISC_RCVD, 	MAX_ACC_REJECT_PAYLOAD},
2096		{FC_ELS_CMD_FDISC, 	OCS_EVT_FDISC_RCVD, 	MAX_ACC_REJECT_PAYLOAD},
2097		{FC_ELS_CMD_ADISC, 	OCS_EVT_ADISC_RCVD, 	sizeof(fc_adisc_payload_t)},
2098		{FC_ELS_CMD_RSCN, 	OCS_EVT_RSCN_RCVD, 	MAX_ACC_REJECT_PAYLOAD},
2099		{FC_ELS_CMD_SCR	, 	OCS_EVT_SCR_RCVD, 	MAX_ACC_REJECT_PAYLOAD},
2100	};
2101	ocs_t *ocs = node->ocs;
2102	ocs_node_cb_t cbdata;
2103	fc_header_t *hdr = seq->header->dma.virt;
2104	uint8_t *buf = seq->payload->dma.virt;
2105	ocs_sm_event_t evt = OCS_EVT_ELS_RCVD;
2106	uint32_t payload_size = MAX_ACC_REJECT_PAYLOAD;
2107	uint32_t i;
2108
2109	ocs_memset(&cbdata, 0, sizeof(cbdata));
2110	cbdata.header = seq->header;
2111	cbdata.payload = seq->payload;
2112
2113	/* find a matching event for the ELS command */
2114	for (i = 0; i < ARRAY_SIZE(els_cmd_list); i ++) {
2115		if (els_cmd_list[i].cmd == buf[0]) {
2116			evt = els_cmd_list[i].evt;
2117			payload_size = els_cmd_list[i].payload_size;
2118			break;
2119		}
2120	}
2121
2122	switch(evt) {
2123	case OCS_EVT_FLOGI_RCVD:
2124		ocs_display_sparams(node->display_name, "flogi rcvd req", 0, NULL, ((uint8_t*)seq->payload->dma.virt)+4);
2125		break;
2126	case OCS_EVT_FDISC_RCVD:
2127		ocs_display_sparams(node->display_name, "fdisc rcvd req", 0, NULL, ((uint8_t*)seq->payload->dma.virt)+4);
2128		break;
2129	case OCS_EVT_PLOGI_RCVD:
2130		ocs_display_sparams(node->display_name, "plogi rcvd req", 0, NULL, ((uint8_t*)seq->payload->dma.virt)+4);
2131		break;
2132	default:
2133		break;
2134	}
2135
2136	cbdata.io = ocs_els_io_alloc(node, payload_size, OCS_ELS_ROLE_RESPONDER);
2137
2138	if (cbdata.io != NULL) {
2139		cbdata.io->hw_priv = seq->hw_priv;
2140		/* if we're here, sequence initiative has been transferred */
2141		cbdata.io->seq_init = 1;
2142
2143		ocs_node_post_event(node, evt, &cbdata);
2144	} else {
2145		node_printf(node, "failure to allocate SCSI IO for ELS s_id %06x d_id %06x ox_id %04x rx_id %04x\n",
2146			    fc_be24toh(hdr->s_id), fc_be24toh(hdr->d_id), ocs_be16toh(hdr->ox_id), ocs_be16toh(hdr->rx_id));
2147	}
2148	ocs_hw_sequence_free(&ocs->hw, seq);
2149	return 0;
2150}
2151
2152/**
2153 * @ingroup node_common
2154 * @brief Dispatch a ABTS frame (RQ Pair/sequence coalescing).
2155 *
2156 * <h3 class="desc">Description</h3>
2157 * An ABTS frame is dispatched to the node state machine. This
2158 * function is used for both RQ Pair and sequence coalescing.
2159 *
2160 * @param node Node that originated the frame.
2161 * @param seq Header/payload sequence buffers
2162 *
2163 * @return Returns 0 if frame processed and RX buffers cleaned
2164 * up appropriately, -1 if frame not handled and RX buffers need
2165 * to be returned.
2166 */
2167
2168int32_t
2169ocs_node_recv_abts_frame(ocs_node_t *node, ocs_hw_sequence_t *seq)
2170{
2171	ocs_t *ocs = node->ocs;
2172	ocs_xport_t *xport = ocs->xport;
2173	fc_header_t *hdr = seq->header->dma.virt;
2174	uint16_t ox_id = ocs_be16toh(hdr->ox_id);
2175	uint16_t rx_id = ocs_be16toh(hdr->rx_id);
2176	ocs_node_cb_t cbdata;
2177	int32_t rc = 0;
2178
2179	node->abort_cnt++;
2180
2181	/*
2182	 * Check to see if the IO we want to abort is active, if it not active,
2183	 * then we can send the BA_ACC using the send frame option
2184	 */
2185	if (ocs_io_find_tgt_io(ocs, node, ox_id, rx_id) == NULL) {
2186		uint32_t send_frame_capable;
2187
2188		ocs_log_debug(ocs, "IO not found (ox_id %04x)\n", ox_id);
2189
2190		/* If we have SEND_FRAME capability, then use it to send BA_ACC */
2191		rc = ocs_hw_get(&ocs->hw, OCS_HW_SEND_FRAME_CAPABLE, &send_frame_capable);
2192		if ((rc == 0) && send_frame_capable) {
2193			rc = ocs_sframe_send_bls_acc(node, seq);
2194			if (rc) {
2195				ocs_log_test(ocs, "ocs_bls_acc_send_frame failed\n");
2196			}
2197			return rc;
2198		}
2199		/* continuing */
2200	}
2201
2202	ocs_memset(&cbdata, 0, sizeof(cbdata));
2203	cbdata.header = seq->header;
2204	cbdata.payload = seq->payload;
2205
2206	cbdata.io = ocs_scsi_io_alloc(node, OCS_SCSI_IO_ROLE_RESPONDER);
2207	if (cbdata.io != NULL) {
2208		cbdata.io->hw_priv = seq->hw_priv;
2209		/* If we got this far, SIT=1 */
2210		cbdata.io->seq_init = 1;
2211
2212		/* fill out generic fields */
2213		cbdata.io->ocs = ocs;
2214		cbdata.io->node = node;
2215		cbdata.io->cmd_tgt = TRUE;
2216
2217		ocs_node_post_event(node, OCS_EVT_ABTS_RCVD, &cbdata);
2218	} else {
2219		ocs_atomic_add_return(&xport->io_alloc_failed_count, 1);
2220		node_printf(node, "SCSI IO allocation failed for ABTS received s_id %06x d_id %06x ox_id %04x rx_id %04x\n",
2221			    fc_be24toh(hdr->s_id), fc_be24toh(hdr->d_id), ocs_be16toh(hdr->ox_id), ocs_be16toh(hdr->rx_id));
2222	}
2223
2224	/* ABTS processed, return RX buffer to the chip */
2225	ocs_hw_sequence_free(&ocs->hw, seq);
2226	return 0;
2227}
2228
2229/**
2230 * @ingroup node_common
2231 * @brief Dispatch a CT frame.
2232 *
2233 * <h3 class="desc">Description</h3>
2234 * A CT frame is dispatched to the \c node state machine.
2235 * RQ Pair mode: this function is always called with a NULL hw
2236 * io.
2237 *
2238 * @param node Node that originated the frame.
2239 * @param seq header/payload sequence buffers
2240 *
2241 * @return Returns 0 if frame processed and RX buffers cleaned
2242 * up appropriately, -1 if frame not handled and RX buffers need
2243 * to be returned.
2244 */
2245
2246int32_t
2247ocs_node_recv_ct_frame(ocs_node_t *node, ocs_hw_sequence_t *seq)
2248{
2249	ocs_t *ocs = node->ocs;
2250	fc_header_t *hdr = seq->header->dma.virt;
2251	fcct_iu_header_t *iu = seq->payload->dma.virt;
2252	ocs_sm_event_t evt = OCS_EVT_ELS_RCVD;
2253	uint32_t payload_size = MAX_ACC_REJECT_PAYLOAD;
2254	uint16_t gscmd = ocs_be16toh(iu->cmd_rsp_code);
2255	ocs_node_cb_t cbdata;
2256	uint32_t i;
2257	struct {
2258		uint32_t cmd;
2259		ocs_sm_event_t evt;
2260		uint32_t payload_size;
2261	} ct_cmd_list[] = {
2262		{FC_GS_NAMESERVER_RFF_ID, OCS_EVT_RFF_ID_RCVD, 100},
2263		{FC_GS_NAMESERVER_RFT_ID, OCS_EVT_RFT_ID_RCVD, 100},
2264		{FC_GS_NAMESERVER_GNN_ID, OCS_EVT_GNN_ID_RCVD, 100},
2265		{FC_GS_NAMESERVER_GPN_ID, OCS_EVT_GPN_ID_RCVD, 100},
2266		{FC_GS_NAMESERVER_GFPN_ID, OCS_EVT_GFPN_ID_RCVD, 100},
2267		{FC_GS_NAMESERVER_GFF_ID, OCS_EVT_GFF_ID_RCVD, 100},
2268		{FC_GS_NAMESERVER_GID_FT, OCS_EVT_GID_FT_RCVD, 256},
2269		{FC_GS_NAMESERVER_GID_PT, OCS_EVT_GID_PT_RCVD, 256},
2270		{FC_GS_NAMESERVER_RPN_ID, OCS_EVT_RPN_ID_RCVD, 100},
2271		{FC_GS_NAMESERVER_RNN_ID, OCS_EVT_RNN_ID_RCVD, 100},
2272		{FC_GS_NAMESERVER_RCS_ID, OCS_EVT_RCS_ID_RCVD, 100},
2273		{FC_GS_NAMESERVER_RSNN_NN, OCS_EVT_RSNN_NN_RCVD, 100},
2274		{FC_GS_NAMESERVER_RSPN_ID, OCS_EVT_RSPN_ID_RCVD, 100},
2275		{FC_GS_NAMESERVER_RHBA, OCS_EVT_RHBA_RCVD, 100},
2276		{FC_GS_NAMESERVER_RPA, OCS_EVT_RPA_RCVD, 100},
2277	};
2278
2279	ocs_memset(&cbdata, 0, sizeof(cbdata));
2280	cbdata.header = seq->header;
2281	cbdata.payload = seq->payload;
2282
2283	/* find a matching event for the ELS/GS command */
2284	for (i = 0; i < ARRAY_SIZE(ct_cmd_list); i ++) {
2285		if (ct_cmd_list[i].cmd == gscmd) {
2286			evt = ct_cmd_list[i].evt;
2287			payload_size = ct_cmd_list[i].payload_size;
2288			break;
2289		}
2290	}
2291
2292	/* Allocate an IO and send a reject */
2293	cbdata.io = ocs_els_io_alloc(node, payload_size, OCS_ELS_ROLE_RESPONDER);
2294	if (cbdata.io == NULL) {
2295		node_printf(node, "GS IO failed for s_id %06x d_id %06x ox_id %04x rx_id %04x\n",
2296			fc_be24toh(hdr->s_id), fc_be24toh(hdr->d_id),
2297			ocs_be16toh(hdr->ox_id), ocs_be16toh(hdr->rx_id));
2298		return -1;
2299	}
2300	cbdata.io->hw_priv = seq->hw_priv;
2301	ocs_node_post_event(node, evt, &cbdata);
2302
2303	ocs_hw_sequence_free(&ocs->hw, seq);
2304	return 0;
2305}
2306
2307/**
2308 * @ingroup node_common
2309 * @brief Dispatch a FCP command frame when the node is not ready.
2310 *
2311 * <h3 class="desc">Description</h3>
2312 * A frame is dispatched to the \c node state machine.
2313 *
2314 * @param node Node that originated the frame.
2315 * @param seq header/payload sequence buffers
2316 *
2317 * @return Returns 0 if frame processed and RX buffers cleaned
2318 * up appropriately, -1 if frame not handled.
2319 */
2320
2321int32_t
2322ocs_node_recv_fcp_cmd(ocs_node_t *node, ocs_hw_sequence_t *seq)
2323{
2324	ocs_node_cb_t cbdata;
2325	ocs_t *ocs = node->ocs;
2326
2327	ocs_memset(&cbdata, 0, sizeof(cbdata));
2328	cbdata.header = seq->header;
2329	cbdata.payload = seq->payload;
2330	ocs_node_post_event(node, OCS_EVT_FCP_CMD_RCVD, &cbdata);
2331	ocs_hw_sequence_free(&ocs->hw, seq);
2332	return 0;
2333}
2334
2335/**
2336 * @ingroup node_common
2337 * @brief Stub handler for non-ABTS BLS frames
2338 *
2339 * <h3 class="desc">Description</h3>
2340 * Log message and drop. Customer can plumb it to their back-end as needed
2341 *
2342 * @param node Node that originated the frame.
2343 * @param seq header/payload sequence buffers
2344 *
2345 * @return Returns 0
2346 */
2347
2348int32_t
2349ocs_node_recv_bls_no_sit(ocs_node_t *node, ocs_hw_sequence_t *seq)
2350{
2351	fc_header_t *hdr = seq->header->dma.virt;
2352
2353	node_printf(node, "Dropping frame hdr = %08x %08x %08x %08x %08x %08x\n",
2354		    ocs_htobe32(((uint32_t *)hdr)[0]),
2355		    ocs_htobe32(((uint32_t *)hdr)[1]),
2356		    ocs_htobe32(((uint32_t *)hdr)[2]),
2357		    ocs_htobe32(((uint32_t *)hdr)[3]),
2358		    ocs_htobe32(((uint32_t *)hdr)[4]),
2359		    ocs_htobe32(((uint32_t *)hdr)[5]));
2360
2361	return -1;
2362}
2363