rc = __qlt_send_term_exchange(vha, cmd, atio);
        spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
 done:
-       if (rc == 1) {
+       /*
+        * Terminate exchange will tell fw to release any active CTIO
+        * that's in FW posession and cleanup the exchange.
+        *
+        * "cmd->state == QLA_TGT_STATE_ABORTED" means CTIO is still
+        * down at FW.  Free the cmd later when CTIO comes back later
+        * w/aborted(0x2) status.
+        *
+        * "cmd->state != QLA_TGT_STATE_ABORTED" means CTIO is already
+        * back w/some err.  Free the cmd now.
+        */
+       if ((rc == 1) && (cmd->state != QLA_TGT_STATE_ABORTED)) {
                if (!ha_locked && !in_interrupt())
                        msleep(250); /* just in case */
 
                        qlt_unmap_sg(vha, cmd);
                vha->hw->tgt.tgt_ops->free_cmd(cmd);
        }
+       return;
 }
 
 void qlt_free_cmd(struct qla_tgt_cmd *cmd)
                case CTIO_LIP_RESET:
                case CTIO_TARGET_RESET:
                case CTIO_ABORTED:
+                       /* driver request abort via Terminate exchange */
                case CTIO_TIMEOUT:
                case CTIO_INVALID_RX_ID:
                        /* They are OK */
                        break;
                }
 
-               if (cmd->state != QLA_TGT_STATE_NEED_DATA)
+
+               /* "cmd->state == QLA_TGT_STATE_ABORTED" means
+                * cmd is already aborted/terminated, we don't
+                * need to terminate again.  The exchange is already
+                * cleaned up/freed at FW level.  Just cleanup at driver
+                * level.
+                */
+               if ((cmd->state != QLA_TGT_STATE_NEED_DATA) &&
+                       (cmd->state != QLA_TGT_STATE_ABORTED)) {
                        if (qlt_term_ctio_exchange(vha, ctio, cmd, status))
                                return;
+               }
        }
 skip_term:
 
                    "not return a CTIO complete\n", vha->vp_idx, cmd->state);
        }
 
-       if (unlikely(status != CTIO_SUCCESS)) {
+       if (unlikely(status != CTIO_SUCCESS) &&
+               (cmd->state != QLA_TGT_STATE_ABORTED)) {
                ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01f, "Finishing failed CTIO\n");
                dump_stack();
        }