if (!sp)
                return sp;
 
+       atomic_set(&sp->ref_count, 1);
        sp->fcport = fcport;
        sp->cmd = cmd;
        sp->flags = 0;
        return (return_status);
 }
 
+static void
+sp_get(struct srb *sp)
+{
+       atomic_inc(&sp->ref_count);
+}
+
 /**************************************************************************
 * qla2xxx_eh_abort
 *
        struct qla_hw_data *ha = vha->hw;
        struct req_que *req = vha->req;
        srb_t *spt;
+       int got_ref = 0;
 
        fc_block_scsi_eh(cmd);
 
                DEBUG2(printk("%s(%ld): aborting sp %p from RISC."
                " pid=%ld.\n", __func__, vha->host_no, sp, serial));
 
+               /* Get a reference to the sp and drop the lock.*/
+               sp_get(sp);
+               got_ref++;
+
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
                if (ha->isp_ops->abort_command(sp)) {
                        DEBUG2(printk("%s(%ld): abort_command "
                }
        }
 
+       if (got_ref)
+               qla2x00_sp_compl(ha, sp);
+
        qla_printk(KERN_INFO, ha,
            "scsi(%ld:%d:%d): Abort command issued -- %d %lx %x.\n",
            vha->host_no, id, lun, wait, serial, ret);
 }
 
 void
-qla2x00_sp_compl(struct qla_hw_data *ha, srb_t *sp)
+qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp)
 {
        struct scsi_cmnd *cmd = sp->cmd;
 
        cmd->scsi_done(cmd);
 }
 
+void
+qla2x00_sp_compl(struct qla_hw_data *ha, srb_t *sp)
+{
+       if (atomic_read(&sp->ref_count) == 0) {
+               DEBUG2(qla_printk(KERN_WARNING, ha,
+                   "SP reference-count to ZERO -- sp=%p\n", sp));
+               DEBUG2(BUG());
+               return;
+       }
+       if (!atomic_dec_and_test(&sp->ref_count))
+               return;
+       qla2x00_sp_final_compl(ha, sp);
+}
+
 /**************************************************************************
 *   qla2x00_timer
 *