Register the local NVMe/FC port only after fabric login has completed.

The VIOS returns the client port ID in the fabric login response, and
that port ID is required to populate the local-port information passed
to the NVMe-FC midlayer. Delay local-port registration until that data
is available and update the registration helper accordingly.

Signed-off-by: Tyrel Datwyler <[email protected]>
---
 drivers/scsi/ibmvscsi/ibmvfc-core.c |  5 +++++
 drivers/scsi/ibmvscsi/ibmvfc-nvme.c | 17 ++++++++++++++---
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c 
b/drivers/scsi/ibmvscsi/ibmvfc-core.c
index ff84ca0f9f45..81d9229bf388 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc-core.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c
@@ -5210,6 +5210,8 @@ static void ibmvfc_fabric_login_nvme_done(struct 
ibmvfc_event *evt)
 
        switch (mad_status) {
        case IBMVFC_MAD_SUCCESS:
+               fc_host_port_id(vhost->host) = be64_to_cpu(rsp->nport_id);
+               ibmvfc_nvme_register(vhost);
                ibmvfc_dbg(vhost, "NVMe fabric login succeeded\n");
                break;
        case IBMVFC_MAD_FAILED:
@@ -5271,6 +5273,7 @@ static void ibmvfc_fabric_login_scsi_done(struct 
ibmvfc_event *evt)
 
        switch (mad_status) {
        case IBMVFC_MAD_SUCCESS:
+               fc_host_port_id(vhost->host) = be64_to_cpu(rsp->nport_id);
                ibmvfc_dbg(vhost, "SCSI fabric login succeeded\n");
                break;
        case IBMVFC_MAD_FAILED:
@@ -5653,6 +5656,7 @@ static void ibmvfc_npiv_logout_done(struct ibmvfc_event 
*evt)
        case IBMVFC_MAD_SUCCESS:
                if (list_empty(&vhost->crq.sent) &&
                    vhost->action == IBMVFC_HOST_ACTION_LOGO_WAIT) {
+                       ibmvfc_nvme_unregister(vhost);
                        ibmvfc_init_host(vhost);
                        return;
                }
@@ -5931,6 +5935,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)
                list_splice_init(&vhost->purge, &purge);
                spin_unlock_irqrestore(vhost->host->host_lock, flags);
                ibmvfc_complete_purge(&purge);
+               ibmvfc_nvme_unregister(vhost);
                rc = ibmvfc_reset_crq(vhost);
 
                spin_lock_irqsave(vhost->host->host_lock, flags);
diff --git a/drivers/scsi/ibmvscsi/ibmvfc-nvme.c 
b/drivers/scsi/ibmvscsi/ibmvfc-nvme.c
index d679d1ca366a..637d7d7015cf 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc-nvme.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc-nvme.c
@@ -145,14 +145,17 @@ int ibmvfc_nvme_register(struct ibmvfc_host *vhost)
        pinfo.dev_loss_tmo = 0;
 
        rc = nvme_fc_register_localport(&pinfo, &ibmvfc_nvme_fc_transport,
-                                       vhost->dev, &vhost->nvme_local_port);
+                                       get_device(vhost->dev),
+                                       &vhost->nvme_local_port);
 
        if (!rc) {
                ibmvfc_log(vhost, 2, "register_localport: 
host-traddr=nn-0x%llx:pn-0x%llx on portID:%x\n",
                           pinfo.node_name, pinfo.port_name, pinfo.port_id);
                vhost->nvme_local_port->private = vhost;
-       } else
+       } else {
                dev_err(vhost->dev, "Failed to register NVMe fc localport 
(%d)\n", rc);
+               put_device(vhost->dev);
+       }
 
        return rc;
 }
@@ -165,9 +168,17 @@ void ibmvfc_nvme_unregister(struct ibmvfc_host *vhost)
                return;
 
        if (vhost->nvme_local_port) {
+               ibmvfc_log(vhost, 2, "unregister_localport: 
host-traddr=nn-0x%llx:pn-0x%llx on portID:%x\n",
+                          vhost->nvme_local_port->node_name,
+                          vhost->nvme_local_port->port_name,
+                          vhost->nvme_local_port->port_id);
                init_completion(&vhost->nvme_delete_done);
                rc = nvme_fc_unregister_localport(vhost->nvme_local_port);
-               if (!rc)
+               if (!rc) {
                        wait_for_completion(&vhost->nvme_delete_done);
+               } else
+                       dev_err(vhost->dev, "Failed to unregister NVMe fc 
localport (%d)\n", rc);
+
+               put_device(vhost->dev);
        }
 }
-- 
2.55.0


Reply via email to