]> git.ipfire.org Git - thirdparty/u-boot.git/blobdiff - fs/fs.c
Merge branch '2023-12-21-header-inclusion-cleanup' into next
[thirdparty/u-boot.git] / fs / fs.c
diff --git a/fs/fs.c b/fs/fs.c
index 5e80648b5b56ce9b4f3f144f5959cb59e4296ec7..f33b85f92b61dff6326caa5f8cb1483aa80eb74f 100644 (file)
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -7,24 +7,30 @@
 
 #include <command.h>
 #include <config.h>
+#include <display_options.h>
 #include <errno.h>
 #include <common.h>
 #include <env.h>
 #include <lmb.h>
 #include <log.h>
+#include <malloc.h>
 #include <mapmem.h>
 #include <part.h>
 #include <ext4fs.h>
 #include <fat.h>
 #include <fs.h>
 #include <sandboxfs.h>
+#include <semihostingfs.h>
 #include <ubifs_uboot.h>
 #include <btrfs.h>
+#include <asm/global_data.h>
 #include <asm/io.h>
 #include <div64.h>
 #include <linux/math64.h>
+#include <linux/sizes.h>
 #include <efi_loader.h>
 #include <squashfs.h>
+#include <erofs.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -33,10 +39,15 @@ static int fs_dev_part;
 static struct disk_partition fs_partition;
 static int fs_type = FS_TYPE_ANY;
 
+void fs_set_type(int type)
+{
+       fs_type = type;
+}
+
 static inline int fs_probe_unsupported(struct blk_desc *fs_dev_desc,
                                      struct disk_partition *fs_partition)
 {
-       log_err("** Unrecognized filesystem type **\n");
+       log_debug("Unrecognized filesystem type\n");
        return -1;
 }
 
@@ -174,7 +185,7 @@ struct fstype_info {
 };
 
 static struct fstype_info fstypes[] = {
-#ifdef CONFIG_FS_FAT
+#if CONFIG_IS_ENABLED(FS_FAT)
        {
                .fstype = FS_TYPE_FAT,
                .name = "fat",
@@ -226,7 +237,7 @@ static struct fstype_info fstypes[] = {
                .mkdir = fs_mkdir_unsupported,
        },
 #endif
-#ifdef CONFIG_SANDBOX
+#if IS_ENABLED(CONFIG_SANDBOX) && !IS_ENABLED(CONFIG_SPL_BUILD)
        {
                .fstype = FS_TYPE_SANDBOX,
                .name = "sandbox",
@@ -245,6 +256,26 @@ static struct fstype_info fstypes[] = {
                .ln = fs_ln_unsupported,
        },
 #endif
+#ifdef CONFIG_SEMIHOSTING
+       {
+               .fstype = FS_TYPE_SEMIHOSTING,
+               .name = "semihosting",
+               .null_dev_desc_ok = true,
+               .probe = smh_fs_set_blk_dev,
+               .close = fs_close_unsupported,
+               .ls = fs_ls_unsupported,
+               .exists = fs_exists_unsupported,
+               .size = smh_fs_size,
+               .read = smh_fs_read,
+               .write = smh_fs_write,
+               .uuid = fs_uuid_unsupported,
+               .opendir = fs_opendir_unsupported,
+               .unlink = fs_unlink_unsupported,
+               .mkdir = fs_mkdir_unsupported,
+               .ln = fs_ln_unsupported,
+       },
+#endif
+#ifndef CONFIG_SPL_BUILD
 #ifdef CONFIG_CMD_UBIFS
        {
                .fstype = FS_TYPE_UBIFS,
@@ -264,6 +295,8 @@ static struct fstype_info fstypes[] = {
                .ln = fs_ln_unsupported,
        },
 #endif
+#endif
+#ifndef CONFIG_SPL_BUILD
 #ifdef CONFIG_FS_BTRFS
        {
                .fstype = FS_TYPE_BTRFS,
@@ -283,7 +316,8 @@ static struct fstype_info fstypes[] = {
                .ln = fs_ln_unsupported,
        },
 #endif
-#if IS_ENABLED(CONFIG_FS_SQUASHFS)
+#endif
+#if CONFIG_IS_ENABLED(FS_SQUASHFS)
        {
                .fstype = FS_TYPE_SQUASHFS,
                .name = "squashfs",
@@ -303,6 +337,27 @@ static struct fstype_info fstypes[] = {
                .unlink = fs_unlink_unsupported,
                .mkdir = fs_mkdir_unsupported,
        },
+#endif
+#if IS_ENABLED(CONFIG_FS_EROFS)
+       {
+               .fstype = FS_TYPE_EROFS,
+               .name = "erofs",
+               .null_dev_desc_ok = false,
+               .probe = erofs_probe,
+               .opendir = erofs_opendir,
+               .readdir = erofs_readdir,
+               .ls = fs_ls_generic,
+               .read = erofs_read,
+               .size = erofs_size,
+               .close = erofs_close,
+               .closedir = erofs_closedir,
+               .exists = erofs_exists,
+               .uuid = fs_uuid_unsupported,
+               .write = fs_write_unsupported,
+               .ln = fs_ln_unsupported,
+               .unlink = fs_unlink_unsupported,
+               .mkdir = fs_mkdir_unsupported,
+       },
 #endif
        {
                .fstype = FS_TYPE_ANY,
@@ -367,25 +422,9 @@ int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype)
 {
        struct fstype_info *info;
        int part, i;
-#ifdef CONFIG_NEEDS_MANUAL_RELOC
-       static int relocated;
-
-       if (!relocated) {
-               for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes);
-                               i++, info++) {
-                       info->name += gd->reloc_off;
-                       info->probe += gd->reloc_off;
-                       info->close += gd->reloc_off;
-                       info->ls += gd->reloc_off;
-                       info->read += gd->reloc_off;
-                       info->write += gd->reloc_off;
-               }
-               relocated = 1;
-       }
-#endif
 
-       part = blk_get_device_part_str(ifname, dev_part_str, &fs_dev_desc,
-                                       &fs_partition, 1);
+       part = part_get_info_by_dev_and_name_or_num(ifname, dev_part_str, &fs_dev_desc,
+                                                   &fs_partition, 1);
        if (part < 0)
                return -1;
 
@@ -710,17 +749,19 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[],
        if (argc > 7)
                return CMD_RET_USAGE;
 
-       if (fs_set_blk_dev(argv[1], (argc >= 3) ? argv[2] : NULL, fstype))
+       if (fs_set_blk_dev(argv[1], cmd_arg2(argc, argv), fstype)) {
+               log_err("Can't set block device\n");
                return 1;
+       }
 
        if (argc >= 4) {
-               addr = simple_strtoul(argv[3], &ep, 16);
+               addr = hextoul(argv[3], &ep);
                if (ep == argv[3] || *ep != '\0')
                        return CMD_RET_USAGE;
        } else {
                addr_str = env_get("loadaddr");
                if (addr_str != NULL)
-                       addr = simple_strtoul(addr_str, NULL, 16);
+                       addr = hextoul(addr_str, NULL);
                else
                        addr = CONFIG_SYS_LOAD_ADDR;
        }
@@ -734,11 +775,11 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[],
                }
        }
        if (argc >= 6)
-               bytes = simple_strtoul(argv[5], NULL, 16);
+               bytes = hextoul(argv[5], NULL);
        else
                bytes = 0;
        if (argc >= 7)
-               pos = simple_strtoul(argv[6], NULL, 16);
+               pos = hextoul(argv[6], NULL);
        else
                pos = 0;
 
@@ -752,7 +793,8 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[],
 
        if (IS_ENABLED(CONFIG_CMD_BOOTEFI))
                efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
-                               (argc > 4) ? argv[4] : "");
+                               (argc > 4) ? argv[4] : "", map_sysmem(addr, 0),
+                               len_read);
 
        printf("%llu bytes read in %lu ms", len_read, time);
        if (time > 0) {
@@ -776,7 +818,7 @@ int do_ls(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[],
        if (argc > 4)
                return CMD_RET_USAGE;
 
-       if (fs_set_blk_dev(argv[1], (argc >= 3) ? argv[2] : NULL, fstype))
+       if (fs_set_blk_dev(argv[1], cmd_arg2(argc, argv), fstype))
                return 1;
 
        if (fs_ls(argc >= 4 ? argv[3] : "/"))
@@ -811,11 +853,11 @@ int do_save(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[],
        if (fs_set_blk_dev(argv[1], argv[2], fstype))
                return 1;
 
-       addr = simple_strtoul(argv[3], NULL, 16);
+       addr = hextoul(argv[3], NULL);
        filename = argv[4];
-       bytes = simple_strtoul(argv[5], NULL, 16);
+       bytes = hextoul(argv[5], NULL);
        if (argc >= 7)
-               pos = simple_strtoul(argv[6], NULL, 16);
+               pos = hextoul(argv[6], NULL);
        else
                pos = 0;
 
@@ -952,3 +994,59 @@ int do_fs_types(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
        puts("\n");
        return CMD_RET_SUCCESS;
 }
+
+int fs_read_alloc(const char *fname, ulong size, uint align, void **bufp)
+{
+       loff_t bytes_read;
+       ulong addr;
+       char *buf;
+       int ret;
+
+       buf = memalign(align, size + 1);
+       if (!buf)
+               return log_msg_ret("buf", -ENOMEM);
+       addr = map_to_sysmem(buf);
+
+       ret = fs_read(fname, addr, 0, size, &bytes_read);
+       if (ret) {
+               free(buf);
+               return log_msg_ret("read", ret);
+       }
+       if (size != bytes_read)
+               return log_msg_ret("bread", -EIO);
+       buf[size] = '\0';
+
+       *bufp = buf;
+
+       return 0;
+}
+
+int fs_load_alloc(const char *ifname, const char *dev_part_str,
+                 const char *fname, ulong max_size, ulong align, void **bufp,
+                 ulong *sizep)
+{
+       loff_t size;
+       void *buf;
+       int ret;
+
+       if (fs_set_blk_dev(ifname, dev_part_str, FS_TYPE_ANY))
+               return log_msg_ret("set", -ENOMEDIUM);
+
+       ret = fs_size(fname, &size);
+       if (ret)
+               return log_msg_ret("sz", -ENOENT);
+
+       if (size >= (max_size ?: SZ_1G))
+               return log_msg_ret("sz", -E2BIG);
+
+       if (fs_set_blk_dev(ifname, dev_part_str, FS_TYPE_ANY))
+               return log_msg_ret("set", -ENOMEDIUM);
+
+       ret = fs_read_alloc(fname, size, align, &buf);
+       if (ret)
+               return log_msg_ret("al", ret);
+       *sizep = size;
+       *bufp = buf;
+
+       return 0;
+}