diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2021-05-17 16:23:51 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2021-05-17 16:23:51 +0200 |
commit | dee7a15dfaa640130d0b9bc289e5d55b358a2dbc (patch) | |
tree | 8ea7b1c341b1ea5453d1a3576fb238dc21edaa37 /common | |
parent | c5e0e697de769d0e78a00b1cb47fe864fade9974 (diff) | |
parent | 7ef2912d40b52202f563806fbffb9f615d2d2220 (diff) | |
download | barebox-dee7a15dfaa640130d0b9bc289e5d55b358a2dbc.tar.gz barebox-dee7a15dfaa640130d0b9bc289e5d55b358a2dbc.tar.xz |
Merge branch 'for-next/usb-gadget'
Diffstat (limited to 'common')
-rw-r--r-- | common/Kconfig | 15 | ||||
-rw-r--r-- | common/Makefile | 3 | ||||
-rw-r--r-- | common/bbu.c | 24 | ||||
-rw-r--r-- | common/console_common.c | 20 | ||||
-rw-r--r-- | common/fastboot.c | 28 | ||||
-rw-r--r-- | common/file-list.c | 85 | ||||
-rw-r--r-- | common/system-partitions.c | 44 | ||||
-rw-r--r-- | common/usbgadget.c | 94 |
8 files changed, 244 insertions, 69 deletions
diff --git a/common/Kconfig b/common/Kconfig index 758acb751d..db7cc6713a 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -91,9 +91,6 @@ config EFI_GUID config EFI_DEVICEPATH bool -config FILE_LIST - bool - config ARCH_DMA_ADDR_T_64BIT bool @@ -117,7 +114,6 @@ config USBGADGET_START bool depends on CMD_USBGADGET || USB_GADGET_AUTOSTART select ENVIRONMENT_VARIABLES - select FILE_LIST default y config BOOT @@ -728,6 +724,17 @@ config MMCBLKDEV_ROOTARG config BAREBOX_UPDATE bool "In-system barebox update infrastructure" +config SYSTEM_PARTITIONS + bool "Generic system partitions support" + depends on GLOBALVAR + help + System partitions are a generic way for boards to specify the + partitions that should be exported for flashing. + Board drivers that set this directly will select this option + automatically. + Say y here if this should be configurable over the + global.system.partitions device parameter as well. + config IMD select CRC32 bool "barebox metadata support" diff --git a/common/Makefile b/common/Makefile index 2c679090a0..382a4f661f 100644 --- a/common/Makefile +++ b/common/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_MACHINE_ID) += machine_id.o obj-$(CONFIG_AUTO_COMPLETE) += complete.o obj-y += version.o obj-$(CONFIG_BAREBOX_UPDATE) += bbu.o +obj-$(CONFIG_SYSTEM_PARTITIONS) += system-partitions.o obj-$(CONFIG_BINFMT) += binfmt.o obj-$(CONFIG_BLOCK) += block.o obj-$(CONFIG_BLSPEC) += blspec.o @@ -65,7 +66,7 @@ obj-$(CONFIG_EFI_GUID) += efi-guid.o obj-$(CONFIG_EFI_DEVICEPATH) += efi-devicepath.o lwl-$(CONFIG_IMD) += imd-barebox.o obj-$(CONFIG_IMD) += imd.o -obj-$(CONFIG_FILE_LIST) += file-list.o +obj-y += file-list.o obj-$(CONFIG_FIRMWARE) += firmware.o obj-$(CONFIG_UBIFORMAT) += ubiformat.o obj-$(CONFIG_BAREBOX_UPDATE_IMX_NAND_FCB) += imx-bbu-nand-fcb.o diff --git a/common/bbu.c b/common/bbu.c index ee9f78ecc9..1a1edda96b 100644 --- a/common/bbu.c +++ b/common/bbu.c @@ -16,22 +16,28 @@ #include <malloc.h> #include <linux/stat.h> #include <image-metadata.h> +#include <file-list.h> static LIST_HEAD(bbu_image_handlers); -int bbu_handlers_iterate(int (*fn)(struct bbu_handler *, void *), void *ctx) +static void append_bbu_entry(struct bbu_handler *handler, struct file_list *files) { - struct bbu_handler *handler; + char *name; - list_for_each_entry(handler, &bbu_image_handlers, list) { - int ret; + name = basprintf("bbu-%s", handler->name); - ret = fn(handler, ctx); - if (ret) - return ret; - } + if (file_list_add_entry(files, name, handler->devicefile, 0)) + pr_warn("duplicate partition name %s\n", name); - return 0; + free(name); +} + +void bbu_append_handlers_to_file_list(struct file_list *files) +{ + struct bbu_handler *handler; + + list_for_each_entry(handler, &bbu_image_handlers, list) + append_bbu_entry(handler, files); } int bbu_force(struct bbu_data *data, const char *fmt, ...) diff --git a/common/console_common.c b/common/console_common.c index 98ff8d0ef9..91a81e50fa 100644 --- a/common/console_common.c +++ b/common/console_common.c @@ -183,6 +183,26 @@ static int console_common_init(void) } device_initcall(console_common_init); +int log_writefile(const char *filepath) +{ + int ret = 0, nbytes = 0, fd = -1; + struct log_entry *log; + + fd = open(filepath, O_WRONLY | O_CREAT | O_TRUNC); + if (fd < 0) + return -errno; + + list_for_each_entry(log, &barebox_logbuf, list) { + ret = dputs(fd, log->msg); + if (ret < 0) + break; + nbytes += ret; + } + + close(fd); + return ret < 0 ? ret : nbytes; +} + void log_print(unsigned flags, unsigned levels) { struct log_entry *log; diff --git a/common/fastboot.c b/common/fastboot.c index a394d07e28..75f6691b08 100644 --- a/common/fastboot.c +++ b/common/fastboot.c @@ -41,6 +41,7 @@ #include <linux/stat.h> #include <linux/mtd/mtd.h> #include <fastboot.h> +#include <system-partitions.h> #define FASTBOOT_VERSION "0.4" @@ -149,21 +150,6 @@ out: return ret; } -static int fastboot_add_bbu_variables(struct bbu_handler *handler, void *ctx) -{ - struct fastboot *fb = ctx; - char *name; - int ret; - - name = basprintf("bbu-%s", handler->name); - - ret = file_list_add_entry(fb->files, name, handler->devicefile, 0); - - free(name); - - return ret; -} - int fastboot_generic_init(struct fastboot *fb, bool export_bbu) { int ret; @@ -185,8 +171,8 @@ int fastboot_generic_init(struct fastboot *fb, bool export_bbu) if (!fb->tempname) return -ENOMEM; - if (IS_ENABLED(CONFIG_BAREBOX_UPDATE) && export_bbu) - bbu_handlers_iterate(fastboot_add_bbu_variables, fb); + if (export_bbu) + bbu_append_handlers_to_file_list(fb->files); file_list_for_each_entry(fb->files, fentry) { ret = fastboot_add_partition_variables(fb, fentry); @@ -930,9 +916,13 @@ bool get_fastboot_bbu(void) return fastboot_bbu; } -const char *get_fastboot_partitions(void) +struct file_list *get_fastboot_partitions(void) { - return fastboot_partitions; + if (fastboot_partitions && *fastboot_partitions) + return file_list_parse(fastboot_partitions); + if (!system_partitions_empty()) + return system_partitions_get(); + return NULL; } static int fastboot_globalvars_init(void) diff --git a/common/file-list.c b/common/file-list.c index cd52b5e045..05f44514fb 100644 --- a/common/file-list.c +++ b/common/file-list.c @@ -6,7 +6,9 @@ #include <malloc.h> #include <fs.h> #include <file-list.h> +#include <stringlist.h> #include <linux/err.h> +#include <driver.h> #define PARSE_DEVICE 0 #define PARSE_NAME 1 @@ -109,6 +111,25 @@ static int file_list_parse_one(struct file_list *files, const char *partstr, con return file_list_add_entry(files, name, filename, flags); } +static const char *flags_to_str(int flags) +{ + static char str[sizeof "srcu"]; + char *s = str;; + + if (flags & FILE_LIST_FLAG_SAFE) + *s++ = 's'; + if (flags & FILE_LIST_FLAG_READBACK) + *s++ = 'r'; + if (flags & FILE_LIST_FLAG_CREATE) + *s++ = 'c'; + if (flags & FILE_LIST_FLAG_UBI) + *s++ = 'u'; + + *s = '\0'; + + return str; +} + struct file_list *file_list_parse(const char *str) { struct file_list *files; @@ -141,6 +162,9 @@ void file_list_free(struct file_list *files) { struct file_list_entry *entry, *tmp; + if (!files) + return; + list_for_each_entry_safe(entry, tmp, &files->list, list) { free(entry->name); free(entry->filename); @@ -149,3 +173,64 @@ void file_list_free(struct file_list *files) free(files); } + +struct file_list *file_list_dup(struct file_list *old) +{ + struct file_list_entry *old_entry; + struct file_list *new; + + new = xzalloc(sizeof(*new)); + + INIT_LIST_HEAD(&new->list); + + list_for_each_entry(old_entry, &old->list, list) { + (void)file_list_add_entry(new, old_entry->name, old_entry->filename, + old_entry->flags); /* can't fail */ + new->num_entries++; + } + + return new; +} + +char *file_list_to_str(const struct file_list *files) +{ + struct file_list_entry *entry; + struct string_list sl; + char *str; + + if (!files) + return strdup(""); + + string_list_init(&sl); + + list_for_each_entry(entry, &files->list, list) { + int ret = string_list_add_asprintf(&sl, "%s(%s)%s", entry->filename, entry->name, + flags_to_str(entry->flags)); + if (ret) { + str = ERR_PTR(ret); + goto out; + } + } + + str = string_list_join(&sl, ","); +out: + string_list_free(&sl); + + return str; +} + +int file_list_detect_all(const struct file_list *files) +{ + struct file_list_entry *fentry; + struct stat s; + int i = 0; + + list_for_each_entry(fentry, &files->list, list) { + if (stat(fentry->filename, &s)) + continue; + if (device_detect_by_name(devpath_to_name(fentry->filename)) == 0) + i++; + } + + return i; +} diff --git a/common/system-partitions.c b/common/system-partitions.c new file mode 100644 index 0000000000..547e08a9f3 --- /dev/null +++ b/common/system-partitions.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 Ahmad Fatoum, Pengutronix + */ + +#include <file-list.h> +#include <param.h> +#include <globalvar.h> +#include <init.h> +#include <magicvar.h> +#include <system-partitions.h> + +static struct file_list *system_partitions; + +bool system_partitions_empty(void) +{ + return file_list_empty(system_partitions); +} + +struct file_list *system_partitions_get(void) +{ + return file_list_dup(system_partitions); +} + +void system_partitions_set(struct file_list *files) +{ + file_list_free(system_partitions); + system_partitions = files; +} + +static int system_partitions_var_init(void) +{ + struct param_d *param; + + system_partitions = file_list_parse(""); + param = dev_add_param_file_list(&global_device, "system.partitions", + NULL, NULL, &system_partitions, NULL); + + return PTR_ERR_OR_ZERO(param); +} +postcore_initcall(system_partitions_var_init); + +BAREBOX_MAGICVAR(global.system.partitions, + "board-specific list of updatable partitions"); diff --git a/common/usbgadget.c b/common/usbgadget.c index feec0b6634..d4437b5169 100644 --- a/common/usbgadget.c +++ b/common/usbgadget.c @@ -17,6 +17,7 @@ #include <usb/gadget-multi.h> #include <globalvar.h> #include <magicvar.h> +#include <system-partitions.h> static int autostart; static int acm; @@ -24,14 +25,29 @@ static char *dfu_function; static struct file_list *parse(const char *files) { - struct file_list *list = file_list_parse(files); + struct file_list *list; + + if (!files) + return NULL; + + list = file_list_parse(files); if (IS_ERR(list)) { pr_err("Parsing file list \"%s\" failed: %pe\n", files, list); return NULL; } + return list; } +static inline struct file_list *get_dfu_function(void) +{ + if (dfu_function && *dfu_function) + return file_list_parse(dfu_function); + if (!system_partitions_empty()) + return system_partitions_get(); + return NULL; +} + int usbgadget_register(bool dfu, const char *dfu_opts, bool fastboot, const char *fastboot_opts, bool acm, bool export_bbu) @@ -39,46 +55,44 @@ int usbgadget_register(bool dfu, const char *dfu_opts, int ret; struct device_d *dev; struct f_multi_opts *opts; - const char *fastboot_partitions = get_fastboot_partitions(); - - if (dfu && !dfu_opts && dfu_function && *dfu_function) - dfu_opts = dfu_function; - - if (IS_ENABLED(CONFIG_FASTBOOT_BASE) && fastboot && !fastboot_opts && - fastboot_partitions && *fastboot_partitions) - fastboot_opts = fastboot_partitions; - - if (!dfu_opts && !fastboot_opts && !acm) - return COMMAND_ERROR_USAGE; - - /* - * Creating a gadget with both DFU and Fastboot doesn't work. - * Both client tools seem to assume that the device only has - * a single configuration - */ - if (fastboot_opts && dfu_opts) { - pr_err("Only one of Fastboot and DFU allowed\n"); - return -EINVAL; - } opts = xzalloc(sizeof(*opts)); opts->release = usb_multi_opts_release; - if (fastboot_opts) { + if (dfu) { + opts->dfu_opts.files = parse(dfu_opts); + if (IS_ENABLED(CONFIG_USB_GADGET_DFU) && file_list_empty(opts->dfu_opts.files)) { + file_list_free(opts->dfu_opts.files); + opts->dfu_opts.files = get_dfu_function(); + } + } + + if (fastboot) { opts->fastboot_opts.files = parse(fastboot_opts); + if (IS_ENABLED(CONFIG_FASTBOOT_BASE) && file_list_empty(opts->fastboot_opts.files)) { + file_list_free(opts->fastboot_opts.files); + opts->fastboot_opts.files = get_fastboot_partitions(); + } + opts->fastboot_opts.export_bbu = export_bbu; } - if (dfu_opts) - opts->dfu_opts.files = parse(dfu_opts); + opts->create_acm = acm; - if (!opts->dfu_opts.files && !opts->fastboot_opts.files && !acm) { + if (usb_multi_count_functions(opts) == 0) { pr_warn("No functions to register\n"); - free(opts); - return 0; + ret = COMMAND_ERROR_USAGE; + goto err; } - opts->create_acm = acm; + /* + * Creating a gadget with both DFU and Fastboot may not work. + * fastboot 1:8.1.0+r23-5 can deal with it, but dfu-util 0.9 + * seems to assume that the device only has a single configuration + * That's not our fault though. Emit a warning and continue + */ + if (!file_list_empty(opts->fastboot_opts.files) && !file_list_empty(opts->dfu_opts.files)) + pr_warn("Both DFU and Fastboot enabled. dfu-util may not like this!\n"); dev = get_device_by_name("otg"); if (dev) @@ -86,7 +100,11 @@ int usbgadget_register(bool dfu, const char *dfu_opts, ret = usb_multi_register(opts); if (ret) - usb_multi_opts_release(opts); + goto err; + + return 0; +err: + usb_multi_opts_release(opts); return ret; } @@ -97,7 +115,7 @@ static int usbgadget_autostart_set(struct param_d *param, void *ctx) bool fastboot_bbu = get_fastboot_bbu(); int err; - if (!IS_ENABLED(CONFIG_USB_GADGET_AUTOSTART) || !autostart || started) + if (!autostart || started) return 0; err = usbgadget_register(true, NULL, true, NULL, acm, fastboot_bbu); @@ -109,17 +127,21 @@ static int usbgadget_autostart_set(struct param_d *param, void *ctx) static int usbgadget_globalvars_init(void) { - if (IS_ENABLED(CONFIG_USB_GADGET_AUTOSTART)) { - globalvar_add_bool("usbgadget.autostart", usbgadget_autostart_set, - &autostart, NULL); - globalvar_add_simple_bool("usbgadget.acm", &acm); - } + globalvar_add_simple_bool("usbgadget.acm", &acm); globalvar_add_simple_string("usbgadget.dfu_function", &dfu_function); return 0; } device_initcall(usbgadget_globalvars_init); +static int usbgadget_autostart_init(void) +{ + if (IS_ENABLED(CONFIG_USB_GADGET_AUTOSTART)) + globalvar_add_bool("usbgadget.autostart", usbgadget_autostart_set, &autostart, NULL); + return 0; +} +postenvironment_initcall(usbgadget_autostart_init); + BAREBOX_MAGICVAR(global.usbgadget.autostart, "usbgadget: Automatically start usbgadget on boot"); BAREBOX_MAGICVAR(global.usbgadget.acm, |