drivers/scsi/elx/libefc/efc_node.c

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

File Facts

System
Linux kernel
Corpus path
drivers/scsi/elx/libefc/efc_node.c
Extension
.c
Size
26756 bytes
Lines
1103
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 (fc_id == FC_FID_DOM_MGR) {
			snprintf(buffer, buffer_length, "dctl%02x",
				 (fc_id & 0x0000ff));
		} else {
			snprintf(buffer, buffer_length, "%06x", fc_id);
		}
		break;
	}
}

void
efc_node_update_display_name(struct efc_node *node)
{
	u32 port_id = node->rnode.fc_id;
	struct efc_nport *nport = node->nport;
	char portid_display[16];

	efc_node_fcid_display(port_id, portid_display, sizeof(portid_display));

	snprintf(node->display_name, sizeof(node->display_name), "%s.%s",
		 nport->display_name, portid_display);
}

void
efc_node_send_ls_io_cleanup(struct efc_node *node)
{
	if (node->send_ls_acc != EFC_NODE_SEND_LS_ACC_NONE) {
		efc_log_debug(node->efc, "[%s] cleaning up LS_ACC oxid=0x%x\n",
			      node->display_name, node->ls_acc_oxid);

		node->send_ls_acc = EFC_NODE_SEND_LS_ACC_NONE;
		node->ls_acc_io = NULL;
	}
}

static void efc_node_handle_implicit_logo(struct efc_node *node)
{
	int rc;

	/*
	 * currently, only case for implicit logo is PLOGI
	 * recvd. Thus, node's ELS IO pending list won't be
	 * empty (PLOGI will be on it)
	 */
	WARN_ON(node->send_ls_acc != EFC_NODE_SEND_LS_ACC_PLOGI);
	node_printf(node, "Reason: implicit logout, re-authenticate\n");

	/* Re-attach node with the same HW node resources */
	node->req_free = false;
	rc = efc_node_attach(node);
	efc_node_transition(node, __efc_d_wait_node_attach, NULL);
	node->els_io_enabled = true;

	if (rc < 0)
		efc_node_post_event(node, EFC_EVT_NODE_ATTACH_FAIL, NULL);
}

static void efc_node_handle_explicit_logo(struct efc_node *node)
{
	s8 pend_frames_empty;
	unsigned long flags = 0;

	/* cleanup any pending LS_ACC ELSs */
	efc_node_send_ls_io_cleanup(node);

	spin_lock_irqsave(&node->pend_frames_lock, flags);
	pend_frames_empty = list_empty(&node->pend_frames);
	spin_unlock_irqrestore(&node->pend_frames_lock, flags);

	/*
	 * there are two scenarios where we want to keep
	 * this node alive:
	 * 1. there are pending frames that need to be
	 *    processed or
	 * 2. we're an initiator and the remote node is
	 *    a target and we need to re-authenticate
	 */
	node_printf(node, "Shutdown: explicit logo pend=%d ", !pend_frames_empty);
	node_printf(node, "nport.ini=%d node.tgt=%d\n",
		    node->nport->enable_ini, node->targ);
	if (!pend_frames_empty || (node->nport->enable_ini && node->targ)) {
		u8 send_plogi = false;

		if (node->nport->enable_ini && node->targ) {
			/*
			 * we're an initiator and
			 * node shutting down is a target;
			 * we'll need to re-authenticate in
			 * initial state
			 */

Annotation

Implementation Notes