From 45ac0c0da99785fe2b3ed87eef058bd1c7de0223 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 14 Apr 2021 16:01:52 +0200 Subject: [PATCH] Revert "UPSTREAM: scsi: ufs: core: Fix wrong Task Tag used in task management request UPIUs" This reverts commit 486309a680c2389e19d5550f576c73ee8c84fb0d. It causes a abi break in the ufs code that is not needed in this branch. Bug: 161946584 Signed-off-by: Greg Kroah-Hartman Change-Id: Iea6cdcf5c1fa150a2012837667afeb4066c6ed3b --- drivers/scsi/ufs/ufshcd.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 0d6468f6f74d..9aa61abdb349 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -6254,31 +6254,35 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, DECLARE_COMPLETION_ONSTACK(wait); struct request *req; unsigned long flags; - int task_tag, err; + int free_slot, task_tag, err; /* - * blk_get_request() is used here only to get a free tag. + * Get free slot, sleep if slots are unavailable. + * Even though we use wait_event() which sleeps indefinitely, + * the maximum wait time is bounded by %TM_CMD_TIMEOUT. */ req = blk_get_request(q, REQ_OP_DRV_OUT, BLK_MQ_REQ_RESERVED); req->end_io_data = &wait; + free_slot = req->tag; + WARN_ON_ONCE(free_slot < 0 || free_slot >= hba->nutmrs); ufshcd_hold(hba, false); spin_lock_irqsave(host->host_lock, flags); + task_tag = hba->nutrs + free_slot; blk_mq_start_request(req); - task_tag = req->tag; treq->req_header.dword_0 |= cpu_to_be32(task_tag); - memcpy(hba->utmrdl_base_addr + task_tag, treq, sizeof(*treq)); - ufshcd_vops_setup_task_mgmt(hba, task_tag, tm_function); + memcpy(hba->utmrdl_base_addr + free_slot, treq, sizeof(*treq)); + ufshcd_vops_setup_task_mgmt(hba, free_slot, tm_function); /* send command to the controller */ - __set_bit(task_tag, &hba->outstanding_tasks); + __set_bit(free_slot, &hba->outstanding_tasks); /* Make sure descriptors are ready before ringing the task doorbell */ wmb(); - ufshcd_writel(hba, 1 << task_tag, REG_UTP_TASK_REQ_DOOR_BELL); + ufshcd_writel(hba, 1 << free_slot, REG_UTP_TASK_REQ_DOOR_BELL); /* Make sure that doorbell is committed immediately */ wmb(); @@ -6298,24 +6302,24 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, ufshcd_add_tm_upiu_trace(hba, task_tag, "tm_complete_err"); dev_err(hba->dev, "%s: task management cmd 0x%.2x timed-out\n", __func__, tm_function); - if (ufshcd_clear_tm_cmd(hba, task_tag)) - dev_WARN(hba->dev, "%s: unable to clear tm cmd (slot %d) after timeout\n", - __func__, task_tag); + if (ufshcd_clear_tm_cmd(hba, free_slot)) + dev_WARN(hba->dev, "%s: unable clear tm cmd (slot %d) after timeout\n", + __func__, free_slot); err = -ETIMEDOUT; } else { err = 0; - memcpy(treq, hba->utmrdl_base_addr + task_tag, sizeof(*treq)); + memcpy(treq, hba->utmrdl_base_addr + free_slot, sizeof(*treq)); ufshcd_add_tm_upiu_trace(hba, task_tag, "tm_complete"); } spin_lock_irqsave(hba->host->host_lock, flags); - __clear_bit(task_tag, &hba->outstanding_tasks); + __clear_bit(free_slot, &hba->outstanding_tasks); spin_unlock_irqrestore(hba->host->host_lock, flags); - ufshcd_release(hba); blk_put_request(req); + ufshcd_release(hba); return err; }