list_del(&task->t_state_list);
cmd = task->task_se_cmd;
- spin_lock_irqsave(&cmd->t_state_lock, flags);
pr_debug("LUN_RESET: %s cmd: %p task: %p"
" ITT/CmdSN: 0x%08x/0x%08x, i_state: %d, t_state/"
"def_t_state: %d/%d cdb: 0x%02x\n",
atomic_read(&cmd->t_transport_stop),
atomic_read(&cmd->t_transport_sent));
- if (task->task_flags & TF_ACTIVE) {
- task->task_flags |= TF_REQUEST_STOP;
- spin_unlock_irqrestore(
- &cmd->t_state_lock, flags);
-
- pr_debug("LUN_RESET: Waiting for task: %p to shutdown"
- " for dev: %p\n", task, dev);
- wait_for_completion(&task->task_stop_comp);
- pr_debug("LUN_RESET 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);
- task->task_flags &= ~(TF_ACTIVE | TF_REQUEST_STOP);
- }
- __transport_stop_task_timer(task, &flags);
+ spin_lock_irqsave(&cmd->t_state_lock, flags);
+ target_stop_task(task, &flags);
if (!atomic_dec_and_test(&cmd->t_task_cdbs_ex_left)) {
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
}
EXPORT_SYMBOL(transport_generic_free_cmd_intr);
+/*
+ * If the task is active, request it to be stopped and sleep until it
+ * has completed.
+ */
+bool target_stop_task(struct se_task *task, unsigned long *flags)
+{
+ struct se_cmd *cmd = task->task_se_cmd;
+ bool was_active = false;
+
+ if (task->task_flags & TF_ACTIVE) {
+ task->task_flags |= TF_REQUEST_STOP;
+ spin_unlock_irqrestore(&cmd->t_state_lock, *flags);
+
+ pr_debug("Task %p waiting to complete\n", task);
+ wait_for_completion(&task->task_stop_comp);
+ pr_debug("Task %p stopped successfully\n", task);
+
+ spin_lock_irqsave(&cmd->t_state_lock, *flags);
+ atomic_dec(&cmd->t_task_cdbs_left);
+ task->task_flags &= ~(TF_ACTIVE | TF_REQUEST_STOP);
+ was_active = true;
+ }
+
+ __transport_stop_task_timer(task, flags);
+ return was_active;
+}
+
static int transport_stop_tasks_for_cmd(struct se_cmd *cmd)
{
struct se_task *task, *task_tmp;
continue;
}
- /*
- * If the struct se_task is active, sleep until it is returned
- * from the plugin.
- */
- if (task->task_flags & TF_ACTIVE) {
- task->task_flags |= TF_REQUEST_STOP;
- spin_unlock_irqrestore(&cmd->t_state_lock,
- flags);
-
- pr_debug("Task %p waiting to complete\n", task);
- wait_for_completion(&task->task_stop_comp);
- pr_debug("Task %p stopped successfully\n", task);
-
- spin_lock_irqsave(&cmd->t_state_lock, flags);
- atomic_dec(&cmd->t_task_cdbs_left);
- task->task_flags &= ~(TF_ACTIVE | TF_REQUEST_STOP);
- } else {
+ if (!target_stop_task(task, &flags)) {
pr_debug("Task %p - did nothing\n", task);
ret++;
}
-
- __transport_stop_task_timer(task, &flags);
}
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
extern void transport_new_cmd_failure(struct se_cmd *);
extern int transport_generic_handle_tmr(struct se_cmd *);
extern void transport_generic_free_cmd_intr(struct se_cmd *);
+extern bool target_stop_task(struct se_task *task, unsigned long *flags);
extern void __transport_stop_task_timer(struct se_task *, unsigned long *);
extern int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32,
struct scatterlist *, u32);