]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/scsi/qla2xxx/tcm_qla2xxx.c
Revert "qla2xxx: Fix incorrect tcm_qla2xxx_free_cmd use during TMR ABORT"
[mirror_ubuntu-artful-kernel.git] / drivers / scsi / qla2xxx / tcm_qla2xxx.c
index 8c1bf9b14bb2f2d66e4e3eceb1bc5dd0fbe1dbeb..75aeb9fdfd06e9a3422c898ae5815ae2b539061e 100644 (file)
@@ -415,7 +415,6 @@ static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd)
 
 static int tcm_qla2xxx_write_pending_status(struct se_cmd *se_cmd)
 {
-       struct qla_tgt_cmd *cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
        unsigned long flags;
        /*
         * Check for WRITE_PENDING status to determine if we need to wait for
@@ -425,7 +424,8 @@ static int tcm_qla2xxx_write_pending_status(struct se_cmd *se_cmd)
        if (se_cmd->t_state == TRANSPORT_WRITE_PENDING ||
            se_cmd->t_state == TRANSPORT_COMPLETE_QF_WP) {
                spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
-               wait_for_completion(&cmd->write_pending_abort_comp);
+               wait_for_completion_timeout(&se_cmd->t_transport_stop_comp,
+                                               50);
                return 0;
        }
        spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
@@ -501,6 +501,7 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
 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.
@@ -508,6 +509,17 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
         */
        cmd->cmd_in_wq = 0;
 
+       spin_lock_irqsave(&cmd->cmd_lock, flags);
+       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->vha->tgt_counters.qla_core_ret_ctio++;
        if (!cmd->write_data_transferred) {
                /*
@@ -515,7 +527,7 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
                 * waiting upon completion in tcm_qla2xxx_write_pending_status()
                 */
                if (cmd->se_cmd.transport_state & CMD_T_ABORTED) {
-                       complete(&cmd->write_pending_abort_comp);
+                       complete(&cmd->se_cmd.t_transport_stop_comp);
                        return;
                }
 
@@ -741,13 +753,31 @@ static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
        qlt_xmit_tm_rsp(mcmd);
 }
 
+#define DATA_WORK_NOT_FREE(_cmd) (_cmd->data_work && !_cmd->data_work_free)
 static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
 {
        struct qla_tgt_cmd *cmd = container_of(se_cmd,
                                struct qla_tgt_cmd, se_cmd);
+       unsigned long flags;
 
        if (qlt_abort_cmd(cmd))
                return;
+
+       spin_lock_irqsave(&cmd->cmd_lock, flags);
+       if ((cmd->state == QLA_TGT_STATE_NEW)||
+           ((cmd->state == QLA_TGT_STATE_DATA_IN) &&
+               DATA_WORK_NOT_FREE(cmd))) {
+               cmd->data_work_free = 1;
+               spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+               /*
+                * cmd has not reached fw, Use this trigger to free it.
+                */
+               tcm_qla2xxx_free_cmd(cmd);
+               return;
+       }
+       spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+       return;
+
 }
 
 static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,