Hey Saurav & Co,

Another quick question..  So I'm trying to configure a QLogic Sanbox
5600 switch to test the NPIV target related code..

However, I'm currently running into failures during
qla_mid.c:qla24xx_vport_create_req_sanity_check() at the point where the
switch is checked for NPIV support, eg:

        /* Check up whether npiv supported switch presented */
        if (!(ha->switch_cap & FLOGI_MID_SUPPORT))
                return VPCERR_NO_FABRIC_SUPP;

which is failing with both the original patch, as well as the updated
version to call fc_vport_create() directly from tcm_qla2xxx control path
code.

FYI, this is with the latest firmware (V7.4.0.29.0) on the 5600.  Is
there anything special that I need to do extra to enable / configure
NPIV here..?

TIA!

--nab

On Mon, 2014-01-13 at 17:36 -0800, Nicholas A. Bellinger wrote:
> 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 <[email protected]>
> > Signed-off-by: Quinn Tran <[email protected]>
> > Signed-off-by: Saurav Kashyap <[email protected]>
> > ---
> >  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;
>  


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

Reply via email to