spin_lock_irqsave(hba->host->host_lock, flags);
- /* Clear completed tasks from outstanding_tasks */
- __clear_bit(index, &hba->outstanding_tasks);
-
task_req_descp = hba->utmrdl_base_addr;
ocs_value = ufshcd_get_tmr_ocs(&task_req_descp[index]);
tm_doorbell = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
hba->tm_condition = tm_doorbell ^ hba->outstanding_tasks;
+ hba->outstanding_tasks ^= hba->tm_condition;
wake_up(&hba->tm_wq);
}
u32 mask = 1 << tag;
unsigned long flags;
- if (!test_bit(tag, &hba->outstanding_tasks))
- goto out;
-
spin_lock_irqsave(hba->host->host_lock, flags);
ufshcd_utmrl_clear(hba, tag);
spin_unlock_irqrestore(hba->host->host_lock, flags);
err = ufshcd_wait_for_register(hba,
REG_UTP_TASK_REQ_DOOR_BELL,
mask, 0, 1000, 1000, true);
-out:
return err;
}
if (!err) {
dev_err(hba->dev, "%s: task management cmd 0x%.2x timed-out\n",
__func__, tm_function);
- if (ufshcd_clear_tm_cmd(hba, free_slot))
+ if (!ufshcd_clear_tm_cmd(hba, free_slot)) {
+ spin_lock_irqsave(hba->host->host_lock, flags);
+ __clear_bit(free_slot, &hba->outstanding_tasks);
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
+ } else {
dev_WARN(hba->dev, "%s: unable clear tm cmd (slot %d) after timeout\n",
__func__, free_slot);
+ }
err = -ETIMEDOUT;
} else {
err = ufshcd_task_req_compl(hba, free_slot, tm_response);