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 | 3 +++ drivers/scsi/ibmvscsi/ibmvfc-nvme.c | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c b/drivers/scsi/ibmvscsi/ibmvfc-core.c index 9a6a885aa57e..2c7ecf7bdde9 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc-core.c +++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c @@ -5184,6 +5184,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: @@ -5245,6 +5247,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: diff --git a/drivers/scsi/ibmvscsi/ibmvfc-nvme.c b/drivers/scsi/ibmvscsi/ibmvfc-nvme.c index 202e8d0b0081..fc4337fc9b3f 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc-nvme.c +++ b/drivers/scsi/ibmvscsi/ibmvfc-nvme.c @@ -137,14 +137,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; } @@ -154,9 +157,18 @@ void ibmvfc_nvme_unregister(struct ibmvfc_host *vhost) int rc; 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); + vhost->nvme_local_port->private = NULL; + } else + dev_err(vhost->dev, "Failed to unregister NVMe fc localport (%d)\n", rc); + + put_device(vhost->dev); } } -- 2.54.0
