ibmvfc_reg_sub_crqs() clears vhost->do_enquiry unconditionally when any
channel registration fails.  The function is called for SCSI channels
first and then for NVMe channels (in ibmvfc_init_sub_crqs(),
ibmvfc_reset_crq(), and ibmvfc_reenable_crq_queue()).  If the NVMe
channel registration fails, do_enquiry is cleared even though SCSI
channels registered successfully, preventing the IBMVFC_CHANNEL_ENQUIRY
MAD from being sent and silently disabling multiqueue support for SCSI.

ibmvfc_init_sub_crqs() already handles NVMe *allocation* failure
correctly — it only clears nvme_enabled without touching do_enquiry.
The same logic needs to apply when NVMe *registration* fails.

Fix ibmvfc_reg_sub_crqs() to check channels->protocol in the failure
path: clear do_enquiry only for a SCSI channel failure (preserving
existing behaviour), and clear nvme_enabled instead for an NVMe channel
failure.  This covers all three call sites in one place.

Fixes: 319f6545a2d4 ("scsi: ibmvfc: alloc/dealloc sub-queues for nvme channels")
Signed-off-by: Tyrel Datwyler <[email protected]>
---
 drivers/scsi/ibmvscsi/ibmvfc-core.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c 
b/drivers/scsi/ibmvscsi/ibmvfc-core.c
index 701a9ebf2b7f..914dafd576a0 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc-core.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c
@@ -992,6 +992,8 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host 
*vhost)
        vhost->do_scsi_login = 0;
        vhost->do_nvme_login = 0;
        vhost->do_nvme_register = 0;
+       if (vhost->nvme_scrqs.scrqs)
+               vhost->nvme_enabled = 1;
        spin_unlock(vhost->crq.q_lock);
        spin_unlock_irqrestore(&vhost->host->host_lock, flags);
 
@@ -1034,6 +1036,8 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost)
        vhost->do_scsi_login = 0;
        vhost->do_nvme_login = 0;
        vhost->do_nvme_register = 0;
+       if (vhost->nvme_scrqs.scrqs)
+               vhost->nvme_enabled = 1;
 
        /* Clean out the queue */
        memset(crq->msgs.crq, 0, PAGE_SIZE);
@@ -6532,7 +6536,10 @@ static void ibmvfc_reg_sub_crqs(struct ibmvfc_host 
*vhost,
                if (ibmvfc_register_channel(vhost, channels, i)) {
                        for (j = i; j > 0; j--)
                                ibmvfc_deregister_channel(vhost, channels, j - 
1);
-                       vhost->do_enquiry = 0;
+                       if (channels->protocol == IBMVFC_PROTO_SCSI)
+                               vhost->do_enquiry = 0;
+                       else
+                               vhost->nvme_enabled = 0;
                        return;
                }
        }
-- 
2.55.0


Reply via email to