2023-03-08 04:04:26

by Bao D. Nguyen

[permalink] [raw]
Subject: [RFC PATCH v1 3/4] ufs: mcq: Add support for clean up mcq resources

Update ufshcd_clear_cmds() to clean up the mcq resources similar
to the function ufshcd_utrl_clear() does for sdb mode.

Update ufshcd_try_to_abort_task() to support mcq mode so that
this function can be invoked in either mcq or sdb mode.

Signed-off-by: Bao D. Nguyen <[email protected]>
---
drivers/ufs/core/ufshcd.c | 40 +++++++++++++++++++++++++++++++++++++---
1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 7e52af6..408c16c 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -2988,7 +2988,26 @@ static int ufshcd_compose_dev_cmd(struct ufs_hba *hba,
static int ufshcd_clear_cmds(struct ufs_hba *hba, u32 mask)
{
unsigned long flags;
+ int err, result, tag;

+ if (is_mcq_enabled(hba)) {
+ /*
+ * MCQ mode. Clean up the MCQ resources similar to
+ * what the ufshcd_utrl_clear() does for SDB mode.
+ */
+ flags = (unsigned long)mask;
+ for_each_set_bit(tag, &flags, hba->nutrs) {
+ err = ufshcd_mcq_sq_cleanup(hba, tag, &result);
+ if (err || result) {
+ dev_err(hba->dev, "%s: failed tag=%d. err=%d, result=%d\n",
+ __func__, tag, err, result);
+ return FAILED;
+ }
+ }
+ return 0;
+ }
+
+ /* Single Doorbell Mode */
/* clear outstanding transaction before retry */
spin_lock_irqsave(hba->host->host_lock, flags);
ufshcd_utrl_clear(hba, mask);
@@ -7344,6 +7363,20 @@ static int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag)
*/
dev_err(hba->dev, "%s: cmd at tag %d not pending in the device.\n",
__func__, tag);
+ if (is_mcq_enabled(hba)) {
+ /* mcq mode */
+ if (!lrbp->cmd) {
+ /* command completed already */
+ dev_err(hba->dev, "%s: cmd at tag=%d is cleared.\n",
+ __func__, tag);
+ goto out;
+ }
+ /* sleep for max. 200us to stabilize */
+ usleep_range(100, 200);
+ continue;
+ }
+
+ /* single door bell mode */
reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
if (reg & (1 << tag)) {
/* sleep for max. 200us to stabilize */
@@ -7410,8 +7443,8 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)

ufshcd_hold(hba, false);
reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
- /* If command is already aborted/completed, return FAILED. */
- if (!(test_bit(tag, &hba->outstanding_reqs))) {
+ if (!is_mcq_enabled(hba) && !(test_bit(tag, &hba->outstanding_reqs))) {
+ /* If command is already aborted/completed, return FAILED. */
dev_err(hba->dev,
"%s: cmd at tag %d already completed, outstanding=0x%lx, doorbell=0x%x\n",
__func__, tag, hba->outstanding_reqs, reg);
@@ -7440,7 +7473,8 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
}
hba->req_abort_count++;

- if (!(reg & (1 << tag))) {
+ if (!is_mcq_enabled(hba) && !(reg & (1 << tag))) {
+ /* only execute this code in single doorbell mode */
dev_err(hba->dev,
"%s: cmd was completed, but without a notifying intr, tag = %d",
__func__, tag);
--
2.7.4



2023-03-08 18:53:42

by Bart Van Assche

[permalink] [raw]
Subject: Re: [RFC PATCH v1 3/4] ufs: mcq: Add support for clean up mcq resources

On 3/7/23 20:01, Bao D. Nguyen wrote:
> static int ufshcd_clear_cmds(struct ufs_hba *hba, u32 mask)
> {
> unsigned long flags;
> + int err, result, tag;
>
> + if (is_mcq_enabled(hba)) {
> + /*
> + * MCQ mode. Clean up the MCQ resources similar to
> + * what the ufshcd_utrl_clear() does for SDB mode.
> + */
> + flags = (unsigned long)mask;
> + for_each_set_bit(tag, &flags, hba->nutrs) {
> + err = ufshcd_mcq_sq_cleanup(hba, tag, &result);
> + if (err || result) {
> + dev_err(hba->dev, "%s: failed tag=%d. err=%d, result=%d\n",
> + __func__, tag, err, result);
> + return FAILED;
> + }
> + }
> + return 0;
> + }

Please change the type of the 'mask' argument from u32 into unsigned
long such that the assignment of 'mask' to 'flags' can be removed.

Thanks,

Bart.

2023-03-08 22:28:27

by Bao D. Nguyen

[permalink] [raw]
Subject: Re: [RFC PATCH v1 3/4] ufs: mcq: Add support for clean up mcq resources

On 3/8/2023 10:53 AM, Bart Van Assche wrote:
> On 3/7/23 20:01, Bao D. Nguyen wrote:
>>   static int ufshcd_clear_cmds(struct ufs_hba *hba, u32 mask)
>>   {
>>       unsigned long flags;
>> +    int err, result, tag;
>>   +    if (is_mcq_enabled(hba)) {
>> +        /*
>> +         * MCQ mode. Clean up the MCQ resources similar to
>> +         * what the ufshcd_utrl_clear() does for SDB mode.
>> +         */
>> +        flags = (unsigned long)mask;
>> +        for_each_set_bit(tag, &flags, hba->nutrs) {
>> +            err = ufshcd_mcq_sq_cleanup(hba, tag, &result);
>> +            if (err || result) {
>> +                dev_err(hba->dev, "%s: failed tag=%d. err=%d,
>> result=%d\n",
>> +                    __func__, tag, err, result);
>> +                return FAILED;
>> +            }
>> +        }
>> +        return 0;
>> +    }
>
> Please change the type of the 'mask' argument from u32 into unsigned
> long such that the assignment of 'mask' to 'flags' can be removed.
>
I will make the change in the next rev. Thank you.

> Thanks,
>
> Bart.