Ejemplo n.º 1
0
/*
 * csio_reg_rnode - Register a remote port with FC transport.
 * @rn: Rnode representing remote port.
 *
 * Call fc_remote_port_add() to register this remote port with FC transport.
 * If remote port is Initiator OR Target OR both, change the role appropriately.
 *
 */
void
csio_reg_rnode(struct csio_rnode *rn)
{
	struct csio_lnode *ln		= csio_rnode_to_lnode(rn);
	struct Scsi_Host *shost		= csio_ln_to_shost(ln);
	struct fc_rport_identifiers ids;
	struct fc_rport  *rport;
	struct csio_service_parms *sp;

	ids.node_name	= wwn_to_u64(csio_rn_wwnn(rn));
	ids.port_name	= wwn_to_u64(csio_rn_wwpn(rn));
	ids.port_id	= rn->nport_id;
	ids.roles	= FC_RPORT_ROLE_UNKNOWN;

	if (rn->role & CSIO_RNFR_INITIATOR || rn->role & CSIO_RNFR_TARGET) {
		rport = rn->rport;
		CSIO_ASSERT(rport != NULL);
		goto update_role;
	}

	rn->rport = fc_remote_port_add(shost, 0, &ids);
	if (!rn->rport) {
		csio_ln_err(ln, "Failed to register rport = 0x%x.\n",
					rn->nport_id);
		return;
	}

	ln->num_reg_rnodes++;
	rport = rn->rport;
	spin_lock_irq(shost->host_lock);
	*((struct csio_rnode **)rport->dd_data) = rn;
	spin_unlock_irq(shost->host_lock);

	sp = &rn->rn_sparm;
	rport->maxframe_size = ntohs(sp->csp.sp_bb_data);
	if (ntohs(sp->clsp[2].cp_class) & FC_CPC_VALID)
		rport->supported_classes = FC_COS_CLASS3;
	else
		rport->supported_classes = FC_COS_UNSPECIFIED;
update_role:
	if (rn->role & CSIO_RNFR_INITIATOR)
		ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
	if (rn->role & CSIO_RNFR_TARGET)
		ids.roles |= FC_RPORT_ROLE_FCP_TARGET;

	if (ids.roles != FC_RPORT_ROLE_UNKNOWN)
		fc_remote_port_rolechg(rport, ids.roles);

	rn->scsi_id = rport->scsi_target_id;

	csio_ln_dbg(ln, "Remote port x%x role 0x%x registered\n",
		rn->nport_id, ids.roles);
}
Ejemplo n.º 2
0
static int
bfad_im_vport_disable(struct fc_vport *fc_vport, bool disable)
{
	struct bfad_vport_s *vport;
	struct bfad_s *bfad;
	struct bfa_fcs_vport_s *fcs_vport;
	struct Scsi_Host *vshost;
	wwn_t   pwwn;
	unsigned long flags;

	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);

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

	if (fcs_vport == NULL)
		return VPCERR_BAD_WWN;

	if (disable) {
		bfa_fcs_vport_stop(fcs_vport);
		fc_vport_set_state(fc_vport, FC_VPORT_DISABLED);
	} else {
		bfa_fcs_vport_start(fcs_vport);
		fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE);
	}

	return 0;
}
Ejemplo n.º 3
0
/*
 * csio_fchost_attr_init - Initialize FC transport attributes
 * @ln: Lnode.
 *
 */
void
csio_fchost_attr_init(struct csio_lnode *ln)
{
	struct Scsi_Host  *shost = csio_ln_to_shost(ln);

	fc_host_node_name(shost) = wwn_to_u64(csio_ln_wwnn(ln));
	fc_host_port_name(shost) = wwn_to_u64(csio_ln_wwpn(ln));

	fc_host_supported_classes(shost) = FC_COS_CLASS3;
	fc_host_max_npiv_vports(shost) =
			(csio_lnode_to_hw(ln))->fres_info.max_vnps;
	fc_host_supported_speeds(shost) = FC_PORTSPEED_10GBIT |
		FC_PORTSPEED_1GBIT;

	fc_host_maxframe_size(shost) = ntohs(ln->ln_sparm.csp.sp_bb_data);
	memset(fc_host_supported_fc4s(shost), 0,
		sizeof(fc_host_supported_fc4s(shost)));
	fc_host_supported_fc4s(shost)[7] = 1;

	memset(fc_host_active_fc4s(shost), 0,
		sizeof(fc_host_active_fc4s(shost)));
	fc_host_active_fc4s(shost)[7] = 1;
}
Ejemplo n.º 4
0
/*
 * csio_get_host_fabric_name - Return fabric name
 * @shost: scsi host.
 *
 */
static void
csio_get_host_fabric_name(struct Scsi_Host *shost)
{
	struct csio_lnode *ln = shost_priv(shost);
	struct csio_rnode *rn = NULL;
	struct csio_hw *hw = csio_lnode_to_hw(ln);

	spin_lock_irq(&hw->lock);
	rn = csio_rnode_lookup_portid(ln, FC_FID_FLOGI);
	if (rn)
		fc_host_fabric_name(shost) = wwn_to_u64(csio_rn_wwnn(rn));
	else
		fc_host_fabric_name(shost) = 0;
	spin_unlock_irq(&hw->lock);
}
Ejemplo n.º 5
0
static int
bfad_im_vport_delete(struct fc_vport *fc_vport)
{
	struct bfad_vport_s *vport = (struct bfad_vport_s *)fc_vport->dd_data;
	struct bfad_im_port_s *im_port =
			(struct bfad_im_port_s *) vport->drv_port.im_port;
	struct bfad_s *bfad = im_port->bfad;
	struct bfad_port_s *port;
	struct bfa_fcs_vport_s *fcs_vport;
	struct Scsi_Host *vshost;
	wwn_t   pwwn;
	int rc;
	unsigned long flags;
	struct completion fcomp;

	if (im_port->flags & BFAD_PORT_DELETE)
		goto free_scsi_host;

	port = im_port->port;

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

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

	if (fcs_vport == NULL)
		return VPCERR_BAD_WWN;

	vport->drv_port.flags |= BFAD_PORT_DELETE;

	vport->comp_del = &fcomp;
	init_completion(vport->comp_del);

	spin_lock_irqsave(&bfad->bfad_lock, flags);
	rc = bfa_fcs_vport_delete(&vport->fcs_vport);
	spin_unlock_irqrestore(&bfad->bfad_lock, flags);

	wait_for_completion(vport->comp_del);

free_scsi_host:
	bfad_os_scsi_host_free(bfad, im_port);

	kfree(vport);

	return 0;
}
Ejemplo n.º 6
0
static int
csio_vport_create(struct fc_vport *fc_vport, bool disable)
{
	struct Scsi_Host *shost = fc_vport->shost;
	struct csio_lnode *pln = shost_priv(shost);
	struct csio_lnode *ln = NULL;
	struct csio_hw *hw = csio_lnode_to_hw(pln);
	uint8_t wwn[8];
	int ret = -1;

	ln = csio_shost_init(hw, &fc_vport->dev, false, pln);
	if (!ln)
		goto error;

	if (fc_vport->node_name != 0) {
		u64_to_wwn(fc_vport->node_name, wwn);

		if (!CSIO_VALID_WWN(wwn)) {
			csio_ln_err(ln,
				    "vport create failed. Invalid wwnn\n");
			goto error;
		}
		memcpy(csio_ln_wwnn(ln), wwn, 8);
	}

	if (fc_vport->port_name != 0) {
		u64_to_wwn(fc_vport->port_name, wwn);

		if (!CSIO_VALID_WWN(wwn)) {
			csio_ln_err(ln,
				    "vport create failed. Invalid wwpn\n");
			goto error;
		}

		if (csio_lnode_lookup_by_wwpn(hw, wwn)) {
			csio_ln_err(ln,
			    "vport create failed. wwpn already exists\n");
			goto error;
		}
		memcpy(csio_ln_wwpn(ln), wwn, 8);
	}

	fc_vport_set_state(fc_vport, FC_VPORT_INITIALIZING);

	if (csio_fcoe_alloc_vnp(hw, ln))
		goto error;

	*(struct csio_lnode **)fc_vport->dd_data = ln;
	ln->fc_vport = fc_vport;
	if (!fc_vport->node_name)
		fc_vport->node_name = wwn_to_u64(csio_ln_wwnn(ln));
	if (!fc_vport->port_name)
		fc_vport->port_name = wwn_to_u64(csio_ln_wwpn(ln));
	csio_fchost_attr_init(ln);
	return 0;
error:
	if (ln)
		csio_shost_exit(ln);

	return ret;
}
Ejemplo n.º 7
0
static int
bfad_im_vport_create(struct fc_vport *fc_vport, bool disable)
{
	char *vname = fc_vport->symbolic_name;
	struct Scsi_Host *shost = fc_vport->shost;
	struct bfad_im_port_s *im_port =
		(struct bfad_im_port_s *) shost->hostdata[0];
	struct bfad_s *bfad = im_port->bfad;
	struct bfa_port_cfg_s port_cfg;
	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);

	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);

	if (rc == BFA_STATUS_OK) {
		struct bfad_vport_s   *vport;
		struct bfa_fcs_vport_s *fcs_vport;
		struct Scsi_Host *vshost;

		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);
			return VPCERR_BAD_WWN;
		}

		fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE);
		if (disable) {
			bfa_fcs_vport_stop(fcs_vport);
			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;
		fc_host_node_name(vshost) = wwn_to_u64((u8 *) &port_cfg.nwwn);
		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)
		return VPCERR_BAD_WWN;
	else if (rc == BFA_STATUS_VPORT_MAX)
		return VPCERR_NO_FABRIC_SUPP;
	else if (rc == BFA_STATUS_VPORT_WWN_BP)
		return VPCERR_BAD_WWN;
	 else
		return FC_VPORT_FAILED;

	return status;
}