"%s: sp hdl %x, result=%x bsg ptr %p\n",
            __func__, sp->handle, res, bsg_job);
 
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 
        bsg_reply->result = res;
        bsg_job_done(bsg_job, bsg_reply->result,
 
 done:
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
        return 0;
 }
 
 
         * code.
         */
        void (*put_fn)(struct kref *kref);
+
+       /*
+        * Report completion for asynchronous commands.
+        */
+       void (*async_done)(struct srb *sp, int res);
 } srb_t;
 
 #define GET_CMD_SP(sp) (sp->u.scmd.cmd)
 
 
 static void qla_noop_sp_done(srb_t *sp, int res)
 {
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
 
 /*
 
 extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *);
 extern int qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha,
        struct qla_work_evt *e);
+void qla2x00_sp_release(struct kref *kref);
 
 /*
  * Global Function Prototypes in qla_mbx.c source file.
 
                if (!e)
                        goto err2;
 
-               del_timer(&sp->u.iocb_cmd.timer);
                e->u.iosb.sp = sp;
                qla2x00_post_work(vha, e);
                return;
                        sp->u.iocb_cmd.u.ctarg.rsp = NULL;
                }
 
-               sp->free(sp);
-
+               /* ref: INIT */
+               kref_put(&sp->cmd_kref, qla2x00_sp_release);
                return;
        }
 
        if (!vha->flags.online)
                goto done;
 
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
        if (!sp)
                goto done;
        }
        return rval;
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 done:
        return rval;
 }
        srb_t *sp;
        struct ct_sns_pkt *ct_sns;
 
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
        if (!sp)
                goto done;
        return rval;
 
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 done:
        return rval;
 }
        srb_t *sp;
        struct ct_sns_pkt *ct_sns;
 
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
        if (!sp)
                goto done;
        return rval;
 
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 done:
        return rval;
 }
        srb_t *sp;
        struct ct_sns_pkt *ct_sns;
 
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
        if (!sp)
                goto done;
        return rval;
 
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 done:
        return rval;
 }
        qla24xx_handle_gpsc_event(vha, &ea);
 
 done:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
 
 int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport)
        if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
                return rval;
 
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
        if (!sp)
                goto done;
        return rval;
 
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 done:
        return rval;
 }
                break;
        }
 
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
 
 void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
        if (res) {
                if (res == QLA_FUNCTION_TIMEOUT) {
                        qla24xx_post_gpnid_work(sp->vha, &ea.id);
-                       sp->free(sp);
+                       /* ref: INIT */
+                       kref_put(&sp->cmd_kref, qla2x00_sp_release);
                        return;
                }
        } else if (sp->gen1) {
                /* There was another RSCN for this Nport ID */
                qla24xx_post_gpnid_work(sp->vha, &ea.id);
-               sp->free(sp);
+               /* ref: INIT */
+               kref_put(&sp->cmd_kref, qla2x00_sp_release);
                return;
        }
 
                                  sp->u.iocb_cmd.u.ctarg.rsp_dma);
                sp->u.iocb_cmd.u.ctarg.rsp = NULL;
 
-               sp->free(sp);
+               /* ref: INIT */
+               kref_put(&sp->cmd_kref, qla2x00_sp_release);
                return;
        }
 
        if (!vha->flags.online)
                goto done;
 
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
        if (!sp)
                goto done;
                if (tsp->u.iocb_cmd.u.ctarg.id.b24 == id->b24) {
                        tsp->gen1++;
                        spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
-                       sp->free(sp);
+                       /* ref: INIT */
+                       kref_put(&sp->cmd_kref, qla2x00_sp_release);
                        goto done;
                }
        }
                        sp->u.iocb_cmd.u.ctarg.rsp_dma);
                sp->u.iocb_cmd.u.ctarg.rsp = NULL;
        }
-
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 done:
        return rval;
 }
        ea.rc = res;
 
        qla24xx_handle_gffid_event(vha, &ea);
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
 
 /* Get FC4 Feature with Nport ID. */
        if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
                return rval;
 
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
        if (!sp)
                return rval;
 
        return rval;
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
        fcport->flags &= ~FCF_ASYNC_SENT;
        return rval;
 }
            "Async done-%s res %x FC4Type %x\n",
            sp->name, res, sp->gen2);
 
-       del_timer(&sp->u.iocb_cmd.timer);
        sp->rc = res;
        if (res) {
                unsigned long flags;
                    sp->u.iocb_cmd.u.ctarg.rsp_dma);
                sp->u.iocb_cmd.u.ctarg.rsp = NULL;
        }
-
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 
        spin_lock_irqsave(&vha->work_lock, flags);
        vha->scan.scan_flags &= ~SF_SCANNING;
                ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
                    "%s: Performing FCP Scan\n", __func__);
 
-               if (sp)
-                       sp->free(sp); /* should not happen */
+               if (sp) {
+                       /* ref: INIT */
+                       kref_put(&sp->cmd_kref, qla2x00_sp_release);
+               }
 
+               /* ref: INIT */
                sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
                if (!sp) {
                        spin_lock_irqsave(&vha->work_lock, flags);
                            sp->u.iocb_cmd.u.ctarg.req,
                            sp->u.iocb_cmd.u.ctarg.req_dma);
                        sp->u.iocb_cmd.u.ctarg.req = NULL;
+                       /* ref: INIT */
                        qla2x00_rel_sp(sp);
                        return rval;
                }
                sp->u.iocb_cmd.u.ctarg.rsp = NULL;
        }
 
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 
        spin_lock_irqsave(&vha->work_lock, flags);
        vha->scan.scan_flags &= ~SF_SCANNING;
 
        qla24xx_handle_gnnid_event(vha, &ea);
 
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
 
 int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport)
                return rval;
 
        qla2x00_set_fcport_disc_state(fcport, DSC_GNN_ID);
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
        if (!sp)
                goto done;
        return rval;
 
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
        fcport->flags &= ~FCF_ASYNC_SENT;
 done:
        return rval;
 
        qla24xx_handle_gfpnid_event(vha, &ea);
 
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
 
 int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport)
        if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
                return rval;
 
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
        if (!sp)
                goto done;
        return rval;
 
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 done:
        return rval;
 }
 
        WARN_ON(irqs_disabled());
        iocb = &sp->u.iocb_cmd;
        iocb->timeout(sp);
+
+       /* ref: TMR */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
 
 void qla2x00_sp_free(srb_t *sp)
        }
        spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
 
-       if (sp->cmd_sp)
+       if (sp->cmd_sp) {
+               /*
+                * This done function should take care of
+                * original command ref: INIT
+                */
                sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED);
+       }
 
        abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT);
        sp->done(sp, QLA_OS_TIMER_EXPIRED);
        if (orig_sp)
                qla_wait_nvme_release_cmd_kref(orig_sp);
 
-       del_timer(&sp->u.iocb_cmd.timer);
        if (sp->flags & SRB_WAKEUP_ON_COMP)
                complete(&abt->u.abt.comp);
        else
-               sp->free(sp);
+               /* ref: INIT */
+               kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
 
 int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
        srb_t *sp;
        int rval = QLA_FUNCTION_FAILED;
 
+       /* ref: INIT for ABTS command */
        sp = qla2xxx_get_qpair_sp(cmd_sp->vha, cmd_sp->qpair, cmd_sp->fcport,
                                  GFP_ATOMIC);
        if (!sp)
 
        rval = qla2x00_start_sp(sp);
        if (rval != QLA_SUCCESS) {
-               sp->free(sp);
+               /* ref: INIT */
+               kref_put(&sp->cmd_kref, qla2x00_sp_release);
                return rval;
        }
 
                wait_for_completion(&abt_iocb->u.abt.comp);
                rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ?
                        QLA_SUCCESS : QLA_ERR_FROM_FW;
-               sp->free(sp);
+               /* ref: INIT */
+               kref_put(&sp->cmd_kref, qla2x00_sp_release);
        }
 
        return rval;
                qla24xx_handle_plogi_done_event(vha, &ea);
        }
 
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
 
 int
                return rval;
        }
 
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
        if (!sp)
                goto done;
        return rval;
 
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
        fcport->flags &= ~FCF_ASYNC_SENT;
 done:
        fcport->flags &= ~FCF_ASYNC_ACTIVE;
        sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
        sp->fcport->login_gen++;
        qlt_logo_completion_handler(sp->fcport, sp->u.iocb_cmd.u.logio.data[0]);
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
 
 int
        int rval = QLA_FUNCTION_FAILED;
 
        fcport->flags |= FCF_ASYNC_SENT;
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
        if (!sp)
                goto done;
        return rval;
 
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 done:
        fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
        return rval;
        if (!test_bit(UNLOADING, &vha->dpc_flags))
                qla2x00_post_async_prlo_done_work(sp->fcport->vha, sp->fcport,
                    lio->u.logio.data);
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
 
 int
        int rval;
 
        rval = QLA_FUNCTION_FAILED;
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
        if (!sp)
                goto done;
        return rval;
 
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 done:
        fcport->flags &= ~FCF_ASYNC_ACTIVE;
        return rval;
        ea.sp = sp;
 
        qla24xx_handle_adisc_event(vha, &ea);
-
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
 
 int
                return rval;
 
        fcport->flags |= FCF_ASYNC_SENT;
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
        if (!sp)
                goto done;
        return rval;
 
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 done:
        fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
        qla2x00_post_async_adisc_work(vha, fcport, data);
        }
        spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
 
 int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport)
        vha->gnl.sent = 1;
        spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
        if (!sp)
                goto done;
        return rval;
 
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 done:
        fcport->flags &= ~(FCF_ASYNC_ACTIVE | FCF_ASYNC_SENT);
        return rval;
        dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in,
                sp->u.iocb_cmd.u.mbx.in_dma);
 
-       sp->free(sp);
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
 
 int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport)
                qla24xx_handle_prli_done_event(vha, &ea);
        }
 
-       sp->free(sp);
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
 
 int
        return rval;
 
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
        fcport->flags &= ~FCF_ASYNC_SENT;
        return rval;
 }
        if (pd)
                dma_pool_free(ha->s_dma_pool, pd, pd_dma);
 
-       sp->free(sp);
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
        fcport->flags &= ~FCF_ASYNC_SENT;
 done:
        fcport->flags &= ~FCF_ASYNC_ACTIVE;
        srb_t *sp;
        int rval = QLA_FUNCTION_FAILED;
 
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
        if (!sp)
                goto done;
        }
 
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
        fcport->flags &= ~FCF_ASYNC_SENT;
 done:
        return rval;
 
        sp->vha = vha;
        sp->qpair = qpair;
        sp->cmd_type = TYPE_SRB;
+       /* ref : INIT - normal flow */
+       kref_init(&sp->cmd_kref);
        INIT_LIST_HEAD(&sp->elem);
 }
 
 
        }
 }
 
+void
+qla2x00_sp_release(struct kref *kref)
+{
+       struct srb *sp = container_of(kref, struct srb, cmd_kref);
+
+       sp->free(sp);
+}
+
 void
 qla2x00_init_async_sp(srb_t *sp, unsigned long tmo,
                     void (*done)(struct srb *sp, int res))
               return -ENOMEM;
        }
 
-       /* Alloc SRB structure */
+       /* Alloc SRB structure
+        * ref: INIT
+        */
        sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
        if (!sp) {
                kfree(fcport);
                            GFP_KERNEL);
 
        if (!elsio->u.els_logo.els_logo_pyld) {
-               sp->free(sp);
+               /* ref: INIT */
+               kref_put(&sp->cmd_kref, qla2x00_sp_release);
                return QLA_FUNCTION_FAILED;
        }
 
 
        rval = qla2x00_start_sp(sp);
        if (rval != QLA_SUCCESS) {
-               sp->free(sp);
+               /* ref: INIT */
+               kref_put(&sp->cmd_kref, qla2x00_sp_release);
                return QLA_FUNCTION_FAILED;
        }
 
 
        wait_for_completion(&elsio->u.els_logo.comp);
 
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
        return rval;
 }
 
            sp->name, res, sp->handle, fcport->d_id.b24, fcport->port_name);
 
        fcport->flags &= ~(FCF_ASYNC_SENT|FCF_ASYNC_ACTIVE);
-       del_timer(&sp->u.iocb_cmd.timer);
 
        if (sp->flags & SRB_WAKEUP_ON_COMP)
                complete(&lio->u.els_plogi.comp);
                        struct srb_iocb *elsio = &sp->u.iocb_cmd;
 
                        qla2x00_els_dcmd2_free(vha, &elsio->u.els_plogi);
-                       sp->free(sp);
+                       /* ref: INIT */
+                       kref_put(&sp->cmd_kref, qla2x00_sp_release);
                        return;
                }
                e->u.iosb.sp = sp;
        int rval = QLA_SUCCESS;
        void    *ptr, *resp_ptr;
 
-       /* Alloc SRB structure */
+       /* Alloc SRB structure
+        * ref: INIT
+        */
        sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
        if (!sp) {
                ql_log(ql_log_info, vha, 0x70e6,
 out:
        fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
        qla2x00_els_dcmd2_free(vha, &elsio->u.els_plogi);
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 done:
        return rval;
 }
                break;
        }
 
-       if (sp->start_timer)
+       if (sp->start_timer) {
+               /* ref: TMR timer ref
+                * this code should be just before start_iocbs function
+                * This will make sure that caller function don't to do
+                * kref_put even on failure
+                */
+               kref_get(&sp->cmd_kref);
                add_timer(&sp->u.iocb_cmd.timer);
+       }
 
        wmb();
        qla2x00_start_iocbs(vha, qp->req);
 
        if (!vha->hw->flags.fw_started)
                goto done;
 
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
        if (!sp)
                goto done;
        }
 
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 done:
        return rval;
 }
 
        if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
                return QLA_PARAMETER_ERROR;
 
+       /* ref: INIT */
        sp = qla2x00_get_sp(base_vha, NULL, GFP_KERNEL);
        if (!sp)
                return rval;
                break;
        }
 done:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
        return rval;
 }
 
        struct register_host_info *preg_hsi;
        struct new_utsname *p_sysid = NULL;
 
+       /* ref: INIT */
        sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
        if (!sp)
                goto done;
                dma_free_coherent(&ha->pdev->dev, fdisc->u.fxiocb.req_len,
                    fdisc->u.fxiocb.req_addr, fdisc->u.fxiocb.req_dma_handle);
 done_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 done:
        return rval;
 }
 
        struct scsi_cmnd *cmd = GET_CMD_SP(sp);
        struct completion *comp = sp->comp;
 
-       sp->free(sp);
+       /* kref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
        cmd->result = res;
        CMD_SP(cmd) = NULL;
        scsi_done(cmd);
        struct scsi_cmnd *cmd = GET_CMD_SP(sp);
        struct completion *comp = sp->comp;
 
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
        cmd->result = res;
        CMD_SP(cmd) = NULL;
        scsi_done(cmd);
                goto qc24_target_busy;
 
        sp = scsi_cmd_priv(cmd);
+       /* ref: INIT */
        qla2xxx_init_sp(sp, vha, vha->hw->base_qpair, fcport);
 
        sp->u.scmd.cmd = cmd;
        return 0;
 
 qc24_host_busy_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 
 qc24_target_busy:
        return SCSI_MLQUEUE_TARGET_BUSY;
                goto qc24_target_busy;
 
        sp = scsi_cmd_priv(cmd);
+       /* ref: INIT */
        qla2xxx_init_sp(sp, vha, qpair, fcport);
 
        sp->u.scmd.cmd = cmd;
        return 0;
 
 qc24_host_busy_free_sp:
-       sp->free(sp);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 
 qc24_target_busy:
        return SCSI_MLQUEUE_TARGET_BUSY;
 
        }
        spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 
-       sp->free(sp);
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
 
 int qla24xx_async_notify_ack(scsi_qla_host_t *vha, fc_port_t *fcport,
        return rval;
 
 done_free_sp:
-       sp->free(sp);
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
 done:
        fcport->flags &= ~FCF_ASYNC_SENT;
        return rval;