183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0
2045fa1e1SStephen Warren /*
3045fa1e1SStephen Warren * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
4045fa1e1SStephen Warren */
5045fa1e1SStephen Warren
6045fa1e1SStephen Warren #include <config.h>
759e890efSChristian Gmeiner #include <errno.h>
8045fa1e1SStephen Warren #include <common.h>
90eb25b61SJoe Hershberger #include <mapmem.h>
10045fa1e1SStephen Warren #include <part.h>
11045fa1e1SStephen Warren #include <ext4fs.h>
12045fa1e1SStephen Warren #include <fat.h>
13045fa1e1SStephen Warren #include <fs.h>
1492ccc96bSSimon Glass #include <sandboxfs.h>
15251cee0dSHans de Goede #include <ubifs_uboot.h>
160c936ee3SMarek Behún #include <btrfs.h>
17117e0507SSimon Glass #include <asm/io.h>
189e374e7bSTom Rini #include <div64.h>
199e374e7bSTom Rini #include <linux/math64.h>
20045fa1e1SStephen Warren
21a1b231ceSStephen Warren DECLARE_GLOBAL_DATA_PTR;
22a1b231ceSStephen Warren
234101f687SSimon Glass static struct blk_desc *fs_dev_desc;
244bbcc965SRob Clark static int fs_dev_part;
25045fa1e1SStephen Warren static disk_partition_t fs_partition;
26045fa1e1SStephen Warren static int fs_type = FS_TYPE_ANY;
27045fa1e1SStephen Warren
fs_probe_unsupported(struct blk_desc * fs_dev_desc,disk_partition_t * fs_partition)284101f687SSimon Glass static inline int fs_probe_unsupported(struct blk_desc *fs_dev_desc,
292ded0d47SSimon Glass disk_partition_t *fs_partition)
30436e2b73SSimon Glass {
31436e2b73SSimon Glass printf("** Unrecognized filesystem type **\n");
32436e2b73SSimon Glass return -1;
33436e2b73SSimon Glass }
34436e2b73SSimon Glass
fs_ls_unsupported(const char * dirname)35045fa1e1SStephen Warren static inline int fs_ls_unsupported(const char *dirname)
36045fa1e1SStephen Warren {
37045fa1e1SStephen Warren return -1;
38045fa1e1SStephen Warren }
39045fa1e1SStephen Warren
4089191d62SRob Clark /* generic implementation of ls in terms of opendir/readdir/closedir */
4189191d62SRob Clark __maybe_unused
fs_ls_generic(const char * dirname)4289191d62SRob Clark static int fs_ls_generic(const char *dirname)
4389191d62SRob Clark {
4489191d62SRob Clark struct fs_dir_stream *dirs;
4589191d62SRob Clark struct fs_dirent *dent;
4689191d62SRob Clark int nfiles = 0, ndirs = 0;
4789191d62SRob Clark
4889191d62SRob Clark dirs = fs_opendir(dirname);
4989191d62SRob Clark if (!dirs)
5089191d62SRob Clark return -errno;
5189191d62SRob Clark
5289191d62SRob Clark while ((dent = fs_readdir(dirs))) {
5389191d62SRob Clark if (dent->type == FS_DT_DIR) {
5489191d62SRob Clark printf(" %s/\n", dent->name);
5589191d62SRob Clark ndirs++;
5689191d62SRob Clark } else {
5789191d62SRob Clark printf(" %8lld %s\n", dent->size, dent->name);
5889191d62SRob Clark nfiles++;
5989191d62SRob Clark }
6089191d62SRob Clark }
6189191d62SRob Clark
6289191d62SRob Clark fs_closedir(dirs);
6389191d62SRob Clark
6489191d62SRob Clark printf("\n%d file(s), %d dir(s)\n\n", nfiles, ndirs);
6589191d62SRob Clark
6689191d62SRob Clark return 0;
6789191d62SRob Clark }
6889191d62SRob Clark
fs_exists_unsupported(const char * filename)696152916aSStephen Warren static inline int fs_exists_unsupported(const char *filename)
706152916aSStephen Warren {
716152916aSStephen Warren return 0;
726152916aSStephen Warren }
736152916aSStephen Warren
fs_size_unsupported(const char * filename,loff_t * size)74d455d878SSuriyan Ramasami static inline int fs_size_unsupported(const char *filename, loff_t *size)
75cf659819SStephen Warren {
76cf659819SStephen Warren return -1;
77cf659819SStephen Warren }
78cf659819SStephen Warren
fs_read_unsupported(const char * filename,void * buf,loff_t offset,loff_t len,loff_t * actread)79117e0507SSimon Glass static inline int fs_read_unsupported(const char *filename, void *buf,
80d455d878SSuriyan Ramasami loff_t offset, loff_t len,
81d455d878SSuriyan Ramasami loff_t *actread)
82045fa1e1SStephen Warren {
83045fa1e1SStephen Warren return -1;
84045fa1e1SStephen Warren }
85045fa1e1SStephen Warren
fs_write_unsupported(const char * filename,void * buf,loff_t offset,loff_t len,loff_t * actwrite)86a8f6ab52SSimon Glass static inline int fs_write_unsupported(const char *filename, void *buf,
87d455d878SSuriyan Ramasami loff_t offset, loff_t len,
88d455d878SSuriyan Ramasami loff_t *actwrite)
89a8f6ab52SSimon Glass {
90a8f6ab52SSimon Glass return -1;
91a8f6ab52SSimon Glass }
92a8f6ab52SSimon Glass
fs_close_unsupported(void)93436e2b73SSimon Glass static inline void fs_close_unsupported(void)
94436e2b73SSimon Glass {
95436e2b73SSimon Glass }
96436e2b73SSimon Glass
fs_uuid_unsupported(char * uuid_str)9759e890efSChristian Gmeiner static inline int fs_uuid_unsupported(char *uuid_str)
9859e890efSChristian Gmeiner {
9959e890efSChristian Gmeiner return -1;
10059e890efSChristian Gmeiner }
10159e890efSChristian Gmeiner
fs_opendir_unsupported(const char * filename,struct fs_dir_stream ** dirs)1024bbcc965SRob Clark static inline int fs_opendir_unsupported(const char *filename,
1034bbcc965SRob Clark struct fs_dir_stream **dirs)
1044bbcc965SRob Clark {
1054bbcc965SRob Clark return -EACCES;
1064bbcc965SRob Clark }
1074bbcc965SRob Clark
fs_unlink_unsupported(const char * filename)108e2519dafSAKASHI Takahiro static inline int fs_unlink_unsupported(const char *filename)
109e2519dafSAKASHI Takahiro {
110e2519dafSAKASHI Takahiro return -1;
111e2519dafSAKASHI Takahiro }
112e2519dafSAKASHI Takahiro
fs_mkdir_unsupported(const char * dirname)113e7074cffSAKASHI Takahiro static inline int fs_mkdir_unsupported(const char *dirname)
114e7074cffSAKASHI Takahiro {
115e7074cffSAKASHI Takahiro return -1;
116e7074cffSAKASHI Takahiro }
117e7074cffSAKASHI Takahiro
118436e2b73SSimon Glass struct fstype_info {
119045fa1e1SStephen Warren int fstype;
1201a1ad8e0SSjoerd Simons char *name;
121377202b5SStephen Warren /*
122377202b5SStephen Warren * Is it legal to pass NULL as .probe()'s fs_dev_desc parameter? This
123377202b5SStephen Warren * should be false in most cases. For "virtual" filesystems which
124377202b5SStephen Warren * aren't based on a U-Boot block device (e.g. sandbox), this can be
125ca230b09SHeinrich Schuchardt * set to true. This should also be true for the dummy entry at the end
126377202b5SStephen Warren * of fstypes[], since that is essentially a "virtual" (non-existent)
127377202b5SStephen Warren * filesystem.
128377202b5SStephen Warren */
129377202b5SStephen Warren bool null_dev_desc_ok;
1304101f687SSimon Glass int (*probe)(struct blk_desc *fs_dev_desc,
1312ded0d47SSimon Glass disk_partition_t *fs_partition);
132436e2b73SSimon Glass int (*ls)(const char *dirname);
1336152916aSStephen Warren int (*exists)(const char *filename);
134d455d878SSuriyan Ramasami int (*size)(const char *filename, loff_t *size);
135d455d878SSuriyan Ramasami int (*read)(const char *filename, void *buf, loff_t offset,
136d455d878SSuriyan Ramasami loff_t len, loff_t *actread);
137d455d878SSuriyan Ramasami int (*write)(const char *filename, void *buf, loff_t offset,
138d455d878SSuriyan Ramasami loff_t len, loff_t *actwrite);
139436e2b73SSimon Glass void (*close)(void);
14059e890efSChristian Gmeiner int (*uuid)(char *uuid_str);
1414bbcc965SRob Clark /*
1424bbcc965SRob Clark * Open a directory stream. On success return 0 and directory
1434bbcc965SRob Clark * stream pointer via 'dirsp'. On error, return -errno. See
1444bbcc965SRob Clark * fs_opendir().
1454bbcc965SRob Clark */
1464bbcc965SRob Clark int (*opendir)(const char *filename, struct fs_dir_stream **dirsp);
1474bbcc965SRob Clark /*
1484bbcc965SRob Clark * Read next entry from directory stream. On success return 0
1494bbcc965SRob Clark * and directory entry pointer via 'dentp'. On error return
1504bbcc965SRob Clark * -errno. See fs_readdir().
1514bbcc965SRob Clark */
1524bbcc965SRob Clark int (*readdir)(struct fs_dir_stream *dirs, struct fs_dirent **dentp);
1534bbcc965SRob Clark /* see fs_closedir() */
1544bbcc965SRob Clark void (*closedir)(struct fs_dir_stream *dirs);
155e2519dafSAKASHI Takahiro int (*unlink)(const char *filename);
156e7074cffSAKASHI Takahiro int (*mkdir)(const char *dirname);
157436e2b73SSimon Glass };
158436e2b73SSimon Glass
159436e2b73SSimon Glass static struct fstype_info fstypes[] = {
160436e2b73SSimon Glass #ifdef CONFIG_FS_FAT
161045fa1e1SStephen Warren {
162045fa1e1SStephen Warren .fstype = FS_TYPE_FAT,
1631a1ad8e0SSjoerd Simons .name = "fat",
164377202b5SStephen Warren .null_dev_desc_ok = false,
165e6d52415SSimon Glass .probe = fat_set_blk_dev,
166e6d52415SSimon Glass .close = fat_close,
16789191d62SRob Clark .ls = fs_ls_generic,
168b7b5f319SStephen Warren .exists = fat_exists,
169cf659819SStephen Warren .size = fat_size,
170e6d52415SSimon Glass .read = fat_read_file,
171d8c3ea99STien Fong Chee #if CONFIG_IS_ENABLED(FAT_WRITE)
172d455d878SSuriyan Ramasami .write = file_fat_write,
173f8240ce9SAKASHI Takahiro .unlink = fat_unlink,
17431a18d57SAKASHI Takahiro .mkdir = fat_mkdir,
175d455d878SSuriyan Ramasami #else
176bd6fb31fSStephen Warren .write = fs_write_unsupported,
177f8240ce9SAKASHI Takahiro .unlink = fs_unlink_unsupported,
17831a18d57SAKASHI Takahiro .mkdir = fs_mkdir_unsupported,
179d455d878SSuriyan Ramasami #endif
18059e890efSChristian Gmeiner .uuid = fs_uuid_unsupported,
18189191d62SRob Clark .opendir = fat_opendir,
18289191d62SRob Clark .readdir = fat_readdir,
18389191d62SRob Clark .closedir = fat_closedir,
184045fa1e1SStephen Warren },
185436e2b73SSimon Glass #endif
186cafc429fSTien Fong Chee
187cafc429fSTien Fong Chee #if CONFIG_IS_ENABLED(FS_EXT4)
188045fa1e1SStephen Warren {
189045fa1e1SStephen Warren .fstype = FS_TYPE_EXT,
1901a1ad8e0SSjoerd Simons .name = "ext4",
191377202b5SStephen Warren .null_dev_desc_ok = false,
192e6d52415SSimon Glass .probe = ext4fs_probe,
193e6d52415SSimon Glass .close = ext4fs_close,
194436e2b73SSimon Glass .ls = ext4fs_ls,
19555af5c93SStephen Warren .exists = ext4fs_exists,
196cf659819SStephen Warren .size = ext4fs_size,
197e6d52415SSimon Glass .read = ext4_read_file,
198d455d878SSuriyan Ramasami #ifdef CONFIG_CMD_EXT4_WRITE
199d455d878SSuriyan Ramasami .write = ext4_write_file,
200d455d878SSuriyan Ramasami #else
201bd6fb31fSStephen Warren .write = fs_write_unsupported,
202d455d878SSuriyan Ramasami #endif
20359e890efSChristian Gmeiner .uuid = ext4fs_uuid,
2044bbcc965SRob Clark .opendir = fs_opendir_unsupported,
205e2519dafSAKASHI Takahiro .unlink = fs_unlink_unsupported,
206e7074cffSAKASHI Takahiro .mkdir = fs_mkdir_unsupported,
207436e2b73SSimon Glass },
208436e2b73SSimon Glass #endif
20992ccc96bSSimon Glass #ifdef CONFIG_SANDBOX
21092ccc96bSSimon Glass {
21192ccc96bSSimon Glass .fstype = FS_TYPE_SANDBOX,
2121a1ad8e0SSjoerd Simons .name = "sandbox",
213377202b5SStephen Warren .null_dev_desc_ok = true,
21492ccc96bSSimon Glass .probe = sandbox_fs_set_blk_dev,
21592ccc96bSSimon Glass .close = sandbox_fs_close,
21692ccc96bSSimon Glass .ls = sandbox_fs_ls,
2170a30aa1eSStephen Warren .exists = sandbox_fs_exists,
218cf659819SStephen Warren .size = sandbox_fs_size,
21992ccc96bSSimon Glass .read = fs_read_sandbox,
2207eb2c8d5SSimon Glass .write = fs_write_sandbox,
22159e890efSChristian Gmeiner .uuid = fs_uuid_unsupported,
2224bbcc965SRob Clark .opendir = fs_opendir_unsupported,
223e2519dafSAKASHI Takahiro .unlink = fs_unlink_unsupported,
224e7074cffSAKASHI Takahiro .mkdir = fs_mkdir_unsupported,
22592ccc96bSSimon Glass },
22692ccc96bSSimon Glass #endif
227251cee0dSHans de Goede #ifdef CONFIG_CMD_UBIFS
228251cee0dSHans de Goede {
229251cee0dSHans de Goede .fstype = FS_TYPE_UBIFS,
230251cee0dSHans de Goede .name = "ubifs",
231251cee0dSHans de Goede .null_dev_desc_ok = true,
232251cee0dSHans de Goede .probe = ubifs_set_blk_dev,
233251cee0dSHans de Goede .close = ubifs_close,
234251cee0dSHans de Goede .ls = ubifs_ls,
235251cee0dSHans de Goede .exists = ubifs_exists,
236251cee0dSHans de Goede .size = ubifs_size,
237251cee0dSHans de Goede .read = ubifs_read,
238251cee0dSHans de Goede .write = fs_write_unsupported,
239251cee0dSHans de Goede .uuid = fs_uuid_unsupported,
2404bbcc965SRob Clark .opendir = fs_opendir_unsupported,
241e2519dafSAKASHI Takahiro .unlink = fs_unlink_unsupported,
242e7074cffSAKASHI Takahiro .mkdir = fs_mkdir_unsupported,
243251cee0dSHans de Goede },
244251cee0dSHans de Goede #endif
2450c936ee3SMarek Behún #ifdef CONFIG_FS_BTRFS
2460c936ee3SMarek Behún {
2470c936ee3SMarek Behún .fstype = FS_TYPE_BTRFS,
2480c936ee3SMarek Behún .name = "btrfs",
2490c936ee3SMarek Behún .null_dev_desc_ok = false,
2500c936ee3SMarek Behún .probe = btrfs_probe,
2510c936ee3SMarek Behún .close = btrfs_close,
2520c936ee3SMarek Behún .ls = btrfs_ls,
2530c936ee3SMarek Behún .exists = btrfs_exists,
2540c936ee3SMarek Behún .size = btrfs_size,
2550c936ee3SMarek Behún .read = btrfs_read,
2560c936ee3SMarek Behún .write = fs_write_unsupported,
2570c936ee3SMarek Behún .uuid = btrfs_uuid,
25838fc683dSMarek Behún .opendir = fs_opendir_unsupported,
259e2519dafSAKASHI Takahiro .unlink = fs_unlink_unsupported,
260e7074cffSAKASHI Takahiro .mkdir = fs_mkdir_unsupported,
2610c936ee3SMarek Behún },
2620c936ee3SMarek Behún #endif
263436e2b73SSimon Glass {
264436e2b73SSimon Glass .fstype = FS_TYPE_ANY,
2651a1ad8e0SSjoerd Simons .name = "unsupported",
266377202b5SStephen Warren .null_dev_desc_ok = true,
267436e2b73SSimon Glass .probe = fs_probe_unsupported,
268436e2b73SSimon Glass .close = fs_close_unsupported,
269436e2b73SSimon Glass .ls = fs_ls_unsupported,
2706152916aSStephen Warren .exists = fs_exists_unsupported,
271cf659819SStephen Warren .size = fs_size_unsupported,
272436e2b73SSimon Glass .read = fs_read_unsupported,
273a8f6ab52SSimon Glass .write = fs_write_unsupported,
27459e890efSChristian Gmeiner .uuid = fs_uuid_unsupported,
2754bbcc965SRob Clark .opendir = fs_opendir_unsupported,
276e2519dafSAKASHI Takahiro .unlink = fs_unlink_unsupported,
277e7074cffSAKASHI Takahiro .mkdir = fs_mkdir_unsupported,
278045fa1e1SStephen Warren },
279045fa1e1SStephen Warren };
280045fa1e1SStephen Warren
fs_get_info(int fstype)281c6f548d2SSimon Glass static struct fstype_info *fs_get_info(int fstype)
282c6f548d2SSimon Glass {
283c6f548d2SSimon Glass struct fstype_info *info;
284c6f548d2SSimon Glass int i;
285c6f548d2SSimon Glass
286c6f548d2SSimon Glass for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes) - 1; i++, info++) {
287c6f548d2SSimon Glass if (fstype == info->fstype)
288c6f548d2SSimon Glass return info;
289c6f548d2SSimon Glass }
290c6f548d2SSimon Glass
291c6f548d2SSimon Glass /* Return the 'unsupported' sentinel */
292c6f548d2SSimon Glass return info;
293c6f548d2SSimon Glass }
294c6f548d2SSimon Glass
2950d488e8fSAlex Kiernan /**
2960d488e8fSAlex Kiernan * fs_get_type_name() - Get type of current filesystem
2970d488e8fSAlex Kiernan *
2980d488e8fSAlex Kiernan * Return: Pointer to filesystem name
2990d488e8fSAlex Kiernan *
3000d488e8fSAlex Kiernan * Returns a string describing the current filesystem, or the sentinel
3010d488e8fSAlex Kiernan * "unsupported" for any unrecognised filesystem.
3020d488e8fSAlex Kiernan */
fs_get_type_name(void)3030d488e8fSAlex Kiernan const char *fs_get_type_name(void)
3040d488e8fSAlex Kiernan {
3050d488e8fSAlex Kiernan return fs_get_info(fs_type)->name;
3060d488e8fSAlex Kiernan }
3070d488e8fSAlex Kiernan
fs_set_blk_dev(const char * ifname,const char * dev_part_str,int fstype)308045fa1e1SStephen Warren int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype)
309045fa1e1SStephen Warren {
310436e2b73SSimon Glass struct fstype_info *info;
311045fa1e1SStephen Warren int part, i;
312a1b231ceSStephen Warren #ifdef CONFIG_NEEDS_MANUAL_RELOC
313a1b231ceSStephen Warren static int relocated;
314a1b231ceSStephen Warren
315a1b231ceSStephen Warren if (!relocated) {
316436e2b73SSimon Glass for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes);
317436e2b73SSimon Glass i++, info++) {
3181a1ad8e0SSjoerd Simons info->name += gd->reloc_off;
319436e2b73SSimon Glass info->probe += gd->reloc_off;
320436e2b73SSimon Glass info->close += gd->reloc_off;
321436e2b73SSimon Glass info->ls += gd->reloc_off;
322436e2b73SSimon Glass info->read += gd->reloc_off;
323a8f6ab52SSimon Glass info->write += gd->reloc_off;
324436e2b73SSimon Glass }
325a1b231ceSStephen Warren relocated = 1;
326a1b231ceSStephen Warren }
327a1b231ceSStephen Warren #endif
328045fa1e1SStephen Warren
329e35929e4SSimon Glass part = blk_get_device_part_str(ifname, dev_part_str, &fs_dev_desc,
330045fa1e1SStephen Warren &fs_partition, 1);
331045fa1e1SStephen Warren if (part < 0)
332045fa1e1SStephen Warren return -1;
333045fa1e1SStephen Warren
334436e2b73SSimon Glass for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes); i++, info++) {
335436e2b73SSimon Glass if (fstype != FS_TYPE_ANY && info->fstype != FS_TYPE_ANY &&
336436e2b73SSimon Glass fstype != info->fstype)
337045fa1e1SStephen Warren continue;
338045fa1e1SStephen Warren
339377202b5SStephen Warren if (!fs_dev_desc && !info->null_dev_desc_ok)
340377202b5SStephen Warren continue;
341377202b5SStephen Warren
3422ded0d47SSimon Glass if (!info->probe(fs_dev_desc, &fs_partition)) {
343436e2b73SSimon Glass fs_type = info->fstype;
3444bbcc965SRob Clark fs_dev_part = part;
3454bbcc965SRob Clark return 0;
3464bbcc965SRob Clark }
3474bbcc965SRob Clark }
3484bbcc965SRob Clark
3494bbcc965SRob Clark return -1;
3504bbcc965SRob Clark }
3514bbcc965SRob Clark
3524bbcc965SRob Clark /* set current blk device w/ blk_desc + partition # */
fs_set_blk_dev_with_part(struct blk_desc * desc,int part)3534bbcc965SRob Clark int fs_set_blk_dev_with_part(struct blk_desc *desc, int part)
3544bbcc965SRob Clark {
3554bbcc965SRob Clark struct fstype_info *info;
3564bbcc965SRob Clark int ret, i;
3574bbcc965SRob Clark
3584bbcc965SRob Clark if (part >= 1)
3594bbcc965SRob Clark ret = part_get_info(desc, part, &fs_partition);
3604bbcc965SRob Clark else
3614bbcc965SRob Clark ret = part_get_info_whole_disk(desc, &fs_partition);
3624bbcc965SRob Clark if (ret)
3634bbcc965SRob Clark return ret;
3644bbcc965SRob Clark fs_dev_desc = desc;
3654bbcc965SRob Clark
3664bbcc965SRob Clark for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes); i++, info++) {
3674bbcc965SRob Clark if (!info->probe(fs_dev_desc, &fs_partition)) {
3684bbcc965SRob Clark fs_type = info->fstype;
369b0c78d8fSAKASHI Takahiro fs_dev_part = part;
370045fa1e1SStephen Warren return 0;
371045fa1e1SStephen Warren }
372045fa1e1SStephen Warren }
373045fa1e1SStephen Warren
374045fa1e1SStephen Warren return -1;
375045fa1e1SStephen Warren }
376045fa1e1SStephen Warren
fs_close(void)377045fa1e1SStephen Warren static void fs_close(void)
378045fa1e1SStephen Warren {
379c6f548d2SSimon Glass struct fstype_info *info = fs_get_info(fs_type);
380045fa1e1SStephen Warren
381c6f548d2SSimon Glass info->close();
382e6d52415SSimon Glass
383045fa1e1SStephen Warren fs_type = FS_TYPE_ANY;
384045fa1e1SStephen Warren }
385045fa1e1SStephen Warren
fs_uuid(char * uuid_str)38659e890efSChristian Gmeiner int fs_uuid(char *uuid_str)
38759e890efSChristian Gmeiner {
38859e890efSChristian Gmeiner struct fstype_info *info = fs_get_info(fs_type);
38959e890efSChristian Gmeiner
39059e890efSChristian Gmeiner return info->uuid(uuid_str);
39159e890efSChristian Gmeiner }
39259e890efSChristian Gmeiner
fs_ls(const char * dirname)393045fa1e1SStephen Warren int fs_ls(const char *dirname)
394045fa1e1SStephen Warren {
395045fa1e1SStephen Warren int ret;
396045fa1e1SStephen Warren
397c6f548d2SSimon Glass struct fstype_info *info = fs_get_info(fs_type);
398c6f548d2SSimon Glass
399c6f548d2SSimon Glass ret = info->ls(dirname);
400045fa1e1SStephen Warren
401e6d52415SSimon Glass fs_type = FS_TYPE_ANY;
402045fa1e1SStephen Warren fs_close();
403045fa1e1SStephen Warren
404045fa1e1SStephen Warren return ret;
405045fa1e1SStephen Warren }
406045fa1e1SStephen Warren
fs_exists(const char * filename)4076152916aSStephen Warren int fs_exists(const char *filename)
4086152916aSStephen Warren {
4096152916aSStephen Warren int ret;
4106152916aSStephen Warren
4116152916aSStephen Warren struct fstype_info *info = fs_get_info(fs_type);
4126152916aSStephen Warren
4136152916aSStephen Warren ret = info->exists(filename);
4146152916aSStephen Warren
4156152916aSStephen Warren fs_close();
4166152916aSStephen Warren
4176152916aSStephen Warren return ret;
4186152916aSStephen Warren }
4196152916aSStephen Warren
fs_size(const char * filename,loff_t * size)420d455d878SSuriyan Ramasami int fs_size(const char *filename, loff_t *size)
421cf659819SStephen Warren {
422cf659819SStephen Warren int ret;
423cf659819SStephen Warren
424cf659819SStephen Warren struct fstype_info *info = fs_get_info(fs_type);
425cf659819SStephen Warren
426d455d878SSuriyan Ramasami ret = info->size(filename, size);
427cf659819SStephen Warren
428cf659819SStephen Warren fs_close();
429cf659819SStephen Warren
430cf659819SStephen Warren return ret;
431cf659819SStephen Warren }
432cf659819SStephen Warren
433aa3c609eSSimon Goldschmidt #ifdef CONFIG_LMB
434aa3c609eSSimon Goldschmidt /* Check if a file may be read to the given address */
fs_read_lmb_check(const char * filename,ulong addr,loff_t offset,loff_t len,struct fstype_info * info)435aa3c609eSSimon Goldschmidt static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset,
436aa3c609eSSimon Goldschmidt loff_t len, struct fstype_info *info)
437aa3c609eSSimon Goldschmidt {
438aa3c609eSSimon Goldschmidt struct lmb lmb;
439aa3c609eSSimon Goldschmidt int ret;
440aa3c609eSSimon Goldschmidt loff_t size;
441aa3c609eSSimon Goldschmidt loff_t read_len;
442aa3c609eSSimon Goldschmidt
443aa3c609eSSimon Goldschmidt /* get the actual size of the file */
444aa3c609eSSimon Goldschmidt ret = info->size(filename, &size);
445aa3c609eSSimon Goldschmidt if (ret)
446aa3c609eSSimon Goldschmidt return ret;
447aa3c609eSSimon Goldschmidt if (offset >= size) {
448aa3c609eSSimon Goldschmidt /* offset >= EOF, no bytes will be written */
449aa3c609eSSimon Goldschmidt return 0;
450aa3c609eSSimon Goldschmidt }
451aa3c609eSSimon Goldschmidt read_len = size - offset;
452aa3c609eSSimon Goldschmidt
453aa3c609eSSimon Goldschmidt /* limit to 'len' if it is smaller */
454aa3c609eSSimon Goldschmidt if (len && len < read_len)
455aa3c609eSSimon Goldschmidt read_len = len;
456aa3c609eSSimon Goldschmidt
4579cc2323fSSimon Goldschmidt lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
458aa3c609eSSimon Goldschmidt lmb_dump_all(&lmb);
459aa3c609eSSimon Goldschmidt
460aa3c609eSSimon Goldschmidt if (lmb_alloc_addr(&lmb, addr, read_len) == addr)
461aa3c609eSSimon Goldschmidt return 0;
462aa3c609eSSimon Goldschmidt
463aa3c609eSSimon Goldschmidt printf("** Reading file would overwrite reserved memory **\n");
464aa3c609eSSimon Goldschmidt return -ENOSPC;
465aa3c609eSSimon Goldschmidt }
466aa3c609eSSimon Goldschmidt #endif
467aa3c609eSSimon Goldschmidt
_fs_read(const char * filename,ulong addr,loff_t offset,loff_t len,int do_lmb_check,loff_t * actread)468aa3c609eSSimon Goldschmidt static int _fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
469aa3c609eSSimon Goldschmidt int do_lmb_check, loff_t *actread)
470045fa1e1SStephen Warren {
471c6f548d2SSimon Glass struct fstype_info *info = fs_get_info(fs_type);
472117e0507SSimon Glass void *buf;
473045fa1e1SStephen Warren int ret;
474045fa1e1SStephen Warren
475aa3c609eSSimon Goldschmidt #ifdef CONFIG_LMB
476aa3c609eSSimon Goldschmidt if (do_lmb_check) {
477aa3c609eSSimon Goldschmidt ret = fs_read_lmb_check(filename, addr, offset, len, info);
478aa3c609eSSimon Goldschmidt if (ret)
479aa3c609eSSimon Goldschmidt return ret;
480aa3c609eSSimon Goldschmidt }
481aa3c609eSSimon Goldschmidt #endif
482aa3c609eSSimon Goldschmidt
483117e0507SSimon Glass /*
484117e0507SSimon Glass * We don't actually know how many bytes are being read, since len==0
485117e0507SSimon Glass * means read the whole file.
486117e0507SSimon Glass */
487117e0507SSimon Glass buf = map_sysmem(addr, len);
488d455d878SSuriyan Ramasami ret = info->read(filename, buf, offset, len, actread);
489117e0507SSimon Glass unmap_sysmem(buf);
490045fa1e1SStephen Warren
491c6f548d2SSimon Glass /* If we requested a specific number of bytes, check we got it */
4927a3e70cfSMax Krummenacher if (ret == 0 && len && *actread != len)
493a327bde7SHeinrich Schuchardt debug("** %s shorter than offset + len **\n", filename);
494045fa1e1SStephen Warren fs_close();
495045fa1e1SStephen Warren
496045fa1e1SStephen Warren return ret;
497045fa1e1SStephen Warren }
498045fa1e1SStephen Warren
fs_read(const char * filename,ulong addr,loff_t offset,loff_t len,loff_t * actread)499aa3c609eSSimon Goldschmidt int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
500aa3c609eSSimon Goldschmidt loff_t *actread)
501aa3c609eSSimon Goldschmidt {
502aa3c609eSSimon Goldschmidt return _fs_read(filename, addr, offset, len, 0, actread);
503aa3c609eSSimon Goldschmidt }
504aa3c609eSSimon Goldschmidt
fs_write(const char * filename,ulong addr,loff_t offset,loff_t len,loff_t * actwrite)505d455d878SSuriyan Ramasami int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len,
506d455d878SSuriyan Ramasami loff_t *actwrite)
507a8f6ab52SSimon Glass {
508a8f6ab52SSimon Glass struct fstype_info *info = fs_get_info(fs_type);
509a8f6ab52SSimon Glass void *buf;
510a8f6ab52SSimon Glass int ret;
511a8f6ab52SSimon Glass
512a8f6ab52SSimon Glass buf = map_sysmem(addr, len);
513d455d878SSuriyan Ramasami ret = info->write(filename, buf, offset, len, actwrite);
514a8f6ab52SSimon Glass unmap_sysmem(buf);
515a8f6ab52SSimon Glass
516d455d878SSuriyan Ramasami if (ret < 0 && len != *actwrite) {
517a8f6ab52SSimon Glass printf("** Unable to write file %s **\n", filename);
518a8f6ab52SSimon Glass ret = -1;
519a8f6ab52SSimon Glass }
520a8f6ab52SSimon Glass fs_close();
521a8f6ab52SSimon Glass
522a8f6ab52SSimon Glass return ret;
523a8f6ab52SSimon Glass }
524a8f6ab52SSimon Glass
fs_opendir(const char * filename)5254bbcc965SRob Clark struct fs_dir_stream *fs_opendir(const char *filename)
5264bbcc965SRob Clark {
5274bbcc965SRob Clark struct fstype_info *info = fs_get_info(fs_type);
5284bbcc965SRob Clark struct fs_dir_stream *dirs = NULL;
5294bbcc965SRob Clark int ret;
5304bbcc965SRob Clark
5314bbcc965SRob Clark ret = info->opendir(filename, &dirs);
5324bbcc965SRob Clark fs_close();
5334bbcc965SRob Clark if (ret) {
5344bbcc965SRob Clark errno = -ret;
5354bbcc965SRob Clark return NULL;
5364bbcc965SRob Clark }
5374bbcc965SRob Clark
5384bbcc965SRob Clark dirs->desc = fs_dev_desc;
5394bbcc965SRob Clark dirs->part = fs_dev_part;
5404bbcc965SRob Clark
5414bbcc965SRob Clark return dirs;
5424bbcc965SRob Clark }
5434bbcc965SRob Clark
fs_readdir(struct fs_dir_stream * dirs)5444bbcc965SRob Clark struct fs_dirent *fs_readdir(struct fs_dir_stream *dirs)
5454bbcc965SRob Clark {
5464bbcc965SRob Clark struct fstype_info *info;
5474bbcc965SRob Clark struct fs_dirent *dirent;
5484bbcc965SRob Clark int ret;
5494bbcc965SRob Clark
5504bbcc965SRob Clark fs_set_blk_dev_with_part(dirs->desc, dirs->part);
5514bbcc965SRob Clark info = fs_get_info(fs_type);
5524bbcc965SRob Clark
5534bbcc965SRob Clark ret = info->readdir(dirs, &dirent);
5544bbcc965SRob Clark fs_close();
5554bbcc965SRob Clark if (ret) {
5564bbcc965SRob Clark errno = -ret;
5574bbcc965SRob Clark return NULL;
5584bbcc965SRob Clark }
5594bbcc965SRob Clark
5604bbcc965SRob Clark return dirent;
5614bbcc965SRob Clark }
5624bbcc965SRob Clark
fs_closedir(struct fs_dir_stream * dirs)5634bbcc965SRob Clark void fs_closedir(struct fs_dir_stream *dirs)
5644bbcc965SRob Clark {
5654bbcc965SRob Clark struct fstype_info *info;
5664bbcc965SRob Clark
5674bbcc965SRob Clark if (!dirs)
5684bbcc965SRob Clark return;
5694bbcc965SRob Clark
5704bbcc965SRob Clark fs_set_blk_dev_with_part(dirs->desc, dirs->part);
5714bbcc965SRob Clark info = fs_get_info(fs_type);
5724bbcc965SRob Clark
5734bbcc965SRob Clark info->closedir(dirs);
5744bbcc965SRob Clark fs_close();
5754bbcc965SRob Clark }
5764bbcc965SRob Clark
fs_unlink(const char * filename)577e2519dafSAKASHI Takahiro int fs_unlink(const char *filename)
578e2519dafSAKASHI Takahiro {
579e2519dafSAKASHI Takahiro int ret;
580e2519dafSAKASHI Takahiro
581e2519dafSAKASHI Takahiro struct fstype_info *info = fs_get_info(fs_type);
582e2519dafSAKASHI Takahiro
583e2519dafSAKASHI Takahiro ret = info->unlink(filename);
584e2519dafSAKASHI Takahiro
585e2519dafSAKASHI Takahiro fs_type = FS_TYPE_ANY;
586e2519dafSAKASHI Takahiro fs_close();
587e2519dafSAKASHI Takahiro
588e2519dafSAKASHI Takahiro return ret;
589e2519dafSAKASHI Takahiro }
5904bbcc965SRob Clark
fs_mkdir(const char * dirname)591e7074cffSAKASHI Takahiro int fs_mkdir(const char *dirname)
592e7074cffSAKASHI Takahiro {
593e7074cffSAKASHI Takahiro int ret;
594e7074cffSAKASHI Takahiro
595e7074cffSAKASHI Takahiro struct fstype_info *info = fs_get_info(fs_type);
596e7074cffSAKASHI Takahiro
597e7074cffSAKASHI Takahiro ret = info->mkdir(dirname);
598e7074cffSAKASHI Takahiro
599e7074cffSAKASHI Takahiro fs_type = FS_TYPE_ANY;
600e7074cffSAKASHI Takahiro fs_close();
601e7074cffSAKASHI Takahiro
602e7074cffSAKASHI Takahiro return ret;
603e7074cffSAKASHI Takahiro }
604e7074cffSAKASHI Takahiro
do_size(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[],int fstype)605cf659819SStephen Warren int do_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
606cf659819SStephen Warren int fstype)
607cf659819SStephen Warren {
608d455d878SSuriyan Ramasami loff_t size;
609cf659819SStephen Warren
610cf659819SStephen Warren if (argc != 4)
611cf659819SStephen Warren return CMD_RET_USAGE;
612cf659819SStephen Warren
613cf659819SStephen Warren if (fs_set_blk_dev(argv[1], argv[2], fstype))
614cf659819SStephen Warren return 1;
615cf659819SStephen Warren
616d455d878SSuriyan Ramasami if (fs_size(argv[3], &size) < 0)
617cf659819SStephen Warren return CMD_RET_FAILURE;
618cf659819SStephen Warren
619018f5303SSimon Glass env_set_hex("filesize", size);
620cf659819SStephen Warren
621cf659819SStephen Warren return 0;
622cf659819SStephen Warren }
623cf659819SStephen Warren
do_load(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[],int fstype)624f9b55e22SStephen Warren int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
625b770e88aSWolfgang Denk int fstype)
626045fa1e1SStephen Warren {
627045fa1e1SStephen Warren unsigned long addr;
628045fa1e1SStephen Warren const char *addr_str;
629045fa1e1SStephen Warren const char *filename;
630d455d878SSuriyan Ramasami loff_t bytes;
631d455d878SSuriyan Ramasami loff_t pos;
632d455d878SSuriyan Ramasami loff_t len_read;
633d455d878SSuriyan Ramasami int ret;
634da1fd96cSAndreas Bießmann unsigned long time;
635949bbd7cSPavel Machek char *ep;
636045fa1e1SStephen Warren
637e9b0f99eSStephen Warren if (argc < 2)
638e9b0f99eSStephen Warren return CMD_RET_USAGE;
639e9b0f99eSStephen Warren if (argc > 7)
640045fa1e1SStephen Warren return CMD_RET_USAGE;
641045fa1e1SStephen Warren
642e9b0f99eSStephen Warren if (fs_set_blk_dev(argv[1], (argc >= 3) ? argv[2] : NULL, fstype))
643045fa1e1SStephen Warren return 1;
644045fa1e1SStephen Warren
645045fa1e1SStephen Warren if (argc >= 4) {
646949bbd7cSPavel Machek addr = simple_strtoul(argv[3], &ep, 16);
647949bbd7cSPavel Machek if (ep == argv[3] || *ep != '\0')
648949bbd7cSPavel Machek return CMD_RET_USAGE;
649045fa1e1SStephen Warren } else {
65000caae6dSSimon Glass addr_str = env_get("loadaddr");
651045fa1e1SStephen Warren if (addr_str != NULL)
652045fa1e1SStephen Warren addr = simple_strtoul(addr_str, NULL, 16);
653045fa1e1SStephen Warren else
654045fa1e1SStephen Warren addr = CONFIG_SYS_LOAD_ADDR;
655045fa1e1SStephen Warren }
656045fa1e1SStephen Warren if (argc >= 5) {
657045fa1e1SStephen Warren filename = argv[4];
658045fa1e1SStephen Warren } else {
65900caae6dSSimon Glass filename = env_get("bootfile");
660045fa1e1SStephen Warren if (!filename) {
661045fa1e1SStephen Warren puts("** No boot file defined **\n");
662045fa1e1SStephen Warren return 1;
663045fa1e1SStephen Warren }
664045fa1e1SStephen Warren }
665045fa1e1SStephen Warren if (argc >= 6)
666b770e88aSWolfgang Denk bytes = simple_strtoul(argv[5], NULL, 16);
667045fa1e1SStephen Warren else
668045fa1e1SStephen Warren bytes = 0;
669045fa1e1SStephen Warren if (argc >= 7)
670b770e88aSWolfgang Denk pos = simple_strtoul(argv[6], NULL, 16);
671045fa1e1SStephen Warren else
672045fa1e1SStephen Warren pos = 0;
673045fa1e1SStephen Warren
674da1fd96cSAndreas Bießmann time = get_timer(0);
675aa3c609eSSimon Goldschmidt ret = _fs_read(filename, addr, pos, bytes, 1, &len_read);
676da1fd96cSAndreas Bießmann time = get_timer(time);
677d455d878SSuriyan Ramasami if (ret < 0)
678045fa1e1SStephen Warren return 1;
679045fa1e1SStephen Warren
680d455d878SSuriyan Ramasami printf("%llu bytes read in %lu ms", len_read, time);
681da1fd96cSAndreas Bießmann if (time > 0) {
682da1fd96cSAndreas Bießmann puts(" (");
6839e374e7bSTom Rini print_size(div_u64(len_read, time) * 1000, "/s");
684da1fd96cSAndreas Bießmann puts(")");
685da1fd96cSAndreas Bießmann }
686da1fd96cSAndreas Bießmann puts("\n");
687045fa1e1SStephen Warren
688018f5303SSimon Glass env_set_hex("fileaddr", addr);
689018f5303SSimon Glass env_set_hex("filesize", len_read);
690045fa1e1SStephen Warren
691045fa1e1SStephen Warren return 0;
692045fa1e1SStephen Warren }
693045fa1e1SStephen Warren
do_ls(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[],int fstype)694045fa1e1SStephen Warren int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
695045fa1e1SStephen Warren int fstype)
696045fa1e1SStephen Warren {
697045fa1e1SStephen Warren if (argc < 2)
698045fa1e1SStephen Warren return CMD_RET_USAGE;
699e9b0f99eSStephen Warren if (argc > 4)
700e9b0f99eSStephen Warren return CMD_RET_USAGE;
701045fa1e1SStephen Warren
702045fa1e1SStephen Warren if (fs_set_blk_dev(argv[1], (argc >= 3) ? argv[2] : NULL, fstype))
703045fa1e1SStephen Warren return 1;
704045fa1e1SStephen Warren
705e9b0f99eSStephen Warren if (fs_ls(argc >= 4 ? argv[3] : "/"))
706045fa1e1SStephen Warren return 1;
707045fa1e1SStephen Warren
708045fa1e1SStephen Warren return 0;
709045fa1e1SStephen Warren }
710a8f6ab52SSimon Glass
file_exists(const char * dev_type,const char * dev_part,const char * file,int fstype)7116152916aSStephen Warren int file_exists(const char *dev_type, const char *dev_part, const char *file,
7126152916aSStephen Warren int fstype)
7136152916aSStephen Warren {
7146152916aSStephen Warren if (fs_set_blk_dev(dev_type, dev_part, fstype))
7156152916aSStephen Warren return 0;
7166152916aSStephen Warren
7176152916aSStephen Warren return fs_exists(file);
7186152916aSStephen Warren }
7196152916aSStephen Warren
do_save(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[],int fstype)720a8f6ab52SSimon Glass int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
721b770e88aSWolfgang Denk int fstype)
722a8f6ab52SSimon Glass {
723a8f6ab52SSimon Glass unsigned long addr;
724a8f6ab52SSimon Glass const char *filename;
725d455d878SSuriyan Ramasami loff_t bytes;
726d455d878SSuriyan Ramasami loff_t pos;
727d455d878SSuriyan Ramasami loff_t len;
728d455d878SSuriyan Ramasami int ret;
729a8f6ab52SSimon Glass unsigned long time;
730a8f6ab52SSimon Glass
731a8f6ab52SSimon Glass if (argc < 6 || argc > 7)
732a8f6ab52SSimon Glass return CMD_RET_USAGE;
733a8f6ab52SSimon Glass
734a8f6ab52SSimon Glass if (fs_set_blk_dev(argv[1], argv[2], fstype))
735a8f6ab52SSimon Glass return 1;
736a8f6ab52SSimon Glass
737d455d878SSuriyan Ramasami addr = simple_strtoul(argv[3], NULL, 16);
738d455d878SSuriyan Ramasami filename = argv[4];
739b770e88aSWolfgang Denk bytes = simple_strtoul(argv[5], NULL, 16);
740a8f6ab52SSimon Glass if (argc >= 7)
741b770e88aSWolfgang Denk pos = simple_strtoul(argv[6], NULL, 16);
742a8f6ab52SSimon Glass else
743a8f6ab52SSimon Glass pos = 0;
744a8f6ab52SSimon Glass
745a8f6ab52SSimon Glass time = get_timer(0);
746d455d878SSuriyan Ramasami ret = fs_write(filename, addr, pos, bytes, &len);
747a8f6ab52SSimon Glass time = get_timer(time);
748d455d878SSuriyan Ramasami if (ret < 0)
749a8f6ab52SSimon Glass return 1;
750a8f6ab52SSimon Glass
751d455d878SSuriyan Ramasami printf("%llu bytes written in %lu ms", len, time);
752a8f6ab52SSimon Glass if (time > 0) {
753a8f6ab52SSimon Glass puts(" (");
7549e374e7bSTom Rini print_size(div_u64(len, time) * 1000, "/s");
755a8f6ab52SSimon Glass puts(")");
756a8f6ab52SSimon Glass }
757a8f6ab52SSimon Glass puts("\n");
758a8f6ab52SSimon Glass
759a8f6ab52SSimon Glass return 0;
760a8f6ab52SSimon Glass }
76159e890efSChristian Gmeiner
do_fs_uuid(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[],int fstype)76259e890efSChristian Gmeiner int do_fs_uuid(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
76359e890efSChristian Gmeiner int fstype)
76459e890efSChristian Gmeiner {
76559e890efSChristian Gmeiner int ret;
76659e890efSChristian Gmeiner char uuid[37];
76759e890efSChristian Gmeiner memset(uuid, 0, sizeof(uuid));
76859e890efSChristian Gmeiner
76959e890efSChristian Gmeiner if (argc < 3 || argc > 4)
77059e890efSChristian Gmeiner return CMD_RET_USAGE;
77159e890efSChristian Gmeiner
77259e890efSChristian Gmeiner if (fs_set_blk_dev(argv[1], argv[2], fstype))
77359e890efSChristian Gmeiner return 1;
77459e890efSChristian Gmeiner
77559e890efSChristian Gmeiner ret = fs_uuid(uuid);
77659e890efSChristian Gmeiner if (ret)
77759e890efSChristian Gmeiner return CMD_RET_FAILURE;
77859e890efSChristian Gmeiner
77959e890efSChristian Gmeiner if (argc == 4)
780382bee57SSimon Glass env_set(argv[3], uuid);
78159e890efSChristian Gmeiner else
78259e890efSChristian Gmeiner printf("%s\n", uuid);
78359e890efSChristian Gmeiner
78459e890efSChristian Gmeiner return CMD_RET_SUCCESS;
78559e890efSChristian Gmeiner }
7861a1ad8e0SSjoerd Simons
do_fs_type(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])7871a1ad8e0SSjoerd Simons int do_fs_type(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
7881a1ad8e0SSjoerd Simons {
7891a1ad8e0SSjoerd Simons struct fstype_info *info;
7901a1ad8e0SSjoerd Simons
7911a1ad8e0SSjoerd Simons if (argc < 3 || argc > 4)
7921a1ad8e0SSjoerd Simons return CMD_RET_USAGE;
7931a1ad8e0SSjoerd Simons
7941a1ad8e0SSjoerd Simons if (fs_set_blk_dev(argv[1], argv[2], FS_TYPE_ANY))
7951a1ad8e0SSjoerd Simons return 1;
7961a1ad8e0SSjoerd Simons
7971a1ad8e0SSjoerd Simons info = fs_get_info(fs_type);
7981a1ad8e0SSjoerd Simons
7991a1ad8e0SSjoerd Simons if (argc == 4)
800382bee57SSimon Glass env_set(argv[3], info->name);
8011a1ad8e0SSjoerd Simons else
8021a1ad8e0SSjoerd Simons printf("%s\n", info->name);
8031a1ad8e0SSjoerd Simons
804*e531c673SMarek Vasut fs_close();
805*e531c673SMarek Vasut
8061a1ad8e0SSjoerd Simons return CMD_RET_SUCCESS;
8071a1ad8e0SSjoerd Simons }
8081a1ad8e0SSjoerd Simons
do_rm(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[],int fstype)809e2519dafSAKASHI Takahiro int do_rm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
810e2519dafSAKASHI Takahiro int fstype)
811e2519dafSAKASHI Takahiro {
812e2519dafSAKASHI Takahiro if (argc != 4)
813e2519dafSAKASHI Takahiro return CMD_RET_USAGE;
814e2519dafSAKASHI Takahiro
815e2519dafSAKASHI Takahiro if (fs_set_blk_dev(argv[1], argv[2], fstype))
816e2519dafSAKASHI Takahiro return 1;
817e2519dafSAKASHI Takahiro
818e2519dafSAKASHI Takahiro if (fs_unlink(argv[3]))
819e2519dafSAKASHI Takahiro return 1;
820e2519dafSAKASHI Takahiro
821e2519dafSAKASHI Takahiro return 0;
822e2519dafSAKASHI Takahiro }
823e2519dafSAKASHI Takahiro
do_mkdir(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[],int fstype)824e7074cffSAKASHI Takahiro int do_mkdir(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
825e7074cffSAKASHI Takahiro int fstype)
826e7074cffSAKASHI Takahiro {
827e7074cffSAKASHI Takahiro int ret;
828e7074cffSAKASHI Takahiro
829e7074cffSAKASHI Takahiro if (argc != 4)
830e7074cffSAKASHI Takahiro return CMD_RET_USAGE;
831e7074cffSAKASHI Takahiro
832e7074cffSAKASHI Takahiro if (fs_set_blk_dev(argv[1], argv[2], fstype))
833e7074cffSAKASHI Takahiro return 1;
834e7074cffSAKASHI Takahiro
835e7074cffSAKASHI Takahiro ret = fs_mkdir(argv[3]);
836e7074cffSAKASHI Takahiro if (ret) {
837e7074cffSAKASHI Takahiro printf("** Unable to create a directory \"%s\" **\n", argv[3]);
838e7074cffSAKASHI Takahiro return 1;
839e7074cffSAKASHI Takahiro }
840e7074cffSAKASHI Takahiro
841e7074cffSAKASHI Takahiro return 0;
842e7074cffSAKASHI Takahiro }
843