Implement the NVMe-FC queue create and delete callbacks and map NVMe
controller queues onto ibmvfc hardware queues.

Use qidx of NVMe controller queue to map onto a ibmvfc_queue channel.
The Admin queue is always qidx 0 and general practice among other
drivers is to map both the Admin queue and first IO queue to the same HW
queue. Add a new ibmvfc_nvme_qhandle struct that will be used as the
opaque queue handle by the NVMe-FC layer when issuing fcp IO.

Signed-off-by: Tyrel Datwyler <[email protected]>
---
 drivers/scsi/ibmvscsi/ibmvfc-nvme.c | 38 +++++++++++++++++++++++++++--
 drivers/scsi/ibmvscsi/ibmvfc-nvme.h |  7 ++++++
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc-nvme.c 
b/drivers/scsi/ibmvscsi/ibmvfc-nvme.c
index fc4337fc9b3f..1108d11d6b2d 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc-nvme.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc-nvme.c
@@ -28,6 +28,40 @@ static void ibmvfc_nvme_remoteport_delete(struct 
nvme_fc_remote_port *rport)
        complete(&tgt->nvme_delete_done);
 }
 
+static int ibmvfc_nvme_create_queue(struct nvme_fc_local_port *lport, unsigned 
int qidx,
+                                   u16 qsize, void **handle)
+{
+       struct ibmvfc_host *vhost = lport->private;
+       struct ibmvfc_nvme_qhandle *qhandle;
+
+       if (!vhost->nvme_scrqs.active_queues)
+               return -ENODEV;
+
+       qhandle = kzalloc_obj(struct ibmvfc_nvme_qhandle);
+       if (!qhandle)
+               return -ENOMEM;
+
+       qhandle->cpu_id = raw_smp_processor_id();
+       qhandle->qidx = qidx;
+
+       /* Admin and first IO queue are both mapped to index 0 */
+       if (qidx)
+               qhandle->index = (qidx - 1) % vhost->nvme_scrqs.active_queues;
+       else
+               qhandle->index = qidx;
+
+       qhandle->queue = &vhost->nvme_scrqs.scrqs[qhandle->index];
+
+       *handle = qhandle;
+       return 0;
+}
+
+static void ibmvfc_nvme_delete_queue(struct nvme_fc_local_port *lport, 
unsigned int qidx,
+                                    void *handle)
+{
+       kfree(handle);
+}
+
 static int ibmvfc_nvme_ls_req(struct nvme_fc_local_port *lport,
                              struct nvme_fc_remote_port *rport,
                              struct nvmefc_ls_req *ls_req)
@@ -59,8 +93,8 @@ static void ibmvfc_nvme_fcp_abort(struct nvme_fc_local_port 
*lport,
 static struct nvme_fc_port_template ibmvfc_nvme_fc_transport = {
        .localport_delete       = ibmvfc_nvme_localport_delete,
        .remoteport_delete      = ibmvfc_nvme_remoteport_delete,
-       .create_queue           = NULL,
-       .delete_queue           = NULL,
+       .create_queue           = ibmvfc_nvme_create_queue,
+       .delete_queue           = ibmvfc_nvme_delete_queue,
        .ls_req                 = ibmvfc_nvme_ls_req,
        .ls_abort               = ibmvfc_nvme_ls_abort,
        .fcp_io                 = ibmvfc_nvme_fcp_io,
diff --git a/drivers/scsi/ibmvscsi/ibmvfc-nvme.h 
b/drivers/scsi/ibmvscsi/ibmvfc-nvme.h
index 3aa285788795..4c6146048a6f 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc-nvme.h
+++ b/drivers/scsi/ibmvscsi/ibmvfc-nvme.h
@@ -27,6 +27,13 @@ extern unsigned int ibmvfc_debug;
 struct ibmvfc_host;
 struct ibmvfc_target;
 
+struct ibmvfc_nvme_qhandle {
+       unsigned int qidx;
+       u16 cpu_id;
+       unsigned long index;
+       struct ibmvfc_queue *queue;
+};
+
 int ibmvfc_nvme_register_remoteport(struct ibmvfc_target *tgt);
 void ibmvfc_nvme_unregister_remoteport(struct ibmvfc_target *tgt);
 int ibmvfc_nvme_register(struct ibmvfc_host *vhost);
-- 
2.54.0


Reply via email to