drivers/scsi/elx/libefc/efc_nport.c

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

File Facts

System
Linux kernel
Corpus path
drivers/scsi/elx/libefc/efc_nport.c
Extension
.c
Size
18743 bytes
Lines
778
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 (nport) {
			efc_log_err(domain->efc,
				    "NPORT %016llX %016llX already allocated\n",
				    wwnn, wwpn);
			return NULL;
		}
	}

	nport = kzalloc_obj(*nport, GFP_ATOMIC);
	if (!nport)
		return nport;

	/* initialize refcount */
	kref_init(&nport->ref);
	nport->release = _efc_nport_free;

	nport->efc = domain->efc;
	snprintf(nport->display_name, sizeof(nport->display_name), "------");
	nport->domain = domain;
	xa_init(&nport->lookup);
	nport->instance_index = domain->nport_count++;
	nport->sm.app = nport;
	nport->enable_ini = enable_ini;
	nport->enable_tgt = enable_tgt;
	nport->enable_rscn = (nport->enable_ini ||
			(nport->enable_tgt && enable_target_rscn(nport->efc)));

	/* Copy service parameters from domain */
	memcpy(nport->service_params, domain->service_params,
	       sizeof(struct fc_els_flogi));

	/* Update requested fc_id */
	nport->fc_id = fc_id;

	/* Update the nport's service parameters for the new wwn's */
	nport->wwpn = wwpn;
	nport->wwnn = wwnn;
	snprintf(nport->wwnn_str, sizeof(nport->wwnn_str), "%016llX",
		 (unsigned long long)wwnn);

	/*
	 * if this is the "first" nport of the domain,
	 * then make it the "phys" nport
	 */
	if (list_empty(&domain->nport_list))
		domain->nport = nport;

	INIT_LIST_HEAD(&nport->list_entry);
	list_add_tail(&nport->list_entry, &domain->nport_list);

	kref_get(&domain->ref);

	efc_log_debug(domain->efc, "New Nport [%s]\n", nport->display_name);

	return nport;
}

void
efc_nport_free(struct efc_nport *nport)
{
	struct efc_domain *domain;

	if (!nport)
		return;

	domain = nport->domain;
	efc_log_debug(domain->efc, "[%s] free nport\n", nport->display_name);
	list_del(&nport->list_entry);
	/*
	 * if this is the physical nport,
	 * then clear it out of the domain
	 */
	if (nport == domain->nport)
		domain->nport = NULL;

	xa_destroy(&nport->lookup);
	xa_erase(&domain->lookup, nport->fc_id);

	if (list_empty(&domain->nport_list))
		efc_domain_post_event(domain, EFC_EVT_ALL_CHILD_NODES_FREE,
				      NULL);

	kref_put(&domain->ref, domain->release);
	kref_put(&nport->ref, nport->release);
}

struct efc_nport *
efc_nport_find(struct efc_domain *domain, u32 d_id)
{
	struct efc_nport *nport;

Annotation

Implementation Notes