drivers/scsi/fcoe/fcoe_ctlr.c

Source file repositories/reference/linux-study-clean/drivers/scsi/fcoe/fcoe_ctlr.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/fcoe/fcoe_ctlr.c
Extension
.c
Size
89674 bytes
Lines
3254
Domain
Driver Families
Bucket
drivers/scsi
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

struct fip_sol {
		struct ethhdr eth;
		struct fip_header fip;
		struct {
			struct fip_mac_desc mac;
			struct fip_wwn_desc wwnn;
			struct fip_size_desc size;
		} __packed desc;
	}  __packed * sol;
	u32 fcoe_size;

	skb = dev_alloc_skb(sizeof(*sol));
	if (!skb)
		return;

	sol = (struct fip_sol *)skb->data;

	memset(sol, 0, sizeof(*sol));
	memcpy(sol->eth.h_dest, fcf ? fcf->fcf_mac : fcoe_all_fcfs, ETH_ALEN);
	memcpy(sol->eth.h_source, fip->ctl_src_addr, ETH_ALEN);
	sol->eth.h_proto = htons(ETH_P_FIP);

	sol->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
	sol->fip.fip_op = htons(FIP_OP_DISC);
	sol->fip.fip_subcode = FIP_SC_SOL;
	sol->fip.fip_dl_len = htons(sizeof(sol->desc) / FIP_BPW);
	sol->fip.fip_flags = htons(FIP_FL_FPMA);
	if (fip->spma)
		sol->fip.fip_flags |= htons(FIP_FL_SPMA);

	sol->desc.mac.fd_desc.fip_dtype = FIP_DT_MAC;
	sol->desc.mac.fd_desc.fip_dlen = sizeof(sol->desc.mac) / FIP_BPW;
	memcpy(sol->desc.mac.fd_mac, fip->ctl_src_addr, ETH_ALEN);

	sol->desc.wwnn.fd_desc.fip_dtype = FIP_DT_NAME;
	sol->desc.wwnn.fd_desc.fip_dlen = sizeof(sol->desc.wwnn) / FIP_BPW;
	put_unaligned_be64(fip->lp->wwnn, &sol->desc.wwnn.fd_wwn);

	fcoe_size = fcoe_ctlr_fcoe_size(fip);
	sol->desc.size.fd_desc.fip_dtype = FIP_DT_FCOE_SIZE;
	sol->desc.size.fd_desc.fip_dlen = sizeof(sol->desc.size) / FIP_BPW;
	sol->desc.size.fd_size = htons(fcoe_size);

	skb_put(skb, sizeof(*sol));
	skb->protocol = htons(ETH_P_FIP);
	skb->priority = fip->priority;
	skb_reset_mac_header(skb);
	skb_reset_network_header(skb);
	fip->send(fip, skb);

	if (!fcf)
		fip->sol_time = jiffies;
}

/**
 * fcoe_ctlr_link_up() - Start FCoE controller
 * @fip: The FCoE controller to start
 *
 * Called from the LLD when the network link is ready.
 */
void fcoe_ctlr_link_up(struct fcoe_ctlr *fip)
{
	mutex_lock(&fip->ctlr_mutex);
	if (fip->state == FIP_ST_NON_FIP || fip->state == FIP_ST_AUTO) {
		mutex_unlock(&fip->ctlr_mutex);
		fc_linkup(fip->lp);
	} else if (fip->state == FIP_ST_LINK_WAIT) {
		if (fip->mode == FIP_MODE_NON_FIP)
			fcoe_ctlr_set_state(fip, FIP_ST_NON_FIP);
		else
			fcoe_ctlr_set_state(fip, FIP_ST_AUTO);
		switch (fip->mode) {
		default:
			LIBFCOE_FIP_DBG(fip, "invalid mode %d\n", fip->mode);
			fallthrough;
		case FIP_MODE_AUTO:
			LIBFCOE_FIP_DBG(fip, "%s", "setting AUTO mode.\n");
			fallthrough;
		case FIP_MODE_FABRIC:
		case FIP_MODE_NON_FIP:
			mutex_unlock(&fip->ctlr_mutex);
			fc_linkup(fip->lp);
			fcoe_ctlr_solicit(fip, NULL);
			break;
		case FIP_MODE_VN2VN:
			fcoe_ctlr_vn_start(fip);
			mutex_unlock(&fip->ctlr_mutex);
			fc_linkup(fip->lp);
			break;
		}

Annotation

Implementation Notes