Currently when any of speed_mode, part, or dev fails to be parse as a number, no error is reported. In this case __init_mmc_device() is called with weird arguments, probably zeroes if there's no digit prefixing the argument, which is especially confusing when the invocation occasionally succeeds.
Let's check whether arguments are valid numbers without trailing characters. This is quite helpful for speed_mode: it requires an index instead of a mode name, one may easily pass in a string, which will be parsed as zero (MMC_LEGACY), without carefully reading the documentation, then finds the MMC device is under an unexpected mode. Signed-off-by: Yao Zi <[email protected]> --- cmd/mmc.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/cmd/mmc.c b/cmd/mmc.c index f2a59af087cb..512bd482ae82 100644 --- a/cmd/mmc.c +++ b/cmd/mmc.c @@ -559,15 +559,25 @@ static int do_mmc_dev(struct cmd_tbl *cmdtp, int flag, { enum bus_mode speed_mode = MMC_MODES_END; int dev = curr_device, part = 0, ret; + char *endp; struct mmc *mmc; switch (argc) { case 4: - speed_mode = (int)dectoul(argv[3], NULL); + speed_mode = (int)dectoul(argv[3], &endp); + if (*endp) { + printf("Invalid speed mode index '%s', " + "did you specify a mode name?\n", argv[3]); + return CMD_RET_USAGE; + } + fallthrough; case 3: - part = (int)dectoul(argv[2], NULL); - if (part > PART_ACCESS_MASK) { + part = (int)dectoul(argv[2], &endp); + if (*endp) { + printf("Invalid part number '%s'\n", argv[2]); + return CMD_RET_USAGE; + } else if (part > PART_ACCESS_MASK) { printf("#part_num shouldn't be larger than %d\n", PART_ACCESS_MASK); return CMD_RET_FAILURE; @@ -575,7 +585,12 @@ static int do_mmc_dev(struct cmd_tbl *cmdtp, int flag, fallthrough; case 2: - dev = (int)dectoul(argv[1], NULL); + dev = (int)dectoul(argv[1], &endp); + if (*endp) { + printf("Invalid device number '%s'\n", argv[1]); + return CMD_RET_USAGE; + } + fallthrough; case 1: mmc = __init_mmc_device(dev, true, speed_mode); -- 2.52.0

