summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSawan Chandak2017-06-14 05:47:19 +0200
committerMartin K. Petersen2017-06-28 03:21:40 +0200
commitd65237c7f086042b5630d94fe2d151f62c09f723 (patch)
treeb9a52b70191cb79251c3c42230003964f9ade519
parentscsi: qla2xxx: Enable Target Multi Queue (diff)
downloadkernel-qcow2-linux-d65237c7f086042b5630d94fe2d151f62c09f723.tar.gz
kernel-qcow2-linux-d65237c7f086042b5630d94fe2d151f62c09f723.tar.xz
kernel-qcow2-linux-d65237c7f086042b5630d94fe2d151f62c09f723.zip
scsi: qla2xxx: Fix mailbox failure while deleting Queue pairs
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>
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c10
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c1
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 4366b12b0e6d..6230f33f2b85 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -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);
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());