From: Sawan Chandak <sawan.chan...@cavium.com>

In target mode driver, queue pairs are created at the configuration
time, instead of load time, after chip reset. If a user tries to
load/unload driver after queue pairs are created, then there would
be mailbox failure while trying to delete queue pairs. This patch adds
a flag to check if queue pairs are created. Queue pairs will be
deleted only If they were created during target configuration.

Signed-off-by: Sawan Chandak <sawan.chan...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h  |  2 ++
 drivers/scsi/qla2xxx/qla_init.c | 10 ++++++++--
 drivers/scsi/qla2xxx/qla_mid.c  |  4 ++++
 drivers/scsi/qla2xxx/qla_os.c   |  1 +
 4 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 005ca2de3795..8b52f431a812 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3997,6 +3997,8 @@ typedef struct scsi_qla_host {
                uint32_t        fw_tgt_reported:1;
                uint32_t        bbcr_enable:1;
                uint32_t        qpairs_available:1;
+               uint32_t        qpairs_req_created:1;
+               uint32_t        qpairs_rsp_created:1;
        } flags;
 
        atomic_t        loop_state;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index fa5e6ab8e4a7..dcc306121a3d 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -7719,9 +7719,12 @@ struct qla_qpair *qla2xxx_create_qpair(struct 
scsi_qla_host *vha, int qos,
 
 int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair)
 {
-       int ret;
+       int ret = QLA_FUNCTION_FAILED;
        struct qla_hw_data *ha = qpair->hw;
 
+       if (!vha->flags.qpairs_req_created && !vha->flags.qpairs_rsp_created)
+               goto fail;
+
        qpair->delete_in_progress = 1;
        while (atomic_read(&qpair->ref_count))
                msleep(500);
@@ -7738,8 +7741,11 @@ int qla2xxx_delete_qpair(struct scsi_qla_host *vha, 
struct qla_qpair *qpair)
        clear_bit(qpair->id, ha->qpair_qid_map);
        ha->num_qpairs--;
        list_del(&qpair->qp_list_elem);
-       if (list_empty(&vha->qp_list))
+       if (list_empty(&vha->qp_list)) {
                vha->flags.qpairs_available = 0;
+               vha->flags.qpairs_req_created = 0;
+               vha->flags.qpairs_rsp_created = 0;
+       }
        mempool_destroy(qpair->srb_mempool);
        kfree(qpair);
        mutex_unlock(&ha->mq_lock);
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index 4ad452a42dbe..f0605cd196fb 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -645,6 +645,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t 
options,
        int ret = 0;
        struct req_que *req = NULL;
        struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
+       struct scsi_qla_host *vha = pci_get_drvdata(ha->pdev);
        uint16_t que_id = 0;
        device_reg_t *reg;
        uint32_t cnt;
@@ -741,6 +742,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t 
options,
                        mutex_unlock(&ha->mq_lock);
                        goto que_failed;
                }
+               vha->flags.qpairs_req_created = 1;
        }
 
        return req->id;
@@ -772,6 +774,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t 
options,
        int ret = 0;
        struct rsp_que *rsp = NULL;
        struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
+       struct scsi_qla_host *vha = pci_get_drvdata(ha->pdev);
        uint16_t que_id = 0;
        device_reg_t *reg;
 
@@ -855,6 +858,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t 
options,
                        mutex_unlock(&ha->mq_lock);
                        goto que_failed;
                }
+               vha->flags.qpairs_rsp_created = 1;
        }
        rsp->req = NULL;
 
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 3963602aef35..13e4d2428a9a 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -384,6 +384,7 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, 
struct req_que *req,
        ha->base_qpair->rsp = rsp;
        ha->base_qpair->vha = vha;
        ha->base_qpair->qp_lock_ptr = &ha->hardware_lock;
+       /* init qpair to this cpu. Will adjust at run time. */
        ha->base_qpair->msix = &ha->msix_entries[QLA_MSIX_RSP_Q];
        INIT_LIST_HEAD(&ha->base_qpair->hints_list);
        qla_cpu_update(rsp->qpair, smp_processor_id());
-- 
2.12.0

Reply via email to