[PATCH 24/29] ibmvfc: implement LLDD callbacks for mapping nvme-fc queues
From: Tyrel Datwyler
Date: Mon Jun 22 2026 - 21:41:22 EST
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 <tyreld@xxxxxxxxxxxxx>
---
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