[RFC,v3,1/2] ufs: support various values per device
diff mbox series

Message ID dc21b368f44c8a9a257d1b00549e3b5aeec00755.1593753896.git.kwmad.kim@samsung.com
State Changes Requested
Headers show
Series
  • ufs: support various values per device
Related show

Commit Message

Kiwoong Kim July 3, 2020, 5:30 a.m. UTC
Respective UFS devices have their own characteristics and
many of them could be a form of numbers, such as timeout
and a number of retires. This introduces the way to set
those things per specific device vendor or specific device.

I wrote this like the style of ufs_fixups stuffs.

Signed-off-by: Kiwoong Kim <kwmad.kim@samsung.com>
---
 drivers/scsi/ufs/ufs_quirks.h | 13 +++++++++++++
 drivers/scsi/ufs/ufshcd.c     | 39 +++++++++++++++++++++++++++++++++++++++
 drivers/scsi/ufs/ufshcd.h     |  1 +
 3 files changed, 53 insertions(+)

Comments

Avri Altman July 5, 2020, 11:14 a.m. UTC | #1
> 
> Respective UFS devices have their own characteristics and
> many of them could be a form of numbers, such as timeout
> and a number of retires. This introduces the way to set
> those things per specific device vendor or specific device.
> 
> I wrote this like the style of ufs_fixups stuffs.
> 
> Signed-off-by: Kiwoong Kim <kwmad.kim@samsung.com>
This patch legitimize quirks of all kinds and shapes.
I am not sure that we should allow it.


> ---
>  drivers/scsi/ufs/ufs_quirks.h | 13 +++++++++++++
>  drivers/scsi/ufs/ufshcd.c     | 39
> +++++++++++++++++++++++++++++++++++++++
>  drivers/scsi/ufs/ufshcd.h     |  1 +
>  3 files changed, 53 insertions(+)
> 
> diff --git a/drivers/scsi/ufs/ufs_quirks.h b/drivers/scsi/ufs/ufs_quirks.h
> index 2a00414..f074093 100644
> --- a/drivers/scsi/ufs/ufs_quirks.h
> +++ b/drivers/scsi/ufs/ufs_quirks.h
> @@ -29,6 +29,19 @@ struct ufs_dev_fix {
>         unsigned int quirk;
>  };
> 
> +enum dev_val_type {
> +       DEV_VAL_FDEVICEINIT     = 0x0,

            /* keep last */
> +       DEV_VAL_NUM,
> +};
> +
> +struct ufs_dev_value {
> +       u16 wmanufacturerid;
> +       u8 *model;
> +       u32 key;
> +       u32 val;
> +       bool enable;
> +};
> +
>  #define END_FIX { }
> 
>  /* add specific device quirk */
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index 52abe82..b26f182 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -207,6 +207,21 @@ static struct ufs_dev_fix ufs_fixups[] = {
>         END_FIX
>  };
> 
> +static const struct ufs_dev_value ufs_dev_values[] = {
> +       {0, 0, 0, 0, false},
> +};
> +
> +static inline bool
> +ufs_get_dev_specific_value(struct ufs_hba *hba,
> +                          enum dev_val_type type, u32 *val)
> +{
If (ARRAY_SIZE(ufs_dev_values) <= type)
    return false;


Thanks,
Avri
Bart Van Assche July 5, 2020, 3:07 p.m. UTC | #2
On 2020-07-02 22:30, Kiwoong Kim wrote:
> +static const struct ufs_dev_value ufs_dev_values[] = {
> +	{0, 0, 0, 0, false},
> +};

A minor stylistic request: please change "{0, 0, 0, 0, false}" into "{
}". The C language requires that structure members that have not been
specified are zero-initialized.

Thanks,

Bart.
Kiwoong Kim July 6, 2020, 6:43 a.m. UTC | #3
> On 2020-07-02 22:30, Kiwoong Kim wrote:
> > +static const struct ufs_dev_value ufs_dev_values[] = {
> > +	{0, 0, 0, 0, false},
> > +};
> 
> A minor stylistic request: please change "{0, 0, 0, 0, false}" into "{ }".
> The C language requires that structure members that have not been
> specified are zero-initialized.
> 
> Thanks,
> 
> Bart.

Got it and I experienced the tool chain to show warning messages for not specifying details in there.

Thanks.
Kiwoong Kim
Grant Jung July 6, 2020, 11:35 a.m. UTC | #4
> > Respective UFS devices have their own characteristics and many of them
> > could be a form of numbers, such as timeout and a number of retires.
> > This introduces the way to set those things per specific device vendor
> > or specific device.
> >
> > I wrote this like the style of ufs_fixups stuffs.
> >
> > Signed-off-by: Kiwoong Kim <kwmad.kim@samsung.com>
> This patch legitimize quirks of all kinds and shapes.
> I am not sure that we should allow it.
> 
> 
> > ---
> >  drivers/scsi/ufs/ufs_quirks.h | 13 +++++++++++++
> >  drivers/scsi/ufs/ufshcd.c     | 39
> > +++++++++++++++++++++++++++++++++++++++
> >  drivers/scsi/ufs/ufshcd.h     |  1 +
> >  3 files changed, 53 insertions(+)
> >
> > diff --git a/drivers/scsi/ufs/ufs_quirks.h
> > b/drivers/scsi/ufs/ufs_quirks.h index 2a00414..f074093 100644
> > --- a/drivers/scsi/ufs/ufs_quirks.h
> > +++ b/drivers/scsi/ufs/ufs_quirks.h
> > @@ -29,6 +29,19 @@ struct ufs_dev_fix {
> >         unsigned int quirk;
> >  };
> >
> > +enum dev_val_type {
> > +       DEV_VAL_FDEVICEINIT     = 0x0,
> 
>             /* keep last */
> > +       DEV_VAL_NUM,
> > +};
> > +
> > +struct ufs_dev_value {
> > +       u16 wmanufacturerid;
> > +       u8 *model;
> > +       u32 key;
> > +       u32 val;
> > +       bool enable;
> > +};
> > +
> >  #define END_FIX { }
> >
> >  /* add specific device quirk */
> > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> > index 52abe82..b26f182 100644
> > --- a/drivers/scsi/ufs/ufshcd.c
> > +++ b/drivers/scsi/ufs/ufshcd.c
> > @@ -207,6 +207,21 @@ static struct ufs_dev_fix ufs_fixups[] = {
> >         END_FIX
> >  };
> >
> > +static const struct ufs_dev_value ufs_dev_values[] = {
> > +       {0, 0, 0, 0, false},
> > +};
> > +
> > +static inline bool
> > +ufs_get_dev_specific_value(struct ufs_hba *hba,
> > +                          enum dev_val_type type, u32 *val) {
> If (ARRAY_SIZE(ufs_dev_values) <= type)
>     return false;
> 
> 
> Thanks,
> Avri

There is no specification for fdeviceinit timeout value like eMMC CMD1 which is 1s.
Usually this value is small but can be increased under some abnormal situation like SPO(fdeviceinit after Sudden Power Off).
I think that 1000 retries take less than 1 second but it is inaccurate and not enough. Some UFS vendor wants 1.5s.
Moreover, the latency of resuming ufs driver can be dependent on this value when vcc and vccq is off during suspend.
So it's bad to set with big value to apply all UFS devices.
 
I wonder quirk is needed for that.

BR
Grant
Bart Van Assche July 6, 2020, 5:52 p.m. UTC | #5
On 2020-07-05 23:43, Kiwoong Kim wrote:
>> On 2020-07-02 22:30, Kiwoong Kim wrote:
>>> +static const struct ufs_dev_value ufs_dev_values[] = {
>>> +	{0, 0, 0, 0, false},
>>> +};
>>
>> A minor stylistic request: please change "{0, 0, 0, 0, false}" into "{ }".
>> The C language requires that structure members that have not been
>> specified are zero-initialized.
> 
> Got it and I experienced the tool chain to show warning messages for not specifying details in there.

That's unexpected. Which warning was shown and which toolchain did
display that warning?

Thanks,

Bart.
Kiwoong Kim July 15, 2020, 8:03 a.m. UTC | #6
> > Respective UFS devices have their own characteristics and many of them
> > could be a form of numbers, such as timeout and a number of retires.
> > This introduces the way to set those things per specific device vendor
> > or specific device.
> >
> > I wrote this like the style of ufs_fixups stuffs.
> >
> > Signed-off-by: Kiwoong Kim <kwmad.kim@samsung.com>
> This patch legitimize quirks of all kinds and shapes.
> I am not sure that we should allow it.
If you're concerning the name 'quirk' literally, I can change the way
to use another values by device tree or whatever.
Or do you concern introducing various values?

> 
> 
> > ---
> >  drivers/scsi/ufs/ufs_quirks.h | 13 +++++++++++++
> >  drivers/scsi/ufs/ufshcd.c     | 39
> > +++++++++++++++++++++++++++++++++++++++
> >  drivers/scsi/ufs/ufshcd.h     |  1 +
> >  3 files changed, 53 insertions(+)
> >
> > diff --git a/drivers/scsi/ufs/ufs_quirks.h
> > b/drivers/scsi/ufs/ufs_quirks.h index 2a00414..f074093 100644
> > --- a/drivers/scsi/ufs/ufs_quirks.h
> > +++ b/drivers/scsi/ufs/ufs_quirks.h
> > @@ -29,6 +29,19 @@ struct ufs_dev_fix {
> >         unsigned int quirk;
> >  };
> >
> > +enum dev_val_type {
> > +       DEV_VAL_FDEVICEINIT     = 0x0,
> 
>             /* keep last */
> > +       DEV_VAL_NUM,
> > +};
> > +
> > +struct ufs_dev_value {
> > +       u16 wmanufacturerid;
> > +       u8 *model;
> > +       u32 key;
> > +       u32 val;
> > +       bool enable;
> > +};
> > +
> >  #define END_FIX { }
> >
> >  /* add specific device quirk */
> > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> > index 52abe82..b26f182 100644
> > --- a/drivers/scsi/ufs/ufshcd.c
> > +++ b/drivers/scsi/ufs/ufshcd.c
> > @@ -207,6 +207,21 @@ static struct ufs_dev_fix ufs_fixups[] = {
> >         END_FIX
> >  };
> >
> > +static const struct ufs_dev_value ufs_dev_values[] = {
> > +       {0, 0, 0, 0, false},
> > +};
> > +
> > +static inline bool
> > +ufs_get_dev_specific_value(struct ufs_hba *hba,
> > +                          enum dev_val_type type, u32 *val) {
> If (ARRAY_SIZE(ufs_dev_values) <= type)
>     return false;
> 
> 
> Thanks,
> Avri
Got it.

Thanks.
Kiwoong Kim

Patch
diff mbox series

diff --git a/drivers/scsi/ufs/ufs_quirks.h b/drivers/scsi/ufs/ufs_quirks.h
index 2a00414..f074093 100644
--- a/drivers/scsi/ufs/ufs_quirks.h
+++ b/drivers/scsi/ufs/ufs_quirks.h
@@ -29,6 +29,19 @@  struct ufs_dev_fix {
 	unsigned int quirk;
 };
 
+enum dev_val_type {
+	DEV_VAL_FDEVICEINIT	= 0x0,
+	DEV_VAL_NUM,
+};
+
+struct ufs_dev_value {
+	u16 wmanufacturerid;
+	u8 *model;
+	u32 key;
+	u32 val;
+	bool enable;
+};
+
 #define END_FIX { }
 
 /* add specific device quirk */
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 52abe82..b26f182 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -207,6 +207,21 @@  static struct ufs_dev_fix ufs_fixups[] = {
 	END_FIX
 };
 
+static const struct ufs_dev_value ufs_dev_values[] = {
+	{0, 0, 0, 0, false},
+};
+
+static inline bool
+ufs_get_dev_specific_value(struct ufs_hba *hba,
+			   enum dev_val_type type, u32 *val)
+{
+	if (!ufs_dev_values[type].enable)
+		return false;
+
+	*val = hba->dev_value[type];
+	return true;
+}
+
 static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba);
 static void ufshcd_async_scan(void *data, async_cookie_t cookie);
 static int ufshcd_reset_and_restore(struct ufs_hba *hba);
@@ -6923,11 +6938,35 @@  void ufshcd_fixup_dev_quirks(struct ufs_hba *hba, struct ufs_dev_fix *fixups)
 }
 EXPORT_SYMBOL_GPL(ufshcd_fixup_dev_quirks);
 
+static void ufshcd_set_dev_values(struct ufs_hba *hba,
+				  const struct ufs_dev_value *value)
+{
+	struct ufs_dev_value *f;
+	struct ufs_dev_info *dev_info = &hba->dev_info;
+
+	if (!value)
+		return;
+
+	for (f = (struct ufs_dev_value *)value; f->val; f++) {
+		if ((f->wmanufacturerid == dev_info->wmanufacturerid ||
+					f->wmanufacturerid == UFS_ANY_VENDOR) &&
+				((dev_info->model &&
+				  STR_PRFX_EQUAL(f->model, dev_info->model)) ||
+				 !strcmp(f->model, UFS_ANY_MODEL))) {
+			f->enable = true;
+			hba->dev_value[f->key] = f->val;
+		}
+	}
+}
+
 static void ufs_fixup_device_setup(struct ufs_hba *hba)
 {
 	/* fix by general quirk table */
 	ufshcd_fixup_dev_quirks(hba, ufs_fixups);
 
+	/* set device specific values */
+	ufshcd_set_dev_values(hba, ufs_dev_values);
+
 	/* allow vendors to fix quirks */
 	ufshcd_vops_fixup_dev_quirks(hba);
 }
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index c774012..f221ca7 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -670,6 +670,7 @@  struct ufs_hba {
 
 	/* Device deviations from standard UFS device spec. */
 	unsigned int dev_quirks;
+	u32 dev_value[DEV_VAL_NUM];
 
 	struct blk_mq_tag_set tmf_tag_set;
 	struct request_queue *tmf_queue;