scsi: qla2xxx: Fix mailbox failure while deleting Queue pairs
authorSawan Chandak <sawan.chandak@cavium.com>
Wed, 14 Jun 2017 03:47:19 +0000 (20:47 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 28 Jun 2017 01:21:40 +0000 (21:21 -0400)
In target mode driver, queue pairs are not created during driver load
time, instead they are created at the configuration time after chip
reset.  If a user tries to load/unload driver after queue pairs are
created, then there would be mailbox failure, while deleting queue
pairs.  Flag is added to check if queue pairs are created or not. Queue
pairs will be deleted only If they were created during target
configuration.

Signed-off-by: Sawan Chandak <sawan.chandak@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_mid.c
drivers/scsi/qla2xxx/qla_os.c

index 005ca2de3795d08f84bc202a90196072d95b9ac2..8b52f431a812ba6f12b217595f18b6be36865cd6 100644 (file)
@@ -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;
index 4366b12b0e6d74826b93f9792beaac1decd3cfff..6230f33f2b859c2ae94c5134667f9539b88ca53a 100644 (file)
@@ -7719,9 +7719,12 @@ fail_qid_map:
 
 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);
index 4ad452a42dbe6b5786ddee243db66c6b81998389..f0605cd196fb4e84c35bf4f59879af5b268924a5 100644 (file)
@@ -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;
 
index 3963602aef35051ca588ffbcf94ee888909d5650..13e4d2428a9ad347d9ad808a7f86aa4bdc8e604c 100644 (file)
@@ -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());