diff --git a/commands/usbgadget.c b/commands/usbgadget.c index a7e8d6c..314884a 100644 --- a/commands/usbgadget.c +++ b/commands/usbgadget.c @@ -31,10 +31,10 @@ static int do_usbgadget(int argc, char *argv[]) { - int opt; + int opt, ret; int acm = 1, create_serial = 0; char *fastboot_opts = NULL, *dfu_opts = NULL; - struct f_multi_opts opts = {}; + struct f_multi_opts *opts; while ((opt = getopt(argc, argv, "asdA:D:")) > 0) { switch (opt) { @@ -73,19 +73,26 @@ return -EINVAL; } + opts = xzalloc(sizeof(*opts)); + opts->release = usb_multi_opts_release; + if (fastboot_opts) { - opts.fastboot_opts.files = file_list_parse(fastboot_opts); + opts->fastboot_opts.files = file_list_parse(fastboot_opts); } if (dfu_opts) { - opts.dfu_opts.files = file_list_parse(dfu_opts); + opts->dfu_opts.files = file_list_parse(dfu_opts); } if (create_serial) { - opts.create_acm = acm; + opts->create_acm = acm; } - return usb_multi_register(&opts); + ret = usb_multi_register(opts); + if (ret) + usb_multi_opts_release(opts); + + return ret; } BAREBOX_CMD_HELP_START(usbgadget) diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index a2cfc8d..6385c16 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -246,8 +246,22 @@ void usb_multi_unregister(void) { - if (gadget_multi_opts) - usb_composite_unregister(&multi_driver); + if (!gadget_multi_opts) + return; + + usb_composite_unregister(&multi_driver); + if (gadget_multi_opts->release) + gadget_multi_opts->release(gadget_multi_opts); gadget_multi_opts = NULL; } + +void usb_multi_opts_release(struct f_multi_opts *opts) +{ + if (opts->fastboot_opts.files) + file_list_free(opts->fastboot_opts.files); + if (opts->dfu_opts.files) + file_list_free(opts->dfu_opts.files); + + free(opts); +} diff --git a/include/usb/gadget-multi.h b/include/usb/gadget-multi.h index 5ca4623..81beddc 100644 --- a/include/usb/gadget-multi.h +++ b/include/usb/gadget-multi.h @@ -9,9 +9,11 @@ struct f_fastboot_opts fastboot_opts; struct f_dfu_opts dfu_opts; int create_acm; + void (*release)(struct f_multi_opts *opts); }; int usb_multi_register(struct f_multi_opts *opts); void usb_multi_unregister(void); +void usb_multi_opts_release(struct f_multi_opts *opts); #endif /* __USB_GADGET_MULTI_H */