Currently it is not possible to add additional OEM commands without extending the array `cmd_oem_dispatch_info[]`. Add the possibility to register commands from e.g. board files by replacing the array with a list. Signed-off-by: Thomas Haemmerle <thomas.haemmerle@xxxxxxxxxxxxxxxxxxxx> --- common/fastboot.c | 53 +++++++++++++++++++++++++++++++++++----------- include/fastboot.h | 9 ++++++++ 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/common/fastboot.c b/common/fastboot.c index f8a01dea7a..8f78b0e517 100644 --- a/common/fastboot.c +++ b/common/fastboot.c @@ -885,24 +885,41 @@ static void cb_oem_exec(struct fastboot *fb, const char *cmd) fastboot_tx_print(fb, FASTBOOT_MSG_OKAY, ""); } -static const struct cmd_dispatch_info cmd_oem_dispatch_info[] = { - { - .cmd = "getenv ", - .cb = cb_oem_getenv, - }, { - .cmd = "setenv ", - .cb = cb_oem_setenv, - }, { - .cmd = "exec ", - .cb = cb_oem_exec, - }, +struct oem_command { + char *cmd; + void (*cb)(struct fastboot *fb, const char *opt); + struct list_head list; }; +LIST_HEAD(oem_cmd_list); + +int fastboot_register_oem_command(char *cmd, void (*cb)(struct fastboot *fb, const char *opt)) +{ + struct oem_command *oem_cmd = xzalloc(sizeof(*oem_cmd)); + + oem_cmd->cmd = xstrdup(cmd); + oem_cmd->cb = cb; + + list_add_tail(&oem_cmd->list, &oem_cmd_list); + + return 0; +} + static void __maybe_unused cb_oem(struct fastboot *fb, const char *cmd) { + struct oem_command *oem_cmd; + pr_debug("%s: \"%s\"\n", __func__, cmd); - fb_run_command(fb, cmd, cmd_oem_dispatch_info, ARRAY_SIZE(cmd_oem_dispatch_info)); + list_for_each_entry(oem_cmd, &oem_cmd_list, list) { + if (!strcmp_l1(oem_cmd->cmd, cmd)) { + oem_cmd->cb(fb, cmd + strlen(oem_cmd->cmd)); + return; + } + } + + fastboot_tx_print(fb, FASTBOOT_MSG_FAIL, "unknown OEM command %s", + cmd); } static const struct cmd_dispatch_info cmd_dispatch_info[] = { @@ -969,6 +986,18 @@ struct file_list *get_fastboot_partitions(void) return system_partitions_get_null(); } +static int fastboot_oem_cmds_init(void) +{ + if (!IS_ENABLED(CONFIG_FASTBOOT_CMD_OEM)) + return 0; + + fastboot_register_oem_command("getenv ", cb_oem_getenv); + fastboot_register_oem_command("setenv ", cb_oem_setenv); + fastboot_register_oem_command("exec ", cb_oem_exec); + return 0; +} +device_initcall(fastboot_oem_cmds_init); + static int fastboot_globalvars_init(void) { if (IS_ENABLED(CONFIG_FASTBOOT_SPARSE)) { diff --git a/include/fastboot.h b/include/fastboot.h index cd415847e3..38b0728a89 100644 --- a/include/fastboot.h +++ b/include/fastboot.h @@ -78,6 +78,15 @@ static inline struct file_list *get_fastboot_partitions(void) } #endif +#ifdef CONFIG_FASTBOOT_CMD_OEM +int fastboot_register_oem_command(char *cmd, void (*cb)(struct fastboot *fb, const char *opt)); +#else +static inline int fastboot_register_oem_command(char *cmd, void (*cb)(struct fastboot *fb, const char *opt)) +{ + return -ENOSYS; +} +#endif + int fastboot_generic_init(struct fastboot *fb, bool export_bbu); void fastboot_generic_close(struct fastboot *fb); void fastboot_generic_free(struct fastboot *fb); base-commit: e70a514bce4bc84429c46fa378622024ac6c6863 -- 2.34.1