Re: [PATCH] qla2xxx: Enhancements to enable NPIV support for QLOGIC ISPs with TCM/LIO.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Saurav & Co,

Thanks for posting, and apologies for the slight delay.

Comments are below.

On Thu, 2014-01-09 at 15:13 -0500, Saurav Kashyap wrote:
> Signed-off-by: Sawan Chandak <sawan.chandak@xxxxxxxxxx>
> Signed-off-by: Quinn Tran <quinn.tran@xxxxxxxxxx>
> Signed-off-by: Saurav Kashyap <saurav.kashyap@xxxxxxxxxx>
> ---
>  drivers/scsi/qla2xxx/qla_attr.c    |    2 +
>  drivers/scsi/qla2xxx/qla_def.h     |   12 ++-
>  drivers/scsi/qla2xxx/qla_target.c  |  150 +++++++++++++++++++-----------------
>  drivers/scsi/qla2xxx/tcm_qla2xxx.c |  110 +++++++++++++++-----------
>  drivers/scsi/qla2xxx/tcm_qla2xxx.h |    4 -
>  5 files changed, 153 insertions(+), 125 deletions(-)

<SNIP>

> diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
> index 7eb19be..113ca95 100644
> --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
> +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c

<SNIP>

> @@ -1650,6 +1645,9 @@ static struct se_wwn *tcm_qla2xxx_npiv_make_lport(
>  	struct tcm_qla2xxx_lport *lport;
>  	u64 npiv_wwpn, npiv_wwnn;
>  	int ret;
> +	struct scsi_qla_host *vha = NULL;
> +	struct qla_hw_data *ha = NULL;
> +	scsi_qla_host_t *base_vha = NULL;
>  
>  	if (tcm_qla2xxx_npiv_parse_wwn(name, strlen(name)+1,
>  				&npiv_wwpn, &npiv_wwnn) < 0)
> @@ -1666,12 +1664,29 @@ static struct se_wwn *tcm_qla2xxx_npiv_make_lport(
>  			TCM_QLA2XXX_NAMELEN, npiv_wwpn, npiv_wwnn);
>  	sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) npiv_wwpn);
>  
> -/* FIXME: tcm_qla2xxx_npiv_make_lport */
> -	ret = -ENOSYS;
> +	ret = tcm_qla2xxx_init_lport(lport);
>  	if (ret != 0)
>  		goto out;
>  
> +	ret = qlt_lport_register(&tcm_qla2xxx_template, npiv_wwpn,
> +				tcm_qla2xxx_lport_register_cb, lport);
> +
> +	if (ret != 0)
> +		goto out_lport;
> +
> +	vha = lport->qla_vha;
> +	ha = vha->hw;
> +	base_vha = pci_get_drvdata(ha->pdev);
> +
> +	if (!qla_tgt_mode_enabled(base_vha)) {
> +		ret = -EPERM;
> +		goto out_lport;
> +	}
> +

As discussed off-list, I'd rather perform the fc_vport creation using
fc_vport_create() from within tcm_qla2xxx_npiv_make_lport() context,
instead of using external sysfs attributes separate from the NPIV
specific TFO->make_wwpn() configfs call.

This makes life easier for existing userspace code that persists
configurations across target restart when metadata required to do NPIV
configuration is entirely encapsulated within the configfs hierarchy. 

For /sys/kernel/config/target/qla2xxx_npiv/$WWPN, I'd like to propose
the following format:

      $PARENT_WWPN@$NPIV_WWPN:$NPIV_WWNN

which would appear under configfs as:

      21:00:00:24:ff:31:4c:49@21000000deadbeef:200000000000ffff

The changes required look something like the following below, that
applies atop your current patch.

The qlt_lport_register() (*callback) has been modified to accept the
passed npiv_wwpn + npiv_wwnn, and then tcm_qla2xxx code calls a NPIV
specific tcm_qla2xxx_lport_register_npiv_cb() to invoke
fc_vport_create() directly.

>From there, the struct scsi_qla_host *npiv_vha is extracted from
vport->dd_data, and pointer assignment set in lport->qla_vha.

Btw, this code needs a bit more work to extract phys_wwpn from the
passed configfs name, but should give an idea of how this can work.

Any objections to this approach..?

--nab

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 202060d..cebe356 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -4235,8 +4235,10 @@ static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn,
  * @callback:  lport initialization callback for tcm_qla2xxx code
  * @target_lport_ptr: pointer for tcm_qla2xxx specific lport data
  */
-int qlt_lport_register(struct qla_tgt_func_tmpl *qla_tgt_ops, u64 wwpn,
-	int (*callback)(struct scsi_qla_host *), void *target_lport_ptr)
+int qlt_lport_register(struct qla_tgt_func_tmpl *qla_tgt_ops, u64 phys_wwpn,
+		       u64 npiv_wwpn, u64 npiv_wwnn,
+		       int (*callback)(struct scsi_qla_host *, u64, u64),
+		       void *target_lport_ptr)
 {
 	struct qla_tgt *tgt;
 	struct scsi_qla_host *vha;
@@ -4259,7 +4261,7 @@ int qlt_lport_register(struct qla_tgt_func_tmpl *qla_tgt_ops, u64 wwpn,
 			continue;
 
 		spin_lock_irqsave(&ha->hardware_lock, flags);
-		if (host->active_mode & MODE_TARGET) {
+		if ((!npiv_wwpn || !npiv_wwnn) && host->active_mode & MODE_TARGET) {
 			pr_debug("MODE_TARGET already active on qla2xxx(%d)\n",
 			    host->host_no);
 			spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -4273,7 +4275,7 @@ int qlt_lport_register(struct qla_tgt_func_tmpl *qla_tgt_ops, u64 wwpn,
 			    " qla2xxx scsi_host\n");
 			continue;
 		}
-		qlt_lport_dump(vha, wwpn, b);
+		qlt_lport_dump(vha, phys_wwpn, b);
 
 		if (memcmp(vha->port_name, b, WWN_SIZE)) {
 			scsi_host_put(host);
@@ -4284,7 +4286,7 @@ int qlt_lport_register(struct qla_tgt_func_tmpl *qla_tgt_ops, u64 wwpn,
 		 */
 		ha->tgt.tgt_ops = qla_tgt_ops;
 		vha->vha_tgt.target_lport_ptr = target_lport_ptr;
-		rc = (*callback)(vha);
+		rc = (*callback)(vha, npiv_wwpn, npiv_wwnn);
 		if (rc != 0) {
 			ha->tgt.tgt_ops = NULL;
 			vha->vha_tgt.target_lport_ptr = NULL;
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index b33e411..2a5d3cb 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -932,8 +932,8 @@ void qlt_disable_vha(struct scsi_qla_host *);
  */
 extern int qlt_add_target(struct qla_hw_data *, struct scsi_qla_host *);
 extern int qlt_remove_target(struct qla_hw_data *, struct scsi_qla_host *);
-extern int qlt_lport_register(struct qla_tgt_func_tmpl *, u64,
-			int (*callback)(struct scsi_qla_host *), void *);
+extern int qlt_lport_register(struct qla_tgt_func_tmpl *, u64, u64, u64,
+			int (*callback)(struct scsi_qla_host *, u64, u64), void *);
 extern void qlt_lport_deregister(struct scsi_qla_host *);
 extern void qlt_unreg_sess(struct qla_tgt_sess *);
 extern void qlt_fc_port_added(struct scsi_qla_host *, fc_port_t *);
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 113ca95..080fae2 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -1559,7 +1559,8 @@ static int tcm_qla2xxx_init_lport(struct tcm_qla2xxx_lport *lport)
 	return 0;
 }
 
-static int tcm_qla2xxx_lport_register_cb(struct scsi_qla_host *vha)
+static int tcm_qla2xxx_lport_register_cb(struct scsi_qla_host *vha,
+					 u64 npiv_wwpn, u64 npiv_wwnn)
 {
 	struct tcm_qla2xxx_lport *lport;
 	/*
@@ -1598,7 +1599,7 @@ static struct se_wwn *tcm_qla2xxx_make_lport(
 	if (ret != 0)
 		goto out;
 
-	ret = qlt_lport_register(&tcm_qla2xxx_template, wwpn,
+	ret = qlt_lport_register(&tcm_qla2xxx_template, wwpn, 0, 0,
 				tcm_qla2xxx_lport_register_cb, lport);
 	if (ret != 0)
 		goto out_lport;
@@ -1637,17 +1638,53 @@ static void tcm_qla2xxx_drop_lport(struct se_wwn *wwn)
 	kfree(lport);
 }
 
+static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *vha,
+					      u64 npiv_wwpn, u64 npiv_wwnn)
+{
+	struct fc_vport *vport;
+	struct Scsi_Host *sh;
+	struct scsi_qla_host *npiv_vha;
+	struct tcm_qla2xxx_lport *lport;
+	struct fc_vport_identifiers vport_id;
+
+	lport = (struct tcm_qla2xxx_lport *)vha->vha_tgt.target_lport_ptr;
+	sh = vha->host;;
+
+	memset(&vport_id, 0, sizeof(vport_id));
+	vport_id.port_name = npiv_wwpn;
+	vport_id.node_name = npiv_wwnn;
+	vport_id.roles = FC_PORT_ROLE_FCP_INITIATOR;
+	vport_id.vport_type = FC_PORTTYPE_NPIV;
+	vport_id.disable = false;
+
+	vport = fc_vport_create(sh, 0, &vport_id);
+	if (!vport) {
+		lport->qla_vha = NULL;
+		return -ENODEV;
+	}
+	/*
+	 * Setup local pointer to NPIV vhba
+	 */
+	npiv_vha = *(struct scsi_qla_host **)vport->dd_data;
+	lport->qla_vha = npiv_vha;
+
+	return 0;
+}
+
+
 static struct se_wwn *tcm_qla2xxx_npiv_make_lport(
 	struct target_fabric_configfs *tf,
 	struct config_group *group,
 	const char *name)
 {
 	struct tcm_qla2xxx_lport *lport;
-	u64 npiv_wwpn, npiv_wwnn;
+	u64 phys_wwpn, npiv_wwpn, npiv_wwnn;
 	int ret;
 	struct scsi_qla_host *vha = NULL;
 	struct qla_hw_data *ha = NULL;
 	scsi_qla_host_t *base_vha = NULL;
+#warning FIXME: Extract phys_wwpn from passed *name
+	phys_wwpn = 0;
 
 	if (tcm_qla2xxx_npiv_parse_wwn(name, strlen(name)+1,
 				&npiv_wwpn, &npiv_wwnn) < 0)
@@ -1668,9 +1705,9 @@ static struct se_wwn *tcm_qla2xxx_npiv_make_lport(
 	if (ret != 0)
 		goto out;
 
-	ret = qlt_lport_register(&tcm_qla2xxx_template, npiv_wwpn,
-				tcm_qla2xxx_lport_register_cb, lport);
-
+	ret = qlt_lport_register(&tcm_qla2xxx_template, phys_wwpn, npiv_wwpn,
+				 npiv_wwnn, tcm_qla2xxx_lport_register_npiv_cb,
+				 lport);
 	if (ret != 0)
 		goto out_lport;
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux