Skip to content

Commit 49a47f2

Browse files
author
Nicholas Bellinger
committed
qla2xxx: Configure NPIV fc_vport via tcm_qla2xxx_npiv_make_lport
This patch changes qla2xxx qlt_lport_register() code to accept target_lport_ptr + npiv_wwpn + npiv_wwnn parameters, and updates tcm_qla2xxx to use the new tcm_qla2xxx_lport_register_npiv_cb() callback for invoking fc_vport_create() from configfs context via tcm_qla2xxx_npiv_make_lport() code. In order for this to work, the qlt_lport_register() callback is now called without holding qla_tgt_mutex, as the fc_vport creation process will call qlt_vport_create() -> qlt_add_target(), which already expects to acquire it. It enforces /sys/kernel/config/target/qla2xxx_npiv/$NPIV_WWPN naming in the following format: $PHYSICAL_WWPN@$NPIV_WWPN:$NPIV_WWNN and assumes the $PHYSICAL_WWPN in question has already had been configured for target mode in non NPIV mode. Finally, it updates existing tcm_qla2xxx_lport_register_cb() logic to setup the non NPIV assignments that have now been moved out of qlt_lport_register() code. Cc: Sawan Chandak <sawan.chandak@qlogic.com> Cc: Quinn Tran <quinn.tran@qlogic.com> Cc: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
1 parent 0e8cd71 commit 49a47f2

File tree

3 files changed

+88
-47
lines changed

3 files changed

+88
-47
lines changed

drivers/scsi/qla2xxx/qla_target.c

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4235,8 +4235,9 @@ static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn,
42354235
* @callback: lport initialization callback for tcm_qla2xxx code
42364236
* @target_lport_ptr: pointer for tcm_qla2xxx specific lport data
42374237
*/
4238-
int qlt_lport_register(struct qla_tgt_func_tmpl *qla_tgt_ops, u64 wwpn,
4239-
int (*callback)(struct scsi_qla_host *), void *target_lport_ptr)
4238+
int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn,
4239+
u64 npiv_wwpn, u64 npiv_wwnn,
4240+
int (*callback)(struct scsi_qla_host *, void *, u64, u64))
42404241
{
42414242
struct qla_tgt *tgt;
42424243
struct scsi_qla_host *vha;
@@ -4259,7 +4260,7 @@ int qlt_lport_register(struct qla_tgt_func_tmpl *qla_tgt_ops, u64 wwpn,
42594260
continue;
42604261

42614262
spin_lock_irqsave(&ha->hardware_lock, flags);
4262-
if (host->active_mode & MODE_TARGET) {
4263+
if ((!npiv_wwpn || !npiv_wwnn) && host->active_mode & MODE_TARGET) {
42634264
pr_debug("MODE_TARGET already active on qla2xxx(%d)\n",
42644265
host->host_no);
42654266
spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -4273,24 +4274,18 @@ int qlt_lport_register(struct qla_tgt_func_tmpl *qla_tgt_ops, u64 wwpn,
42734274
" qla2xxx scsi_host\n");
42744275
continue;
42754276
}
4276-
qlt_lport_dump(vha, wwpn, b);
4277+
qlt_lport_dump(vha, phys_wwpn, b);
42774278

42784279
if (memcmp(vha->port_name, b, WWN_SIZE)) {
42794280
scsi_host_put(host);
42804281
continue;
42814282
}
4282-
/*
4283-
* Setup passed parameters ahead of invoking callback
4284-
*/
4285-
ha->tgt.tgt_ops = qla_tgt_ops;
4286-
vha->vha_tgt.target_lport_ptr = target_lport_ptr;
4287-
rc = (*callback)(vha);
4288-
if (rc != 0) {
4289-
ha->tgt.tgt_ops = NULL;
4290-
vha->vha_tgt.target_lport_ptr = NULL;
4291-
scsi_host_put(host);
4292-
}
42934283
mutex_unlock(&qla_tgt_mutex);
4284+
4285+
rc = (*callback)(vha, target_lport_ptr, npiv_wwpn, npiv_wwnn);
4286+
if (rc != 0)
4287+
scsi_host_put(host);
4288+
42944289
return rc;
42954290
}
42964291
mutex_unlock(&qla_tgt_mutex);

drivers/scsi/qla2xxx/qla_target.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -932,8 +932,8 @@ void qlt_disable_vha(struct scsi_qla_host *);
932932
*/
933933
extern int qlt_add_target(struct qla_hw_data *, struct scsi_qla_host *);
934934
extern int qlt_remove_target(struct qla_hw_data *, struct scsi_qla_host *);
935-
extern int qlt_lport_register(struct qla_tgt_func_tmpl *, u64,
936-
int (*callback)(struct scsi_qla_host *), void *);
935+
extern int qlt_lport_register(void *, u64, u64, u64,
936+
int (*callback)(struct scsi_qla_host *, void *, u64, u64));
937937
extern void qlt_lport_deregister(struct scsi_qla_host *);
938938
extern void qlt_unreg_sess(struct qla_tgt_sess *);
939939
extern void qlt_fc_port_added(struct scsi_qla_host *, fc_port_t *);

drivers/scsi/qla2xxx/tcm_qla2xxx.c

Lines changed: 76 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,14 +1559,18 @@ static int tcm_qla2xxx_init_lport(struct tcm_qla2xxx_lport *lport)
15591559
return 0;
15601560
}
15611561

1562-
static int tcm_qla2xxx_lport_register_cb(struct scsi_qla_host *vha)
1562+
static int tcm_qla2xxx_lport_register_cb(struct scsi_qla_host *vha,
1563+
void *target_lport_ptr,
1564+
u64 npiv_wwpn, u64 npiv_wwnn)
15631565
{
1564-
struct tcm_qla2xxx_lport *lport;
1566+
struct qla_hw_data *ha = vha->hw;
1567+
struct tcm_qla2xxx_lport *lport =
1568+
(struct tcm_qla2xxx_lport *)target_lport_ptr;
15651569
/*
1566-
* Setup local pointer to vha, NPIV VP pointer (if present) and
1567-
* vha->tcm_lport pointer
1570+
* Setup tgt_ops, local pointer to vha and target_lport_ptr
15681571
*/
1569-
lport = (struct tcm_qla2xxx_lport *)vha->vha_tgt.target_lport_ptr;
1572+
ha->tgt.tgt_ops = &tcm_qla2xxx_template;
1573+
vha->vha_tgt.target_lport_ptr = target_lport_ptr;
15701574
lport->qla_vha = vha;
15711575

15721576
return 0;
@@ -1598,8 +1602,8 @@ static struct se_wwn *tcm_qla2xxx_make_lport(
15981602
if (ret != 0)
15991603
goto out;
16001604

1601-
ret = qlt_lport_register(&tcm_qla2xxx_template, wwpn,
1602-
tcm_qla2xxx_lport_register_cb, lport);
1605+
ret = qlt_lport_register(lport, wwpn, 0, 0,
1606+
tcm_qla2xxx_lport_register_cb);
16031607
if (ret != 0)
16041608
goto out_lport;
16051609

@@ -1637,20 +1641,70 @@ static void tcm_qla2xxx_drop_lport(struct se_wwn *wwn)
16371641
kfree(lport);
16381642
}
16391643

1644+
static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha,
1645+
void *target_lport_ptr,
1646+
u64 npiv_wwpn, u64 npiv_wwnn)
1647+
{
1648+
struct fc_vport *vport;
1649+
struct Scsi_Host *sh = base_vha->host;
1650+
struct scsi_qla_host *npiv_vha;
1651+
struct tcm_qla2xxx_lport *lport =
1652+
(struct tcm_qla2xxx_lport *)target_lport_ptr;
1653+
struct fc_vport_identifiers vport_id;
1654+
1655+
if (!qla_tgt_mode_enabled(base_vha)) {
1656+
pr_err("qla2xxx base_vha not enabled for target mode\n");
1657+
return -EPERM;
1658+
}
1659+
1660+
memset(&vport_id, 0, sizeof(vport_id));
1661+
vport_id.port_name = npiv_wwpn;
1662+
vport_id.node_name = npiv_wwnn;
1663+
vport_id.roles = FC_PORT_ROLE_FCP_INITIATOR;
1664+
vport_id.vport_type = FC_PORTTYPE_NPIV;
1665+
vport_id.disable = false;
1666+
1667+
vport = fc_vport_create(sh, 0, &vport_id);
1668+
if (!vport) {
1669+
pr_err("fc_vport_create failed for qla2xxx_npiv\n");
1670+
return -ENODEV;
1671+
}
1672+
/*
1673+
* Setup local pointer to NPIV vhba + target_lport_ptr
1674+
*/
1675+
npiv_vha = (struct scsi_qla_host *)vport->dd_data;
1676+
npiv_vha->vha_tgt.target_lport_ptr = target_lport_ptr;
1677+
lport->qla_vha = npiv_vha;
1678+
1679+
scsi_host_get(npiv_vha->host);
1680+
return 0;
1681+
}
1682+
1683+
16401684
static struct se_wwn *tcm_qla2xxx_npiv_make_lport(
16411685
struct target_fabric_configfs *tf,
16421686
struct config_group *group,
16431687
const char *name)
16441688
{
16451689
struct tcm_qla2xxx_lport *lport;
1646-
u64 npiv_wwpn, npiv_wwnn;
1690+
u64 phys_wwpn, npiv_wwpn, npiv_wwnn;
1691+
char *p, tmp[128];
16471692
int ret;
1648-
struct scsi_qla_host *vha = NULL;
1649-
struct qla_hw_data *ha = NULL;
1650-
scsi_qla_host_t *base_vha = NULL;
16511693

1652-
if (tcm_qla2xxx_npiv_parse_wwn(name, strlen(name)+1,
1653-
&npiv_wwpn, &npiv_wwnn) < 0)
1694+
snprintf(tmp, 128, "%s", name);
1695+
1696+
p = strchr(tmp, '@');
1697+
if (!p) {
1698+
pr_err("Unable to locate NPIV '@' seperator\n");
1699+
return ERR_PTR(-EINVAL);
1700+
}
1701+
*p++ = '\0';
1702+
1703+
if (tcm_qla2xxx_parse_wwn(tmp, &phys_wwpn, 1) < 0)
1704+
return ERR_PTR(-EINVAL);
1705+
1706+
if (tcm_qla2xxx_npiv_parse_wwn(p, strlen(p)+1,
1707+
&npiv_wwpn, &npiv_wwnn) < 0)
16541708
return ERR_PTR(-EINVAL);
16551709

16561710
lport = kzalloc(sizeof(struct tcm_qla2xxx_lport), GFP_KERNEL);
@@ -1668,21 +1722,11 @@ static struct se_wwn *tcm_qla2xxx_npiv_make_lport(
16681722
if (ret != 0)
16691723
goto out;
16701724

1671-
ret = qlt_lport_register(&tcm_qla2xxx_template, npiv_wwpn,
1672-
tcm_qla2xxx_lport_register_cb, lport);
1673-
1725+
ret = qlt_lport_register(lport, phys_wwpn, npiv_wwpn, npiv_wwnn,
1726+
tcm_qla2xxx_lport_register_npiv_cb);
16741727
if (ret != 0)
16751728
goto out_lport;
16761729

1677-
vha = lport->qla_vha;
1678-
ha = vha->hw;
1679-
base_vha = pci_get_drvdata(ha->pdev);
1680-
1681-
if (!qla_tgt_mode_enabled(base_vha)) {
1682-
ret = -EPERM;
1683-
goto out_lport;
1684-
}
1685-
16861730
return &lport->lport_wwn;
16871731
out_lport:
16881732
vfree(lport->lport_loopid_map);
@@ -1696,14 +1740,16 @@ static void tcm_qla2xxx_npiv_drop_lport(struct se_wwn *wwn)
16961740
{
16971741
struct tcm_qla2xxx_lport *lport = container_of(wwn,
16981742
struct tcm_qla2xxx_lport, lport_wwn);
1699-
struct scsi_qla_host *vha = lport->qla_vha;
1700-
struct Scsi_Host *sh = vha->host;
1743+
struct scsi_qla_host *npiv_vha = lport->qla_vha;
1744+
struct qla_hw_data *ha = npiv_vha->hw;
1745+
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
1746+
1747+
scsi_host_put(npiv_vha->host);
17011748
/*
17021749
* Notify libfc that we want to release the vha->fc_vport
17031750
*/
1704-
fc_vport_terminate(vha->fc_vport);
1705-
1706-
scsi_host_put(sh);
1751+
fc_vport_terminate(npiv_vha->fc_vport);
1752+
scsi_host_put(base_vha->host);
17071753
kfree(lport);
17081754
}
17091755

0 commit comments

Comments
 (0)