diff options
Diffstat (limited to 'drivers/misc/fs_loader.c')
-rw-r--r-- | drivers/misc/fs_loader.c | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/drivers/misc/fs_loader.c b/drivers/misc/fs_loader.c index 66803f4b997..32aff35835b 100644 --- a/drivers/misc/fs_loader.c +++ b/drivers/misc/fs_loader.c @@ -148,7 +148,7 @@ static int _request_firmware_prepare(struct udevice *dev, */ static int fw_get_filesystem_firmware(struct udevice *dev) { - loff_t actread; + loff_t actread = 0; char *storage_interface, *dev_part, *ubi_mtdpart, *ubi_volume; int ret; @@ -228,6 +228,53 @@ int request_firmware_into_buf(struct udevice *dev, return ret; } +int request_firmware_into_buf_via_script(void **buf, size_t max_size, + const char *script_name, + size_t *retsize) +{ + char *args[2] = { "run", (char *)script_name }; + int ret, repeatable; + ulong addr, size; + + if (!buf || !script_name || !max_size) + return -EINVAL; + + /* Run the firmware loading script */ + ret = cmd_process(0, 2, args, &repeatable, NULL); + if (ret) { + log_err("Firmware loading script '%s' not defined or failed.\n", + script_name); + return -EINVAL; + } + + /* Find out where the firmware got loaded and how long it is */ + addr = env_get_hex("fw_addr", 0); + size = env_get_hex("fw_size", 0); + + /* Clear the variables set by the firmware loading script */ + env_set("fw_addr", NULL); + env_set("fw_size", NULL); + + if (!addr || !size) { + log_err("Firmware address (0x%lx) or size (0x%lx) are invalid.\n", + addr, size); + return -EINVAL; + } + + if (size > max_size) { + log_err("Loaded firmware size 0x%lx exceeded maximum allowed size 0x%zx.\n", + size, max_size); + return -E2BIG; + } + + if (retsize) + *retsize = size; + + memcpy(*buf, (void *)addr, size); + + return 0; +} + static int fs_loader_of_to_plat(struct udevice *dev) { u32 phandlepart[2]; |