Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d9883548 authored by Jing Huang's avatar Jing Huang Committed by James Bottomley
Browse files

[SCSI] bfa: PBC vport create



This patch enables creating PBC vport.
During fcs init, fcs will read PBC vport using bfa iocfc API and invoke fcb
callback to add the pbc vport entries into a list. The pbc vport list will be
traversed in the subsequent pci probe process and vport will be created using
fc transport provided vport create function.

Signed-off-by: default avatarJing Huang <huangj@brocade.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent ed969324
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -99,14 +99,22 @@ bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
void
bfa_fcs_init(struct bfa_fcs_s *fcs)
{
	int             i;
	int i, npbc_vports;
	struct bfa_fcs_mod_s  *mod;
	struct bfi_pbc_vport_s pbc_vports[BFI_PBC_MAX_VPORTS];

	for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
		mod = &fcs_modules[i];
		if (mod->modinit)
			mod->modinit(fcs);
	}
	/* Initialize pbc vports */
	if (!fcs->min_cfg) {
		npbc_vports =
			bfa_iocfc_get_pbc_vports(fcs->bfa, pbc_vports);
		for (i = 0; i < npbc_vports; i++)
			bfa_fcb_pbc_vport_create(fcs->bfa->bfad, pbc_vports[i]);
	}
}

/**
+11 −0
Original line number Diff line number Diff line
@@ -882,6 +882,17 @@ bfa_iocfc_get_pbc_boot_cfg(struct bfa_s *bfa, struct bfa_boot_pbc_s *pbcfg)
	memcpy(pbcfg->pblun, cfgrsp->pbc_cfg.blun, sizeof(pbcfg->pblun));
}

int
bfa_iocfc_get_pbc_vports(struct bfa_s *bfa, struct bfi_pbc_vport_s *pbc_vport)
{
	struct bfa_iocfc_s *iocfc = &bfa->iocfc;
	struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;

	memcpy(pbc_vport, cfgrsp->pbc_cfg.vport, sizeof(cfgrsp->pbc_cfg.vport));
	return cfgrsp->pbc_cfg.nvports;
}


#endif

+3 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <bfa_ioc.h>
#include <bfa.h>
#include <bfi/bfi_iocfc.h>
#include <bfi/bfi_pbc.h>
#include <bfa_callback_priv.h>

#define BFA_REQQ_NELEMS_MIN	(4)
@@ -169,6 +170,8 @@ void bfa_com_attach(struct bfa_s *bfa, struct bfa_meminfo_s *mi,
void bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t **wwns);
void bfa_iocfc_get_pbc_boot_cfg(struct bfa_s *bfa,
		struct bfa_boot_pbc_s *pbcfg);
int bfa_iocfc_get_pbc_vports(struct bfa_s *bfa,
		struct bfi_pbc_vport_s *pbc_vport);

#endif /* __BFA_IOCFC_H__ */
+56 −5
Original line number Diff line number Diff line
@@ -322,7 +322,31 @@ bfa_fcb_rport_alloc(struct bfad_s *bfad, struct bfa_fcs_rport_s **rport,
	return rc;
}

/**
 * @brief
 * FCS PBC VPORT Create
 */
void
bfa_fcb_pbc_vport_create(struct bfad_s *bfad, struct bfi_pbc_vport_s pbc_vport)
{

	struct bfad_pcfg_s *pcfg;

	pcfg = kzalloc(sizeof(struct bfad_pcfg_s), GFP_ATOMIC);
	if (!pcfg) {
		bfa_trc(bfad, 0);
		return;
	}

	pcfg->port_cfg.roles = BFA_PORT_ROLE_FCP_IM;
	pcfg->port_cfg.pwwn = pbc_vport.vp_pwwn;
	pcfg->port_cfg.nwwn = pbc_vport.vp_nwwn;
	pcfg->port_cfg.preboot_vp  = BFA_TRUE;

	list_add_tail(&pcfg->list_entry, &bfad->pbc_pcfg_list);

	return;
}

void
bfad_hal_mem_release(struct bfad_s *bfad)
@@ -496,8 +520,12 @@ bfad_vport_create(struct bfad_s *bfad, u16 vf_id,

	vport->drv_port.bfad = bfad;
	spin_lock_irqsave(&bfad->bfad_lock, flags);
	rc = bfa_fcs_vport_create(&vport->fcs_vport, &bfad->bfa_fcs, vf_id,
				  port_cfg, vport);
	if (port_cfg->preboot_vp == BFA_TRUE)
		rc = bfa_fcs_pbc_vport_create(&vport->fcs_vport,
				&bfad->bfa_fcs, vf_id, port_cfg, vport);
	else
		rc = bfa_fcs_vport_create(&vport->fcs_vport,
				&bfad->bfa_fcs, vf_id, port_cfg, vport);
	spin_unlock_irqrestore(&bfad->bfad_lock, flags);

	if (rc != BFA_STATUS_OK)
@@ -884,6 +912,7 @@ bfa_status_t
bfad_start_ops(struct bfad_s *bfad)
{
	int retval;
	struct bfad_pcfg_s *pcfg, *pcfg_new;

	/* PPORT FCS config */
	bfad_fcs_port_cfg(bfad);
@@ -901,6 +930,27 @@ bfad_start_ops(struct bfad_s *bfad)

	bfad_drv_start(bfad);

	/* pbc vport creation */
	list_for_each_entry_safe(pcfg, pcfg_new,  &bfad->pbc_pcfg_list,
					list_entry) {
		struct fc_vport_identifiers vid;
		struct fc_vport *fc_vport;

		memset(&vid, 0, sizeof(vid));
		vid.roles = FC_PORT_ROLE_FCP_INITIATOR;
		vid.vport_type = FC_PORTTYPE_NPIV;
		vid.disable = false;
		vid.node_name = wwn_to_u64((u8 *)&pcfg->port_cfg.nwwn);
		vid.port_name = wwn_to_u64((u8 *)&pcfg->port_cfg.pwwn);
		fc_vport = fc_vport_create(bfad->pport.im_port->shost, 0, &vid);
		if (!fc_vport)
			printk(KERN_WARNING "bfad%d: failed to create pbc vport"
				" %llx\n", bfad->inst_no, vid.port_name);
		list_del(&pcfg->list_entry);
		kfree(pcfg);

	}

	/*
	 * If bfa_linkup_delay is set to -1 default; try to retrive the
	 * value using the bfad_os_get_linkup_delay(); else use the
@@ -1031,6 +1081,7 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)

	bfad->ref_count = 0;
	bfad->pport.bfad = bfad;
	INIT_LIST_HEAD(&bfad->pbc_pcfg_list);

	bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s",
					"bfad_worker");
+26 −17
Original line number Diff line number Diff line
@@ -373,20 +373,27 @@ bfad_im_vport_create(struct fc_vport *fc_vport, bool disable)
		(struct bfad_im_port_s *) shost->hostdata[0];
	struct bfad_s *bfad = im_port->bfad;
	struct bfa_port_cfg_s port_cfg;
	struct bfad_pcfg_s *pcfg;
	int status = 0, rc;
	unsigned long flags;

	memset(&port_cfg, 0, sizeof(port_cfg));

	port_cfg.pwwn = wwn_to_u64((u8 *) &fc_vport->port_name);
	port_cfg.nwwn = wwn_to_u64((u8 *) &fc_vport->node_name);

	u64_to_wwn(fc_vport->node_name, (u8 *)&port_cfg.nwwn);
	u64_to_wwn(fc_vport->port_name, (u8 *)&port_cfg.pwwn);
	if (strlen(vname) > 0)
		strcpy((char *)&port_cfg.sym_name, vname);

	port_cfg.roles = BFA_PORT_ROLE_FCP_IM;
	rc = bfad_vport_create(bfad, 0, &port_cfg, &fc_vport->dev);

	spin_lock_irqsave(&bfad->bfad_lock, flags);
	list_for_each_entry(pcfg, &bfad->pbc_pcfg_list, list_entry) {
		if (port_cfg.pwwn == pcfg->port_cfg.pwwn) {
			port_cfg.preboot_vp = pcfg->port_cfg.preboot_vp;
			break;
		}
	}
	spin_unlock_irqrestore(&bfad->bfad_lock, flags);

	rc = bfad_vport_create(bfad, 0, &port_cfg, &fc_vport->dev);
	if (rc == BFA_STATUS_OK) {
		struct bfad_vport_s *vport;
		struct bfa_fcs_vport_s *fcs_vport;
@@ -395,17 +402,17 @@ bfad_im_vport_create(struct fc_vport *fc_vport, bool disable)
		spin_lock_irqsave(&bfad->bfad_lock, flags);
		fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0,
					port_cfg.pwwn);
		if (fcs_vport == NULL) {
		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
		if (fcs_vport == NULL)
			return VPCERR_BAD_WWN;
		}

		fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE);
		if (disable) {
			spin_lock_irqsave(&bfad->bfad_lock, flags);
			bfa_fcs_vport_stop(fcs_vport);
			spin_unlock_irqrestore(&bfad->bfad_lock, flags);
			fc_vport_set_state(fc_vport, FC_VPORT_DISABLED);
		}
		spin_unlock_irqrestore(&bfad->bfad_lock, flags);

		vport = fcs_vport->vport_drv;
		vshost = vport->drv_port.im_port->shost;
@@ -413,7 +420,6 @@ bfad_im_vport_create(struct fc_vport *fc_vport, bool disable)
		fc_host_port_name(vshost) = wwn_to_u64((u8 *)&port_cfg.pwwn);
		fc_vport->dd_data = vport;
		vport->drv_port.im_port->fc_vport = fc_vport;

	} else if (rc == BFA_STATUS_INVALID_WWN)
		return VPCERR_BAD_WWN;
	else if (rc == BFA_STATUS_VPORT_EXISTS)
@@ -449,7 +455,7 @@ bfad_im_vport_delete(struct fc_vport *fc_vport)
	port = im_port->port;

	vshost = vport->drv_port.im_port->shost;
	pwwn = wwn_to_u64((u8 *) &fc_host_port_name(vshost));
	u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn);

	spin_lock_irqsave(&bfad->bfad_lock, flags);
	fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn);
@@ -467,6 +473,9 @@ bfad_im_vport_delete(struct fc_vport *fc_vport)
	rc = bfa_fcs_vport_delete(&vport->fcs_vport);
	spin_unlock_irqrestore(&bfad->bfad_lock, flags);

	if (rc == BFA_STATUS_PBC)
		return -1;

	wait_for_completion(vport->comp_del);

free_scsi_host:
@@ -490,7 +499,7 @@ bfad_im_vport_disable(struct fc_vport *fc_vport, bool disable)
	vport = (struct bfad_vport_s *)fc_vport->dd_data;
	bfad = vport->drv_port.bfad;
	vshost = vport->drv_port.im_port->shost;
	pwwn = wwn_to_u64((u8 *) &fc_vport->port_name);
	u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn);

	spin_lock_irqsave(&bfad->bfad_lock, flags);
	fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn);
Loading