diff mbox

[04/15] qla2xxx: Fix mailbox failure while deleting Queue pairs

Message ID 20170607214333.23110-5-himanshu.madhani@cavium.com (mailing list archive)
State New, archived
Headers show

Commit Message

Madhani, Himanshu June 7, 2017, 9:43 p.m. UTC
From: Sawan Chandak <sawan.chandak@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.chandak@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@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 mbox

Patch

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());