mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH 3/5] cdev-alias: add support for storage{.removable,.builtin}
Date: Thu, 11 Dec 2025 22:00:45 +0100	[thread overview]
Message-ID: <20251211210049.3170349-3-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20251211210049.3170349-1-a.fatoum@pengutronix.de>

Our current of global.boot.default expanding to bootsource doesn't work
when booting from boot-only flash. Improve upon this by adding cdev
aliases for removable and builtin storage devices.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 Documentation/user/booting-linux.rst | 25 ++++++++
 common/cdev-alias.c                  | 86 ++++++++++++++++++++++++++++
 include/driver.h                     |  5 ++
 3 files changed, 116 insertions(+)

diff --git a/Documentation/user/booting-linux.rst b/Documentation/user/booting-linux.rst
index b164c538c62a..f1df5ee2bbf0 100644
--- a/Documentation/user/booting-linux.rst
+++ b/Documentation/user/booting-linux.rst
@@ -182,6 +182,31 @@ and configure the overrides as arguments to the ``boot`` command:
 
   boot -o bootm.image=/mnt/tftp/oftree mmc
 
+Generic Boot Targets
+^^^^^^^^^^^^^^^^^^^^
+
+A single boot target can yield multiple entries, e.g., one for each
+bootloader spec file detected at runtime as described in the next section.
+
+There is also a number of generic default boot targets available, when
+``CONFIG_BOOT_DEFAULTS`` is enabled. These expands to a single device at most:
+
+* ``bootsource``: expands to the device barebox booted from
+* ``diskuuid.*``: expands to the device with specified ``*`` diskuuid
+
+For these targets that expand to a single device, a partition can also be specified,
+e.g., ``bootsource.esp`` to reference the partition with the ``esp`` partition
+label within the bootsource.
+
+Following target can expand to multiple devices:
+
+* ``storage.removable``: expands to built-in storage devices, like USB sticks
+* ``storage.builtin``: expands to built-in storage devices, like eMMC
+* ``storage``: expands to all of the above ``storage.*``
+
+If the bootsource exists within any of these targets, it will be the first
+device in the returned list.
+
 .. _bootloader_spec:
 
 Boot Loader Specification
diff --git a/common/cdev-alias.c b/common/cdev-alias.c
index 3732fd90525f..82b91108c1fc 100644
--- a/common/cdev-alias.c
+++ b/common/cdev-alias.c
@@ -9,7 +9,9 @@
 #include <stringlist.h>
 #include <bootsource.h>
 #include <driver.h>
+#include <block.h>
 #include <init.h>
+#include <linux/bits.h>
 
 struct cdev_alias_res {
 	const char *name;
@@ -77,9 +79,93 @@ static int cdev_alias_resolve_diskuuid(struct cdev_alias_res *cdev_alias_res,
 	return ret;
 }
 
+#define STORAGE_REMOVABLE	BIT(0)
+#define STORAGE_BUILTIN		BIT(1)
+
+/**
+ * call_for_each_storage() - invoke callback for each storage medium
+ *
+ * @fn:			callback to invoke
+ * @data:		callback-specific data
+ * @filter:		OR-ed types of STORAGE_* to filter for
+ * @only_bootsource:	If true, include only bootsource if available,
+ *			otherwise omit always
+ * Return:		number of successful callback invocations or a negative error
+ */
+static int call_for_each_storage(cdev_alias_processor_t fn,
+				 void *data,
+				 unsigned filter,
+				 bool only_bootsource)
+{
+	struct cdev *cdev, *bootcdev;
+	int ret, nmatches = 0;
+
+	bootcdev = bootsource_of_cdev_find();
+
+	for_each_cdev(cdev) {
+		struct block_device *bdev;
+
+		if (!cdev_is_storage(cdev) || cdev_is_partition(cdev))
+			continue;
+
+		bdev = cdev_get_block_device(cdev);
+
+		if (((filter & STORAGE_REMOVABLE) && bdev && bdev->removable) ||
+		    ((filter & STORAGE_BUILTIN) && (!bdev || !bdev->removable))) {
+			if (only_bootsource && cdev != bootcdev)
+				continue;
+			if (!only_bootsource && cdev == bootcdev)
+				continue;
+
+			ret = fn(cdev, data);
+			if (ret < 0)
+				return ret;
+			nmatches++;
+
+			/* Got our bootsource, no need to continue iteration */
+			if (only_bootsource)
+				break;
+		}
+	}
+
+	return nmatches;
+}
+
+static int cdev_alias_resolve_storage(struct cdev_alias_res *cdev_alias_res,
+				      const char *class,
+				      cdev_alias_processor_t fn,
+				      void *data)
+{
+	struct cdev *bootcdev;
+	unsigned filter = 0;
+	int bootsource, nmatches;
+
+	if (!class)
+		filter = ~0;
+	else if (streq_ptr(class, "removable"))
+		filter |= STORAGE_REMOVABLE;
+	else if (streq_ptr(class, "builtin"))
+		filter |= STORAGE_BUILTIN;
+	else
+		return -EINVAL;
+
+	bootcdev = bootsource_of_cdev_find();
+
+	bootsource = call_for_each_storage(fn, data, filter, true);
+	if (bootsource < 0)
+		return bootsource;
+
+	nmatches = call_for_each_storage(fn, data, filter, false);
+	if (nmatches < 0)
+		return nmatches;
+
+	return bootsource + nmatches;
+}
+
 static struct cdev_alias_res cdev_alias_aliases[] = {
 	{ "bootsource", cdev_alias_resolve_bootsource },
 	{ "diskuuid", cdev_alias_resolve_diskuuid },
+	{ "storage", cdev_alias_resolve_storage },
 	{ /* sentinel */}
 };
 
diff --git a/include/driver.h b/include/driver.h
index a941ca6127e6..de5a63c379eb 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -597,6 +597,11 @@ get_inheritable_devfs_flags(const struct cdev *parent_cdev)
 	return parent_cdev->flags & DEVFS_INHERITABLE_FLAGS;
 }
 
+static inline bool cdev_is_storage(const struct cdev *cdev)
+{
+	return (cdev->flags & DEVFS_IS_BLOCK_DEV) || cdev->mtd;
+}
+
 struct cdev *
 cdev_find_child_by_gpt_typeuuid(struct cdev *cdev, const guid_t *typeuuid);
 
-- 
2.47.3




  parent reply	other threads:[~2025-12-11 21:01 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-11 21:00 [PATCH 1/5] cdev-alias: support referencing diskuuid without child partition Ahmad Fatoum
2025-12-11 21:00 ` [PATCH 2/5] cdev-alias: fix memory leak in diskuuid handling Ahmad Fatoum
2025-12-11 21:00 ` Ahmad Fatoum [this message]
2025-12-12  8:32   ` [PATCH 3/5] cdev-alias: add support for storage{.removable,.builtin} Sascha Hauer
2025-12-11 21:00 ` [PATCH 4/5] boot: try builtin and removable media before net for boot.default Ahmad Fatoum
2025-12-11 21:00 ` [PATCH 5/5] boot: assign names to bootentry providers Ahmad Fatoum
2025-12-12  8:36 ` [PATCH 1/5] cdev-alias: support referencing diskuuid without child partition 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=20251211210049.3170349-3-a.fatoum@pengutronix.de \
    --to=a.fatoum@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /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