[PATCH v16 10/12] scsi: ibmvfc: extend channel reg/dereg helpers for async sub-CRQ

From: Dave Marquardt via B4 Relay

Date: Mon Oct 26 2026 - 12:19:47 EST


From: Dave Marquardt <davemarq@xxxxxxxxxxxxx>

ibmvfc_register_channel() and ibmvfc_deregister_channel() previously only
handled SCSI and NVMe sub-CRQ channels identified by the channel protocol
(IBMVFC_PROTO_SCSI, IBMVFC_PROTO_NVME). The async sub-CRQ had no
registration path through these helpers, requiring separate handling.

Add a new IBMVFC_PROTO_ASYNC protocol value to enum ibmvfc_protocol.
Extend both functions to handle IBMVFC_PROTO_ASYNC channels: the IRQ is
named "ibmvfc-<addr>-async<index>" and the handler is set to
ibmvfc_interrupt_async_subq rather than the per-protocol
ibmvfc_interrupt_mq handler.

Remove the __maybe_unused annotation from ibmvfc_interrupt_async_subq
now that it is referenced in ibmvfc_register_channel().

Error messages in both paths are updated to include the channel protocol
to distinguish async sub-CRQ failures from SCSI/NVMe sub-CRQ failures.
Kernel-doc headers are added to both functions.

Signed-off-by: Dave Marquardt <davemarq@xxxxxxxxxxxxx>
Signed-off-by: Tyrel Datwyler <tyreld@xxxxxxxxxxxxx>
---
drivers/scsi/ibmvscsi/ibmvfc-core.c | 30 +++++++++++++++++++++++++-----
drivers/scsi/ibmvscsi/ibmvfc.h | 1 +
2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c b/drivers/scsi/ibmvscsi/ibmvfc-core.c
index 2cb38757333a..af11726b76be 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc-core.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c
@@ -4443,7 +4443,7 @@ static void ibmvfc_drain_async_subq(struct ibmvfc_queue *scrq)
* @scrq_instance: async subq
*
**/
-static irqreturn_t __maybe_unused ibmvfc_interrupt_async_subq(int irq, void *scrq_instance)
+static irqreturn_t ibmvfc_interrupt_async_subq(int irq, void *scrq_instance)
{
struct ibmvfc_queue *scrq = (struct ibmvfc_queue *)scrq_instance;

@@ -6833,6 +6833,19 @@ static int ibmvfc_init_crq(struct ibmvfc_host *vhost)
return retrc;
}

+/**
+ * ibmvfc_register_channel - Register a sub-CRQ channel with the hypervisor
+ * @vhost: ibmvfc host struct
+ * @channels: ibmvfc channels struct containing the channel array and protocol
+ * @index: index into the channels array for the queue to register
+ *
+ * Register a sub-CRQ with the hypervisor via h_reg_sub_crq, map its hardware
+ * IRQ to a Linux IRQ, and bind an interrupt handler to it. The handler is
+ * selected based on the channel protocol.
+ *
+ * Return value:
+ * 0 on success / non-zero on failure
+ **/
static int ibmvfc_register_channel(struct ibmvfc_host *vhost,
struct ibmvfc_channels *channels,
int index)
@@ -6860,7 +6873,8 @@ static int ibmvfc_register_channel(struct ibmvfc_host *vhost,

if (!scrq->irq) {
rc = -EINVAL;
- dev_err(dev, "Error mapping sub-crq[%d] irq\n", index);
+ dev_err(dev, "Error mapping protocol (%d) sub-crq[%d] irq\n",
+ channels->protocol, index);
goto irq_failed;
}

@@ -6875,23 +6889,29 @@ static int ibmvfc_register_channel(struct ibmvfc_host *vhost,
vdev->unit_address, index);
scrq->handler = ibmvfc_interrupt_mq;
break;
+ case IBMVFC_PROTO_ASYNC:
+ snprintf(scrq->name, sizeof(scrq->name), "ibmvfc-%x-async%d",
+ vdev->unit_address, index);
+ scrq->handler = ibmvfc_interrupt_async_subq;
+ break;
default:
dev_err(dev, "Unknown channel protocol (%d)\n",
channels->protocol);
goto irq_failed;
}

+ scrq->hwq_id = index;
+
rc = request_irq(scrq->irq, scrq->handler, 0, scrq->name, scrq);

if (rc) {
- dev_err(dev, "Couldn't register sub-crq[%d] irq\n", index);
+ dev_err(dev, "Couldn't register protocol (%d) sub-crq[%d] irq\n",
+ channels->protocol, index);
irq_dispose_mapping(scrq->irq);
scrq->irq = 0;
goto irq_failed;
}

- scrq->hwq_id = index;
-
LEAVE;
return 0;

diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h
index 86b600ec57c7..f77966c85b0e 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.h
+++ b/drivers/scsi/ibmvscsi/ibmvfc.h
@@ -839,6 +839,7 @@ enum ibmvfc_target_action {
enum ibmvfc_protocol {
IBMVFC_PROTO_SCSI = 0,
IBMVFC_PROTO_NVME = 1,
+ IBMVFC_PROTO_ASYNC = 2,
};

struct ibmvfc_target {

--
2.56.0