From: Sawan Chandak <sawan.chandak@xxxxxxxxxx> 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@xxxxxxxxxx> Signed-off-by: Himanshu Madhani <himanshu.madhani@xxxxxxxxxx> --- 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