struct scsi_cmnd *cmd = GET_CMD_SP(sp);
        struct completion *comp = sp->comp;
 
-       if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0))
-               return;
-
-       atomic_dec(&sp->ref_count);
-
        sp->free(sp);
        cmd->result = res;
        CMD_SP(cmd) = NULL;
        struct scsi_cmnd *cmd = GET_CMD_SP(sp);
        struct completion *comp = sp->comp;
 
-       if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0))
-               return;
-
-       atomic_dec(&sp->ref_count);
-
        sp->free(sp);
        cmd->result = res;
        CMD_SP(cmd) = NULL;
 
        sp->u.scmd.cmd = cmd;
        sp->type = SRB_SCSI_CMD;
-       atomic_set(&sp->ref_count, 1);
+
        CMD_SP(cmd) = (void *)sp;
        sp->free = qla2x00_sp_free_dma;
        sp->done = qla2x00_sp_compl;
 
        sp->u.scmd.cmd = cmd;
        sp->type = SRB_SCSI_CMD;
-       atomic_set(&sp->ref_count, 1);
        CMD_SP(cmd) = (void *)sp;
        sp->free = qla2xxx_qpair_sp_free_dma;
        sp->done = qla2xxx_qpair_sp_compl;
-       sp->qpair = qpair;
 
        rval = ha->isp_ops->start_scsi_mq(sp);
        if (rval != QLA_SUCCESS) {
        return return_status;
 }
 
-static int
-sp_get(struct srb *sp)
-{
-       if (!refcount_inc_not_zero((refcount_t *)&sp->ref_count))
-               /* kref get fail */
-               return ENXIO;
-       else
-               return 0;
-}
-
 #define ISP_REG_DISCONNECT 0xffffffffU
 /**************************************************************************
 * qla2x00_isp_reg_stat
        uint64_t lun;
        int rval;
        struct qla_hw_data *ha = vha->hw;
+       uint32_t ratov_j;
+       struct qla_qpair *qpair;
+       unsigned long flags;
 
        if (qla2x00_isp_reg_stat(ha)) {
                ql_log(ql_log_info, vha, 0x8042,
                return ret;
 
        sp = scsi_cmd_priv(cmd);
+       qpair = sp->qpair;
 
-       if (sp->fcport && sp->fcport->deleted)
+       if ((sp->fcport && sp->fcport->deleted) || !qpair)
                return SUCCESS;
 
-       /* Return if the command has already finished. */
-       if (sp_get(sp))
+       spin_lock_irqsave(qpair->qp_lock_ptr, flags);
+       if (sp->completed) {
+               spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
                return SUCCESS;
+       }
+
+       if (sp->abort || sp->aborted) {
+               spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
+               return FAILED;
+       }
+
+       sp->abort = 1;
+       sp->comp = ∁
+       spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
+
 
        id = cmd->device->id;
        lun = cmd->device->lun;
            "Aborting from RISC nexus=%ld:%d:%llu sp=%p cmd=%p handle=%x\n",
            vha->host_no, id, lun, sp, cmd, sp->handle);
 
+       /*
+        * Abort will release the original Command/sp from FW. Let the
+        * original command call scsi_done. In return, he will wakeup
+        * this sleeping thread.
+        */
        rval = ha->isp_ops->abort_command(sp);
+
        ql_dbg(ql_dbg_taskm, vha, 0x8003,
               "Abort command mbx cmd=%p, rval=%x.\n", cmd, rval);
 
+       /* Wait for the command completion. */
+       ratov_j = ha->r_a_tov/10 * 4 * 1000;
+       ratov_j = msecs_to_jiffies(ratov_j);
        switch (rval) {
        case QLA_SUCCESS:
-               /*
-                * The command has been aborted. That means that the firmware
-                * won't report a completion.
-                */
-               sp->done(sp, DID_ABORT << 16);
-               ret = SUCCESS;
-               break;
-       case QLA_FUNCTION_PARAMETER_ERROR: {
-               /* Wait for the command completion. */
-               uint32_t ratov = ha->r_a_tov/10;
-               uint32_t ratov_j = msecs_to_jiffies(4 * ratov * 1000);
-
-               WARN_ON_ONCE(sp->comp);
-               sp->comp = ∁
                if (!wait_for_completion_timeout(&comp, ratov_j)) {
                        ql_dbg(ql_dbg_taskm, vha, 0xffff,
                            "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n",
-                           __func__, ha->r_a_tov);
+                           __func__, ha->r_a_tov/10);
                        ret = FAILED;
                } else {
                        ret = SUCCESS;
                }
                break;
-       }
        default:
-               /*
-                * Either abort failed or abort and completion raced. Let
-                * the SCSI core retry the abort in the former case.
-                */
                ret = FAILED;
                break;
        }
 
        sp->comp = NULL;
-       atomic_dec(&sp->ref_count);
+
        ql_log(ql_log_info, vha, 0x801c,
            "Abort command issued nexus=%ld:%d:%llu -- %x.\n",
            vha->host_no, id, lun, ret);
        scsi_qla_host_t *vha = qp->vha;
        struct qla_hw_data *ha = vha->hw;
        int rval;
+       bool ret_cmd;
+       uint32_t ratov_j;
 
-       if (sp_get(sp))
+       if (qla2x00_chip_is_down(vha)) {
+               sp->done(sp, res);
                return;
+       }
 
        if (sp->type == SRB_NVME_CMD || sp->type == SRB_NVME_LS ||
            (sp->type == SRB_SCSI_CMD && !ha->flags.eeh_busy &&
             !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
             !qla2x00_isp_reg_stat(ha))) {
+               if (sp->comp) {
+                       sp->done(sp, res);
+                       return;
+               }
+
                sp->comp = ∁
+               sp->abort =  1;
                spin_unlock_irqrestore(qp->qp_lock_ptr, *flags);
-               rval = ha->isp_ops->abort_command(sp);
 
+               rval = ha->isp_ops->abort_command(sp);
+               /* Wait for command completion. */
+               ret_cmd = false;
+               ratov_j = ha->r_a_tov/10 * 4 * 1000;
+               ratov_j = msecs_to_jiffies(ratov_j);
                switch (rval) {
                case QLA_SUCCESS:
-                       sp->done(sp, res);
+                       if (wait_for_completion_timeout(&comp, ratov_j)) {
+                               ql_dbg(ql_dbg_taskm, vha, 0xffff,
+                                   "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n",
+                                   __func__, ha->r_a_tov/10);
+                               ret_cmd = true;
+                       }
+                       /* else FW return SP to driver */
                        break;
-               case QLA_FUNCTION_PARAMETER_ERROR:
-                       wait_for_completion(&comp);
+               default:
+                       ret_cmd = true;
                        break;
                }
 
                spin_lock_irqsave(qp->qp_lock_ptr, *flags);
-               sp->comp = NULL;
+               if (ret_cmd && (!sp->completed || !sp->aborted))
+                       sp->done(sp, res);
+       } else {
+               sp->done(sp, res);
        }
-
-       atomic_dec(&sp->ref_count);
 }
 
 static void
        for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
                sp = req->outstanding_cmds[cnt];
                if (sp) {
-                       req->outstanding_cmds[cnt] = NULL;
                        switch (sp->cmd_type) {
                        case TYPE_SRB:
                                qla2x00_abort_srb(qp, sp, res, &flags);
                        default:
                                break;
                        }
+                       req->outstanding_cmds[cnt] = NULL;
                }
        }
        spin_unlock_irqrestore(qp->qp_lock_ptr, flags);