Commit 814b661448d50462c37232a456d3d09450fd9f72
Committed by
Tom Rini
1 parent
a5a83dc9dc
Exists in
v2017.01-smarct4x
and in
40 other branches
cmd_fuse: return CMD_RET_FAILURE on error
Fuse drivers, like the mxs_ocotp.c, may return negative error codes but the commands are only allowed to return CMD_RET_* enum values to the shell, otherwise the following error appears: "exit not allowed from main input shell." Signed-off-by: Hector Palacios <hector.palacios@digi.com> Reviewed-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
Showing 1 changed file with 1 additions and 1 deletions Inline Diff
common/cmd_fuse.c
| 1 | /* | 1 | /* |
| 2 | * (C) Copyright 2009-2013 ADVANSEE | 2 | * (C) Copyright 2009-2013 ADVANSEE |
| 3 | * Benoît Thébaudeau <benoit.thebaudeau@advansee.com> | 3 | * Benoît Thébaudeau <benoit.thebaudeau@advansee.com> |
| 4 | * | 4 | * |
| 5 | * Based on the mpc512x iim code: | 5 | * Based on the mpc512x iim code: |
| 6 | * Copyright 2008 Silicon Turnkey Express, Inc. | 6 | * Copyright 2008 Silicon Turnkey Express, Inc. |
| 7 | * Martha Marx <mmarx@silicontkx.com> | 7 | * Martha Marx <mmarx@silicontkx.com> |
| 8 | * | 8 | * |
| 9 | * SPDX-License-Identifier: GPL-2.0+ | 9 | * SPDX-License-Identifier: GPL-2.0+ |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <common.h> | 12 | #include <common.h> |
| 13 | #include <command.h> | 13 | #include <command.h> |
| 14 | #include <fuse.h> | 14 | #include <fuse.h> |
| 15 | #include <asm/errno.h> | 15 | #include <asm/errno.h> |
| 16 | 16 | ||
| 17 | static int strtou32(const char *str, unsigned int base, u32 *result) | 17 | static int strtou32(const char *str, unsigned int base, u32 *result) |
| 18 | { | 18 | { |
| 19 | char *ep; | 19 | char *ep; |
| 20 | 20 | ||
| 21 | *result = simple_strtoul(str, &ep, base); | 21 | *result = simple_strtoul(str, &ep, base); |
| 22 | if (ep == str || *ep != '\0') | 22 | if (ep == str || *ep != '\0') |
| 23 | return -EINVAL; | 23 | return -EINVAL; |
| 24 | 24 | ||
| 25 | return 0; | 25 | return 0; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | static int confirm_prog(void) | 28 | static int confirm_prog(void) |
| 29 | { | 29 | { |
| 30 | puts("Warning: Programming fuses is an irreversible operation!\n" | 30 | puts("Warning: Programming fuses is an irreversible operation!\n" |
| 31 | " This may brick your system.\n" | 31 | " This may brick your system.\n" |
| 32 | " Use this command only if you are sure of " | 32 | " Use this command only if you are sure of " |
| 33 | "what you are doing!\n" | 33 | "what you are doing!\n" |
| 34 | "\nReally perform this fuse programming? <y/N>\n"); | 34 | "\nReally perform this fuse programming? <y/N>\n"); |
| 35 | 35 | ||
| 36 | if (confirm_yesno()) | 36 | if (confirm_yesno()) |
| 37 | return 1; | 37 | return 1; |
| 38 | 38 | ||
| 39 | puts("Fuse programming aborted\n"); | 39 | puts("Fuse programming aborted\n"); |
| 40 | return 0; | 40 | return 0; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | static int do_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) | 43 | static int do_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) |
| 44 | { | 44 | { |
| 45 | const char *op = argc >= 2 ? argv[1] : NULL; | 45 | const char *op = argc >= 2 ? argv[1] : NULL; |
| 46 | int confirmed = argc >= 3 && !strcmp(argv[2], "-y"); | 46 | int confirmed = argc >= 3 && !strcmp(argv[2], "-y"); |
| 47 | u32 bank, word, cnt, val; | 47 | u32 bank, word, cnt, val; |
| 48 | int ret, i; | 48 | int ret, i; |
| 49 | 49 | ||
| 50 | argc -= 2 + confirmed; | 50 | argc -= 2 + confirmed; |
| 51 | argv += 2 + confirmed; | 51 | argv += 2 + confirmed; |
| 52 | 52 | ||
| 53 | if (argc < 2 || strtou32(argv[0], 0, &bank) || | 53 | if (argc < 2 || strtou32(argv[0], 0, &bank) || |
| 54 | strtou32(argv[1], 0, &word)) | 54 | strtou32(argv[1], 0, &word)) |
| 55 | return CMD_RET_USAGE; | 55 | return CMD_RET_USAGE; |
| 56 | 56 | ||
| 57 | if (!strcmp(op, "read")) { | 57 | if (!strcmp(op, "read")) { |
| 58 | if (argc == 2) | 58 | if (argc == 2) |
| 59 | cnt = 1; | 59 | cnt = 1; |
| 60 | else if (argc != 3 || strtou32(argv[2], 0, &cnt)) | 60 | else if (argc != 3 || strtou32(argv[2], 0, &cnt)) |
| 61 | return CMD_RET_USAGE; | 61 | return CMD_RET_USAGE; |
| 62 | 62 | ||
| 63 | printf("Reading bank %u:\n", bank); | 63 | printf("Reading bank %u:\n", bank); |
| 64 | for (i = 0; i < cnt; i++, word++) { | 64 | for (i = 0; i < cnt; i++, word++) { |
| 65 | if (!(i % 4)) | 65 | if (!(i % 4)) |
| 66 | printf("\nWord 0x%.8x:", word); | 66 | printf("\nWord 0x%.8x:", word); |
| 67 | 67 | ||
| 68 | ret = fuse_read(bank, word, &val); | 68 | ret = fuse_read(bank, word, &val); |
| 69 | if (ret) | 69 | if (ret) |
| 70 | goto err; | 70 | goto err; |
| 71 | 71 | ||
| 72 | printf(" %.8x", val); | 72 | printf(" %.8x", val); |
| 73 | } | 73 | } |
| 74 | putc('\n'); | 74 | putc('\n'); |
| 75 | } else if (!strcmp(op, "sense")) { | 75 | } else if (!strcmp(op, "sense")) { |
| 76 | if (argc == 2) | 76 | if (argc == 2) |
| 77 | cnt = 1; | 77 | cnt = 1; |
| 78 | else if (argc != 3 || strtou32(argv[2], 0, &cnt)) | 78 | else if (argc != 3 || strtou32(argv[2], 0, &cnt)) |
| 79 | return CMD_RET_USAGE; | 79 | return CMD_RET_USAGE; |
| 80 | 80 | ||
| 81 | printf("Sensing bank %u:\n", bank); | 81 | printf("Sensing bank %u:\n", bank); |
| 82 | for (i = 0; i < cnt; i++, word++) { | 82 | for (i = 0; i < cnt; i++, word++) { |
| 83 | if (!(i % 4)) | 83 | if (!(i % 4)) |
| 84 | printf("\nWord 0x%.8x:", word); | 84 | printf("\nWord 0x%.8x:", word); |
| 85 | 85 | ||
| 86 | ret = fuse_sense(bank, word, &val); | 86 | ret = fuse_sense(bank, word, &val); |
| 87 | if (ret) | 87 | if (ret) |
| 88 | goto err; | 88 | goto err; |
| 89 | 89 | ||
| 90 | printf(" %.8x", val); | 90 | printf(" %.8x", val); |
| 91 | } | 91 | } |
| 92 | putc('\n'); | 92 | putc('\n'); |
| 93 | } else if (!strcmp(op, "prog")) { | 93 | } else if (!strcmp(op, "prog")) { |
| 94 | if (argc < 3) | 94 | if (argc < 3) |
| 95 | return CMD_RET_USAGE; | 95 | return CMD_RET_USAGE; |
| 96 | 96 | ||
| 97 | for (i = 2; i < argc; i++, word++) { | 97 | for (i = 2; i < argc; i++, word++) { |
| 98 | if (strtou32(argv[i], 16, &val)) | 98 | if (strtou32(argv[i], 16, &val)) |
| 99 | return CMD_RET_USAGE; | 99 | return CMD_RET_USAGE; |
| 100 | 100 | ||
| 101 | printf("Programming bank %u word 0x%.8x to 0x%.8x...\n", | 101 | printf("Programming bank %u word 0x%.8x to 0x%.8x...\n", |
| 102 | bank, word, val); | 102 | bank, word, val); |
| 103 | if (!confirmed && !confirm_prog()) | 103 | if (!confirmed && !confirm_prog()) |
| 104 | return CMD_RET_FAILURE; | 104 | return CMD_RET_FAILURE; |
| 105 | ret = fuse_prog(bank, word, val); | 105 | ret = fuse_prog(bank, word, val); |
| 106 | if (ret) | 106 | if (ret) |
| 107 | goto err; | 107 | goto err; |
| 108 | } | 108 | } |
| 109 | } else if (!strcmp(op, "override")) { | 109 | } else if (!strcmp(op, "override")) { |
| 110 | if (argc < 3) | 110 | if (argc < 3) |
| 111 | return CMD_RET_USAGE; | 111 | return CMD_RET_USAGE; |
| 112 | 112 | ||
| 113 | for (i = 2; i < argc; i++, word++) { | 113 | for (i = 2; i < argc; i++, word++) { |
| 114 | if (strtou32(argv[i], 16, &val)) | 114 | if (strtou32(argv[i], 16, &val)) |
| 115 | return CMD_RET_USAGE; | 115 | return CMD_RET_USAGE; |
| 116 | 116 | ||
| 117 | printf("Overriding bank %u word 0x%.8x with " | 117 | printf("Overriding bank %u word 0x%.8x with " |
| 118 | "0x%.8x...\n", bank, word, val); | 118 | "0x%.8x...\n", bank, word, val); |
| 119 | ret = fuse_override(bank, word, val); | 119 | ret = fuse_override(bank, word, val); |
| 120 | if (ret) | 120 | if (ret) |
| 121 | goto err; | 121 | goto err; |
| 122 | } | 122 | } |
| 123 | } else { | 123 | } else { |
| 124 | return CMD_RET_USAGE; | 124 | return CMD_RET_USAGE; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | return 0; | 127 | return 0; |
| 128 | 128 | ||
| 129 | err: | 129 | err: |
| 130 | puts("ERROR\n"); | 130 | puts("ERROR\n"); |
| 131 | return ret; | 131 | return CMD_RET_FAILURE; |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | U_BOOT_CMD( | 134 | U_BOOT_CMD( |
| 135 | fuse, CONFIG_SYS_MAXARGS, 0, do_fuse, | 135 | fuse, CONFIG_SYS_MAXARGS, 0, do_fuse, |
| 136 | "Fuse sub-system", | 136 | "Fuse sub-system", |
| 137 | "read <bank> <word> [<cnt>] - read 1 or 'cnt' fuse words,\n" | 137 | "read <bank> <word> [<cnt>] - read 1 or 'cnt' fuse words,\n" |
| 138 | " starting at 'word'\n" | 138 | " starting at 'word'\n" |
| 139 | "fuse sense <bank> <word> [<cnt>] - sense 1 or 'cnt' fuse words,\n" | 139 | "fuse sense <bank> <word> [<cnt>] - sense 1 or 'cnt' fuse words,\n" |
| 140 | " starting at 'word'\n" | 140 | " starting at 'word'\n" |
| 141 | "fuse prog [-y] <bank> <word> <hexval> [<hexval>...] - program 1 or\n" | 141 | "fuse prog [-y] <bank> <word> <hexval> [<hexval>...] - program 1 or\n" |
| 142 | " several fuse words, starting at 'word' (PERMANENT)\n" | 142 | " several fuse words, starting at 'word' (PERMANENT)\n" |
| 143 | "fuse override <bank> <word> <hexval> [<hexval>...] - override 1 or\n" | 143 | "fuse override <bank> <word> <hexval> [<hexval>...] - override 1 or\n" |
| 144 | " several fuse words, starting at 'word'" | 144 | " several fuse words, starting at 'word'" |
| 145 | ); | 145 | ); |
| 146 | 146 |