Add an NVMe-specific remote-port add helper and update the rport worker
thread to walk the NVMe target list, register new NVMe remote ports, and
rescan existing ones through the NVMe-FC midlayer. Also handle delete
and delete-with-logout transitions for NVMe remote ports in the same
worker context used for SCSI rports.

This keeps remote-port registration serialized in the existing worker
model while allowing NVMe targets to participate in the common target
state machine.

Signed-off-by: Tyrel Datwyler <[email protected]>
---
 drivers/scsi/ibmvscsi/ibmvfc-core.c | 68 ++++++++++++++++++++++++++++-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c 
b/drivers/scsi/ibmvscsi/ibmvfc-core.c
index 2c7ecf7bdde9..5f6ee99d0dba 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc-core.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c
@@ -5829,6 +5829,51 @@ static void ibmvfc_log_ae(struct ibmvfc_host *vhost, int 
events)
                fc_host_post_event(vhost->host, fc_get_event_number(), 
FCH_EVT_LINKUP, 0);
 }
 
+/**
+ * ibmvfc_tgt_add_nvme_rport - Tell the FC transport about a new remote port
+ * @tgt:               ibmvfc target struct
+ *
+ **/
+static void ibmvfc_tgt_add_nvme_rport(struct ibmvfc_target *tgt)
+{
+       struct ibmvfc_host *vhost = tgt->vhost;
+       struct nvme_fc_remote_port *rport;
+       unsigned long flags;
+
+       tgt_dbg(tgt, "Adding NVMe rport\n");
+       ibmvfc_nvme_register_remoteport(tgt);
+       spin_lock_irqsave(vhost->host->host_lock, flags);
+       rport = tgt->nvme_remote_port;
+
+       if (rport && tgt->action == IBMVFC_TGT_ACTION_DEL_RPORT) {
+               tgt_dbg(tgt, "Deleting NVMe rport\n");
+               list_del(&tgt->queue);
+               ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DELETED_RPORT);
+               spin_unlock_irqrestore(vhost->host->host_lock, flags);
+               ibmvfc_nvme_unregister_remoteport(tgt);
+               timer_delete_sync(&tgt->timer);
+               kref_put(&tgt->kref, ibmvfc_release_tgt);
+               return;
+       } else if (rport && tgt->action == 
IBMVFC_TGT_ACTION_DEL_AND_LOGOUT_RPORT) {
+               tgt_dbg(tgt, "Deleting NVMe rport with outstanding I/O\n");
+               ibmvfc_set_tgt_action(tgt, 
IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT);
+               tgt->init_retries = 0;
+               spin_unlock_irqrestore(vhost->host->host_lock, flags);
+               ibmvfc_nvme_unregister_remoteport(tgt);
+               return;
+       } else if (rport && tgt->action == IBMVFC_TGT_ACTION_DELETED_RPORT) {
+               spin_unlock_irqrestore(vhost->host->host_lock, flags);
+               return;
+       }
+
+       if (rport) {
+               tgt_dbg(tgt, "NVMe rport add succeeded\n");
+               tgt->target_id = tgt->nvme_remote_port->port_id;
+       } else
+               tgt_dbg(tgt, "NVMe rport add failed\n");
+       spin_unlock_irqrestore(vhost->host->host_lock, flags);
+}
+
 /**
  * ibmvfc_tgt_add_rport - Tell the FC transport about a new remote port
  * @tgt:               ibmvfc target struct
@@ -6630,6 +6675,7 @@ static void ibmvfc_rport_add_thread(struct work_struct 
*work)
                                                 rport_add_work_q);
        struct ibmvfc_target *tgt;
        struct fc_rport *rport;
+       struct nvme_fc_remote_port *nvme_rport;
        unsigned long flags;
        int did_work;
 
@@ -6663,7 +6709,27 @@ static void ibmvfc_rport_add_thread(struct work_struct 
*work)
                                break;
                        }
                }
-       } while(did_work);
+
+               list_for_each_entry(tgt, &vhost->nvme_scrqs.targets, queue) {
+                       if (tgt->add_rport) {
+                               did_work = 1;
+                               tgt->add_rport = 0;
+                               kref_get(&tgt->kref);
+                               nvme_rport = tgt->nvme_remote_port;
+                               if (!nvme_rport) {
+                                       
spin_unlock_irqrestore(vhost->host->host_lock, flags);
+                                       ibmvfc_tgt_add_nvme_rport(tgt);
+                               } else {
+                                       
spin_unlock_irqrestore(vhost->host->host_lock, flags);
+                                       nvme_fc_rescan_remoteport(nvme_rport);
+                               }
+
+                               kref_put(&tgt->kref, ibmvfc_release_tgt);
+                               spin_lock_irqsave(vhost->host->host_lock, 
flags);
+                               break;
+                       }
+               }
+       } while (did_work);
 
        if (vhost->state == IBMVFC_ACTIVE)
                vhost->scan_complete = 1;
-- 
2.54.0


Reply via email to