From: Christian Marangi <ansuelsmth@gmail.com>
To: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>,
Christian Marangi <ansuelsmth@gmail.com>,
Quentin Schulz <quentin.schulz@cherry.de>,
Peng Fan <peng.fan@nxp.com>,
Casey Connolly <casey.connolly@linaro.org>,
Jonas Karlman <jonas@kwiboo.se>,
Jamie Gibbons <jamie.gibbons@microchip.com>,
Neha Malcom Francis <n-francis@ti.com>,
Justin Klaassen <justin@tidylabs.net>,
Harsha Vardhan V M <h-vm@ti.com>,
Leo Yu-Chi Liang <ycliang@andestech.com>,
Weijie Gao <weijie.gao@mediatek.com>,
Marek Vasut <marek.vasut+renesas@mailbox.org>,
Alif Zakuan Yuslaimi <alif.zakuan.yuslaimi@altera.com>,
"Lucien.Jheng" <lucienzx159@gmail.com>,
u-boot@lists.denx.de
Subject: [PATCH v3 5/5] misc: fw_loader: implement request_firmware_size() OP
Date: Tue, 17 Mar 2026 16:36:09 +0100 [thread overview]
Message-ID: <20260317153614.18409-6-ansuelsmth@gmail.com> (raw)
In-Reply-To: <20260317153614.18409-1-ansuelsmth@gmail.com>
It might be useful to get the firmware size before reading it to allocate
the correct size. This is needed for case where the firmware size change
across different firmware version and is not always the same. In such case
the only way to handle this scenario is to allocate a big-enough buffer to
read the firmware.
To better handle this, introduce the request_firmware_size() OP to get the
firmware size before reading it. This way proper buffer can be allocated
and dynamic firmware size can be better supported.
Both FS and FIP lodaer are updated to handle the new .get_size() handler.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/misc/fw_loader/fip_loader.c | 29 ++++++++++++
drivers/misc/fw_loader/fs_loader.c | 70 ++++++++++++++++++++++++-----
drivers/misc/fw_loader/fw_loader.c | 20 +++++++++
drivers/misc/fw_loader/internal.h | 1 +
include/fw_loader.h | 9 ++++
5 files changed, 118 insertions(+), 11 deletions(-)
diff --git a/drivers/misc/fw_loader/fip_loader.c b/drivers/misc/fw_loader/fip_loader.c
index 5c01013276d7..b50c89c892d6 100644
--- a/drivers/misc/fw_loader/fip_loader.c
+++ b/drivers/misc/fw_loader/fip_loader.c
@@ -495,6 +495,34 @@ static int fw_get_fip_firmware(struct udevice *dev)
return ret;
}
+/**
+ * fw_get_fip_firmware_size - get firmware size.
+ * @dev: An instance of a driver.
+ *
+ * Return: Size of firmware, negative value when error.
+ */
+static int fw_get_fip_firmware_size(struct udevice *dev)
+{
+ struct fip_toc_entry ent;
+ struct fip_storage_info info = { };
+ int ret;
+
+ ret = fw_parse_storage_info(dev, &info);
+ if (ret)
+ return ret;
+
+ struct firmware *firmwarep = dev_get_priv(dev);
+
+ if (!firmwarep)
+ return -EINVAL;
+
+ ret = parse_fip_firmware(firmwarep, &info, &ent);
+ if (ret)
+ return ret;
+
+ return ent.size;
+}
+
static int fip_loader_probe(struct udevice *dev)
{
struct device_plat *plat = dev_get_plat(dev);
@@ -505,6 +533,7 @@ static int fip_loader_probe(struct udevice *dev)
return ret;
plat->get_firmware = fw_get_fip_firmware;
+ plat->get_size = fw_get_fip_firmware_size;
return 0;
};
diff --git a/drivers/misc/fw_loader/fs_loader.c b/drivers/misc/fw_loader/fs_loader.c
index 429abc4f60cd..434e0afbfe2a 100644
--- a/drivers/misc/fw_loader/fs_loader.c
+++ b/drivers/misc/fw_loader/fs_loader.c
@@ -92,15 +92,8 @@ static int select_fs_dev(struct device_plat *plat)
return ret;
}
-/**
- * fw_get_filesystem_firmware - load firmware into an allocated buffer.
- * @dev: An instance of a driver.
- *
- * Return: Size of total read, negative value when error.
- */
-static int fw_get_filesystem_firmware(struct udevice *dev)
+static int __fw_get_filesystem_firmware_prepare(struct udevice *dev)
{
- loff_t actread = 0;
char *storage_interface, *dev_part, *ubi_mtdpart, *ubi_volume;
int ret;
@@ -125,6 +118,28 @@ static int fw_get_filesystem_firmware(struct udevice *dev)
ret = select_fs_dev(dev_get_plat(dev));
}
+ return ret;
+}
+
+static void __fw_get_filesystem_firmware_release(struct udevice *dev)
+{
+#ifdef CONFIG_CMD_UBIFS
+ umount_ubifs();
+#endif
+}
+
+/**
+ * fw_get_filesystem_firmware - load firmware into an allocated buffer.
+ * @dev: An instance of a driver.
+ *
+ * Return: Size of total read, negative value when error.
+ */
+static int fw_get_filesystem_firmware(struct udevice *dev)
+{
+ loff_t actread = 0;
+ int ret;
+
+ ret = __fw_get_filesystem_firmware_prepare(dev);
if (ret)
goto out;
@@ -146,9 +161,41 @@ static int fw_get_filesystem_firmware(struct udevice *dev)
}
out:
-#ifdef CONFIG_CMD_UBIFS
- umount_ubifs();
-#endif
+ __fw_get_filesystem_firmware_release(dev);
+ return ret;
+}
+
+/**
+ * fw_get_filesystem_firmware_size - get firmware size.
+ * @dev: An instance of a driver.
+ *
+ * Return: Size of firmware, negative value when error.
+ */
+static int fw_get_filesystem_firmware_size(struct udevice *dev)
+{
+ loff_t size = 0;
+ int ret;
+
+ ret = __fw_get_filesystem_firmware_prepare(dev);
+ if (ret)
+ goto out;
+
+ struct firmware *firmwarep = dev_get_priv(dev);
+
+ if (!firmwarep)
+ return -ENOMEM;
+
+ ret = fs_size(firmwarep->name, &size);
+
+ if (ret) {
+ debug("Error: %d Failed to get size for %s.\n",
+ ret, firmwarep->name);
+ } else {
+ ret = size;
+ }
+
+out:
+ __fw_get_filesystem_firmware_release(dev);
return ret;
}
@@ -162,6 +209,7 @@ static int fs_loader_probe(struct udevice *dev)
return ret;
plat->get_firmware = fw_get_filesystem_firmware;
+ plat->get_size = fw_get_filesystem_firmware_size;
return 0;
};
diff --git a/drivers/misc/fw_loader/fw_loader.c b/drivers/misc/fw_loader/fw_loader.c
index 26c2ce406ac9..c761fb1ff281 100644
--- a/drivers/misc/fw_loader/fw_loader.c
+++ b/drivers/misc/fw_loader/fw_loader.c
@@ -185,3 +185,23 @@ int request_firmware_into_buf(struct udevice *dev,
return plat->get_firmware(dev);
}
+
+int request_firmware_size(struct udevice *dev, const char *name)
+{
+ struct device_plat *plat;
+ int ret;
+
+ if (!dev)
+ return -EINVAL;
+
+ ret = _request_firmware_prepare(dev, name, NULL, 0, 0);
+ if (ret < 0) /* error */
+ return ret;
+
+ plat = dev_get_plat(dev);
+
+ if (!plat->get_size)
+ return -EOPNOTSUPP;
+
+ return plat->get_size(dev);
+}
diff --git a/drivers/misc/fw_loader/internal.h b/drivers/misc/fw_loader/internal.h
index 9e7585a92808..d823d56e53f5 100644
--- a/drivers/misc/fw_loader/internal.h
+++ b/drivers/misc/fw_loader/internal.h
@@ -36,6 +36,7 @@ struct device_plat {
char *ubivol;
int (*get_firmware)(struct udevice *dev);
+ int (*get_size)(struct udevice *dev);
};
/**
diff --git a/include/fw_loader.h b/include/fw_loader.h
index 7053c7bc6f05..1af3db385161 100644
--- a/include/fw_loader.h
+++ b/include/fw_loader.h
@@ -39,6 +39,15 @@ int request_firmware_into_buf(struct udevice *dev,
const char *name,
void *buf, size_t size, u32 offset);
+/**
+ * request_firmware_size - Get firmware size.
+ * @dev: An instance of a driver.
+ * @name: Name of firmware file.
+ *
+ * Return: Size of firmware, negative value when error.
+ */
+int request_firmware_size(struct udevice *dev, const char *name);
+
/**
* request_firmware_into_buf_via_script() -
* Load firmware using a U-Boot script and copy to buffer
--
2.53.0
next prev parent reply other threads:[~2026-03-17 15:37 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-17 15:36 [PATCH v3 0/5] misc: fs_loader: reorg and split to FS and FW loader + FIP loader Christian Marangi
2026-03-17 15:36 ` [PATCH v3 1/5] misc: fs_loader: fix ubifs not unmounted on dev_get_priv error Christian Marangi
2026-03-17 15:36 ` [PATCH v3 2/5] misc: fs_loader: reorganize and split to FS and FW loader Christian Marangi
2026-03-17 15:36 ` [PATCH v3 3/5] misc: fw_loader: implement generic get_fw_loader_from_node() Christian Marangi
2026-03-17 15:36 ` [PATCH v3 4/5] misc: fw_loader: introduce FIP loader driver Christian Marangi
2026-03-17 15:36 ` Christian Marangi [this message]
2026-03-30 23:07 ` [PATCH v3 0/5] misc: fs_loader: reorg and split to FS and FW loader + FIP loader Tom Rini
2026-03-31 7:54 ` Christian Marangi
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=20260317153614.18409-6-ansuelsmth@gmail.com \
--to=ansuelsmth@gmail.com \
--cc=alif.zakuan.yuslaimi@altera.com \
--cc=casey.connolly@linaro.org \
--cc=h-vm@ti.com \
--cc=jamie.gibbons@microchip.com \
--cc=jonas@kwiboo.se \
--cc=justin@tidylabs.net \
--cc=lucienzx159@gmail.com \
--cc=marek.vasut+renesas@mailbox.org \
--cc=n-francis@ti.com \
--cc=peng.fan@nxp.com \
--cc=quentin.schulz@cherry.de \
--cc=sjg@chromium.org \
--cc=trini@konsulko.com \
--cc=u-boot@lists.denx.de \
--cc=weijie.gao@mediatek.com \
--cc=ycliang@andestech.com \
/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