diff mbox series

[RFC,v1,1/2] ufs: support various values per device

Message ID 1592638297-36155-2-git-send-email-kwmad.kim@samsung.com (mailing list archive)
State Superseded
Headers show
Series support various values per device | expand

Commit Message

Kiwoong Kim June 20, 2020, 7:31 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 | 20 ++++++++++++++++++++
 drivers/scsi/ufs/ufshcd.c     | 38 ++++++++++++++++++++++++++++++++++++++
 drivers/scsi/ufs/ufshcd.h     |  1 +
 3 files changed, 59 insertions(+)

Comments

Bart Van Assche June 20, 2020, 4:26 p.m. UTC | #1
On 2020-06-20 00:31, Kiwoong Kim wrote:
>  #define END_FIX { }

The name of this macro is longer than its value. Additionally, this
macro makes code harder to read instead of easier. Please include a
patch to remove this macro from the UFS driver.

> +#define UFS_DEV_VAL(_vendor, _model, _key, _val) { \
> +	.wmanufacturerid = (_vendor),\
> +	.model = (_model),		\
> +	.key = (_key),			\
> +	.val = (_val),			\
> +}

A macro like the above also makes code harder to read instead of easier.
Please remove this macro definition and use the designated
initialization style directly.

Thanks,

Bart.
Kiwoong Kim June 23, 2020, 1:50 a.m. UTC | #2
> On 2020-06-20 00:31, Kiwoong Kim wrote:
> >  #define END_FIX { }
> 
> The name of this macro is longer than its value. Additionally, this macro
> makes code harder to read instead of easier. Please include a patch to
> remove this macro from the UFS driver.
> 
> > +#define UFS_DEV_VAL(_vendor, _model, _key, _val) { \
> > +	.wmanufacturerid = (_vendor),\
> > +	.model = (_model),		\
> > +	.key = (_key),			\
> > +	.val = (_val),			\
> > +}
> 
> A macro like the above also makes code harder to read instead of easier.
> Please remove this macro definition and use the designated initialization
> style directly.
> 
> Thanks,
> 
> Bart.

Got it. Thanks !
diff mbox series

Patch

diff --git a/drivers/scsi/ufs/ufs_quirks.h b/drivers/scsi/ufs/ufs_quirks.h
index 2a00414..9896d98 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 */
@@ -38,6 +51,13 @@  struct ufs_dev_fix {
 	.quirk = (_quirk),		   \
 }
 
+#define UFS_DEV_VAL(_vendor, _model, _key, _val) { \
+	.wmanufacturerid = (_vendor),\
+	.model = (_model),		\
+	.key = (_key),			\
+	.val = (_val),			\
+}
+
 /*
  * Some vendor's UFS device sends back to back NACs for the DL data frames
  * causing the host controller to raise the DFES error status. Sometimes
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 52abe82..b6bc333 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 struct ufs_dev_value ufs_dev_values[] = {
+	END_FIX
+};
+
+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,34 @@  void ufshcd_fixup_dev_quirks(struct ufs_hba *hba, struct ufs_dev_fix *fixups)
 }
 EXPORT_SYMBOL_GPL(ufshcd_fixup_dev_quirks);
 
+void ufshcd_set_dev_values(struct ufs_hba *hba, struct ufs_dev_value *value)
+{
+	struct ufs_dev_value *f;
+	struct ufs_dev_info *dev_info = &hba->dev_info;
+
+	if (!value)
+		return;
+
+	for (f = 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;
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(ufshcd_set_dev_values);
+
 static void ufs_fixup_device_setup(struct ufs_hba *hba)
 {
 	/* fix by general quirk table */
 	ufshcd_fixup_dev_quirks(hba, ufs_fixups);
 
+	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;