@@ -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;
@@ -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 *);
/*
@@ -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);
@@ -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,
@@ -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;
@@ -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;
@@ -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);
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@marvell.com> Cc: Giridhar Malavali <gmalavali@marvell.com> Signed-off-by: Bart Van Assche <bvanassche@acm.org> --- 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(-)