| From 138f577f6fa5bba523f422a7d24d3d546c7909de Mon Sep 17 00:00:00 2001 |
| From: Martin Wilck <mwilck@suse.com> |
| Date: Wed, 14 Aug 2019 13:28:29 +0000 |
| Subject: [PATCH] scsi: qla2xxx: cleanup trace buffer initialization |
| |
| commit 3cf92f4bfccbb3e378cd86dc46e09c2bc18cda26 upstream. |
| |
| Avoid code duplication between qla2x00_alloc_offload_mem() and |
| qla2x00_alloc_fw_dump() by moving the FCE and EFT buffer allocation and |
| initialization to separate functions. Cleanly track failure and success by |
| making sure that the ha->eft, ha->fce and respective eft_dma, fce_dma |
| members are set if and only if the buffers are properly allocated and |
| initialized. Avoid pointless buffer reallocation. Eliminate some goto |
| statements. Make sure the fce_enabled flag is cleared when the FCE buffer |
| is freed. |
| |
| Fixes: ad0a0b01f088 ("scsi: qla2xxx: Fix Firmware dump size for Extended login and Exchange Offload") |
| Fixes: a28d9e4ef997 ("scsi: qla2xxx: Add support for multiple fwdump templates/segments") |
| Cc: Joe Carnuccio <joe.carnuccio@cavium.com> |
| Cc: Quinn Tran <qutran@marvell.com> |
| Cc: Himanshu Madhani <hmadhani@marvell.com> |
| Cc: Bart Van Assche <bvanassche@acm.org> |
| Signed-off-by: Martin Wilck <mwilck@suse.com> |
| Tested-by: Himanshu Madhani <hmadhani@marvell.com> |
| Reviewed-by: Himanshu Madhani <hmadhani@marvell.com> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c |
| index 1dabbc7a6dff..670259fe08bb 100644 |
| --- a/drivers/scsi/qla2xxx/qla_init.c |
| +++ b/drivers/scsi/qla2xxx/qla_init.c |
| @@ -3096,103 +3096,113 @@ qla24xx_chip_diag(scsi_qla_host_t *vha) |
| } |
| |
| static void |
| -qla2x00_alloc_offload_mem(scsi_qla_host_t *vha) |
| +qla2x00_init_fce_trace(scsi_qla_host_t *vha) |
| { |
| int rval; |
| dma_addr_t tc_dma; |
| void *tc; |
| struct qla_hw_data *ha = vha->hw; |
| |
| - if (ha->eft) { |
| + if (!IS_FWI2_CAPABLE(ha)) |
| + return; |
| + |
| + if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && |
| + !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
| + return; |
| + |
| + if (ha->fce) { |
| ql_dbg(ql_dbg_init, vha, 0x00bd, |
| - "%s: Offload Mem is already allocated.\n", |
| - __func__); |
| + "%s: FCE Mem is already allocated.\n", |
| + __func__); |
| return; |
| } |
| |
| - if (IS_FWI2_CAPABLE(ha)) { |
| - /* Allocate memory for Fibre Channel Event Buffer. */ |
| - if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && |
| - !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
| - goto try_eft; |
| + /* Allocate memory for Fibre Channel Event Buffer. */ |
| + tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma, |
| + GFP_KERNEL); |
| + if (!tc) { |
| + ql_log(ql_log_warn, vha, 0x00be, |
| + "Unable to allocate (%d KB) for FCE.\n", |
| + FCE_SIZE / 1024); |
| + return; |
| + } |
| |
| - if (ha->fce) |
| - dma_free_coherent(&ha->pdev->dev, |
| - FCE_SIZE, ha->fce, ha->fce_dma); |
| + rval = qla2x00_enable_fce_trace(vha, tc_dma, FCE_NUM_BUFFERS, |
| + ha->fce_mb, &ha->fce_bufs); |
| + if (rval) { |
| + ql_log(ql_log_warn, vha, 0x00bf, |
| + "Unable to initialize FCE (%d).\n", rval); |
| + dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, tc_dma); |
| + return; |
| + } |
| |
| - /* Allocate memory for Fibre Channel Event Buffer. */ |
| - tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma, |
| - GFP_KERNEL); |
| - if (!tc) { |
| - ql_log(ql_log_warn, vha, 0x00be, |
| - "Unable to allocate (%d KB) for FCE.\n", |
| - FCE_SIZE / 1024); |
| - goto try_eft; |
| - } |
| - |
| - rval = qla2x00_enable_fce_trace(vha, tc_dma, FCE_NUM_BUFFERS, |
| - ha->fce_mb, &ha->fce_bufs); |
| - if (rval) { |
| - ql_log(ql_log_warn, vha, 0x00bf, |
| - "Unable to initialize FCE (%d).\n", rval); |
| - dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, |
| - tc_dma); |
| - ha->flags.fce_enabled = 0; |
| - goto try_eft; |
| - } |
| - ql_dbg(ql_dbg_init, vha, 0x00c0, |
| - "Allocate (%d KB) for FCE...\n", FCE_SIZE / 1024); |
| - |
| - ha->flags.fce_enabled = 1; |
| - ha->fce_dma = tc_dma; |
| - ha->fce = tc; |
| - |
| -try_eft: |
| - if (ha->eft) |
| - dma_free_coherent(&ha->pdev->dev, |
| - EFT_SIZE, ha->eft, ha->eft_dma); |
| + ql_dbg(ql_dbg_init, vha, 0x00c0, |
| + "Allocated (%d KB) for FCE...\n", FCE_SIZE / 1024); |
| |
| - /* Allocate memory for Extended Trace Buffer. */ |
| - tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, |
| - GFP_KERNEL); |
| - if (!tc) { |
| - ql_log(ql_log_warn, vha, 0x00c1, |
| - "Unable to allocate (%d KB) for EFT.\n", |
| - EFT_SIZE / 1024); |
| - goto eft_err; |
| - } |
| + ha->flags.fce_enabled = 1; |
| + ha->fce_dma = tc_dma; |
| + ha->fce = tc; |
| +} |
| |
| - rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS); |
| - if (rval) { |
| - ql_log(ql_log_warn, vha, 0x00c2, |
| - "Unable to initialize EFT (%d).\n", rval); |
| - dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, |
| - tc_dma); |
| - goto eft_err; |
| - } |
| - ql_dbg(ql_dbg_init, vha, 0x00c3, |
| - "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024); |
| +static void |
| +qla2x00_init_eft_trace(scsi_qla_host_t *vha) |
| +{ |
| + int rval; |
| + dma_addr_t tc_dma; |
| + void *tc; |
| + struct qla_hw_data *ha = vha->hw; |
| + |
| + if (!IS_FWI2_CAPABLE(ha)) |
| + return; |
| |
| - ha->eft_dma = tc_dma; |
| - ha->eft = tc; |
| + if (ha->eft) { |
| + ql_dbg(ql_dbg_init, vha, 0x00bd, |
| + "%s: EFT Mem is already allocated.\n", |
| + __func__); |
| + return; |
| } |
| |
| -eft_err: |
| - return; |
| + /* Allocate memory for Extended Trace Buffer. */ |
| + tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, |
| + GFP_KERNEL); |
| + if (!tc) { |
| + ql_log(ql_log_warn, vha, 0x00c1, |
| + "Unable to allocate (%d KB) for EFT.\n", |
| + EFT_SIZE / 1024); |
| + return; |
| + } |
| + |
| + rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS); |
| + if (rval) { |
| + ql_log(ql_log_warn, vha, 0x00c2, |
| + "Unable to initialize EFT (%d).\n", rval); |
| + dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, tc_dma); |
| + return; |
| + } |
| + |
| + ql_dbg(ql_dbg_init, vha, 0x00c3, |
| + "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024); |
| + |
| + ha->eft_dma = tc_dma; |
| + ha->eft = tc; |
| +} |
| + |
| +static void |
| +qla2x00_alloc_offload_mem(scsi_qla_host_t *vha) |
| +{ |
| + qla2x00_init_fce_trace(vha); |
| + qla2x00_init_eft_trace(vha); |
| } |
| |
| void |
| qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) |
| { |
| - int rval; |
| uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size, |
| eft_size, fce_size, mq_size; |
| struct qla_hw_data *ha = vha->hw; |
| struct req_que *req = ha->req_q_map[0]; |
| struct rsp_que *rsp = ha->rsp_q_map[0]; |
| struct qla2xxx_fw_dump *fw_dump; |
| - dma_addr_t tc_dma; |
| - void *tc; |
| |
| dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0; |
| req_q_size = rsp_q_size = 0; |
| @@ -3230,39 +3240,13 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) |
| } |
| if (ha->tgt.atio_ring) |
| mq_size += ha->tgt.atio_q_length * sizeof(request_t); |
| - /* Allocate memory for Fibre Channel Event Buffer. */ |
| - if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && |
| - !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
| - goto try_eft; |
| |
| - fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE; |
| -try_eft: |
| + qla2x00_init_fce_trace(vha); |
| + if (ha->fce) |
| + fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE; |
| + qla2x00_init_eft_trace(vha); |
| if (ha->eft) |
| - dma_free_coherent(&ha->pdev->dev, |
| - EFT_SIZE, ha->eft, ha->eft_dma); |
| - |
| - /* Allocate memory for Extended Trace Buffer. */ |
| - tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, |
| - GFP_KERNEL); |
| - if (!tc) { |
| - ql_log(ql_log_warn, vha, 0x00c1, |
| - "Unable to allocate (%d KB) for EFT.\n", |
| - EFT_SIZE / 1024); |
| - goto allocate; |
| - } |
| - |
| - rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS); |
| - if (rval) { |
| - ql_log(ql_log_warn, vha, 0x00c2, |
| - "Unable to initialize EFT (%d).\n", rval); |
| - dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, |
| - tc_dma); |
| - } |
| - ql_dbg(ql_dbg_init, vha, 0x00c3, |
| - "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024); |
| - eft_size = EFT_SIZE; |
| - ha->eft_dma = tc_dma; |
| - ha->eft = tc; |
| + eft_size = EFT_SIZE; |
| } |
| |
| if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
| @@ -3284,24 +3268,22 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) |
| j, fwdt->dump_size); |
| dump_size += fwdt->dump_size; |
| } |
| - goto allocate; |
| + } else { |
| + req_q_size = req->length * sizeof(request_t); |
| + rsp_q_size = rsp->length * sizeof(response_t); |
| + dump_size = offsetof(struct qla2xxx_fw_dump, isp); |
| + dump_size += fixed_size + mem_size + req_q_size + rsp_q_size |
| + + eft_size; |
| + ha->chain_offset = dump_size; |
| + dump_size += mq_size + fce_size; |
| + if (ha->exchoffld_buf) |
| + dump_size += sizeof(struct qla2xxx_offld_chain) + |
| + ha->exchoffld_size; |
| + if (ha->exlogin_buf) |
| + dump_size += sizeof(struct qla2xxx_offld_chain) + |
| + ha->exlogin_size; |
| } |
| |
| - req_q_size = req->length * sizeof(request_t); |
| - rsp_q_size = rsp->length * sizeof(response_t); |
| - dump_size = offsetof(struct qla2xxx_fw_dump, isp); |
| - dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + eft_size; |
| - ha->chain_offset = dump_size; |
| - dump_size += mq_size + fce_size; |
| - |
| - if (ha->exchoffld_buf) |
| - dump_size += sizeof(struct qla2xxx_offld_chain) + |
| - ha->exchoffld_size; |
| - if (ha->exlogin_buf) |
| - dump_size += sizeof(struct qla2xxx_offld_chain) + |
| - ha->exlogin_size; |
| - |
| -allocate: |
| if (!ha->fw_dump_len || dump_size > ha->fw_dump_alloc_len) { |
| |
| ql_dbg(ql_dbg_init, vha, 0x00c5, |
| diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c |
| index 3248ffe8c70e..42466f325d87 100644 |
| --- a/drivers/scsi/qla2xxx/qla_os.c |
| +++ b/drivers/scsi/qla2xxx/qla_os.c |
| @@ -4627,6 +4627,7 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha) |
| |
| ha->fce = NULL; |
| ha->fce_dma = 0; |
| + ha->flags.fce_enabled = 0; |
| ha->eft = NULL; |
| ha->eft_dma = 0; |
| ha->fw_dumped = 0; |
| -- |
| 2.27.0 |
| |