Commit 3cf92f4b authored by Martin Wilck's avatar Martin Wilck Committed by Martin K. Petersen

scsi: qla2xxx: cleanup trace buffer initialization

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: ad0a0b01 ("scsi: qla2xxx: Fix Firmware dump size for Extended login and Exchange Offload")
Fixes: a28d9e4e ("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: default avatarMartin Wilck <mwilck@suse.com>
Tested-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
Reviewed-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent edbd5647
...@@ -3032,103 +3032,113 @@ qla24xx_chip_diag(scsi_qla_host_t *vha) ...@@ -3032,103 +3032,113 @@ qla24xx_chip_diag(scsi_qla_host_t *vha)
} }
static void static void
qla2x00_alloc_offload_mem(scsi_qla_host_t *vha) qla2x00_init_fce_trace(scsi_qla_host_t *vha)
{ {
int rval; int rval;
dma_addr_t tc_dma; dma_addr_t tc_dma;
void *tc; void *tc;
struct qla_hw_data *ha = vha->hw; 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, ql_dbg(ql_dbg_init, vha, 0x00bd,
"%s: Offload Mem is already allocated.\n", "%s: FCE Mem is already allocated.\n",
__func__); __func__);
return; return;
} }
if (IS_FWI2_CAPABLE(ha)) { /* Allocate memory for Fibre Channel Event Buffer. */
/* Allocate memory for Fibre Channel Event Buffer. */ tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma,
if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && GFP_KERNEL);
!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) if (!tc) {
goto try_eft; ql_log(ql_log_warn, vha, 0x00be,
"Unable to allocate (%d KB) for FCE.\n",
FCE_SIZE / 1024);
return;
}
if (ha->fce) rval = qla2x00_enable_fce_trace(vha, tc_dma, FCE_NUM_BUFFERS,
dma_free_coherent(&ha->pdev->dev, ha->fce_mb, &ha->fce_bufs);
FCE_SIZE, ha->fce, ha->fce_dma); 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. */ ql_dbg(ql_dbg_init, vha, 0x00c0,
tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma, "Allocated (%d KB) for FCE...\n", FCE_SIZE / 1024);
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);
/* Allocate memory for Extended Trace Buffer. */ ha->flags.fce_enabled = 1;
tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, ha->fce_dma = tc_dma;
GFP_KERNEL); ha->fce = tc;
if (!tc) { }
ql_log(ql_log_warn, vha, 0x00c1,
"Unable to allocate (%d KB) for EFT.\n",
EFT_SIZE / 1024);
goto eft_err;
}
rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS); static void
if (rval) { qla2x00_init_eft_trace(scsi_qla_host_t *vha)
ql_log(ql_log_warn, vha, 0x00c2, {
"Unable to initialize EFT (%d).\n", rval); int rval;
dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, dma_addr_t tc_dma;
tc_dma); void *tc;
goto eft_err; struct qla_hw_data *ha = vha->hw;
}
ql_dbg(ql_dbg_init, vha, 0x00c3, if (!IS_FWI2_CAPABLE(ha))
"Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024); return;
ha->eft_dma = tc_dma; if (ha->eft) {
ha->eft = tc; ql_dbg(ql_dbg_init, vha, 0x00bd,
"%s: EFT Mem is already allocated.\n",
__func__);
return;
} }
eft_err: /* Allocate memory for Extended Trace Buffer. */
return; 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 void
qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) 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, uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size,
eft_size, fce_size, mq_size; eft_size, fce_size, mq_size;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct req_que *req = ha->req_q_map[0]; struct req_que *req = ha->req_q_map[0];
struct rsp_que *rsp = ha->rsp_q_map[0]; struct rsp_que *rsp = ha->rsp_q_map[0];
struct qla2xxx_fw_dump *fw_dump; 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; dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0;
req_q_size = rsp_q_size = 0; req_q_size = rsp_q_size = 0;
...@@ -3166,39 +3176,13 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) ...@@ -3166,39 +3176,13 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
} }
if (ha->tgt.atio_ring) if (ha->tgt.atio_ring)
mq_size += ha->tgt.atio_q_length * sizeof(request_t); 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; qla2x00_init_fce_trace(vha);
try_eft: if (ha->fce)
fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE;
qla2x00_init_eft_trace(vha);
if (ha->eft) if (ha->eft)
dma_free_coherent(&ha->pdev->dev, eft_size = EFT_SIZE;
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;
} }
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
...@@ -3220,24 +3204,22 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) ...@@ -3220,24 +3204,22 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
j, fwdt->dump_size); j, fwdt->dump_size);
dump_size += 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) { if (!ha->fw_dump_len || dump_size > ha->fw_dump_alloc_len) {
ql_dbg(ql_dbg_init, vha, 0x00c5, ql_dbg(ql_dbg_init, vha, 0x00c5,
......
...@@ -4577,6 +4577,7 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha) ...@@ -4577,6 +4577,7 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha)
ha->fce = NULL; ha->fce = NULL;
ha->fce_dma = 0; ha->fce_dma = 0;
ha->flags.fce_enabled = 0;
ha->eft = NULL; ha->eft = NULL;
ha->eft_dma = 0; ha->eft_dma = 0;
ha->fw_dumped = 0; ha->fw_dumped = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment