For each SRB type, make the free function free all memory associated with the SRB. Initialize the .free() function pointer after the qla2x00_init_timer() call and before the first sp->free(sp) call to make sure that all sp->free(sp) calls call the right .free() function. Remove the qla24xx_sp_unmap() function because it is no longer necessary. This patch fixes a memory leak in the timeout handling code in qla24xx_async_gpdb_sp_done(). Cc: Himanshu Madhani <hmadhani@xxxxxxxxxxx> Cc: Giridhar Malavali <gmalavali@xxxxxxxxxxx> Signed-off-by: Bart Van Assche <bvanassche@xxxxxxx> --- drivers/scsi/qla2xxx/qla_def.h | 2 +- drivers/scsi/qla2xxx/qla_gbl.h | 1 - drivers/scsi/qla2xxx/qla_gs.c | 209 ++++++++++++++------------------ drivers/scsi/qla2xxx/qla_init.c | 24 ++-- drivers/scsi/qla2xxx/qla_iocb.c | 48 ++++---- drivers/scsi/qla2xxx/qla_nvme.c | 18 ++- drivers/scsi/qla2xxx/qla_os.c | 4 +- 7 files changed, 142 insertions(+), 164 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 78c5405482f6..3f398475d658 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -395,7 +395,7 @@ struct srb_iocb { struct els_logo_payload *els_logo_pyld; dma_addr_t els_logo_pyld_dma; } els_logo; - struct { + struct els_plogi { #define ELS_DCMD_PLOGI 0x3 uint32_t flags; uint32_t els_cmd; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index aaa78f1020a7..b3affe8ddf29 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -676,7 +676,6 @@ int qla24xx_post_gnnid_work(struct scsi_qla_host *, fc_port_t *); int qla24xx_post_gfpnid_work(struct scsi_qla_host *, fc_port_t *); int qla24xx_async_gfpnid(scsi_qla_host_t *, fc_port_t *); void qla24xx_handle_gfpnid_event(scsi_qla_host_t *, struct event_arg *); -void qla24xx_sp_unmap(scsi_qla_host_t *, srb_t *); void qla_scan_work_fn(struct work_struct *); /* diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 013d64d2be10..863f98ac6a30 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -509,6 +509,28 @@ qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list) return (rval); } +static void qla2x00_async_sns_sp_free(srb_t *sp) +{ + struct scsi_qla_host *vha = sp->vha; + struct ct_arg *ctarg = &sp->u.iocb_cmd.u.ctarg; + + if (&ctarg->rsp) { + dma_free_coherent(&vha->hw->pdev->dev, + ctarg->rsp_allocated_size, ctarg->rsp, + ctarg->rsp_dma); + ctarg->rsp = NULL; + } + + if (&ctarg->req) { + dma_free_coherent(&vha->hw->pdev->dev, + ctarg->req_allocated_size, ctarg->req, + ctarg->req_dma); + ctarg->req = NULL; + } + + qla2x00_sp_free(sp); +} + static void qla2x00_async_sns_sp_done(srb_t *sp, int rc) { struct scsi_qla_host *vha = sp->vha; @@ -549,24 +571,7 @@ static void qla2x00_async_sns_sp_done(srb_t *sp, int rc) err2: if (!e) { /* please ignore kernel warning. otherwise, we have mem leak. */ - if (sp->u.iocb_cmd.u.ctarg.req) { - dma_free_coherent(&vha->hw->pdev->dev, - sp->u.iocb_cmd.u.ctarg.req_allocated_size, - sp->u.iocb_cmd.u.ctarg.req, - sp->u.iocb_cmd.u.ctarg.req_dma); - sp->u.iocb_cmd.u.ctarg.req = NULL; - } - - if (sp->u.iocb_cmd.u.ctarg.rsp) { - dma_free_coherent(&vha->hw->pdev->dev, - sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, - sp->u.iocb_cmd.u.ctarg.rsp, - sp->u.iocb_cmd.u.ctarg.rsp_dma); - sp->u.iocb_cmd.u.ctarg.rsp = NULL; - } - sp->free(sp); - return; } @@ -608,6 +613,8 @@ static int qla_async_rftid(scsi_qla_host_t *vha, port_id_t *d_id) sp->type = SRB_CT_PTHRU_CMD; sp->name = "rft_id"; qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); + sp->free = qla2x00_async_sns_sp_free; + sp->done = qla2x00_async_sns_sp_done; sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev, sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma, @@ -650,7 +657,6 @@ static int qla_async_rftid(scsi_qla_host_t *vha, port_id_t *d_id) sp->u.iocb_cmd.u.ctarg.rsp_size = RFT_ID_RSP_SIZE; sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; - sp->done = qla2x00_async_sns_sp_done; ql_dbg(ql_dbg_disc, vha, 0xffff, "Async-%s - hdl=%x portid %06x.\n", @@ -706,6 +712,8 @@ static int qla_async_rffid(scsi_qla_host_t *vha, port_id_t *d_id, sp->type = SRB_CT_PTHRU_CMD; sp->name = "rff_id"; qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); + sp->free = qla2x00_async_sns_sp_free; + sp->done = qla2x00_async_sns_sp_done; sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev, sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma, @@ -746,7 +754,6 @@ static int qla_async_rffid(scsi_qla_host_t *vha, port_id_t *d_id, sp->u.iocb_cmd.u.ctarg.rsp_size = RFF_ID_RSP_SIZE; sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; - sp->done = qla2x00_async_sns_sp_done; ql_dbg(ql_dbg_disc, vha, 0xffff, "Async-%s - hdl=%x portid %06x feature %x type %x.\n", @@ -799,6 +806,8 @@ static int qla_async_rnnid(scsi_qla_host_t *vha, port_id_t *d_id, sp->type = SRB_CT_PTHRU_CMD; sp->name = "rnid"; qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); + sp->free = qla2x00_async_sns_sp_free; + sp->done = qla2x00_async_sns_sp_done; sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev, sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma, @@ -839,7 +848,6 @@ static int qla_async_rnnid(scsi_qla_host_t *vha, port_id_t *d_id, sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; - sp->done = qla2x00_async_sns_sp_done; ql_dbg(ql_dbg_disc, vha, 0xffff, "Async-%s - hdl=%x portid %06x\n", @@ -909,6 +917,8 @@ static int qla_async_rsnn_nn(scsi_qla_host_t *vha) sp->type = SRB_CT_PTHRU_CMD; sp->name = "rsnn_nn"; qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); + sp->free = qla2x00_async_sns_sp_free; + sp->done = qla2x00_async_sns_sp_done; sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev, sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma, @@ -953,7 +963,6 @@ static int qla_async_rsnn_nn(scsi_qla_host_t *vha) sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; - sp->done = qla2x00_async_sns_sp_done; ql_dbg(ql_dbg_disc, vha, 0xffff, "Async-%s - hdl=%x.\n", @@ -3136,47 +3145,6 @@ int qla24xx_post_gpnid_work(struct scsi_qla_host *vha, port_id_t *id) return qla2x00_post_work(vha, e); } -void qla24xx_sp_unmap(scsi_qla_host_t *vha, srb_t *sp) -{ - struct srb_iocb *c = &sp->u.iocb_cmd; - - switch (sp->type) { - case SRB_ELS_DCMD: - if (c->u.els_plogi.els_plogi_pyld) - dma_free_coherent(&vha->hw->pdev->dev, - c->u.els_plogi.tx_size, - c->u.els_plogi.els_plogi_pyld, - c->u.els_plogi.els_plogi_pyld_dma); - - if (c->u.els_plogi.els_resp_pyld) - dma_free_coherent(&vha->hw->pdev->dev, - c->u.els_plogi.rx_size, - c->u.els_plogi.els_resp_pyld, - c->u.els_plogi.els_resp_pyld_dma); - break; - case SRB_CT_PTHRU_CMD: - default: - if (sp->u.iocb_cmd.u.ctarg.req) { - dma_free_coherent(&vha->hw->pdev->dev, - sp->u.iocb_cmd.u.ctarg.req_allocated_size, - sp->u.iocb_cmd.u.ctarg.req, - sp->u.iocb_cmd.u.ctarg.req_dma); - sp->u.iocb_cmd.u.ctarg.req = NULL; - } - - if (sp->u.iocb_cmd.u.ctarg.rsp) { - dma_free_coherent(&vha->hw->pdev->dev, - sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, - sp->u.iocb_cmd.u.ctarg.rsp, - sp->u.iocb_cmd.u.ctarg.rsp_dma); - sp->u.iocb_cmd.u.ctarg.rsp = NULL; - } - break; - } - - sp->free(sp); -} - void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea) { fc_port_t *fcport, *conflict, *t; @@ -3278,6 +3246,33 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea) } } +static void qla2x00_async_gpnid_sp_free(srb_t *sp) +{ + struct scsi_qla_host *vha = sp->vha; + struct ct_arg *ctarg = &sp->u.iocb_cmd.u.ctarg; + unsigned long flags; + + spin_lock_irqsave(&vha->hw->vport_slock, flags); + list_del_init(&sp->elem); + spin_unlock_irqrestore(&vha->hw->vport_slock, flags); + + if (ctarg->rsp) { + dma_free_coherent(&vha->hw->pdev->dev, + ctarg->rsp_allocated_size, ctarg->rsp, + ctarg->rsp_dma); + ctarg->rsp = NULL; + } + + if (ctarg->req) { + dma_free_coherent(&vha->hw->pdev->dev, + ctarg->req_allocated_size, ctarg->req, + ctarg->req_dma); + ctarg->req = NULL; + } + + qla2x00_sp_free(sp); +} + static void qla2x00_async_gpnid_sp_done(srb_t *sp, int res) { struct scsi_qla_host *vha = sp->vha; @@ -3310,7 +3305,7 @@ static void qla2x00_async_gpnid_sp_done(srb_t *sp, int res) ea.event = FCME_GPNID_DONE; spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); - list_del(&sp->elem); + list_del_init(&sp->elem); spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); if (res) { @@ -3331,21 +3326,6 @@ static void qla2x00_async_gpnid_sp_done(srb_t *sp, int res) e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP); if (!e) { /* please ignore kernel warning. otherwise, we have mem leak. */ - if (sp->u.iocb_cmd.u.ctarg.req) { - dma_free_coherent(&vha->hw->pdev->dev, - sp->u.iocb_cmd.u.ctarg.req_allocated_size, - sp->u.iocb_cmd.u.ctarg.req, - sp->u.iocb_cmd.u.ctarg.req_dma); - sp->u.iocb_cmd.u.ctarg.req = NULL; - } - if (sp->u.iocb_cmd.u.ctarg.rsp) { - dma_free_coherent(&vha->hw->pdev->dev, - sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, - sp->u.iocb_cmd.u.ctarg.rsp, - sp->u.iocb_cmd.u.ctarg.rsp_dma); - sp->u.iocb_cmd.u.ctarg.rsp = NULL; - } - sp->free(sp); return; } @@ -3375,6 +3355,8 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id) sp->u.iocb_cmd.u.ctarg.id = *id; sp->gen1 = 0; qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); + sp->free = qla2x00_async_gpnid_sp_free; + sp->done = qla2x00_async_gpnid_sp_done; spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); list_for_each_entry(tsp, &vha->gpnid_list, elem) { @@ -3425,7 +3407,6 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id) sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; - sp->done = qla2x00_async_gpnid_sp_done; ql_dbg(ql_dbg_disc, vha, 0x2067, "Async-%s hdl=%x ID %3phC.\n", sp->name, @@ -3438,25 +3419,6 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id) return rval; done_free_sp: - spin_lock_irqsave(&vha->hw->vport_slock, flags); - list_del(&sp->elem); - spin_unlock_irqrestore(&vha->hw->vport_slock, flags); - - if (sp->u.iocb_cmd.u.ctarg.req) { - dma_free_coherent(&vha->hw->pdev->dev, - sizeof(struct ct_sns_pkt), - sp->u.iocb_cmd.u.ctarg.req, - sp->u.iocb_cmd.u.ctarg.req_dma); - sp->u.iocb_cmd.u.ctarg.req = NULL; - } - if (sp->u.iocb_cmd.u.ctarg.rsp) { - dma_free_coherent(&vha->hw->pdev->dev, - sizeof(struct ct_sns_pkt), - sp->u.iocb_cmd.u.ctarg.rsp, - sp->u.iocb_cmd.u.ctarg.rsp_dma); - sp->u.iocb_cmd.u.ctarg.rsp = NULL; - } - sp->free(sp); done: return rval; @@ -3747,7 +3709,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) recheck = 1; out: - qla24xx_sp_unmap(vha, sp); + sp->free(sp); spin_lock_irqsave(&vha->work_lock, flags); vha->scan.scan_flags &= ~SF_SCANNING; spin_unlock_irqrestore(&vha->work_lock, flags); @@ -3894,6 +3856,26 @@ static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha, } } +static void qla2x00_async_gpnft_gnnft_sp_free(srb_t *sp) +{ + struct scsi_qla_host *vha = sp->vha; + struct ct_arg *ctarg = &sp->u.iocb_cmd.u.ctarg; + + if (ctarg->rsp) { + dma_free_coherent(&vha->hw->pdev->dev, + ctarg->rsp_allocated_size, ctarg->rsp, + ctarg->rsp_dma); + ctarg->rsp = NULL; + } + if (ctarg->req) { + dma_free_coherent(&vha->hw->pdev->dev, + ctarg->req_allocated_size, ctarg->req, + ctarg->req_dma); + ctarg->req = NULL; + } + qla2x00_sp_free(sp); +} + static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) { struct scsi_qla_host *vha = sp->vha; @@ -3924,7 +3906,7 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) QLA_EVT_GNNFT_DONE); if (rc) { /* Cleanup here to prevent memory leak */ - qla24xx_sp_unmap(vha, sp); + sp->free(sp); spin_lock_irqsave(&vha->work_lock, flags); vha->scan.scan_flags &= ~SF_SCANNING; @@ -3955,7 +3937,7 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) sp->rc = res; rc = qla2x00_post_nvme_gpnft_work(vha, sp, QLA_EVT_GPNFT); if (rc) { - qla24xx_sp_unmap(vha, sp); + sp->free(sp); set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); } @@ -3971,7 +3953,7 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) } if (rc) { - qla24xx_sp_unmap(vha, sp); + sp->free(sp); set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); return; @@ -4025,6 +4007,8 @@ static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp, sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); + sp->free = qla2x00_async_gpnft_gnnft_sp_free; + sp->done = qla2x00_async_gpnft_gnnft_sp_done; memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size); memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size); @@ -4040,8 +4024,6 @@ static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp, sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE; sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; - sp->done = qla2x00_async_gpnft_gnnft_sp_done; - ql_dbg(ql_dbg_disc, vha, 0xffff, "Async-%s hdl=%x FC4Type %x.\n", sp->name, sp->handle, ct_req->req.gpn_ft.port_type); @@ -4057,21 +4039,6 @@ static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp, return rval; done_free_sp: - if (sp->u.iocb_cmd.u.ctarg.req) { - dma_free_coherent(&vha->hw->pdev->dev, - sp->u.iocb_cmd.u.ctarg.req_allocated_size, - sp->u.iocb_cmd.u.ctarg.req, - sp->u.iocb_cmd.u.ctarg.req_dma); - sp->u.iocb_cmd.u.ctarg.req = NULL; - } - if (sp->u.iocb_cmd.u.ctarg.rsp) { - dma_free_coherent(&vha->hw->pdev->dev, - sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, - sp->u.iocb_cmd.u.ctarg.rsp, - sp->u.iocb_cmd.u.ctarg.rsp_dma); - sp->u.iocb_cmd.u.ctarg.rsp = NULL; - } - sp->free(sp); return rval; @@ -4181,6 +4148,8 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); + sp->free = qla2x00_async_gpnft_gnnft_sp_free; + sp->done = qla2x00_async_gpnft_gnnft_sp_done; rspsz = sp->u.iocb_cmd.u.ctarg.rsp_size; memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size); @@ -4195,8 +4164,6 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; - sp->done = qla2x00_async_gpnft_gnnft_sp_done; - ql_dbg(ql_dbg_disc, vha, 0xffff, "Async-%s hdl=%x FC4Type %x.\n", sp->name, sp->handle, ct_req->req.gpn_ft.port_type); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index fc46343f3363..3439cbb3c952 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1093,10 +1093,20 @@ int qla24xx_post_gnl_work(struct scsi_qla_host *vha, fc_port_t *fcport) return qla2x00_post_work(vha, e); } -static void qla24xx_async_gpdb_sp_done(srb_t *sp, int res) +static void qla24xx_async_gpdb_sp_free(srb_t *sp) { struct scsi_qla_host *vha = sp->vha; struct qla_hw_data *ha = vha->hw; + + if (sp->u.iocb_cmd.u.mbx.in) + dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, + sp->u.iocb_cmd.u.mbx.in_dma); + qla2x00_sp_free(sp); +} + +static void qla24xx_async_gpdb_sp_done(srb_t *sp, int res) +{ + struct scsi_qla_host *vha = sp->vha; fc_port_t *fcport = sp->fcport; u16 *mb = sp->u.iocb_cmd.u.mbx.in_mb; struct event_arg ea; @@ -1105,11 +1115,8 @@ static void qla24xx_async_gpdb_sp_done(srb_t *sp, int res) "Async done-%s res %x, WWPN %8phC mb[1]=%x mb[2]=%x \n", sp->name, res, fcport->port_name, mb[1], mb[2]); - if (res == QLA_FUNCTION_TIMEOUT) { - dma_pool_free(sp->vha->hw->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, - sp->u.iocb_cmd.u.mbx.in_dma); - return; - } + if (res == QLA_FUNCTION_TIMEOUT) + goto free_sp; fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); memset(&ea, 0, sizeof(ea)); @@ -1119,9 +1126,7 @@ static void qla24xx_async_gpdb_sp_done(srb_t *sp, int res) qla2x00_fcport_event_handler(vha, &ea); - dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, - sp->u.iocb_cmd.u.mbx.in_dma); - +free_sp: sp->free(sp); } @@ -1283,6 +1288,7 @@ int qla24xx_async_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt) mbx->u.mbx.in = (void *)pd; mbx->u.mbx.in_dma = pd_dma; + sp->free = qla24xx_async_gpdb_sp_free; sp->done = qla24xx_async_gpdb_sp_done; ql_dbg(ql_dbg_disc, vha, 0x20dc, diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 77f3ea4c8a80..42dbe11fbb14 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -2751,6 +2751,27 @@ qla2x00_els_dcmd2_iocb_timeout(void *data) sp->done(sp, QLA_FUNCTION_TIMEOUT); } +static void qla2x00_els_dcmd2_sp_free(srb_t *sp) +{ + struct scsi_qla_host *vha = sp->vha; + struct srb_iocb *elsio = &sp->u.iocb_cmd; + struct els_plogi *els_plogi = &elsio->u.els_plogi; + + if (els_plogi->els_plogi_pyld) + dma_free_coherent(&vha->hw->pdev->dev, + els_plogi->tx_size, + els_plogi->els_plogi_pyld, + els_plogi->els_plogi_pyld_dma); + + if (els_plogi->els_resp_pyld) + dma_free_coherent(&vha->hw->pdev->dev, + els_plogi->rx_size, + els_plogi->els_resp_pyld, + els_plogi->els_resp_pyld_dma); + + qla2x00_sp_free(sp); +} + static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res) { fc_port_t *fcport = sp->fcport; @@ -2781,19 +2802,6 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res) e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP); if (!e) { - struct srb_iocb *elsio = &sp->u.iocb_cmd; - - if (elsio->u.els_plogi.els_plogi_pyld) - dma_free_coherent(&sp->vha->hw->pdev->dev, - elsio->u.els_plogi.tx_size, - elsio->u.els_plogi.els_plogi_pyld, - elsio->u.els_plogi.els_plogi_pyld_dma); - - if (elsio->u.els_plogi.els_resp_pyld) - dma_free_coherent(&sp->vha->hw->pdev->dev, - elsio->u.els_plogi.rx_size, - elsio->u.els_plogi.els_resp_pyld, - elsio->u.els_plogi.els_resp_pyld_dma); sp->free(sp); return; } @@ -2835,7 +2843,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, sp->flags = SRB_WAKEUP_ON_COMP; qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT + 2); - + sp->free = qla2x00_els_dcmd2_sp_free; sp->done = qla2x00_els_dcmd2_sp_done; elsio->u.els_plogi.tx_size = elsio->u.els_plogi.rx_size = DMA_POOL_SIZE; @@ -2893,18 +2901,6 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, out: fcport->flags &= ~(FCF_ASYNC_SENT); - if (elsio->u.els_plogi.els_plogi_pyld) - dma_free_coherent(&sp->vha->hw->pdev->dev, - elsio->u.els_plogi.tx_size, - elsio->u.els_plogi.els_plogi_pyld, - elsio->u.els_plogi.els_plogi_pyld_dma); - - if (elsio->u.els_plogi.els_resp_pyld) - dma_free_coherent(&sp->vha->hw->pdev->dev, - elsio->u.els_plogi.rx_size, - elsio->u.els_plogi.els_resp_pyld, - elsio->u.els_plogi.els_resp_pyld_dma); - sp->free(sp); done: return rval; diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c index fc0c57ecab25..07f83d161304 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c @@ -124,6 +124,11 @@ static int qla_nvme_alloc_queue(struct nvme_fc_local_port *lport, return 0; } +static void qla_nvme_sp_ls_free(srb_t *sp) +{ + qla2x00_rel_sp(sp); +} + static void qla_nvme_sp_ls_done(srb_t *sp, int res) { struct srb_iocb *nvme; @@ -144,7 +149,12 @@ static void qla_nvme_sp_ls_done(srb_t *sp, int res) priv->comp_status = res; schedule_work(&priv->ls_work); /* work schedule doesn't need the sp */ - qla2x00_rel_sp(sp); + sp->free(sp); +} + +static void qla_nvme_sp_free(srb_t *sp) +{ + qla2xxx_rel_qpair_sp(sp->qpair, sp); } static void qla_nvme_sp_done(srb_t *sp, int res) @@ -168,9 +178,7 @@ static void qla_nvme_sp_done(srb_t *sp, int res) } fd->status = 0; fd->done(fd); - qla2xxx_rel_qpair_sp(sp->qpair, sp); - - return; + sp->free(sp); } static void qla_nvme_abort_work(struct work_struct *work) @@ -247,6 +255,7 @@ static int qla_nvme_ls_req(struct nvme_fc_local_port *lport, sp->type = SRB_NVME_LS; sp->name = "nvme_ls"; + sp->free = qla_nvme_sp_ls_free; sp->done = qla_nvme_sp_ls_done; nvme = &sp->u.iocb_cmd; priv->sp = sp; @@ -508,6 +517,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, priv->sp = sp; sp->type = SRB_NVME_CMD; sp->name = "nvme_cmd"; + sp->free = qla_nvme_sp_free; sp->done = qla_nvme_sp_done; sp->qpair = qpair; sp->vha = vha; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 7b9f138ad9e4..619ab9b84b08 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -5177,7 +5177,7 @@ static void qla_sp_retry(struct scsi_qla_host *vha, struct qla_work_evt *e) ql_dbg(ql_dbg_disc, vha, 0x2043, "%s: %s: Re-issue IOCB failed (%d).\n", __func__, sp->name, rval); - qla24xx_sp_unmap(vha, sp); + sp->free(sp); } } @@ -5228,7 +5228,7 @@ qla2x00_do_work(struct scsi_qla_host *vha) qla24xx_async_gpnid(vha, &e->u.gpnid.id); break; case QLA_EVT_UNMAP: - qla24xx_sp_unmap(vha, e->u.iosb.sp); + e->u.iosb.sp->free(e->u.iosb.sp); break; case QLA_EVT_RELOGIN: qla2x00_relogin(vha); -- 2.22.0.rc3