Skip to content

Commit 7aa12d2

Browse files
Bao D. Nguyenmartinkpetersen
authored andcommitted
scsi: ufs: core: Update the ufshcd_clear_cmds() functionality
In the ufshcd_clear_cmds(), the 2nd parameter would be the bit mask of the command to be cleared in the transfer request door bell register. This bit mask mechanism does not scale well in MCQ mode when the queue depth becomes much greater than 64. Change the 2nd parameter to the function to be the task_tag number of the corresponding bit to be cleared in the door bell register. By doing so, MCQ mode with a large queue depth can reuse this function. Since the behavior of this function is changed from handling multiple commands into a single command, rename ufshcd_clear_cmds() into ufshcd_clear_cmd(). Signed-off-by: Bao D. Nguyen <[email protected]> Link: https://lore.kernel.org/r/8411fb5363acc90519bced30ea2c2ac582ff2340.1685396241.git.quic_nguyenb@quicinc.com Reviewed-by: Bart Van Assche <[email protected]> Reviewed-by: Stanley Chu <[email protected]> Tested-by: Stanley Chu <[email protected]> Reviewed-by: Can Guo <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent a8f9a36 commit 7aa12d2

File tree

1 file changed

+21
-16
lines changed

1 file changed

+21
-16
lines changed

drivers/ufs/core/ufshcd.c

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2999,13 +2999,15 @@ static int ufshcd_compose_dev_cmd(struct ufs_hba *hba,
29992999
}
30003000

30013001
/*
3002-
* Clear all the requests from the controller for which a bit has been set in
3003-
* @mask and wait until the controller confirms that these requests have been
3004-
* cleared.
3002+
* Clear the pending command in the controller and wait until
3003+
* the controller confirms that the command has been cleared.
3004+
* @hba: per adapter instance
3005+
* @task_tag: The tag number of the command to be cleared.
30053006
*/
3006-
static int ufshcd_clear_cmds(struct ufs_hba *hba, u32 mask)
3007+
static int ufshcd_clear_cmd(struct ufs_hba *hba, u32 task_tag)
30073008
{
30083009
unsigned long flags;
3010+
u32 mask = 1U << task_tag;
30093011

30103012
/* clear outstanding transaction before retry */
30113013
spin_lock_irqsave(hba->host->host_lock, flags);
@@ -3106,7 +3108,7 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba,
31063108
err = -ETIMEDOUT;
31073109
dev_dbg(hba->dev, "%s: dev_cmd request timedout, tag %d\n",
31083110
__func__, lrbp->task_tag);
3109-
if (ufshcd_clear_cmds(hba, 1U << lrbp->task_tag) == 0) {
3111+
if (ufshcd_clear_cmd(hba, lrbp->task_tag) == 0) {
31103112
/* successfully cleared the command, retry if needed */
31113113
err = -EAGAIN;
31123114
/*
@@ -7279,7 +7281,7 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd)
72797281
unsigned long flags, pending_reqs = 0, not_cleared = 0;
72807282
struct Scsi_Host *host;
72817283
struct ufs_hba *hba;
7282-
u32 pos;
7284+
u32 pos, not_cleared_mask = 0;
72837285
int err;
72847286
u8 resp = 0xF, lun;
72857287

@@ -7302,17 +7304,20 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd)
73027304
hba->outstanding_reqs &= ~pending_reqs;
73037305
spin_unlock_irqrestore(&hba->outstanding_lock, flags);
73047306

7305-
if (ufshcd_clear_cmds(hba, pending_reqs) < 0) {
7306-
spin_lock_irqsave(&hba->outstanding_lock, flags);
7307-
not_cleared = pending_reqs &
7308-
ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
7309-
hba->outstanding_reqs |= not_cleared;
7310-
spin_unlock_irqrestore(&hba->outstanding_lock, flags);
7307+
for_each_set_bit(pos, &pending_reqs, hba->nutrs) {
7308+
if (ufshcd_clear_cmd(hba, pos) < 0) {
7309+
spin_lock_irqsave(&hba->outstanding_lock, flags);
7310+
not_cleared = 1U << pos &
7311+
ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
7312+
hba->outstanding_reqs |= not_cleared;
7313+
not_cleared_mask |= not_cleared;
7314+
spin_unlock_irqrestore(&hba->outstanding_lock, flags);
73117315

7312-
dev_err(hba->dev, "%s: failed to clear requests %#lx\n",
7313-
__func__, not_cleared);
7316+
dev_err(hba->dev, "%s: failed to clear request %d\n",
7317+
__func__, pos);
7318+
}
73147319
}
7315-
__ufshcd_transfer_req_compl(hba, pending_reqs & ~not_cleared);
7320+
__ufshcd_transfer_req_compl(hba, pending_reqs & ~not_cleared_mask);
73167321

73177322
out:
73187323
hba->req_abort_count = 0;
@@ -7409,7 +7414,7 @@ static int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag)
74097414
goto out;
74107415
}
74117416

7412-
err = ufshcd_clear_cmds(hba, 1U << tag);
7417+
err = ufshcd_clear_cmd(hba, tag);
74137418
if (err)
74147419
dev_err(hba->dev, "%s: Failed clearing cmd at tag %d, err %d\n",
74157420
__func__, tag, err);

0 commit comments

Comments
 (0)