static void ibmvfc_tgt_implicit_logout_and_del(struct ibmvfc_target *);
 static void ibmvfc_tgt_move_login(struct ibmvfc_target *);
 
-static void ibmvfc_release_sub_crqs(struct ibmvfc_host *);
-static void ibmvfc_init_sub_crqs(struct ibmvfc_host *);
+static void ibmvfc_dereg_sub_crqs(struct ibmvfc_host *);
+static void ibmvfc_reg_sub_crqs(struct ibmvfc_host *);
 
 static const char *unknown_error = "unknown error";
 
        struct vio_dev *vdev = to_vio_dev(vhost->dev);
        unsigned long flags;
 
-       ibmvfc_release_sub_crqs(vhost);
+       ibmvfc_dereg_sub_crqs(vhost);
 
        /* Re-enable the CRQ */
        do {
        spin_unlock(vhost->crq.q_lock);
        spin_unlock_irqrestore(vhost->host->host_lock, flags);
 
-       ibmvfc_init_sub_crqs(vhost);
+       ibmvfc_reg_sub_crqs(vhost);
 
        return rc;
 }
        struct vio_dev *vdev = to_vio_dev(vhost->dev);
        struct ibmvfc_queue *crq = &vhost->crq;
 
-       ibmvfc_release_sub_crqs(vhost);
+       ibmvfc_dereg_sub_crqs(vhost);
 
        /* Close the CRQ */
        do {
        spin_unlock(vhost->crq.q_lock);
        spin_unlock_irqrestore(vhost->host->host_lock, flags);
 
-       ibmvfc_init_sub_crqs(vhost);
+       ibmvfc_reg_sub_crqs(vhost);
 
        return rc;
 }
 
        ENTER;
 
-       if (ibmvfc_alloc_queue(vhost, scrq, IBMVFC_SUB_CRQ_FMT))
-               return -ENOMEM;
-
        rc = h_reg_sub_crq(vdev->unit_address, scrq->msg_token, PAGE_SIZE,
                           &scrq->cookie, &scrq->hw_irq);
 
                rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq->cookie);
        } while (rtas_busy_delay(rc));
 reg_failed:
-       ibmvfc_free_queue(vhost, scrq);
        LEAVE;
        return rc;
 }
        if (rc)
                dev_err(dev, "Failed to free sub-crq[%d]: rc=%ld\n", index, rc);
 
-       ibmvfc_free_queue(vhost, scrq);
+       /* Clean out the queue */
+       memset(scrq->msgs.crq, 0, PAGE_SIZE);
+       scrq->cur = 0;
+
+       LEAVE;
+}
+
+static void ibmvfc_reg_sub_crqs(struct ibmvfc_host *vhost)
+{
+       int i, j;
+
+       ENTER;
+       if (!vhost->mq_enabled || !vhost->scsi_scrqs.scrqs)
+               return;
+
+       for (i = 0; i < nr_scsi_hw_queues; i++) {
+               if (ibmvfc_register_scsi_channel(vhost, i)) {
+                       for (j = i; j > 0; j--)
+                               ibmvfc_deregister_scsi_channel(vhost, j - 1);
+                       vhost->do_enquiry = 0;
+                       return;
+               }
+       }
+
+       LEAVE;
+}
+
+static void ibmvfc_dereg_sub_crqs(struct ibmvfc_host *vhost)
+{
+       int i;
+
+       ENTER;
+       if (!vhost->mq_enabled || !vhost->scsi_scrqs.scrqs)
+               return;
+
+       for (i = 0; i < nr_scsi_hw_queues; i++)
+               ibmvfc_deregister_scsi_channel(vhost, i);
+
        LEAVE;
 }
 
 static void ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost)
 {
+       struct ibmvfc_queue *scrq;
        int i, j;
 
        ENTER;
        }
 
        for (i = 0; i < nr_scsi_hw_queues; i++) {
-               if (ibmvfc_register_scsi_channel(vhost, i)) {
-                       for (j = i; j > 0; j--)
-                               ibmvfc_deregister_scsi_channel(vhost, j - 1);
+               scrq = &vhost->scsi_scrqs.scrqs[i];
+               if (ibmvfc_alloc_queue(vhost, scrq, IBMVFC_SUB_CRQ_FMT)) {
+                       for (j = i; j > 0; j--) {
+                               scrq = &vhost->scsi_scrqs.scrqs[j - 1];
+                               ibmvfc_free_queue(vhost, scrq);
+                       }
                        kfree(vhost->scsi_scrqs.scrqs);
                        vhost->scsi_scrqs.scrqs = NULL;
                        vhost->scsi_scrqs.active_queues = 0;
                        vhost->do_enquiry = 0;
-                       break;
+                       vhost->mq_enabled = 0;
+                       return;
                }
        }
 
+       ibmvfc_reg_sub_crqs(vhost);
+
        LEAVE;
 }
 
 static void ibmvfc_release_sub_crqs(struct ibmvfc_host *vhost)
 {
+       struct ibmvfc_queue *scrq;
        int i;
 
        ENTER;
        if (!vhost->scsi_scrqs.scrqs)
                return;
 
-       for (i = 0; i < nr_scsi_hw_queues; i++)
-               ibmvfc_deregister_scsi_channel(vhost, i);
+       ibmvfc_dereg_sub_crqs(vhost);
+
+       for (i = 0; i < nr_scsi_hw_queues; i++) {
+               scrq = &vhost->scsi_scrqs.scrqs[i];
+               ibmvfc_free_queue(vhost, scrq);
+       }
 
        kfree(vhost->scsi_scrqs.scrqs);
        vhost->scsi_scrqs.scrqs = NULL;