summaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2018-12-07 10:30:12 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2018-12-07 11:25:23 +0100
commit305b9fb5ef06140685d403a95da4cf55d4cfca64 (patch)
tree3f1623fdcf52a40c0b71407088f2f5f064a40290 /drivers/usb
parent268122c1d4c00794ed87d696985889ec0f873ed2 (diff)
downloadbarebox-305b9fb5ef06140685d403a95da4cf55d4cfca64.tar.gz
barebox-305b9fb5ef06140685d403a95da4cf55d4cfca64.tar.xz
usb: gadget: fastboot: tell host that we are going to shutdown
Some commands like booting a kernel will trigger a shutdown of barebox, but the host will never notice and timeout later. Be more friendly and tell the host we are going to shutdown and end the current fastboot session. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/f_fastboot.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 8b0654dca4..08ea9bce6b 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -80,6 +80,7 @@ struct f_fastboot {
const char *filename, const void *buf, size_t len);
int download_fd;
void *buf;
+ bool active;
size_t download_bytes;
size_t download_size;
@@ -426,6 +427,8 @@ static void fastboot_unbind(struct usb_configuration *c, struct usb_function *f)
list_del(&var->list);
free(var);
}
+
+ f_fb->active = false;
}
static void fastboot_disable(struct usb_function *f)
@@ -478,13 +481,36 @@ err:
return ret;
}
+static struct f_fastboot *g_f_fb;
+
static void fastboot_free_func(struct usb_function *f)
{
struct f_fastboot *f_fb = container_of(f, struct f_fastboot, func);
+ if (g_f_fb == f_fb)
+ g_f_fb = NULL;
+
free(f_fb);
}
+/*
+ * A "oem exec bootm" or similar commands will stop barebox. Tell the
+ * fastboot command on the other side so that it doesn't run into a
+ * timeout.
+ */
+static void fastboot_shutdown(void)
+{
+ struct f_fastboot *f_fb = g_f_fb;
+
+ if (!f_fb || !f_fb->active)
+ return;
+
+ fastboot_tx_print(f_fb, FASTBOOT_MSG_INFO, "barebox shutting down");
+ fastboot_tx_print(f_fb, FASTBOOT_MSG_OKAY, "");
+}
+
+early_exitcall(fastboot_shutdown);
+
static struct usb_function *fastboot_alloc_func(struct usb_function_instance *fi)
{
struct f_fastboot *f_fb;
@@ -501,6 +527,9 @@ static struct usb_function *fastboot_alloc_func(struct usb_function_instance *fi
f_fb->func.unbind = fastboot_unbind;
f_fb->func.free_func = fastboot_free_func;
+ if (!g_f_fb)
+ g_f_fb = f_fb;
+
return &f_fb->func;
}
@@ -573,6 +602,18 @@ int fastboot_tx_print(struct f_fastboot *f_fb, enum fastboot_msg_type type,
n = snprintf(buf, 64, "%s%pV", msg, &vaf);
+ switch (type) {
+ case FASTBOOT_MSG_OKAY:
+ f_fb->active = false;
+ break;
+ case FASTBOOT_MSG_FAIL:
+ f_fb->active = false;
+ break;
+ case FASTBOOT_MSG_INFO:
+ case FASTBOOT_MSG_DATA:
+ break;
+ }
+
va_end(ap);
if (n > 64)
@@ -1258,6 +1299,8 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
if (req->status != 0)
return;
+ f_fb->active = true;
+
*(cmdbuf + req->actual) = 0;
if (f_fb->cmd_exec) {