[RFC PATCH 03/13] scsi: scsi_dh: Introduce scsi_dh_ufshpb
From: Avri Altman
Date: Fri May 15 2020 - 06:31:23 EST
Add a scsi device handler companion to support ufs hpb.
The scsi-device-handler infrastructure was added to the kernel mainly to
facilitate multiple paths for storage devices. The HPB framework,
although far from the original intention of the authors, might as well
fit in. In that sense, using READs and HPB_READs intermittently, can be
perceived as a multi-path.
Device handlers are meant to be called as part of the device mapper
multi-path code. We canât do that â we need to attach & activate the
device handler manually, only after the ufs driver verified that HPB is
supported by both the platform and the device.
At this point just add the bare minimum to allow the ufs driver to
complete its second phase of initialization: attaching and activating
the device handler. This module however, will store the L2P cache,
perform the cache-management functionality, and will setup the HPB_READ
command instead of READ. So it is about to grow extensively.
Signed-off-by: Avri Altman <avri.altman@xxxxxxx>
---
drivers/scsi/device_handler/Makefile | 1 +
drivers/scsi/device_handler/scsi_dh_ufshpb.c | 73 ++++++++++++++++++++++++++++
drivers/scsi/ufs/Kconfig | 1 +
drivers/scsi/ufs/ufshpb.c | 39 +--------------
include/scsi/scsi_dh_ufshpb.h | 50 +++++++++++++++++++
5 files changed, 126 insertions(+), 38 deletions(-)
create mode 100644 drivers/scsi/device_handler/scsi_dh_ufshpb.c
create mode 100644 include/scsi/scsi_dh_ufshpb.h
diff --git a/drivers/scsi/device_handler/Makefile b/drivers/scsi/device_handler/Makefile
index 0a603ae..6587622 100644
--- a/drivers/scsi/device_handler/Makefile
+++ b/drivers/scsi/device_handler/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_SCSI_DH_RDAC) += scsi_dh_rdac.o
obj-$(CONFIG_SCSI_DH_HP_SW) += scsi_dh_hp_sw.o
obj-$(CONFIG_SCSI_DH_EMC) += scsi_dh_emc.o
obj-$(CONFIG_SCSI_DH_ALUA) += scsi_dh_alua.o
+obj-$(CONFIG_SCSI_UFS_HPB) += scsi_dh_ufshpb.o
diff --git a/drivers/scsi/device_handler/scsi_dh_ufshpb.c b/drivers/scsi/device_handler/scsi_dh_ufshpb.c
new file mode 100644
index 0000000..f26208c
--- /dev/null
+++ b/drivers/scsi/device_handler/scsi_dh_ufshpb.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Host Performance Booster(HPB) for UFS devices
+ *
+ * Copyright (C) 2017-2018 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2018, Google, Inc.
+ * Copyright (C) 2020 Western Digital Corporation or its affiliates.
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_dbg.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_dh.h>
+#include <scsi/scsi_dh_ufshpb.h>
+
+#define UFSHPB_NAME "ufshpb"
+
+struct ufshpb_dh_data {
+ const struct ufshpb_config *ufshpb_conf;
+ const struct ufshpb_lun_config *ufshpb_lun_conf;
+};
+
+static int ufshpb_attach(struct scsi_device *sdev)
+{
+ struct ufshpb_dh_data *h;
+
+ h = kzalloc(sizeof(*h), GFP_KERNEL);
+ if (!h)
+ return SCSI_DH_NOMEM;
+
+ sdev_printk(KERN_INFO, sdev, "%s: attached to sdev (lun) %llu\n",
+ UFSHPB_NAME, sdev->lun);
+
+ sdev->handler_data = h;
+
+ return SCSI_DH_OK;
+}
+
+/*
+ * scsi_dh_detach will be called from the ufs driver upon failuire and on
+ * remove.
+ */
+static void ufshpb_detach(struct scsi_device *sdev)
+{
+ kfree(sdev->handler_data);
+ sdev->handler_data = NULL;
+}
+
+static struct scsi_device_handler ufshpb_dh = {
+ .name = UFSHPB_NAME,
+ .module = THIS_MODULE,
+ .attach = ufshpb_attach,
+ .detach = ufshpb_detach,
+};
+
+static int __init ufshpb_init(void)
+{
+ return scsi_register_device_handler(&ufshpb_dh);
+}
+
+static void __exit ufshpb_exit(void)
+{
+ scsi_unregister_device_handler(&ufshpb_dh);
+}
+
+module_init(ufshpb_init);
+module_exit(ufshpb_exit);
+
+MODULE_DESCRIPTION("ufshpb scsi device handler driver");
+MODULE_AUTHOR("Avri Altman <avri.altman@xxxxxxx>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index a540919..0868d53 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -164,6 +164,7 @@ config SCSI_UFS_BSG
config SCSI_UFS_HPB
bool "Support UFS Host Performance Booster (HPB)"
depends on SCSI_UFSHCD
+ select SCSI_DH
help
A UFS feature targeted to improve random read performance. It uses
the hostâs system memory as a cache for L2P map data, so that both
diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
index 181917f..e94e699 100644
--- a/drivers/scsi/ufs/ufshpb.c
+++ b/drivers/scsi/ufs/ufshpb.c
@@ -7,6 +7,7 @@
*/
#include <asm/unaligned.h>
+#include <scsi/scsi_dh_ufshpb.h>
#include "ufshcd.h"
#include "ufs.h"
#include "ufshpb.h"
@@ -22,44 +23,6 @@ enum ufshpb_control_modes {
UFSHPB_DEVICE_CONTROL
};
-/**
- * struct ufshpb_lun_conf - to hold hpb lun config from unit descriptor
- * @lun - lun id
- * @size - lun size = 2^bLogicalBlockSize x qLogicalBlockCount
- * @max_active_regions - Maximum Number of Active HPB Regions for that LU
- * @pinned_starting_idx - HPB Pinned Region Start Offset
- * @pinned_count - Number of HPB Pinned Regions
- */
-struct ufshpb_lun_config {
- u8 lun;
- u64 size;
- u8 hpb_lun_idx;
- u16 max_active_regions;
- u16 pinned_starting_idx;
- u16 pinned_count;
-};
-
-/**
- * struct ufshpb_config - to hold hpb config supported by the device
- * @version - HPB Specification Version
- * @mode - hpb control mode
- * @region_size - HPB Region size[B] = 512B x 2^bHPBRegionSize
- * @max_luns - Maximum number of HPB LU supported by the device <= 0x20
- * @subregion_size - HPB Sub-Region size[B] = 512B x 2^bHPBSubRegionSize
- * @max_active_regions - Maximum number of Active HPB Regions
- * @num_hpb_luns - hpb luns that are configured in the device
- * @hpb_luns - to hold hpb lun config from unit descriptor
- */
-struct ufshpb_config {
- u16 version;
- u8 mode;
- u8 region_size;
- u8 max_luns;
- u8 subregion_size;
- u16 max_active_regions;
- u8 num_hpb_luns;
-};
-
struct ufshpb_lun {
u8 lun;
};
diff --git a/include/scsi/scsi_dh_ufshpb.h b/include/scsi/scsi_dh_ufshpb.h
new file mode 100644
index 0000000..3dcb442
--- /dev/null
+++ b/include/scsi/scsi_dh_ufshpb.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for UFS HPB device handler
+ *
+ * Copyright (C) 2020 Western Digital Corporation or its affiliates.
+ */
+#ifndef _SCSI_DH_UFSHPB_H
+#define _SCSI_DH_UFSHPB_H
+
+#include <scsi/scsi_device.h>
+
+/**
+ * struct ufshpb_lun_conf - to hold hpb lun config from unit descriptor
+ * @lun - lun id
+ * @size - lun size = 2^bLogicalBlockSize x qLogicalBlockCount
+ * @max_active_regions - Maximum Number of Active HPB Regions for that LU
+ * @pinned_starting_idx - HPB Pinned Region Start Offset
+ * @pinned_count - Number of HPB Pinned Regions
+ */
+struct ufshpb_lun_config {
+ u8 lun;
+ u64 size;
+ u8 hpb_lun_idx;
+ u16 max_active_regions;
+ u16 pinned_starting_idx;
+ u16 pinned_count;
+};
+
+/**
+ * struct ufshpb_config - to hold hpb config supported by the device
+ * @version - HPB Specification Version
+ * @mode - hpb control mode
+ * @region_size - HPB Region size[B] = 512B x 2^bHPBRegionSize
+ * @max_luns - Maximum number of HPB LU supported by the device <= 0x20
+ * @subregion_size - HPB Sub-Region size[B] = 512B x 2^bHPBSubRegionSize
+ * @max_active_regions - Maximum number of Active HPB Regions
+ * @num_hpb_luns - hpb luns that are configured in the device
+ * @hpb_luns - to hold hpb lun config from unit descriptor
+ */
+struct ufshpb_config {
+ u16 version;
+ u8 mode;
+ u8 region_size;
+ u8 max_luns;
+ u8 subregion_size;
+ u16 max_active_regions;
+ u8 num_hpb_luns;
+};
+#endif /* _SCSI_DH_UFSHPB_H */
+
--
2.7.4