drivers/scsi/elx/libefc/efc_fabric.c

Source file repositories/reference/linux-study-clean/drivers/scsi/elx/libefc/efc_fabric.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/elx/libefc/efc_fabric.c
Extension
.c
Size
36463 bytes
Lines
1564
Domain
Driver Families
Bucket
drivers/scsi
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (rc < 0) {
			node_printf(node, "Failed freeing HW node, rc=%d\n",
				    rc);
		}
	}
	/*
	 * node has either been detached or is in the process of being detached,
	 * call common node's initiate cleanup function
	 */
	efc_node_initiate_cleanup(node);
}

static void
__efc_fabric_common(const char *funcname, struct efc_sm_ctx *ctx,
		    enum efc_sm_event evt, void *arg)
{
	struct efc_node *node = NULL;

	node = ctx->app;

	switch (evt) {
	case EFC_EVT_DOMAIN_ATTACH_OK:
		break;
	case EFC_EVT_SHUTDOWN:
		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
		efc_fabric_initiate_shutdown(node);
		break;

	default:
		/* call default event handler common to all nodes */
		__efc_node_common(funcname, ctx, evt, arg);
	}
}

void
__efc_fabric_init(struct efc_sm_ctx *ctx, enum efc_sm_event evt,
		  void *arg)
{
	struct efc_node *node = ctx->app;
	struct efc *efc = node->efc;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_REENTER:
		efc_log_debug(efc, ">>> reenter !!\n");
		fallthrough;

	case EFC_EVT_ENTER:
		/* send FLOGI */
		efc_send_flogi(node);
		efc_node_transition(node, __efc_fabric_flogi_wait_rsp, NULL);
		break;

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
efc_fabric_set_topology(struct efc_node *node,
			enum efc_nport_topology topology)
{
	node->nport->topology = topology;
}

void
efc_fabric_notify_topology(struct efc_node *node)
{
	struct efc_node *tmp_node;
	unsigned long index;

	/*
	 * now loop through the nodes in the nport
	 * and send topology notification
	 */
	xa_for_each(&node->nport->lookup, index, tmp_node) {
		if (tmp_node != node) {
			efc_node_post_event(tmp_node,
					    EFC_EVT_NPORT_TOPOLOGY_NOTIFY,
					    &node->nport->topology);
		}
	}
}

static bool efc_rnode_is_nport(struct fc_els_flogi *rsp)
{
	return !(ntohs(rsp->fl_csp.sp_features) & FC_SP_FT_FPORT);

Annotation

Implementation Notes