diff options
| author | Vincent Jardin <[email protected]> | 2026-07-15 18:57:15 +0200 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2026-07-27 09:07:39 -0600 |
| commit | 5b1dac9ee2029c6aa9fe4f8554f2250b94b89da2 (patch) | |
| tree | b8f02eb9cc1fa254065418987d3acf6aceacdf50 | |
| parent | f605dcee103c897b6f1a8873549a36949bd4e2a1 (diff) | |
fs: dispatch null_dev_desc_ok filesystems before lookup
Filesystems that are null_dev_desc_ok (semihosting, ubifs) have
no UCLASS_BLK device under their ifname, so on real hardware
fs_set_blk_dev() always fails at the partition lookup.
The workaround was to add a per-filesystem
command (example cmd/ubifs.c), which duplicates the plumbing of
fstype_info.
Probe such entries with block_desc=NULL up front, so
load semihosting - <addr> <file>
works without a new command.
Sandbox boards that exercise the existing fallback through "host
bind" stay unchanged.
Signed-off-by: Vincent Jardin <[email protected]>
Reviewed-by: Simon Glass <[email protected]>
| -rw-r--r-- | fs/fs.c | 42 |
1 files changed, 42 insertions, 0 deletions
@@ -459,11 +459,53 @@ const char *fs_get_type_name(void) return fs_get_info(fs_type)->name; } +/* + * Some fstypes (semihosting, ubifs) have no underlying block device + * and ignore the block_desc argument of their probe hook. The legacy + * commands (ubifsload, semihosting via env macros) just pass NULL; + * for "load <iface> ..." to behave the same, the dispatcher opts + * those fstypes in by name here, before any block-device lookup is + * attempted. + * + * Returns the matching fstype_info if @ifname names a fstype that + * opts into null_dev_desc_ok dispatch and the caller's @fstype filter + * permits it. Returns NULL otherwise. + */ +static struct fstype_info *fs_lookup_null_dev_info(const char *ifname, + int fstype) +{ + struct fstype_info *info; + int i; + + for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes); i++, info++) { + if (fstype != FS_TYPE_ANY && info->fstype != FS_TYPE_ANY && + fstype != info->fstype) + continue; + if (!info->null_dev_desc_ok || !info->name) + continue; + if (!strcmp(info->name, ifname)) + return info; + } + + return NULL; +} + int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype) { struct fstype_info *info; int part, i; + info = fs_lookup_null_dev_info(ifname, fstype); + if (info) { + fs_dev_desc = NULL; + memset(&fs_partition, 0, sizeof(fs_partition)); + if (!info->probe(NULL, &fs_partition)) { + fs_type = info->fstype; + fs_dev_part = 0; + return 0; + } + } + part = part_get_info_by_dev_and_name_or_num(ifname, dev_part_str, &fs_dev_desc, &fs_partition, 1); if (part < 0) |
