cmd->state = QLA_TGT_STATE_PROCESSED; /* Mid-level is done processing */
+       spin_lock(&cmd->cmd_lock);
        cmd->cmd_sent_to_fw = 1;
+       spin_unlock(&cmd->cmd_lock);
        cmd->ctio_flags = le16_to_cpu(pkt->u.status0.flags);
 
        /* Memory Barrier */
                qlt_load_data_segments(&prm);
 
        cmd->state = QLA_TGT_STATE_NEED_DATA;
+       spin_lock(&cmd->cmd_lock);
        cmd->cmd_sent_to_fw = 1;
+       spin_unlock(&cmd->cmd_lock);
        cmd->ctio_flags = le16_to_cpu(pkt->u.status0.flags);
 
        /* Memory Barrier */
 
 static void tcm_qla2xxx_complete_free(struct work_struct *work)
 {
        struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
+       bool released = false;
+       unsigned long flags;
 
        cmd->cmd_in_wq = 0;
 
        WARN_ON(cmd->trc_flags & TRC_CMD_FREE);
 
+       spin_lock_irqsave(&cmd->cmd_lock, flags);
        cmd->qpair->tgt_counters.qla_core_ret_sta_ctio++;
        cmd->trc_flags |= TRC_CMD_FREE;
-       transport_generic_free_cmd(&cmd->se_cmd, 0);
+       cmd->cmd_sent_to_fw = 0;
+       if (cmd->released)
+               released = true;
+       spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+
+       if (released)
+               qlt_free_cmd(cmd);
+       else
+               transport_generic_free_cmd(&cmd->se_cmd, 0);
 }
 
 /*
 static void tcm_qla2xxx_release_cmd(struct se_cmd *se_cmd)
 {
        struct qla_tgt_cmd *cmd;
+       unsigned long flags;
 
        if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) {
                struct qla_tgt_mgmt_cmd *mcmd = container_of(se_cmd,
                qlt_free_mcmd(mcmd);
                return;
        }
-
        cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
-       qlt_free_cmd(cmd);
+
+       spin_lock_irqsave(&cmd->cmd_lock, flags);
+       if (cmd->cmd_sent_to_fw) {
+               cmd->released = 1;
+               spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+       } else {
+               spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+               qlt_free_cmd(cmd);
+       }
 }
 
 static void tcm_qla2xxx_release_session(struct kref *kref)
 static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
 {
        struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
+       unsigned long flags;
 
        /*
         * Ensure that the complete FCP WRITE payload has been received.
         */
        cmd->cmd_in_wq = 0;
 
+       spin_lock_irqsave(&cmd->cmd_lock, flags);
+       cmd->cmd_sent_to_fw = 0;
+
+       if (cmd->released) {
+               spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+               qlt_free_cmd(cmd);
+               return;
+       }
+
+       cmd->data_work = 1;
+       if (cmd->aborted) {
+               cmd->data_work_free = 1;
+               spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+
+               tcm_qla2xxx_free_cmd(cmd);
+               return;
+       }
+       spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+
        cmd->qpair->tgt_counters.qla_core_ret_ctio++;
        if (!cmd->write_data_transferred) {
                /*