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
