target: Remove unnecessary se_task members
[pandora-kernel.git] / drivers / target / target_core_transport.c
index a4b0a8d..4a787a0 100644 (file)
@@ -26,7 +26,6 @@
  *
  ******************************************************************************/
 
-#include <linux/version.h>
 #include <linux/net.h>
 #include <linux/delay.h>
 #include <linux/string.h>
@@ -70,9 +69,6 @@ struct kmem_cache *t10_alua_lu_gp_mem_cache;
 struct kmem_cache *t10_alua_tg_pt_gp_cache;
 struct kmem_cache *t10_alua_tg_pt_gp_mem_cache;
 
-/* Used for transport_dev_get_map_*() */
-typedef int (*map_func_t)(struct se_task *, u32);
-
 static int transport_generic_write_pending(struct se_cmd *);
 static int transport_processing_thread(void *param);
 static int __transport_execute_tasks(struct se_device *dev);
@@ -87,9 +83,7 @@ static u32 transport_allocate_tasks(struct se_cmd *cmd,
                enum dma_data_direction data_direction,
                struct scatterlist *sgl, unsigned int nents);
 static int transport_generic_get_mem(struct se_cmd *cmd);
-static int transport_generic_remove(struct se_cmd *cmd,
-               int session_reinstatement);
-static void transport_release_fe_cmd(struct se_cmd *cmd);
+static void transport_put_cmd(struct se_cmd *cmd);
 static void transport_remove_cmd_from_queue(struct se_cmd *cmd,
                struct se_queue_obj *qobj);
 static int transport_set_sense_codes(struct se_cmd *cmd, u8 asc, u8 ascq);
@@ -438,16 +432,15 @@ EXPORT_SYMBOL(transport_deregister_session);
  */
 static void transport_all_task_dev_remove_state(struct se_cmd *cmd)
 {
-       struct se_device *dev;
+       struct se_device *dev = cmd->se_dev;
        struct se_task *task;
        unsigned long flags;
 
-       list_for_each_entry(task, &cmd->t_task_list, t_list) {
-               dev = task->se_dev;
-               if (!dev)
-                       continue;
+       if (!dev)
+               return;
 
-               if (atomic_read(&task->task_active))
+       list_for_each_entry(task, &cmd->t_task_list, t_list) {
+               if (task->task_flags & TF_ACTIVE)
                        continue;
 
                if (!atomic_read(&task->task_state_active))
@@ -594,23 +587,15 @@ check_lun:
 
 void transport_cmd_finish_abort(struct se_cmd *cmd, int remove)
 {
-       transport_remove_cmd_from_queue(cmd, &cmd->se_dev->dev_queue_obj);
-       transport_lun_remove_cmd(cmd);
-
-       if (transport_cmd_check_stop_to_fabric(cmd))
-               return;
-       if (remove)
-               transport_generic_remove(cmd, 0);
-}
-
-void transport_cmd_finish_abort_tmr(struct se_cmd *cmd)
-{
-       transport_remove_cmd_from_queue(cmd, &cmd->se_dev->dev_queue_obj);
+       if (!cmd->se_tmr_req)
+               transport_lun_remove_cmd(cmd);
 
        if (transport_cmd_check_stop_to_fabric(cmd))
                return;
-
-       transport_generic_remove(cmd, 0);
+       if (remove) {
+               transport_remove_cmd_from_queue(cmd, &cmd->se_dev->dev_queue_obj);
+               transport_put_cmd(cmd);
+       }
 }
 
 static void transport_add_cmd_to_queue(
@@ -621,8 +606,6 @@ static void transport_add_cmd_to_queue(
        struct se_queue_obj *qobj = &dev->dev_queue_obj;
        unsigned long flags;
 
-       INIT_LIST_HEAD(&cmd->se_queue_node);
-
        if (t_state) {
                spin_lock_irqsave(&cmd->t_state_lock, flags);
                cmd->t_state = t_state;
@@ -631,15 +614,21 @@ static void transport_add_cmd_to_queue(
        }
 
        spin_lock_irqsave(&qobj->cmd_queue_lock, flags);
+
+       /* If the cmd is already on the list, remove it before we add it */
+       if (!list_empty(&cmd->se_queue_node))
+               list_del(&cmd->se_queue_node);
+       else
+               atomic_inc(&qobj->queue_cnt);
+
        if (cmd->se_cmd_flags & SCF_EMULATE_QUEUE_FULL) {
                cmd->se_cmd_flags &= ~SCF_EMULATE_QUEUE_FULL;
                list_add(&cmd->se_queue_node, &qobj->qobj_list);
        } else
                list_add_tail(&cmd->se_queue_node, &qobj->qobj_list);
-       atomic_inc(&cmd->t_transport_queue_active);
+       atomic_set(&cmd->t_transport_queue_active, 1);
        spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags);
 
-       atomic_inc(&qobj->queue_cnt);
        wake_up_interruptible(&qobj->thread_wq);
 }
 
@@ -656,9 +645,9 @@ transport_get_cmd_from_queue(struct se_queue_obj *qobj)
        }
        cmd = list_first_entry(&qobj->qobj_list, struct se_cmd, se_queue_node);
 
-       atomic_dec(&cmd->t_transport_queue_active);
+       atomic_set(&cmd->t_transport_queue_active, 0);
 
-       list_del(&cmd->se_queue_node);
+       list_del_init(&cmd->se_queue_node);
        atomic_dec(&qobj->queue_cnt);
        spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags);
 
@@ -668,7 +657,6 @@ transport_get_cmd_from_queue(struct se_queue_obj *qobj)
 static void transport_remove_cmd_from_queue(struct se_cmd *cmd,
                struct se_queue_obj *qobj)
 {
-       struct se_cmd *t;
        unsigned long flags;
 
        spin_lock_irqsave(&qobj->cmd_queue_lock, flags);
@@ -676,14 +664,9 @@ static void transport_remove_cmd_from_queue(struct se_cmd *cmd,
                spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags);
                return;
        }
-
-       list_for_each_entry(t, &qobj->qobj_list, se_queue_node)
-               if (t == cmd) {
-                       atomic_dec(&cmd->t_transport_queue_active);
-                       atomic_dec(&qobj->queue_cnt);
-                       list_del(&cmd->se_queue_node);
-                       break;
-               }
+       atomic_set(&cmd->t_transport_queue_active, 0);
+       atomic_dec(&qobj->queue_cnt);
+       list_del_init(&cmd->se_queue_node);
        spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags);
 
        if (atomic_read(&cmd->t_transport_queue_active)) {
@@ -724,7 +707,7 @@ EXPORT_SYMBOL(transport_complete_sync_cache);
 void transport_complete_task(struct se_task *task, int success)
 {
        struct se_cmd *cmd = task->task_se_cmd;
-       struct se_device *dev = task->se_dev;
+       struct se_device *dev = cmd->se_dev;
        int t_state;
        unsigned long flags;
 #if 0
@@ -735,7 +718,7 @@ void transport_complete_task(struct se_task *task, int success)
                atomic_inc(&dev->depth_left);
 
        spin_lock_irqsave(&cmd->t_state_lock, flags);
-       atomic_set(&task->task_active, 0);
+       task->task_flags &= ~TF_ACTIVE;
 
        /*
         * See if any sense data exists, if so set the TASK_SENSE flag.
@@ -754,14 +737,14 @@ void transport_complete_task(struct se_task *task, int success)
         * See if we are waiting for outstanding struct se_task
         * to complete for an exception condition
         */
-       if (atomic_read(&task->task_stop)) {
+       if (task->task_flags & TF_REQUEST_STOP) {
                /*
                 * Decrement cmd->t_se_count if this task had
                 * previously thrown its timeout exception handler.
                 */
-               if (atomic_read(&task->task_timeout)) {
+               if (task->task_flags & TF_TIMEOUT) {
                        atomic_dec(&cmd->t_se_count);
-                       atomic_set(&task->task_timeout, 0);
+                       task->task_flags &= ~TF_TIMEOUT;
                }
                spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
@@ -773,7 +756,7 @@ void transport_complete_task(struct se_task *task, int success)
         * left counter to determine when the struct se_cmd is ready to be queued to
         * the processing thread.
         */
-       if (atomic_read(&task->task_timeout)) {
+       if (task->task_flags & TF_TIMEOUT) {
                if (!atomic_dec_and_test(
                                &cmd->t_task_cdbs_timeout_left)) {
                        spin_unlock_irqrestore(&cmd->t_state_lock,
@@ -902,14 +885,12 @@ static void __transport_add_task_to_execute_queue(
 
 static void transport_add_tasks_to_state_queue(struct se_cmd *cmd)
 {
-       struct se_device *dev;
+       struct se_device *dev = cmd->se_dev;
        struct se_task *task;
        unsigned long flags;
 
        spin_lock_irqsave(&cmd->t_state_lock, flags);
        list_for_each_entry(task, &cmd->t_task_list, t_list) {
-               dev = task->se_dev;
-
                if (atomic_read(&task->task_state_active))
                        continue;
 
@@ -934,38 +915,36 @@ static void transport_add_tasks_from_cmd(struct se_cmd *cmd)
 
        spin_lock_irqsave(&dev->execute_task_lock, flags);
        list_for_each_entry(task, &cmd->t_task_list, t_list) {
-               if (atomic_read(&task->task_execute_queue))
+               if (!list_empty(&task->t_execute_list))
                        continue;
                /*
                 * __transport_add_task_to_execute_queue() handles the
                 * SAM Task Attribute emulation if enabled
                 */
                __transport_add_task_to_execute_queue(task, task_prev, dev);
-               atomic_set(&task->task_execute_queue, 1);
                task_prev = task;
        }
        spin_unlock_irqrestore(&dev->execute_task_lock, flags);
 }
 
-/*     transport_remove_task_from_execute_queue():
- *
- *
- */
+void __transport_remove_task_from_execute_queue(struct se_task *task,
+               struct se_device *dev)
+{
+       list_del_init(&task->t_execute_list);
+       atomic_dec(&dev->execute_tasks);
+}
+
 void transport_remove_task_from_execute_queue(
        struct se_task *task,
        struct se_device *dev)
 {
        unsigned long flags;
 
-       if (atomic_read(&task->task_execute_queue) == 0) {
-               dump_stack();
+       if (WARN_ON(list_empty(&task->t_execute_list)))
                return;
-       }
 
        spin_lock_irqsave(&dev->execute_task_lock, flags);
-       list_del(&task->t_execute_list);
-       atomic_set(&task->task_execute_queue, 0);
-       atomic_dec(&dev->execute_tasks);
+       __transport_remove_task_from_execute_queue(task, dev);
        spin_unlock_irqrestore(&dev->execute_task_lock, flags);
 }
 
@@ -1053,41 +1032,6 @@ void transport_dump_dev_state(
        *bl += sprintf(b + *bl, "        ");
 }
 
-/*     transport_release_all_cmds():
- *
- *
- */
-static void transport_release_all_cmds(struct se_device *dev)
-{
-       struct se_cmd *cmd, *tcmd;
-       int bug_out = 0, t_state;
-       unsigned long flags;
-
-       spin_lock_irqsave(&dev->dev_queue_obj.cmd_queue_lock, flags);
-       list_for_each_entry_safe(cmd, tcmd, &dev->dev_queue_obj.qobj_list,
-                               se_queue_node) {
-               t_state = cmd->t_state;
-               list_del(&cmd->se_queue_node);
-               spin_unlock_irqrestore(&dev->dev_queue_obj.cmd_queue_lock,
-                               flags);
-
-               pr_err("Releasing ITT: 0x%08x, i_state: %u,"
-                       " t_state: %u directly\n",
-                       cmd->se_tfo->get_task_tag(cmd),
-                       cmd->se_tfo->get_cmd_state(cmd), t_state);
-
-               transport_release_fe_cmd(cmd);
-               bug_out = 1;
-
-               spin_lock_irqsave(&dev->dev_queue_obj.cmd_queue_lock, flags);
-       }
-       spin_unlock_irqrestore(&dev->dev_queue_obj.cmd_queue_lock, flags);
-#if 0
-       if (bug_out)
-               BUG();
-#endif
-}
-
 void transport_dump_vpd_proto_id(
        struct t10_vpd *vpd,
        unsigned char *p_buf,
@@ -1573,7 +1517,6 @@ transport_generic_get_task(struct se_cmd *cmd,
        INIT_LIST_HEAD(&task->t_state_list);
        init_completion(&task->task_stop_comp);
        task->task_se_cmd = cmd;
-       task->se_dev = dev;
        task->task_data_direction = data_direction;
 
        return task;
@@ -1598,6 +1541,7 @@ void transport_init_se_cmd(
        INIT_LIST_HEAD(&cmd->se_delayed_node);
        INIT_LIST_HEAD(&cmd->se_ordered_node);
        INIT_LIST_HEAD(&cmd->se_qf_node);
+       INIT_LIST_HEAD(&cmd->se_queue_node);
 
        INIT_LIST_HEAD(&cmd->t_task_list);
        init_completion(&cmd->transport_lun_fe_stop_comp);
@@ -1641,21 +1585,6 @@ static int transport_check_alloc_task_attr(struct se_cmd *cmd)
        return 0;
 }
 
-void transport_free_se_cmd(
-       struct se_cmd *se_cmd)
-{
-       if (se_cmd->se_tmr_req)
-               core_tmr_release_req(se_cmd->se_tmr_req);
-       /*
-        * Check and free any extended CDB buffer that was allocated
-        */
-       if (se_cmd->t_task_cdb != se_cmd->__t_task_cdb)
-               kfree(se_cmd->t_task_cdb);
-}
-EXPORT_SYMBOL(transport_free_se_cmd);
-
-static void transport_generic_wait_for_tasks(struct se_cmd *, int, int);
-
 /*     transport_generic_allocate_tasks():
  *
  *     Called from fabric RX Thread.
@@ -1667,12 +1596,6 @@ int transport_generic_allocate_tasks(
        int ret;
 
        transport_generic_prepare_cdb(cdb);
-
-       /*
-        * This is needed for early exceptions.
-        */
-       cmd->transport_wait_for_tasks = &transport_generic_wait_for_tasks;
-
        /*
         * Ensure that the received CDB is less than the max (252 + 8) bytes
         * for VARIABLE_LENGTH_CMD
@@ -1729,24 +1652,6 @@ int transport_generic_allocate_tasks(
 }
 EXPORT_SYMBOL(transport_generic_allocate_tasks);
 
-/*
- * Used by fabric module frontends not defining a TFO->new_cmd_map()
- * to queue up a newly setup se_cmd w/ TRANSPORT_NEW_CMD statis
- */
-int transport_generic_handle_cdb(
-       struct se_cmd *cmd)
-{
-       if (!cmd->se_lun) {
-               dump_stack();
-               pr_err("cmd->se_lun is NULL\n");
-               return -EINVAL;
-       }
-
-       transport_add_cmd_to_queue(cmd, TRANSPORT_NEW_CMD);
-       return 0;
-}
-EXPORT_SYMBOL(transport_generic_handle_cdb);
-
 static void transport_generic_request_failure(struct se_cmd *,
                        struct se_device *, int, int);
 /*
@@ -1773,7 +1678,7 @@ int transport_handle_cdb_direct(
         * Set TRANSPORT_NEW_CMD state and cmd->t_transport_active=1 following
         * transport_generic_handle_cdb*() -> transport_add_cmd_to_queue()
         * in existing usage to ensure that outstanding descriptors are handled
-        * correctly during shutdown via transport_generic_wait_for_tasks()
+        * correctly during shutdown via transport_wait_for_tasks()
         *
         * Also, we don't take cmd->t_state_lock here as we only expect
         * this to be called for initial descriptor submission.
@@ -1853,11 +1758,6 @@ EXPORT_SYMBOL(transport_generic_handle_data);
 int transport_generic_handle_tmr(
        struct se_cmd *cmd)
 {
-       /*
-        * This is needed for early exceptions.
-        */
-       cmd->transport_wait_for_tasks = &transport_generic_wait_for_tasks;
-
        transport_add_cmd_to_queue(cmd, TRANSPORT_PROCESS_TMR);
        return 0;
 }
@@ -1885,21 +1785,18 @@ static int transport_stop_tasks_for_cmd(struct se_cmd *cmd)
        spin_lock_irqsave(&cmd->t_state_lock, flags);
        list_for_each_entry_safe(task, task_tmp,
                                &cmd->t_task_list, t_list) {
-               pr_debug("task_no[%d] - Processing task %p\n",
-                               task->task_no, task);
+               pr_debug("Processing task %p\n", task);
                /*
                 * If the struct se_task has not been sent and is not active,
                 * remove the struct se_task from the execution queue.
                 */
-               if (!atomic_read(&task->task_sent) &&
-                   !atomic_read(&task->task_active)) {
+               if (!(task->task_flags & (TF_ACTIVE | TF_SENT))) {
                        spin_unlock_irqrestore(&cmd->t_state_lock,
                                        flags);
                        transport_remove_task_from_execute_queue(task,
-                                       task->se_dev);
+                                       cmd->se_dev);
 
-                       pr_debug("task_no[%d] - Removed from execute queue\n",
-                               task->task_no);
+                       pr_debug("Task %p removed from execute queue\n", task);
                        spin_lock_irqsave(&cmd->t_state_lock, flags);
                        continue;
                }
@@ -1908,24 +1805,20 @@ static int transport_stop_tasks_for_cmd(struct se_cmd *cmd)
                 * If the struct se_task is active, sleep until it is returned
                 * from the plugin.
                 */
-               if (atomic_read(&task->task_active)) {
-                       atomic_set(&task->task_stop, 1);
+               if (task->task_flags & TF_ACTIVE) {
+                       task->task_flags |= TF_REQUEST_STOP;
                        spin_unlock_irqrestore(&cmd->t_state_lock,
                                        flags);
 
-                       pr_debug("task_no[%d] - Waiting to complete\n",
-                               task->task_no);
+                       pr_debug("Task %p waiting to complete\n", task);
                        wait_for_completion(&task->task_stop_comp);
-                       pr_debug("task_no[%d] - Stopped successfully\n",
-                               task->task_no);
+                       pr_debug("Task %p stopped successfully\n", task);
 
                        spin_lock_irqsave(&cmd->t_state_lock, flags);
                        atomic_dec(&cmd->t_task_cdbs_left);
-
-                       atomic_set(&task->task_active, 0);
-                       atomic_set(&task->task_stop, 0);
+                       task->task_flags &= ~(TF_ACTIVE | TF_REQUEST_STOP);
                } else {
-                       pr_debug("task_no[%d] - Did nothing\n", task->task_no);
+                       pr_debug("Task %p - did nothing\n", task);
                        ret++;
                }
 
@@ -2104,7 +1997,7 @@ static void transport_generic_request_timeout(struct se_cmd *cmd)
        unsigned long flags;
 
        /*
-        * Reset cmd->t_se_count to allow transport_generic_remove()
+        * Reset cmd->t_se_count to allow transport_put_cmd()
         * to allow last call to free memory resources.
         */
        spin_lock_irqsave(&cmd->t_state_lock, flags);
@@ -2115,7 +2008,7 @@ static void transport_generic_request_timeout(struct se_cmd *cmd)
        }
        spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
-       transport_generic_remove(cmd, 0);
+       transport_put_cmd(cmd);
 }
 
 static inline u32 transport_lba_21(unsigned char *cdb)
@@ -2172,18 +2065,18 @@ static void transport_task_timeout_handler(unsigned long data)
        pr_debug("transport task timeout fired! task: %p cmd: %p\n", task, cmd);
 
        spin_lock_irqsave(&cmd->t_state_lock, flags);
-       if (task->task_flags & TF_STOP) {
+       if (task->task_flags & TF_TIMER_STOP) {
                spin_unlock_irqrestore(&cmd->t_state_lock, flags);
                return;
        }
-       task->task_flags &= ~TF_RUNNING;
+       task->task_flags &= ~TF_TIMER_RUNNING;
 
        /*
         * Determine if transport_complete_task() has already been called.
         */
-       if (!atomic_read(&task->task_active)) {
-               pr_debug("transport task: %p cmd: %p timeout task_active"
-                               " == 0\n", task, cmd);
+       if (!(task->task_flags & TF_ACTIVE)) {
+               pr_debug("transport task: %p cmd: %p timeout !TF_ACTIVE\n",
+                        task, cmd);
                spin_unlock_irqrestore(&cmd->t_state_lock, flags);
                return;
        }
@@ -2192,12 +2085,12 @@ static void transport_task_timeout_handler(unsigned long data)
        atomic_inc(&cmd->t_transport_timeout);
        cmd->t_tasks_failed = 1;
 
-       atomic_set(&task->task_timeout, 1);
+       task->task_flags |= TF_TIMEOUT;
        task->task_error_status = PYX_TRANSPORT_TASK_TIMEOUT;
        task->task_scsi_status = 1;
 
-       if (atomic_read(&task->task_stop)) {
-               pr_debug("transport task: %p cmd: %p timeout task_stop"
+       if (task->task_flags & TF_REQUEST_STOP) {
+               pr_debug("transport task: %p cmd: %p timeout TF_REQUEST_STOP"
                                " == 1\n", task, cmd);
                spin_unlock_irqrestore(&cmd->t_state_lock, flags);
                complete(&task->task_stop_comp);
@@ -2224,10 +2117,10 @@ static void transport_task_timeout_handler(unsigned long data)
  */
 static void transport_start_task_timer(struct se_task *task)
 {
-       struct se_device *dev = task->se_dev;
+       struct se_device *dev = task->task_se_cmd->se_dev;
        int timeout;
 
-       if (task->task_flags & TF_RUNNING)
+       if (task->task_flags & TF_TIMER_RUNNING)
                return;
        /*
         * If the task_timeout is disabled, exit now.
@@ -2241,7 +2134,7 @@ static void transport_start_task_timer(struct se_task *task)
        task->task_timer.data = (unsigned long) task;
        task->task_timer.function = transport_task_timeout_handler;
 
-       task->task_flags |= TF_RUNNING;
+       task->task_flags |= TF_TIMER_RUNNING;
        add_timer(&task->task_timer);
 #if 0
        pr_debug("Starting task timer for cmd: %p task: %p seconds:"
@@ -2256,17 +2149,17 @@ void __transport_stop_task_timer(struct se_task *task, unsigned long *flags)
 {
        struct se_cmd *cmd = task->task_se_cmd;
 
-       if (!task->task_flags & TF_RUNNING)
+       if (!(task->task_flags & TF_TIMER_RUNNING))
                return;
 
-       task->task_flags |= TF_STOP;
+       task->task_flags |= TF_TIMER_STOP;
        spin_unlock_irqrestore(&cmd->t_state_lock, *flags);
 
        del_timer_sync(&task->task_timer);
 
        spin_lock_irqsave(&cmd->t_state_lock, *flags);
-       task->task_flags &= ~TF_RUNNING;
-       task->task_flags &= ~TF_STOP;
+       task->task_flags &= ~TF_TIMER_RUNNING;
+       task->task_flags &= ~TF_TIMER_STOP;
 }
 
 static void transport_stop_all_task_timers(struct se_cmd *cmd)
@@ -2448,9 +2341,7 @@ check_depth:
        }
        task = list_first_entry(&dev->execute_task_list,
                                struct se_task, t_execute_list);
-       list_del(&task->t_execute_list);
-       atomic_set(&task->task_execute_queue, 0);
-       atomic_dec(&dev->execute_tasks);
+       __transport_remove_task_from_execute_queue(task, dev);
        spin_unlock_irq(&dev->execute_task_lock);
 
        atomic_dec(&dev->depth_left);
@@ -2458,8 +2349,7 @@ check_depth:
        cmd = task->task_se_cmd;
 
        spin_lock_irqsave(&cmd->t_state_lock, flags);
-       atomic_set(&task->task_active, 1);
-       atomic_set(&task->task_sent, 1);
+       task->task_flags |= (TF_ACTIVE | TF_SENT);
        atomic_inc(&cmd->t_task_cdbs_sent);
 
        if (atomic_read(&cmd->t_task_cdbs_sent) ==
@@ -2477,7 +2367,9 @@ check_depth:
                error = cmd->transport_emulate_cdb(cmd);
                if (error != 0) {
                        cmd->transport_error_status = error;
-                       atomic_set(&task->task_active, 0);
+                       spin_lock_irqsave(&cmd->t_state_lock, flags);
+                       task->task_flags &= ~TF_ACTIVE;
+                       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
                        atomic_set(&cmd->transport_sent, 0);
                        transport_stop_tasks_for_cmd(cmd);
                        transport_generic_request_failure(cmd, dev, 0, 1);
@@ -2513,7 +2405,9 @@ check_depth:
 
                if (error != 0) {
                        cmd->transport_error_status = error;
-                       atomic_set(&task->task_active, 0);
+                       spin_lock_irqsave(&cmd->t_state_lock, flags);
+                       task->task_flags &= ~TF_ACTIVE;
+                       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
                        atomic_set(&cmd->transport_sent, 0);
                        transport_stop_tasks_for_cmd(cmd);
                        transport_generic_request_failure(cmd, dev, 0, 1);
@@ -2538,8 +2432,6 @@ void transport_new_cmd_failure(struct se_cmd *se_cmd)
        spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
 }
 
-static void transport_nop_wait_for_tasks(struct se_cmd *, int, int);
-
 static inline u32 transport_get_sectors_6(
        unsigned char *cdb,
        struct se_cmd *cmd,
@@ -2752,13 +2644,16 @@ out:
 static int transport_get_sense_data(struct se_cmd *cmd)
 {
        unsigned char *buffer = cmd->sense_buffer, *sense_buffer = NULL;
-       struct se_device *dev;
+       struct se_device *dev = cmd->se_dev;
        struct se_task *task = NULL, *task_tmp;
        unsigned long flags;
        u32 offset = 0;
 
        WARN_ON(!cmd->se_lun);
 
+       if (!dev)
+               return 0;
+
        spin_lock_irqsave(&cmd->t_state_lock, flags);
        if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) {
                spin_unlock_irqrestore(&cmd->t_state_lock, flags);
@@ -2767,14 +2662,9 @@ static int transport_get_sense_data(struct se_cmd *cmd)
 
        list_for_each_entry_safe(task, task_tmp,
                                &cmd->t_task_list, t_list) {
-
                if (!task->task_sense)
                        continue;
 
-               dev = task->se_dev;
-               if (!dev)
-                       continue;
-
                if (!dev->transport->get_sense_buffer) {
                        pr_err("dev->transport->get_sense_buffer"
                                        " is NULL\n");
@@ -2783,9 +2673,9 @@ static int transport_get_sense_data(struct se_cmd *cmd)
 
                sense_buffer = dev->transport->get_sense_buffer(task);
                if (!sense_buffer) {
-                       pr_err("ITT[0x%08x]_TASK[%d]: Unable to locate"
+                       pr_err("ITT[0x%08x]_TASK[%p]: Unable to locate"
                                " sense buffer for task with sense\n",
-                               cmd->se_tfo->get_task_tag(cmd), task->task_no);
+                               cmd->se_tfo->get_task_tag(cmd), task);
                        continue;
                }
                spin_unlock_irqrestore(&cmd->t_state_lock, flags);
@@ -2814,7 +2704,6 @@ static int transport_get_sense_data(struct se_cmd *cmd)
 static int
 transport_handle_reservation_conflict(struct se_cmd *cmd)
 {
-       cmd->transport_wait_for_tasks = &transport_nop_wait_for_tasks;
        cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
        cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT;
        cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT;
@@ -2915,8 +2804,6 @@ static int transport_generic_cmd_sequencer(
         * Check for an existing UNIT ATTENTION condition
         */
        if (core_scsi3_ua_check(cmd, cdb) < 0) {
-               cmd->transport_wait_for_tasks =
-                               &transport_nop_wait_for_tasks;
                cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
                cmd->scsi_sense_reason = TCM_CHECK_CONDITION_UNIT_ATTENTION;
                return -EINVAL;
@@ -2926,7 +2813,6 @@ static int transport_generic_cmd_sequencer(
         */
        ret = su_dev->t10_alua.alua_state_check(cmd, cdb, &alua_ascq);
        if (ret != 0) {
-               cmd->transport_wait_for_tasks = &transport_nop_wait_for_tasks;
                /*
                 * Set SCSI additional sense code (ASC) to 'LUN Not Accessible';
                 * The ALUA additional sense code qualifier (ASCQ) is determined
@@ -3430,7 +3316,6 @@ static int transport_generic_cmd_sequencer(
                pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode"
                        " 0x%02x, sending CHECK_CONDITION.\n",
                        cmd->se_tfo->get_fabric_name(), cdb[0]);
-               cmd->transport_wait_for_tasks = &transport_nop_wait_for_tasks;
                goto out_unsupported_cdb;
        }
 
@@ -3720,7 +3605,7 @@ static void transport_free_dev_tasks(struct se_cmd *cmd)
        spin_lock_irqsave(&cmd->t_state_lock, flags);
        list_for_each_entry_safe(task, task_tmp,
                                &cmd->t_task_list, t_list) {
-               if (atomic_read(&task->task_active))
+               if (task->task_flags & TF_ACTIVE)
                        continue;
 
                kfree(task->task_sg_bidi);
@@ -3729,11 +3614,7 @@ static void transport_free_dev_tasks(struct se_cmd *cmd)
                list_del(&task->t_list);
 
                spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-               if (task->se_dev)
-                       task->se_dev->transport->free_task(task);
-               else
-                       pr_err("task[%u] - task->se_dev is NULL\n",
-                               task->task_no);
+               cmd->se_dev->transport->free_task(task);
                spin_lock_irqsave(&cmd->t_state_lock, flags);
        }
        spin_unlock_irqrestore(&cmd->t_state_lock, flags);
@@ -3764,89 +3645,43 @@ static inline void transport_free_pages(struct se_cmd *cmd)
        cmd->t_bidi_data_nents = 0;
 }
 
-static inline void transport_release_tasks(struct se_cmd *cmd)
-{
-       transport_free_dev_tasks(cmd);
-}
-
-static inline int transport_dec_and_check(struct se_cmd *cmd)
+/**
+ * transport_put_cmd - release a reference to a command
+ * @cmd:       command to release
+ *
+ * This routine releases our reference to the command and frees it if possible.
+ */
+static void transport_put_cmd(struct se_cmd *cmd)
 {
        unsigned long flags;
+       int free_tasks = 0;
 
        spin_lock_irqsave(&cmd->t_state_lock, flags);
        if (atomic_read(&cmd->t_fe_count)) {
-               if (!atomic_dec_and_test(&cmd->t_fe_count)) {
-                       spin_unlock_irqrestore(&cmd->t_state_lock,
-                                       flags);
-                       return 1;
-               }
+               if (!atomic_dec_and_test(&cmd->t_fe_count))
+                       goto out_busy;
        }
 
        if (atomic_read(&cmd->t_se_count)) {
-               if (!atomic_dec_and_test(&cmd->t_se_count)) {
-                       spin_unlock_irqrestore(&cmd->t_state_lock,
-                                       flags);
-                       return 1;
-               }
+               if (!atomic_dec_and_test(&cmd->t_se_count))
+                       goto out_busy;
        }
-       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
-       return 0;
-}
-
-static void transport_release_fe_cmd(struct se_cmd *cmd)
-{
-       unsigned long flags;
-
-       if (transport_dec_and_check(cmd))
-               return;
-
-       spin_lock_irqsave(&cmd->t_state_lock, flags);
-       if (!atomic_read(&cmd->transport_dev_active)) {
-               spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-               goto free_pages;
-       }
-       atomic_set(&cmd->transport_dev_active, 0);
-       transport_all_task_dev_remove_state(cmd);
-       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-
-       transport_release_tasks(cmd);
-free_pages:
-       transport_free_pages(cmd);
-       transport_free_se_cmd(cmd);
-       cmd->se_tfo->release_cmd(cmd);
-}
-
-static int
-transport_generic_remove(struct se_cmd *cmd, int session_reinstatement)
-{
-       unsigned long flags;
-
-       if (transport_dec_and_check(cmd)) {
-               if (session_reinstatement) {
-                       spin_lock_irqsave(&cmd->t_state_lock, flags);
-                       transport_all_task_dev_remove_state(cmd);
-                       spin_unlock_irqrestore(&cmd->t_state_lock,
-                                       flags);
-               }
-               return 1;
-       }
-
-       spin_lock_irqsave(&cmd->t_state_lock, flags);
-       if (!atomic_read(&cmd->transport_dev_active)) {
-               spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-               goto free_pages;
+       if (atomic_read(&cmd->transport_dev_active)) {
+               atomic_set(&cmd->transport_dev_active, 0);
+               transport_all_task_dev_remove_state(cmd);
+               free_tasks = 1;
        }
-       atomic_set(&cmd->transport_dev_active, 0);
-       transport_all_task_dev_remove_state(cmd);
        spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
-       transport_release_tasks(cmd);
+       if (free_tasks != 0)
+               transport_free_dev_tasks(cmd);
 
-free_pages:
        transport_free_pages(cmd);
        transport_release_cmd(cmd);
-       return 0;
+       return;
+out_busy:
+       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 }
 
 /*
@@ -4054,15 +3889,13 @@ void transport_do_task_sg_chain(struct se_cmd *cmd)
                /*
                 * For the padded tasks, use the extra SGL vector allocated
                 * in transport_allocate_data_tasks() for the sg_prev_nents
-                * offset into sg_chain() above..  The last task of a
-                * multi-task list, or a single task will not have
-                * task->task_sg_padded set..
+                * offset into sg_chain() above.
+                *
+                * We do not need the padding for the last task (or a single
+                * task), but in that case we will never use the sg_prev_nents
+                * value below which would be incorrect.
                 */
-               if (task->task_padded_sg)
-                       sg_prev_nents = (task->task_sg_nents + 1);
-               else
-                       sg_prev_nents = task->task_sg_nents;
-
+               sg_prev_nents = (task->task_sg_nents + 1);
                sg_prev = task->task_sg;
        }
        /*
@@ -4103,7 +3936,7 @@ static int transport_allocate_data_tasks(
        struct se_task *task;
        struct se_device *dev = cmd->se_dev;
        unsigned long flags;
-       int task_count, i, ret;
+       int task_count, i;
        sector_t sectors, dev_max_sectors = dev->se_sub_dev->se_dev_attrib.max_sectors;
        u32 sector_size = dev->se_sub_dev->se_dev_attrib.block_size;
        struct scatterlist *sg;
@@ -4149,7 +3982,6 @@ static int transport_allocate_data_tasks(
                 */
                if (cmd->se_tfo->task_sg_chaining && (i < (task_count - 1))) {
                        task_sg_nents_padded = (task->task_sg_nents + 1);
-                       task->task_padded_sg = 1;
                } else
                        task_sg_nents_padded = task->task_sg_nents;
 
@@ -4181,20 +4013,6 @@ static int transport_allocate_data_tasks(
                list_add_tail(&task->t_list, &cmd->t_task_list);
                spin_unlock_irqrestore(&cmd->t_state_lock, flags);
        }
-       /*
-        * Now perform the memory map of task->task_sg[] into backend
-        * subsystem memory..
-        */
-       list_for_each_entry(task, &cmd->t_task_list, t_list) {
-               if (atomic_read(&task->task_sent))
-                       continue;
-               if (!dev->transport->map_data_SG)
-                       continue;
-
-               ret = dev->transport->map_data_SG(task);
-               if (ret < 0)
-                       return 0;
-       }
 
        return task_count;
 }
@@ -4206,7 +4024,6 @@ transport_allocate_control_task(struct se_cmd *cmd)
        unsigned char *cdb;
        struct se_task *task;
        unsigned long flags;
-       int ret = 0;
 
        task = transport_generic_get_task(cmd, cmd->data_direction);
        if (!task)
@@ -4233,21 +4050,8 @@ transport_allocate_control_task(struct se_cmd *cmd)
        list_add_tail(&task->t_list, &cmd->t_task_list);
        spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
-       if (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) {
-               if (dev->transport->map_control_SG)
-                       ret = dev->transport->map_control_SG(task);
-       } else if (cmd->se_cmd_flags & SCF_SCSI_NON_DATA_CDB) {
-               if (dev->transport->cdb_none)
-                       ret = dev->transport->cdb_none(task);
-       } else {
-               pr_err("target: Unknown control cmd type!\n");
-               BUG();
-       }
-
        /* Success! Return number of tasks allocated */
-       if (ret == 0)
-               return 1;
-       return ret;
+       return 1;
 }
 
 static u32 transport_allocate_tasks(
@@ -4391,56 +4195,48 @@ queue_full:
        return ret;
 }
 
+/**
+ * transport_release_cmd - free a command
+ * @cmd:       command to free
+ *
+ * This routine unconditionally frees a command, and reference counting
+ * or list removal must be done in the caller.
+ */
 void transport_release_cmd(struct se_cmd *cmd)
 {
        BUG_ON(!cmd->se_tfo);
 
-       transport_free_se_cmd(cmd);
+       if (cmd->se_tmr_req)
+               core_tmr_release_req(cmd->se_tmr_req);
+       if (cmd->t_task_cdb != cmd->__t_task_cdb)
+               kfree(cmd->t_task_cdb);
        cmd->se_tfo->release_cmd(cmd);
 }
 EXPORT_SYMBOL(transport_release_cmd);
 
-/*     transport_generic_free_cmd():
- *
- *     Called from processing frontend to release storage engine resources
- */
-void transport_generic_free_cmd(
-       struct se_cmd *cmd,
-       int wait_for_tasks,
-       int session_reinstatement)
+void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
 {
-       if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD))
+       if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) {
+               if (wait_for_tasks && cmd->se_tmr_req)
+                        transport_wait_for_tasks(cmd);
+
                transport_release_cmd(cmd);
-       else {
+       } else {
+               if (wait_for_tasks)
+                       transport_wait_for_tasks(cmd);
+
                core_dec_lacl_count(cmd->se_sess->se_node_acl, cmd);
 
-               if (cmd->se_lun) {
-#if 0
-                       pr_debug("cmd: %p ITT: 0x%08x contains"
-                               " cmd->se_lun\n", cmd,
-                               cmd->se_tfo->get_task_tag(cmd));
-#endif
+               if (cmd->se_lun)
                        transport_lun_remove_cmd(cmd);
-               }
-
-               if (wait_for_tasks && cmd->transport_wait_for_tasks)
-                       cmd->transport_wait_for_tasks(cmd, 0, 0);
 
                transport_free_dev_tasks(cmd);
 
-               transport_generic_remove(cmd, session_reinstatement);
+               transport_put_cmd(cmd);
        }
 }
 EXPORT_SYMBOL(transport_generic_free_cmd);
 
-static void transport_nop_wait_for_tasks(
-       struct se_cmd *cmd,
-       int remove_cmd,
-       int session_reinstatement)
-{
-       return;
-}
-
 /*     transport_lun_wait_for_tasks():
  *
  *     Called from ConfigFS context to stop the passed struct se_cmd to allow
@@ -4610,22 +4406,30 @@ int transport_clear_lun_from_sessions(struct se_lun *lun)
        return 0;
 }
 
-/*     transport_generic_wait_for_tasks():
+/**
+ * transport_wait_for_tasks - wait for completion to occur
+ * @cmd:       command to wait
  *
- *     Called from frontend or passthrough context to wait for storage engine
- *     to pause and/or release frontend generated struct se_cmd.
+ * Called from frontend fabric context to wait for storage engine
+ * to pause and/or release frontend generated struct se_cmd.
  */
-static void transport_generic_wait_for_tasks(
-       struct se_cmd *cmd,
-       int remove_cmd,
-       int session_reinstatement)
+void transport_wait_for_tasks(struct se_cmd *cmd)
 {
        unsigned long flags;
 
-       if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD) && !(cmd->se_tmr_req))
-               return;
-
        spin_lock_irqsave(&cmd->t_state_lock, flags);
+       if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD) && !(cmd->se_tmr_req)) {
+               spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+               return;
+       }
+       /*
+        * Only perform a possible wait_for_tasks if SCF_SUPPORTED_SAM_OPCODE
+        * has been set in transport_set_supported_SAM_opcode().
+        */
+       if (!(cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) && !cmd->se_tmr_req) {
+               spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+               return;
+       }
        /*
         * If we are already stopped due to an external event (ie: LUN shutdown)
         * sleep until the connection can have the passed struct se_cmd back.
@@ -4665,8 +4469,10 @@ static void transport_generic_wait_for_tasks(
                atomic_set(&cmd->transport_lun_stop, 0);
        }
        if (!atomic_read(&cmd->t_transport_active) ||
-            atomic_read(&cmd->t_transport_aborted))
-               goto remove;
+            atomic_read(&cmd->t_transport_aborted)) {
+               spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+               return;
+       }
 
        atomic_set(&cmd->t_transport_stop, 1);
 
@@ -4689,13 +4495,10 @@ static void transport_generic_wait_for_tasks(
        pr_debug("wait_for_tasks: Stopped wait_for_compltion("
                "&cmd->t_transport_stop_comp) for ITT: 0x%08x\n",
                cmd->se_tfo->get_task_tag(cmd));
-remove:
-       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-       if (!remove_cmd)
-               return;
 
-       transport_generic_free_cmd(cmd, 0, session_reinstatement);
+       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 }
+EXPORT_SYMBOL(transport_wait_for_tasks);
 
 static int transport_get_sense_codes(
        struct se_cmd *cmd,
@@ -4920,6 +4723,15 @@ EXPORT_SYMBOL(transport_check_aborted_status);
 
 void transport_send_task_abort(struct se_cmd *cmd)
 {
+       unsigned long flags;
+
+       spin_lock_irqsave(&cmd->t_state_lock, flags);
+       if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) {
+               spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+               return;
+       }
+       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+
        /*
         * If there are still expected incoming fabric WRITEs, we wait
         * until until they have completed before sending a TASK_ABORTED
@@ -4988,180 +4800,6 @@ int transport_generic_do_tmr(struct se_cmd *cmd)
        return 0;
 }
 
-/*
- *     Called with spin_lock_irq(&dev->execute_task_lock); held
- *
- */
-static struct se_task *
-transport_get_task_from_state_list(struct se_device *dev)
-{
-       struct se_task *task;
-
-       if (list_empty(&dev->state_task_list))
-               return NULL;
-
-       list_for_each_entry(task, &dev->state_task_list, t_state_list)
-               break;
-
-       list_del(&task->t_state_list);
-       atomic_set(&task->task_state_active, 0);
-
-       return task;
-}
-
-static void transport_processing_shutdown(struct se_device *dev)
-{
-       struct se_cmd *cmd;
-       struct se_task *task;
-       unsigned long flags;
-       /*
-        * Empty the struct se_device's struct se_task state list.
-        */
-       spin_lock_irqsave(&dev->execute_task_lock, flags);
-       while ((task = transport_get_task_from_state_list(dev))) {
-               if (!task->task_se_cmd) {
-                       pr_err("task->task_se_cmd is NULL!\n");
-                       continue;
-               }
-               cmd = task->task_se_cmd;
-
-               spin_unlock_irqrestore(&dev->execute_task_lock, flags);
-
-               spin_lock_irqsave(&cmd->t_state_lock, flags);
-
-               pr_debug("PT: cmd: %p task: %p ITT: 0x%08x,"
-                       " i_state: %d, t_state/def_t_state:"
-                       " %d/%d cdb: 0x%02x\n", cmd, task,
-                       cmd->se_tfo->get_task_tag(cmd),
-                       cmd->se_tfo->get_cmd_state(cmd),
-                       cmd->t_state, cmd->deferred_t_state,
-                       cmd->t_task_cdb[0]);
-               pr_debug("PT: ITT[0x%08x] - t_tasks: %d t_task_cdbs_left:"
-                       " %d t_task_cdbs_sent: %d -- t_transport_active: %d"
-                       " t_transport_stop: %d t_transport_sent: %d\n",
-                       cmd->se_tfo->get_task_tag(cmd),
-                       cmd->t_task_list_num,
-                       atomic_read(&cmd->t_task_cdbs_left),
-                       atomic_read(&cmd->t_task_cdbs_sent),
-                       atomic_read(&cmd->t_transport_active),
-                       atomic_read(&cmd->t_transport_stop),
-                       atomic_read(&cmd->t_transport_sent));
-
-               if (atomic_read(&task->task_active)) {
-                       atomic_set(&task->task_stop, 1);
-                       spin_unlock_irqrestore(
-                               &cmd->t_state_lock, flags);
-
-                       pr_debug("Waiting for task: %p to shutdown for dev:"
-                               " %p\n", task, dev);
-                       wait_for_completion(&task->task_stop_comp);
-                       pr_debug("Completed task: %p shutdown for dev: %p\n",
-                               task, dev);
-
-                       spin_lock_irqsave(&cmd->t_state_lock, flags);
-                       atomic_dec(&cmd->t_task_cdbs_left);
-
-                       atomic_set(&task->task_active, 0);
-                       atomic_set(&task->task_stop, 0);
-               } else {
-                       if (atomic_read(&task->task_execute_queue) != 0)
-                               transport_remove_task_from_execute_queue(task, dev);
-               }
-               __transport_stop_task_timer(task, &flags);
-
-               if (!atomic_dec_and_test(&cmd->t_task_cdbs_ex_left)) {
-                       spin_unlock_irqrestore(
-                                       &cmd->t_state_lock, flags);
-
-                       pr_debug("Skipping task: %p, dev: %p for"
-                               " t_task_cdbs_ex_left: %d\n", task, dev,
-                               atomic_read(&cmd->t_task_cdbs_ex_left));
-
-                       spin_lock_irqsave(&dev->execute_task_lock, flags);
-                       continue;
-               }
-
-               if (atomic_read(&cmd->t_transport_active)) {
-                       pr_debug("got t_transport_active = 1 for task: %p, dev:"
-                                       " %p\n", task, dev);
-
-                       if (atomic_read(&cmd->t_fe_count)) {
-                               spin_unlock_irqrestore(
-                                       &cmd->t_state_lock, flags);
-                               transport_send_check_condition_and_sense(
-                                       cmd, TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE,
-                                       0);
-                               transport_remove_cmd_from_queue(cmd,
-                                       &cmd->se_dev->dev_queue_obj);
-
-                               transport_lun_remove_cmd(cmd);
-                               transport_cmd_check_stop(cmd, 1, 0);
-                       } else {
-                               spin_unlock_irqrestore(
-                                       &cmd->t_state_lock, flags);
-
-                               transport_remove_cmd_from_queue(cmd,
-                                       &cmd->se_dev->dev_queue_obj);
-
-                               transport_lun_remove_cmd(cmd);
-
-                               if (transport_cmd_check_stop(cmd, 1, 0))
-                                       transport_generic_remove(cmd, 0);
-                       }
-
-                       spin_lock_irqsave(&dev->execute_task_lock, flags);
-                       continue;
-               }
-               pr_debug("Got t_transport_active = 0 for task: %p, dev: %p\n",
-                               task, dev);
-
-               if (atomic_read(&cmd->t_fe_count)) {
-                       spin_unlock_irqrestore(
-                               &cmd->t_state_lock, flags);
-                       transport_send_check_condition_and_sense(cmd,
-                               TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
-                       transport_remove_cmd_from_queue(cmd,
-                               &cmd->se_dev->dev_queue_obj);
-
-                       transport_lun_remove_cmd(cmd);
-                       transport_cmd_check_stop(cmd, 1, 0);
-               } else {
-                       spin_unlock_irqrestore(
-                               &cmd->t_state_lock, flags);
-
-                       transport_remove_cmd_from_queue(cmd,
-                               &cmd->se_dev->dev_queue_obj);
-                       transport_lun_remove_cmd(cmd);
-
-                       if (transport_cmd_check_stop(cmd, 1, 0))
-                               transport_generic_remove(cmd, 0);
-               }
-
-               spin_lock_irqsave(&dev->execute_task_lock, flags);
-       }
-       spin_unlock_irqrestore(&dev->execute_task_lock, flags);
-       /*
-        * Empty the struct se_device's struct se_cmd list.
-        */
-       while ((cmd = transport_get_cmd_from_queue(&dev->dev_queue_obj))) {
-
-               pr_debug("From Device Queue: cmd: %p t_state: %d\n",
-                               cmd, cmd->t_state);
-
-               if (atomic_read(&cmd->t_fe_count)) {
-                       transport_send_check_condition_and_sense(cmd,
-                               TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
-
-                       transport_lun_remove_cmd(cmd);
-                       transport_cmd_check_stop(cmd, 1, 0);
-               } else {
-                       transport_lun_remove_cmd(cmd);
-                       if (transport_cmd_check_stop(cmd, 1, 0))
-                               transport_generic_remove(cmd, 0);
-               }
-       }
-}
-
 /*     transport_processing_thread():
  *
  *
@@ -5181,14 +4819,6 @@ static int transport_processing_thread(void *param)
                if (ret < 0)
                        goto out;
 
-               spin_lock_irq(&dev->dev_status_lock);
-               if (dev->dev_status & TRANSPORT_DEVICE_SHUTDOWN) {
-                       spin_unlock_irq(&dev->dev_status_lock);
-                       transport_processing_shutdown(dev);
-                       continue;
-               }
-               spin_unlock_irq(&dev->dev_status_lock);
-
 get_cmd:
                __transport_execute_tasks(dev);
 
@@ -5197,6 +4827,9 @@ get_cmd:
                        continue;
 
                switch (cmd->t_state) {
+               case TRANSPORT_NEW_CMD:
+                       BUG();
+                       break;
                case TRANSPORT_NEW_CMD_MAP:
                        if (!cmd->se_tfo->new_cmd_map) {
                                pr_err("cmd->se_tfo->new_cmd_map is"
@@ -5211,8 +4844,6 @@ get_cmd:
                                                    DMA_TO_DEVICE));
                                break;
                        }
-                       /* Fall through */
-               case TRANSPORT_NEW_CMD:
                        ret = transport_generic_new_cmd(cmd);
                        if (ret == -EAGAIN)
                                break;
@@ -5231,10 +4862,10 @@ get_cmd:
                        transport_generic_complete_ok(cmd);
                        break;
                case TRANSPORT_REMOVE:
-                       transport_generic_remove(cmd, 0);
+                       transport_put_cmd(cmd);
                        break;
                case TRANSPORT_FREE_CMD_INTR:
-                       transport_generic_free_cmd(cmd, 0, 0);
+                       transport_generic_free_cmd(cmd, 0);
                        break;
                case TRANSPORT_PROCESS_TMR:
                        transport_generic_do_tmr(cmd);
@@ -5263,7 +4894,8 @@ get_cmd:
        }
 
 out:
-       transport_release_all_cmds(dev);
+       WARN_ON(!list_empty(&dev->state_task_list));
+       WARN_ON(!list_empty(&dev->dev_queue_obj.qobj_list));
        dev->process_thread = NULL;
        return 0;
 }