* [PATCH 0/9] Fastboot customization support
@ 2018-02-09 9:43 Sascha Hauer
2018-02-09 9:43 ` [PATCH 1/9] ubiformat: Allow to ubiformat with a buffer given Sascha Hauer
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: Sascha Hauer @ 2018-02-09 9:43 UTC (permalink / raw)
To: Barebox List
In a customer project we have to do some customization to the fastboot
support. In particular, we have to check signatures in uploaded images,
which requires us to upload the whole image before it can be flashed.
This contradicts Fastboot sparse support, so we make Sparse support
optional in this series.
We decided to use FIT images as format to the signed images, so now we
are in the situation that we want to hold big FIT images in memory and
not unnecessarily copy it. Normally Fastboot temporarily stores a file
in RAMFS. This file can't be directly used by the FIT image code though,
so we add a compile time option to store the temporary fastboot image as
a buffer. This can be directly reused by the FIT image code (thanks to
recent FIT image changes).
Last not least we add hooks to the fastboot code. These can be used
to handle commands in a special way, like for example to deny certain
commands or to implement special commands. Also there is a "flash"
hook which can be used to add a custom flash operation, like for example
for our customer to implement signature checking of the FIT images.
Sascha
Sascha Hauer (9):
ubiformat: Allow to ubiformat with a buffer given
usb: gadget: fastboot: Make sparse support optional
usb: gadget: fastboot: pass struct f_fastboot * around
usb: gadget: fastboot: use read_file_2
usb: gadget: fastboot: Always remove temporary file
usb: gadget: fastboot: fix typo
usb: gadget: fastboot: beautify fb_run_command()
usb: gadget: fastboot: Add option to download to a buffer
usb: gadget: fastboot: Add external command execution support
common/ubiformat.c | 55 ++++++----
drivers/usb/gadget/Kconfig | 22 +++-
drivers/usb/gadget/f_fastboot.c | 216 ++++++++++++++++++++++++++--------------
drivers/usb/gadget/multi.c | 2 +
include/ubiformat.h | 7 ++
include/usb/fastboot.h | 17 ++++
6 files changed, 222 insertions(+), 97 deletions(-)
--
2.15.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/9] ubiformat: Allow to ubiformat with a buffer given
2018-02-09 9:43 [PATCH 0/9] Fastboot customization support Sascha Hauer
@ 2018-02-09 9:43 ` Sascha Hauer
2018-02-09 9:43 ` [PATCH 2/9] usb: gadget: fastboot: Make sparse support optional Sascha Hauer
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2018-02-09 9:43 UTC (permalink / raw)
To: Barebox List
So far ubiformat can only handle files. Make it possible to pass
a buffer into ubiformat.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
common/ubiformat.c | 55 +++++++++++++++++++++++++++++++++++------------------
include/ubiformat.h | 7 +++++++
2 files changed, 43 insertions(+), 19 deletions(-)
diff --git a/common/ubiformat.c b/common/ubiformat.c
index f728119b9a..9fe1c7c501 100644
--- a/common/ubiformat.c
+++ b/common/ubiformat.c
@@ -187,16 +187,22 @@ static int mark_bad(struct ubiformat_args *args, struct mtd_info *mtd,
static int flash_image(struct ubiformat_args *args, struct mtd_info *mtd,
const struct ubigen_info *ui, struct ubi_scan_info *si)
{
- int fd, img_ebs, eb, written_ebs = 0, ret = -1, eb_cnt;
+ int fd = 0, img_ebs, eb, written_ebs = 0, ret = -1, eb_cnt;
off_t st_size;
char *buf = NULL;
uint64_t lastprint = 0;
+ const void *inbuf = NULL;
eb_cnt = mtd_num_pebs(mtd);
- fd = open_file(args->image, &st_size);
- if (fd < 0)
- return fd;
+ if (args->image) {
+ fd = open_file(args->image, &st_size);
+ if (fd < 0)
+ return fd;
+ } else {
+ inbuf = args->image_buf;
+ st_size = args->image_size;
+ }
buf = malloc(mtd->erasesize);
if (!buf) {
@@ -207,20 +213,20 @@ static int flash_image(struct ubiformat_args *args, struct mtd_info *mtd,
img_ebs = st_size / mtd->erasesize;
if (img_ebs > si->good_cnt) {
- sys_errmsg("file \"%s\" is too large (%lld bytes)",
- args->image, (long long)st_size);
+ sys_errmsg("image is too large (%lld bytes)",
+ (long long)st_size);
goto out_close;
}
if (st_size % mtd->erasesize) {
- sys_errmsg("file \"%s\" (size %lld bytes) is not multiple of "
+ sys_errmsg("image (size %lld bytes) is not multiple of "
"eraseblock size (%d bytes)",
- args->image, (long long)st_size, mtd->erasesize);
+ (long long)st_size, mtd->erasesize);
goto out_close;
}
if (st_size == 0) {
- sys_errmsg("file \"%s\" has size 0 bytes", args->image);
+ sys_errmsg("image has size 0 bytes");
goto out_close;
}
@@ -260,11 +266,16 @@ static int flash_image(struct ubiformat_args *args, struct mtd_info *mtd,
continue;
}
- err = read_full(fd, buf, mtd->erasesize);
- if (err < 0) {
- sys_errmsg("failed to read eraseblock %d from \"%s\"",
- written_ebs, args->image);
- goto out_close;
+ if (args->image) {
+ err = read_full(fd, buf, mtd->erasesize);
+ if (err < 0) {
+ sys_errmsg("failed to read eraseblock %d from image",
+ written_ebs);
+ goto out_close;
+ }
+ } else {
+ memcpy(buf, inbuf, mtd->erasesize);
+ inbuf += mtd->erasesize;
}
if (args->override_ec)
@@ -280,8 +291,8 @@ static int flash_image(struct ubiformat_args *args, struct mtd_info *mtd,
err = change_ech((struct ubi_ec_hdr *)buf, ui->image_seq, ec);
if (err) {
- errmsg("bad EC header at eraseblock %d of \"%s\"",
- written_ebs, args->image);
+ errmsg("bad EC header at eraseblock %d of image",
+ written_ebs);
goto out_close;
}
@@ -317,7 +328,8 @@ static int flash_image(struct ubiformat_args *args, struct mtd_info *mtd,
out_close:
free(buf);
- close(fd);
+ if (args->image)
+ close(fd);
return ret;
}
@@ -454,6 +466,11 @@ out_free:
return -1;
}
+static bool ubiformat_has_image(struct ubiformat_args *args)
+{
+ return args->image || args->image_buf;
+}
+
int ubiformat(struct mtd_info *mtd, struct ubiformat_args *args)
{
int err, verbose, eb_cnt;
@@ -555,7 +572,7 @@ int ubiformat(struct mtd_info *mtd, struct ubiformat_args *args)
goto out_free;
}
- if (si->good_cnt < 2 && (!args->novtbl || args->image)) {
+ if (si->good_cnt < 2 && (!args->novtbl || ubiformat_has_image(args))) {
errmsg("too few non-bad eraseblocks (%d) on %s",
si->good_cnt, mtd->name);
err = -EINVAL;
@@ -654,7 +671,7 @@ int ubiformat(struct mtd_info *mtd, struct ubiformat_args *args)
}
}
- if (args->image) {
+ if (ubiformat_has_image(args)) {
err = flash_image(args, mtd, &ui, si);
if (err < 0)
goto out_free;
diff --git a/include/ubiformat.h b/include/ubiformat.h
index 8305a853c7..8a7a16ac18 100644
--- a/include/ubiformat.h
+++ b/include/ubiformat.h
@@ -15,7 +15,14 @@ struct ubiformat_args {
int ubi_ver;
uint32_t image_seq;
long long ec;
+
+ /*
+ * Either set image if you have a file or set image_buf / image_size
+ * if you have a buffer.
+ */
const char *image;
+ const void *image_buf;
+ loff_t image_size;
};
int ubiformat(struct mtd_info *mtd, struct ubiformat_args *args);
--
2.15.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/9] usb: gadget: fastboot: Make sparse support optional
2018-02-09 9:43 [PATCH 0/9] Fastboot customization support Sascha Hauer
2018-02-09 9:43 ` [PATCH 1/9] ubiformat: Allow to ubiformat with a buffer given Sascha Hauer
@ 2018-02-09 9:43 ` Sascha Hauer
2018-02-09 9:43 ` [PATCH 3/9] usb: gadget: fastboot: pass struct f_fastboot * around Sascha Hauer
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2018-02-09 9:43 UTC (permalink / raw)
To: Barebox List
Sparse support is not always desired, make it optional.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/usb/gadget/Kconfig | 10 +++++++++-
drivers/usb/gadget/f_fastboot.c | 14 +++++++++++---
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index b612d39a8e..e2dc7807a0 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -57,7 +57,15 @@ config USB_GADGET_FASTBOOT
bool
select BANNER
select FILE_LIST
- select IMAGE_SPARSE
prompt "Android Fastboot support"
+config USB_GADGET_FASTBOOT_SPARSE
+ bool
+ select IMAGE_SPARSE
+ prompt "Enable Fastboot sparse image support"
+ help
+ Sparse images are a way for the fastboot protocol to write
+ images that are bigger than the available memory. If unsure,
+ say yes here.
+
endif
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 87a43cc60e..8da317f83a 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -322,8 +322,10 @@ static int fastboot_bind(struct usb_configuration *c, struct usb_function *f)
fb_setvar(var, "0.4");
var = fb_addvar(f_fb, "bootloader-version");
fb_setvar(var, release_string);
- var = fb_addvar(f_fb, "max-download-size");
- fb_setvar(var, "%u", fastboot_max_download_size);
+ if (IS_ENABLED(USB_GADGET_FASTBOOT_SPARSE)) {
+ var = fb_addvar(f_fb, "max-download-size");
+ fb_setvar(var, "%u", fastboot_max_download_size);
+ }
if (IS_ENABLED(CONFIG_BAREBOX_UPDATE) && opts->export_bbu)
bbu_handlers_iterate(fastboot_add_bbu_variables, f_fb);
@@ -906,6 +908,11 @@ static void cb_flash(struct usb_ep *ep, struct usb_request *req, const char *cmd
filename = fentry->filename;
if (filetype == filetype_android_sparse) {
+ if (!IS_ENABLED(USB_GADGET_FASTBOOT_SPARSE)) {
+ fastboot_tx_print(f_fb, "FAILsparse image not supported");
+ return;
+ }
+
ret = fastboot_handle_sparse(f_fb, fentry);
if (ret) {
fastboot_tx_print(f_fb, "FAILwriting sparse image: %s",
@@ -1172,7 +1179,8 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
static int fastboot_globalvars_init(void)
{
- globalvar_add_simple_int("usbgadget.fastboot_max_download_size",
+ if (IS_ENABLED(USB_GADGET_FASTBOOT_SPARSE))
+ globalvar_add_simple_int("usbgadget.fastboot_max_download_size",
&fastboot_max_download_size, "%u");
return 0;
--
2.15.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/9] usb: gadget: fastboot: pass struct f_fastboot * around
2018-02-09 9:43 [PATCH 0/9] Fastboot customization support Sascha Hauer
2018-02-09 9:43 ` [PATCH 1/9] ubiformat: Allow to ubiformat with a buffer given Sascha Hauer
2018-02-09 9:43 ` [PATCH 2/9] usb: gadget: fastboot: Make sparse support optional Sascha Hauer
@ 2018-02-09 9:43 ` Sascha Hauer
2018-02-09 9:43 ` [PATCH 4/9] usb: gadget: fastboot: use read_file_2 Sascha Hauer
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2018-02-09 9:43 UTC (permalink / raw)
To: Barebox List
The different fastboot commands mostly do not need the USB endpoint
or the USB request, they need the context data structure struct
f_fastboot * instead, so rather pass this one around between the
different functions.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/usb/gadget/f_fastboot.c | 49 ++++++++++++++++-------------------------
1 file changed, 19 insertions(+), 30 deletions(-)
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 8da317f83a..81522cbba6 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -557,10 +557,8 @@ static void compl_do_reset(struct usb_ep *ep, struct usb_request *req)
restart_machine();
}
-static void cb_reboot(struct usb_ep *ep, struct usb_request *req, const char *cmd)
+static void cb_reboot(struct f_fastboot *f_fb, const char *cmd)
{
- struct f_fastboot *f_fb = req->context;
-
f_fb->in_req->complete = compl_do_reset;
fastboot_tx_print(f_fb, "OKAY");
}
@@ -572,9 +570,8 @@ static int strcmp_l1(const char *s1, const char *s2)
return strncmp(s1, s2, strlen(s1));
}
-static void cb_getvar(struct usb_ep *ep, struct usb_request *req, const char *cmd)
+static void cb_getvar(struct f_fastboot *f_fb, const char *cmd)
{
- struct f_fastboot *f_fb = req->context;
struct fb_variable *var;
pr_debug("getvar: \"%s\"\n", cmd);
@@ -640,10 +637,8 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
usb_ep_queue(ep, req);
}
-static void cb_download(struct usb_ep *ep, struct usb_request *req, const char *cmd)
+static void cb_download(struct f_fastboot *f_fb, const char *cmd)
{
- struct f_fastboot *f_fb = req->context;
-
f_fb->download_size = simple_strtoul(cmd, NULL, 16);
f_fb->download_bytes = 0;
@@ -660,6 +655,8 @@ static void cb_download(struct usb_ep *ep, struct usb_request *req, const char *
if (!f_fb->download_size) {
fastboot_tx_print(f_fb, "FAILdata invalid size");
} else {
+ struct usb_request *req = f_fb->out_req;
+ struct usb_ep *ep = f_fb->out_ep;
fastboot_tx_print(f_fb, "DATA%08x", f_fb->download_size);
req->complete = rx_handler_dl_image;
req->length = EP_BUFFER_SIZE;
@@ -688,11 +685,8 @@ static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req)
pr_err("Booting failed\n");
}
-static void __maybe_unused cb_boot(struct usb_ep *ep, struct usb_request *req,
- const char *opt)
+static void __maybe_unused cb_boot(struct f_fastboot *f_fb, const char *opt)
{
- struct f_fastboot *f_fb = req->context;
-
f_fb->in_req->complete = do_bootm_on_complete;
fastboot_tx_print(f_fb, "OKAY");
}
@@ -888,9 +882,8 @@ out_close_fd:
return ret;
}
-static void cb_flash(struct usb_ep *ep, struct usb_request *req, const char *cmd)
+static void cb_flash(struct f_fastboot *f_fb, const char *cmd)
{
- struct f_fastboot *f_fb = req->context;
struct file_list_entry *fentry;
int ret;
const char *filename = NULL;
@@ -988,9 +981,8 @@ out:
fastboot_tx_print(f_fb, "OKAY");
}
-static void cb_erase(struct usb_ep *ep, struct usb_request *req, const char *cmd)
+static void cb_erase(struct f_fastboot *f_fb, const char *cmd)
{
- struct f_fastboot *f_fb = req->context;
struct file_list_entry *fentry;
int ret;
const char *filename = NULL;
@@ -1027,14 +1019,13 @@ static void cb_erase(struct usb_ep *ep, struct usb_request *req, const char *cmd
struct cmd_dispatch_info {
char *cmd;
- void (*cb)(struct usb_ep *ep, struct usb_request *req, const char *opt);
+ void (*cb)(struct f_fastboot *f_fb, const char *opt);
};
-static void fb_run_command(struct usb_ep *ep, struct usb_request *req, const char *cmd,
+static void fb_run_command(struct f_fastboot *f_fb, const char *cmd,
const struct cmd_dispatch_info *cmds, int num_commands)
{
- void (*func_cb)(struct usb_ep *ep, struct usb_request *req, const char *cmd) = NULL;
- struct f_fastboot *f_fb = req->context;
+ void (*func_cb)(struct f_fastboot *f_fb, const char *cmd) = NULL;
int i;
console_countdown_abort();
@@ -1043,7 +1034,7 @@ static void fb_run_command(struct usb_ep *ep, struct usb_request *req, const cha
if (!strcmp_l1(cmds[i].cmd, cmd)) {
func_cb = cmds[i].cb;
cmd += strlen(cmds[i].cmd);
- func_cb(ep, req, cmd);
+ func_cb(f_fb, cmd);
return;
}
}
@@ -1051,9 +1042,8 @@ static void fb_run_command(struct usb_ep *ep, struct usb_request *req, const cha
fastboot_tx_print(f_fb, "FAILunknown command %s", cmd);
}
-static void cb_oem_getenv(struct usb_ep *ep, struct usb_request *req, const char *cmd)
+static void cb_oem_getenv(struct f_fastboot *f_fb, const char *cmd)
{
- struct f_fastboot *f_fb = req->context;
const char *value;
pr_debug("%s: \"%s\"\n", __func__, cmd);
@@ -1064,9 +1054,8 @@ static void cb_oem_getenv(struct usb_ep *ep, struct usb_request *req, const char
fastboot_tx_print(f_fb, "OKAY");
}
-static void cb_oem_setenv(struct usb_ep *ep, struct usb_request *req, const char *cmd)
+static void cb_oem_setenv(struct f_fastboot *f_fb, const char *cmd)
{
- struct f_fastboot *f_fb = req->context;
char *var = xstrdup(cmd);
char *value;
int ret;
@@ -1093,9 +1082,8 @@ out:
fastboot_tx_print(f_fb, "FAIL%s", strerror(-ret));
}
-static void cb_oem_exec(struct usb_ep *ep, struct usb_request *req, const char *cmd)
+static void cb_oem_exec(struct f_fastboot *f_fb, const char *cmd)
{
- struct f_fastboot *f_fb = req->context;
int ret;
if (!IS_ENABLED(CONFIG_COMMAND_SUPPORT)) {
@@ -1125,11 +1113,11 @@ static const struct cmd_dispatch_info cmd_oem_dispatch_info[] = {
},
};
-static void cb_oem(struct usb_ep *ep, struct usb_request *req, const char *cmd)
+static void cb_oem(struct f_fastboot *f_fb, const char *cmd)
{
pr_debug("%s: \"%s\"\n", __func__, cmd);
- fb_run_command(ep, req, cmd, cmd_oem_dispatch_info, ARRAY_SIZE(cmd_oem_dispatch_info));
+ fb_run_command(f_fb, cmd, cmd_oem_dispatch_info, ARRAY_SIZE(cmd_oem_dispatch_info));
}
static const struct cmd_dispatch_info cmd_dispatch_info[] = {
@@ -1162,13 +1150,14 @@ static const struct cmd_dispatch_info cmd_dispatch_info[] = {
static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
{
char *cmdbuf = req->buf;
+ struct f_fastboot *f_fb = req->context;
if (req->status != 0)
return;
*(cmdbuf + req->actual) = 0;
- fb_run_command(ep, req, cmdbuf, cmd_dispatch_info,
+ fb_run_command(f_fb, cmdbuf, cmd_dispatch_info,
ARRAY_SIZE(cmd_dispatch_info));
*cmdbuf = '\0';
--
2.15.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 4/9] usb: gadget: fastboot: use read_file_2
2018-02-09 9:43 [PATCH 0/9] Fastboot customization support Sascha Hauer
` (2 preceding siblings ...)
2018-02-09 9:43 ` [PATCH 3/9] usb: gadget: fastboot: pass struct f_fastboot * around Sascha Hauer
@ 2018-02-09 9:43 ` Sascha Hauer
2018-02-09 9:43 ` [PATCH 5/9] usb: gadget: fastboot: Always remove temporary file Sascha Hauer
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2018-02-09 9:43 UTC (permalink / raw)
To: Barebox List
read_file_2 gives us a proper error code and allows us
to specify a maximum size which in this case we happen to know.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/usb/gadget/f_fastboot.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 81522cbba6..62b13bcb8c 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -947,8 +947,9 @@ static void cb_flash(struct f_fastboot *f_fb, const char *cmd)
fastboot_tx_print(f_fb, "INFOThis is a barebox image...");
- image = read_file(data.imagefile, &data.len);
- if (!image) {
+ ret = read_file_2(data.imagefile, &data.len, &image,
+ f_fb->download_size);
+ if (ret) {
fastboot_tx_print(f_fb, "FAILreading barebox");
return;
}
--
2.15.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 5/9] usb: gadget: fastboot: Always remove temporary file
2018-02-09 9:43 [PATCH 0/9] Fastboot customization support Sascha Hauer
` (3 preceding siblings ...)
2018-02-09 9:43 ` [PATCH 4/9] usb: gadget: fastboot: use read_file_2 Sascha Hauer
@ 2018-02-09 9:43 ` Sascha Hauer
2018-02-09 9:43 ` [PATCH 6/9] usb: gadget: fastboot: fix typo Sascha Hauer
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2018-02-09 9:43 UTC (permalink / raw)
To: Barebox List
We should consistently remove the temporary image file, regardless
of the error code. To do so, always jump to the end of the function
where the temporary file is removed.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/usb/gadget/f_fastboot.c | 34 ++++++++++++++--------------------
1 file changed, 14 insertions(+), 20 deletions(-)
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 62b13bcb8c..db9b906b2b 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -895,7 +895,8 @@ static void cb_flash(struct f_fastboot *f_fb, const char *cmd)
if (!fentry) {
fastboot_tx_print(f_fb, "FAILNo such partition: %s", cmd);
- return;
+ ret = -ENOENT;
+ goto out;
}
filename = fentry->filename;
@@ -903,22 +904,21 @@ static void cb_flash(struct f_fastboot *f_fb, const char *cmd)
if (filetype == filetype_android_sparse) {
if (!IS_ENABLED(USB_GADGET_FASTBOOT_SPARSE)) {
fastboot_tx_print(f_fb, "FAILsparse image not supported");
- return;
+ ret = -EOPNOTSUPP;
+ goto out;
}
ret = fastboot_handle_sparse(f_fb, fentry);
- if (ret) {
+ if (ret)
fastboot_tx_print(f_fb, "FAILwriting sparse image: %s",
strerror(-ret));
- return;
- }
goto out;
}
ret = check_ubi(f_fb, fentry, filetype);
if (ret < 0)
- return;
+ goto out;
if (ret > 0) {
struct mtd_info *mtd;
@@ -926,11 +926,8 @@ static void cb_flash(struct f_fastboot *f_fb, const char *cmd)
mtd = get_mtd(f_fb, fentry->filename);
ret = do_ubiformat(f_fb, mtd, FASTBOOT_TMPFILE);
- if (ret) {
+ if (ret)
fastboot_tx_print(f_fb, "FAILwrite partition: %s", strerror(-ret));
- return;
- }
-
goto out;
}
@@ -951,7 +948,7 @@ static void cb_flash(struct f_fastboot *f_fb, const char *cmd)
f_fb->download_size);
if (ret) {
fastboot_tx_print(f_fb, "FAILreading barebox");
- return;
+ goto out;
}
data.image = image;
@@ -960,10 +957,8 @@ static void cb_flash(struct f_fastboot *f_fb, const char *cmd)
free(image);
- if (ret) {
+ if (ret)
fastboot_tx_print(f_fb, "FAILupdate barebox: %s", strerror(-ret));
- return;
- }
goto out;
}
@@ -971,15 +966,14 @@ static void cb_flash(struct f_fastboot *f_fb, const char *cmd)
copy:
ret = copy_file(FASTBOOT_TMPFILE, filename, 1);
- unlink(FASTBOOT_TMPFILE);
-
- if (ret) {
+ if (ret)
fastboot_tx_print(f_fb, "FAILwrite partition: %s", strerror(-ret));
- return;
- }
out:
- fastboot_tx_print(f_fb, "OKAY");
+ if (!ret)
+ fastboot_tx_print(f_fb, "OKAY");
+
+ unlink(FASTBOOT_TMPFILE);
}
static void cb_erase(struct f_fastboot *f_fb, const char *cmd)
--
2.15.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 6/9] usb: gadget: fastboot: fix typo
2018-02-09 9:43 [PATCH 0/9] Fastboot customization support Sascha Hauer
` (4 preceding siblings ...)
2018-02-09 9:43 ` [PATCH 5/9] usb: gadget: fastboot: Always remove temporary file Sascha Hauer
@ 2018-02-09 9:43 ` Sascha Hauer
2018-02-09 9:43 ` [PATCH 7/9] usb: gadget: fastboot: beautify fb_run_command() Sascha Hauer
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2018-02-09 9:43 UTC (permalink / raw)
To: Barebox List
s/correspoinding/corresponding/
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/usb/gadget/f_fastboot.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index db9b906b2b..e474543e2c 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -71,7 +71,7 @@ struct fb_variable {
struct f_fastboot {
struct usb_function func;
- /* IN/OUT EP's and correspoinding requests */
+ /* IN/OUT EP's and corresponding requests */
struct usb_ep *in_ep, *out_ep;
struct usb_request *in_req, *out_req;
struct file_list *files;
--
2.15.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 7/9] usb: gadget: fastboot: beautify fb_run_command()
2018-02-09 9:43 [PATCH 0/9] Fastboot customization support Sascha Hauer
` (5 preceding siblings ...)
2018-02-09 9:43 ` [PATCH 6/9] usb: gadget: fastboot: fix typo Sascha Hauer
@ 2018-02-09 9:43 ` Sascha Hauer
2018-02-09 9:43 ` [PATCH 8/9] usb: gadget: fastboot: Add option to download to a buffer Sascha Hauer
2018-02-09 9:43 ` [PATCH 9/9] usb: gadget: fastboot: Add external command execution support Sascha Hauer
8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2018-02-09 9:43 UTC (permalink / raw)
To: Barebox List
Only some refactoring, no functional change intended.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/usb/gadget/f_fastboot.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index e474543e2c..d349227f08 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -1017,24 +1017,25 @@ struct cmd_dispatch_info {
void (*cb)(struct f_fastboot *f_fb, const char *opt);
};
-static void fb_run_command(struct f_fastboot *f_fb, const char *cmd,
+static void fb_run_command(struct f_fastboot *f_fb, const char *cmdbuf,
const struct cmd_dispatch_info *cmds, int num_commands)
{
- void (*func_cb)(struct f_fastboot *f_fb, const char *cmd) = NULL;
+ const struct cmd_dispatch_info *cmd;
int i;
console_countdown_abort();
for (i = 0; i < num_commands; i++) {
- if (!strcmp_l1(cmds[i].cmd, cmd)) {
- func_cb = cmds[i].cb;
- cmd += strlen(cmds[i].cmd);
- func_cb(f_fb, cmd);
+ cmd = &cmds[i];
+
+ if (!strcmp_l1(cmd->cmd, cmdbuf)) {
+ cmd->cb(f_fb, cmdbuf + strlen(cmd->cmd));
+
return;
}
}
- fastboot_tx_print(f_fb, "FAILunknown command %s", cmd);
+ fastboot_tx_print(f_fb, "FAILunknown command %s", cmdbuf);
}
static void cb_oem_getenv(struct f_fastboot *f_fb, const char *cmd)
--
2.15.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 8/9] usb: gadget: fastboot: Add option to download to a buffer
2018-02-09 9:43 [PATCH 0/9] Fastboot customization support Sascha Hauer
` (6 preceding siblings ...)
2018-02-09 9:43 ` [PATCH 7/9] usb: gadget: fastboot: beautify fb_run_command() Sascha Hauer
@ 2018-02-09 9:43 ` Sascha Hauer
2018-02-09 9:43 ` [PATCH 9/9] usb: gadget: fastboot: Add external command execution support Sascha Hauer
8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2018-02-09 9:43 UTC (permalink / raw)
To: Barebox List
This adds an option to download the image data to a temporary
buffer rather than to a file. While a file is generally the
better option, in some special cases a buffer is better for
memory usage.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/usb/gadget/Kconfig | 12 +++++
drivers/usb/gadget/f_fastboot.c | 102 ++++++++++++++++++++++++++++++----------
2 files changed, 88 insertions(+), 26 deletions(-)
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index e2dc7807a0..b0408e3bbe 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -68,4 +68,16 @@ config USB_GADGET_FASTBOOT_SPARSE
images that are bigger than the available memory. If unsure,
say yes here.
+config USB_GADGET_FASTBOOT_BUF
+ bool
+ depends on USB_GADGET_FASTBOOT
+ prompt "Download files to temporary buffer instead of file"
+ help
+ With this option enabled the fastboot code will download files to a
+ temporary buffer instead of a temporary file. Normally you want to
+ use a file as this also works when your memory is fragmented. However,
+ in some special cases, when the file consumer also better copes with
+ a buffer, then using a buffer might be better.
+
+ Say no here unless you know what you are doing.
endif
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index d349227f08..b851e8d1c3 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -76,11 +76,21 @@ struct f_fastboot {
struct usb_request *in_req, *out_req;
struct file_list *files;
int download_fd;
+ void *buf;
+
size_t download_bytes;
size_t download_size;
struct list_head variables;
};
+static inline bool fastboot_download_to_buf(struct f_fastboot *f_fb)
+{
+ if (IS_ENABLED(CONFIG_USB_GADGET_FASTBOOT_BUF))
+ return true;
+ else
+ return false;
+}
+
static inline struct f_fastboot *func_to_fastboot(struct usb_function *f)
{
return container_of(f, struct f_fastboot, func);
@@ -605,10 +615,14 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
return;
}
- ret = write(f_fb->download_fd, buffer, req->actual);
- if (ret < 0) {
- fastboot_tx_print(f_fb, "FAIL%s", strerror(-ret));
- return;
+ if (fastboot_download_to_buf(f_fb)) {
+ memcpy(f_fb->buf + f_fb->download_bytes, buffer, req->actual);
+ } else {
+ ret = write(f_fb->download_fd, buffer, req->actual);
+ if (ret < 0) {
+ fastboot_tx_print(f_fb, "FAIL%s", strerror(-ret));
+ return;
+ }
}
f_fb->download_bytes += req->actual;
@@ -646,10 +660,19 @@ static void cb_download(struct f_fastboot *f_fb, const char *cmd)
init_progression_bar(f_fb->download_size);
- f_fb->download_fd = open(FASTBOOT_TMPFILE, O_WRONLY | O_CREAT | O_TRUNC);
- if (f_fb->download_fd < 0) {
- fastboot_tx_print(f_fb, "FAILInternal Error");
- return;
+ if (fastboot_download_to_buf(f_fb)) {
+ free(f_fb->buf);
+ f_fb->buf = malloc(f_fb->download_size);
+ if (!f_fb->buf) {
+ fastboot_tx_print(f_fb, "FAILnot enough memory");
+ return;
+ }
+ } else {
+ f_fb->download_fd = open(FASTBOOT_TMPFILE, O_WRONLY | O_CREAT | O_TRUNC);
+ if (f_fb->download_fd < 0) {
+ fastboot_tx_print(f_fb, "FAILInternal Error");
+ return;
+ }
}
if (!f_fb->download_size) {
@@ -711,11 +734,13 @@ static struct mtd_info *get_mtd(struct f_fastboot *f_fb, const char *filename)
}
static int do_ubiformat(struct f_fastboot *f_fb, struct mtd_info *mtd,
- const char *file)
+ const char *file, const void *buf, size_t len)
{
struct ubiformat_args args = {
.yes = 1,
.image = file,
+ .image_buf = buf,
+ .image_size = len,
};
if (!file)
@@ -850,7 +875,7 @@ static int fastboot_handle_sparse(struct f_fastboot *f_fb,
}
if (pos == 0) {
- ret = do_ubiformat(f_fb, mtd, NULL);
+ ret = do_ubiformat(f_fb, mtd, NULL, NULL, 0);
if (ret)
goto out;
}
@@ -886,8 +911,16 @@ static void cb_flash(struct f_fastboot *f_fb, const char *cmd)
{
struct file_list_entry *fentry;
int ret;
- const char *filename = NULL;
- enum filetype filetype = file_name_detect_type(FASTBOOT_TMPFILE);
+ const char *filename = NULL, *sourcefile;
+ enum filetype filetype;
+
+ if (fastboot_download_to_buf(f_fb)) {
+ sourcefile = NULL;
+ filetype = file_detect_type(f_fb->buf, f_fb->download_bytes);
+ } else {
+ sourcefile = FASTBOOT_TMPFILE;
+ filetype = file_name_detect_type(FASTBOOT_TMPFILE);
+ }
fastboot_tx_print(f_fb, "INFOCopying file to %s...", cmd);
@@ -908,6 +941,11 @@ static void cb_flash(struct f_fastboot *f_fb, const char *cmd)
goto out;
}
+ if (fastboot_download_to_buf(f_fb)) {
+ fastboot_tx_print(f_fb, "FAILsparse image not supported");
+ goto out;
+ }
+
ret = fastboot_handle_sparse(f_fb, fentry);
if (ret)
fastboot_tx_print(f_fb, "FAILwriting sparse image: %s",
@@ -925,17 +963,19 @@ static void cb_flash(struct f_fastboot *f_fb, const char *cmd)
mtd = get_mtd(f_fb, fentry->filename);
- ret = do_ubiformat(f_fb, mtd, FASTBOOT_TMPFILE);
- if (ret)
+ ret = do_ubiformat(f_fb, mtd, sourcefile, f_fb->buf,
+ f_fb->download_size);
+ if (ret) {
fastboot_tx_print(f_fb, "FAILwrite partition: %s", strerror(-ret));
+ goto out;
+ }
+
goto out;
}
if (IS_ENABLED(CONFIG_BAREBOX_UPDATE) && filetype_is_barebox_image(filetype)) {
- void *image;
struct bbu_data data = {
.devicefile = filename,
- .imagefile = FASTBOOT_TMPFILE,
.flags = BBU_FLAG_YES,
};
@@ -944,19 +984,22 @@ static void cb_flash(struct f_fastboot *f_fb, const char *cmd)
fastboot_tx_print(f_fb, "INFOThis is a barebox image...");
- ret = read_file_2(data.imagefile, &data.len, &image,
- f_fb->download_size);
- if (ret) {
- fastboot_tx_print(f_fb, "FAILreading barebox");
- goto out;
+ if (fastboot_download_to_buf(f_fb)) {
+ data.len = f_fb->download_size;
+ } else {
+ ret = read_file_2(data.imagefile, &data.len, &f_fb->buf,
+ f_fb->download_size);
+ if (ret) {
+ fastboot_tx_print(f_fb, "FAILreading barebox");
+ goto out;
+ }
}
- data.image = image;
+ data.image = f_fb->buf;
+ data.imagefile = sourcefile;
ret = barebox_update(&data);
- free(image);
-
if (ret)
fastboot_tx_print(f_fb, "FAILupdate barebox: %s", strerror(-ret));
@@ -964,7 +1007,10 @@ static void cb_flash(struct f_fastboot *f_fb, const char *cmd)
}
copy:
- ret = copy_file(FASTBOOT_TMPFILE, filename, 1);
+ if (fastboot_download_to_buf(f_fb))
+ ret = write_file(filename, f_fb->buf, f_fb->download_size);
+ else
+ ret = copy_file(FASTBOOT_TMPFILE, filename, 1);
if (ret)
fastboot_tx_print(f_fb, "FAILwrite partition: %s", strerror(-ret));
@@ -973,7 +1019,11 @@ out:
if (!ret)
fastboot_tx_print(f_fb, "OKAY");
- unlink(FASTBOOT_TMPFILE);
+ free(f_fb->buf);
+ f_fb->buf = NULL;
+
+ if (!fastboot_download_to_buf(f_fb))
+ unlink(FASTBOOT_TMPFILE);
}
static void cb_erase(struct f_fastboot *f_fb, const char *cmd)
--
2.15.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 9/9] usb: gadget: fastboot: Add external command execution support
2018-02-09 9:43 [PATCH 0/9] Fastboot customization support Sascha Hauer
` (7 preceding siblings ...)
2018-02-09 9:43 ` [PATCH 8/9] usb: gadget: fastboot: Add option to download to a buffer Sascha Hauer
@ 2018-02-09 9:43 ` Sascha Hauer
8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2018-02-09 9:43 UTC (permalink / raw)
To: Barebox List
Custom projects may need vendor specific expansions to the fastboot
command execution. Allow these to be implemented without messing in
the fastboot code directly.
We have a hook for all commands and also one for the "flash" command.
Each hook can decide if the generic command parser is executed
afterwards (return value FASTBOOT_CMD_FALLTHROUGH) or if the generic
parser shall be skipped (return value 0 or negative error code).
This allows board code to implement vendor specific "oem" commands
or to handle the downloaded image in a special way (i.e. do signature
checks on them)
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/usb/gadget/f_fastboot.c | 21 ++++++++++++++++++++-
drivers/usb/gadget/multi.c | 2 ++
include/usb/fastboot.h | 17 +++++++++++++++++
3 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index b851e8d1c3..787b1205ec 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -75,6 +75,9 @@ struct f_fastboot {
struct usb_ep *in_ep, *out_ep;
struct usb_request *in_req, *out_req;
struct file_list *files;
+ int (*cmd_exec)(struct f_fastboot *, const char *cmd);
+ int (*cmd_flash)(struct f_fastboot *, struct file_list_entry *entry,
+ const char *filename, const void *buf, size_t len);
int download_fd;
void *buf;
@@ -327,6 +330,8 @@ static int fastboot_bind(struct usb_configuration *c, struct usb_function *f)
struct fb_variable *var;
f_fb->files = opts->files;
+ f_fb->cmd_exec = opts->cmd_exec;
+ f_fb->cmd_flash = opts->cmd_flash;
var = fb_addvar(f_fb, "version");
fb_setvar(var, "0.4");
@@ -932,6 +937,13 @@ static void cb_flash(struct f_fastboot *f_fb, const char *cmd)
goto out;
}
+ if (f_fb->cmd_flash) {
+ ret = f_fb->cmd_flash(f_fb, fentry, sourcefile, f_fb->buf,
+ f_fb->download_size);
+ if (ret != FASTBOOT_CMD_FALLTHROUGH)
+ goto out;
+ }
+
filename = fentry->filename;
if (filetype == filetype_android_sparse) {
@@ -1197,15 +1209,22 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
{
char *cmdbuf = req->buf;
struct f_fastboot *f_fb = req->context;
+ int ret;
if (req->status != 0)
return;
*(cmdbuf + req->actual) = 0;
+ if (f_fb->cmd_exec) {
+ ret = f_fb->cmd_exec(f_fb, cmdbuf);
+ if (ret != FASTBOOT_CMD_FALLTHROUGH)
+ goto done;
+ }
+
fb_run_command(f_fb, cmdbuf, cmd_dispatch_info,
ARRAY_SIZE(cmd_dispatch_info));
-
+done:
*cmdbuf = '\0';
req->actual = 0;
memset(req->buf, 0, EP_BUFFER_SIZE);
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index 44969be0c9..d6edfb8cf2 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -128,6 +128,8 @@ static int multi_bind_fastboot(struct usb_composite_dev *cdev)
opts = container_of(fi_fastboot, struct f_fastboot_opts, func_inst);
opts->files = gadget_multi_opts->fastboot_opts.files;
+ opts->cmd_exec = gadget_multi_opts->fastboot_opts.cmd_exec;
+ opts->cmd_flash = gadget_multi_opts->fastboot_opts.cmd_flash;
opts->export_bbu = gadget_multi_opts->fastboot_opts.export_bbu;
f_fastboot = usb_get_function(fi_fastboot);
diff --git a/include/usb/fastboot.h b/include/usb/fastboot.h
index ced890c9ab..00c9d00df5 100644
--- a/include/usb/fastboot.h
+++ b/include/usb/fastboot.h
@@ -5,6 +5,8 @@
#include <file-list.h>
#include <usb/composite.h>
+struct f_fastboot;
+
/**
* struct f_fastboot_opts - options to configure the fastboot gadget
* @func_inst: The USB function instance to register on
@@ -15,6 +17,21 @@ struct f_fastboot_opts {
struct usb_function_instance func_inst;
struct file_list *files;
bool export_bbu;
+ int (*cmd_exec)(struct f_fastboot *, const char *cmd);
+ int (*cmd_flash)(struct f_fastboot *, struct file_list_entry *entry,
+ const char *filename, const void *buf, size_t len);
};
+/*
+ * Return codes for the exec_cmd callback above:
+ *
+ * FASTBOOT_CMD_FALLTHROUGH - Not handled by the external command dispatcher,
+ * handle it with internal dispatcher
+ * Other than these negative error codes mean errors handling the command and
+ * zero means the command has been successfully handled.
+ */
+#define FASTBOOT_CMD_FALLTHROUGH 1
+
+int fastboot_tx_print(struct f_fastboot *f_fb, const char *fmt, ...);
+
#endif /* _USB_FASTBOOT_H */
--
2.15.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2018-02-09 9:43 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-09 9:43 [PATCH 0/9] Fastboot customization support Sascha Hauer
2018-02-09 9:43 ` [PATCH 1/9] ubiformat: Allow to ubiformat with a buffer given Sascha Hauer
2018-02-09 9:43 ` [PATCH 2/9] usb: gadget: fastboot: Make sparse support optional Sascha Hauer
2018-02-09 9:43 ` [PATCH 3/9] usb: gadget: fastboot: pass struct f_fastboot * around Sascha Hauer
2018-02-09 9:43 ` [PATCH 4/9] usb: gadget: fastboot: use read_file_2 Sascha Hauer
2018-02-09 9:43 ` [PATCH 5/9] usb: gadget: fastboot: Always remove temporary file Sascha Hauer
2018-02-09 9:43 ` [PATCH 6/9] usb: gadget: fastboot: fix typo Sascha Hauer
2018-02-09 9:43 ` [PATCH 7/9] usb: gadget: fastboot: beautify fb_run_command() Sascha Hauer
2018-02-09 9:43 ` [PATCH 8/9] usb: gadget: fastboot: Add option to download to a buffer Sascha Hauer
2018-02-09 9:43 ` [PATCH 9/9] usb: gadget: fastboot: Add external command execution support Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox