mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: Barebox List <barebox@lists.infradead.org>
Cc: Michael Olbrich <mol@pengutronix.de>
Subject: [PATCH 8/8] misc: Add storage-by-uuid driver
Date: Mon,  7 Feb 2022 10:49:53 +0100	[thread overview]
Message-ID: <20220207094953.949868-8-s.hauer@pengutronix.de> (raw)
In-Reply-To: <20220207094953.949868-1-s.hauer@pengutronix.de>

This adds a driver which matches to a "barebox,storage-by-uuid"
compatible node. The driver looks for a storage device matching the
given UUID and when found registers a new cdev for the device.

This driver solved a very specific problem. On EFI the storage devices
are not connected to any device tree node. barebox-state however expects
a node to use as its backend. The obvious solution would be to create
a partition with a specific partuuid and use that for state, in our
special usecase though the storage device is partitioned with a MBR
which doesn't have any space left to create a new partition. As this
driver parses the of partition binding we can use that to create
a partition in an unallocated are of the disk which is then used for
state.

This driver has the problem that it depends on storage devices which
are not described in the device tree. This means it cannot work with
deep probe. This is not a problem on EFI though. It's a special purpose
driver, it's not recommended for general use.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/misc/Kconfig           |  23 ++++
 drivers/misc/Makefile          |   1 +
 drivers/misc/storage-by-uuid.c | 199 +++++++++++++++++++++++++++++++++
 3 files changed, 223 insertions(+)
 create mode 100644 drivers/misc/storage-by-uuid.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 5ab0506cd9..78c9c193d8 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -47,4 +47,27 @@ config STARFIVE_PWRSEQ
 	  be accessed over /dev/mem or used from kernels which still depend
 	  on bootloader for initialization.
 
+config STORAGE_BY_UUID
+	bool "storage by UUID"
+	depends on OFDEVICE
+	help
+	  This adds a driver which matches to a "barebox,storage-by-uuid"
+	  compatible node. The driver looks for a storage device matching the
+	  given UUID and when found registers a new cdev for the device.
+
+	  This driver solved a very specific problem. On EFI the storage devices
+	  are not connected to any device tree node. barebox-state however expects
+	  a node to use as its backend. The obvious solution would be to create
+	  a partition with a specific partuuid and use that for state, in our
+	  special usecase though the storage device is partitioned with a MBR
+	  which doesn't have any space left to create a new partition. As this
+	  driver parses the of partition binding we can use that to create
+	  a partition in an unallocated are of the disk which is then used for
+	  state.
+
+	  This driver has the problem that it depends on storage devices which
+	  are not described in the device tree. This means it cannot work with
+	  deep probe. This is not a problem on EFI though. It's a special purpose
+	  driver, it's not recommended for general use.
+
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 6326e784fc..986f7b1b38 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_STATE_DRV)		+= state.o
 obj-$(CONFIG_DEV_MEM)		+= mem.o
 obj-$(CONFIG_UBOOTVAR)		+= ubootvar.o
 obj-$(CONFIG_STARFIVE_PWRSEQ)	+= starfive-pwrseq.o
+obj-$(CONFIG_STORAGE_BY_UUID)	+= storage-by-uuid.o
diff --git a/drivers/misc/storage-by-uuid.c b/drivers/misc/storage-by-uuid.c
new file mode 100644
index 0000000000..c9dd6e9793
--- /dev/null
+++ b/drivers/misc/storage-by-uuid.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <of.h>
+#include <malloc.h>
+#include <partition.h>
+#include <envfs.h>
+#include <fs.h>
+
+static LIST_HEAD(sbu_list);
+
+struct sbu {
+	char *uuid;
+	struct device_d *dev;
+	struct cdev *rcdev;
+	struct cdev cdev;
+	struct list_head list;
+};
+
+void storage_by_uuid_check_exist(struct cdev *cdev);
+
+static ssize_t sbu_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags)
+{
+	struct sbu *sbu = cdev->priv;
+
+	return cdev_read(sbu->rcdev, buf, count, offset, flags);
+}
+
+static ssize_t sbu_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags)
+{
+	struct sbu *sbu = cdev->priv;
+
+	return cdev_write(sbu->rcdev, buf, count, offset, flags);
+}
+
+static int sbu_ioctl(struct cdev *cdev, int request, void *buf)
+{
+	struct sbu *sbu = cdev->priv;
+
+	return cdev_ioctl(sbu->rcdev, request, buf);
+}
+
+static int sbu_open(struct cdev *cdev, unsigned long flags)
+{
+	struct sbu *sbu = cdev->priv;
+
+	return cdev_open(sbu->rcdev, flags);
+}
+
+static int sbu_close(struct cdev *cdev)
+{
+	struct sbu *sbu = cdev->priv;
+
+	cdev_close(sbu->rcdev);
+
+	return 0;
+}
+
+static int sbu_flush(struct cdev *cdev)
+{
+	struct sbu *sbu = cdev->priv;
+
+	return cdev_flush(sbu->rcdev);
+}
+
+static int sbu_erase(struct cdev *cdev, loff_t count, loff_t offset)
+{
+	struct sbu *sbu = cdev->priv;
+
+	return cdev_erase(sbu->rcdev, count, offset);
+}
+
+static int sbu_protect(struct cdev *cdev, size_t count, loff_t offset, int prot)
+{
+	struct sbu *sbu = cdev->priv;
+
+	return cdev_protect(sbu->rcdev, count, offset, prot);
+}
+
+static int sbu_discard_range(struct cdev *cdev, loff_t count, loff_t offset)
+{
+	struct sbu *sbu = cdev->priv;
+
+	return cdev_discard_range(sbu->rcdev, count, offset);
+}
+
+static int sbu_memmap(struct cdev *cdev, void **map, int flags)
+{
+	struct sbu *sbu = cdev->priv;
+
+	return cdev_memmap(sbu->rcdev, map, flags);
+}
+
+static int sbu_truncate(struct cdev *cdev, size_t size)
+{
+	struct sbu *sbu = cdev->priv;
+
+	return cdev_truncate(sbu->rcdev, size);
+}
+
+static struct cdev_operations sbu_ops = {
+        .read = sbu_read,
+        .write = sbu_write,
+        .ioctl = sbu_ioctl,
+        .open = sbu_open,
+        .close = sbu_close,
+        .flush = sbu_flush,
+        .erase = sbu_erase,
+        .protect = sbu_protect,
+        .discard_range = sbu_discard_range,
+        .memmap = sbu_memmap,
+        .truncate = sbu_truncate,
+};
+
+static void storage_by_uuid_add_partitions(struct sbu *sbu, struct cdev *rcdev)
+{
+	int ret;
+
+	if (sbu->rcdev)
+		return;
+
+	sbu->rcdev = rcdev;
+	sbu->cdev.name = sbu->uuid;
+	sbu->cdev.size = rcdev->size;
+	sbu->cdev.ops = &sbu_ops;
+	sbu->cdev.dev = sbu->dev;
+	sbu->cdev.priv = sbu;
+
+	ret = devfs_create(&sbu->cdev);
+	if (ret) {
+		dev_err(sbu->dev, "Failed to create cdev: %s\n", strerror(-ret));
+		return;
+	}
+
+	of_parse_partitions(&sbu->cdev, sbu->dev->device_node);
+}
+
+static void check_exist(struct sbu *sbu)
+{
+	struct cdev *cdev;
+
+	for_each_cdev(cdev) {
+		if (!strcmp(cdev->uuid, sbu->uuid)) {
+			dev_dbg(sbu->dev, "Found %s %s\n", cdev->name, cdev->uuid);
+			storage_by_uuid_add_partitions(sbu, cdev);
+		}
+	}
+}
+
+static int sbu_detect(struct device_d *dev)
+{
+	struct sbu *sbu = dev->priv;
+
+	dev_dbg(dev, "%s\n", __func__);
+
+	check_exist(sbu);
+
+	return 0;
+}
+
+static int storage_by_uuid_probe(struct device_d *dev)
+{
+	struct sbu *sbu;
+	int ret;
+	const char *uuid;
+
+	sbu = xzalloc(sizeof(*sbu));
+
+	ret = of_property_read_string(dev->device_node, "uuid", &uuid);
+	if (ret)
+		return ret;
+
+	sbu->dev = dev;
+	sbu->uuid = xstrdup(uuid);
+
+	list_add_tail(&sbu->list, &sbu_list);
+
+	check_exist(sbu);
+	dev->priv = sbu;
+	dev->detect = sbu_detect;
+
+	return 0;
+}
+
+static struct of_device_id storage_by_uuid_dt_ids[] = {
+	{
+		.compatible = "barebox,storage-by-uuid",
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct driver_d storage_by_uuid_driver = {
+	.name		= "storage-by-uuid",
+	.probe		= storage_by_uuid_probe,
+	.of_compatible	= storage_by_uuid_dt_ids,
+};
+device_platform_driver(storage_by_uuid_driver);
-- 
2.30.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


  parent reply	other threads:[~2022-02-07  9:52 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-07  9:49 [PATCH 1/8] cdev: rename partuuid to uuid Sascha Hauer
2022-02-07  9:49 ` [PATCH 2/8] cdev: add diskuuid support Sascha Hauer
2022-02-07  9:49 ` [PATCH 3/8] rename cdev_open() -> cdev_open_name() Sascha Hauer
2022-02-07 10:43   ` Ahmad Fatoum
2022-02-07  9:49 ` [PATCH 4/8] cdev: implement cdev_open() Sascha Hauer
2022-02-07 10:46   ` Ahmad Fatoum
2022-02-07  9:49 ` [PATCH 5/8] driver: Add functions to free devices Sascha Hauer
2022-02-07  9:49 ` [PATCH 6/8] cdev: Create missing cdev_* functions Sascha Hauer
2022-02-07  9:49 ` [PATCH 7/8] cdev: create iterator for cdev list Sascha Hauer
2022-02-07  9:49 ` Sascha Hauer [this message]
2022-02-07  9:52   ` [PATCH 8/8] misc: Add storage-by-uuid driver Sascha Hauer
2022-02-07 10:59   ` [PATCH] efi: probe devices from the device-tree Michael Olbrich
2022-02-08  9:29   ` [PATCH 8/8] misc: Add storage-by-uuid driver Michael Olbrich
2022-02-08 12:27     ` Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220207094953.949868-8-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    --cc=mol@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox