summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFurquan Shaikh <furquan@google.com>2015-06-22 23:19:04 (GMT)
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-06-23 13:45:14 (GMT)
commitb859621d244ec7b939ea4e077983e81ec38a6b1c (patch)
treeed1b398998c0ba06155fd5d883e3767187e90964
parentd9bcee99916c94795364a8e8a056abd267b7ec75 (diff)
downloaddepthcharge-stabilize-7202.B.tar.gz
depthcharge-stabilize-7202.B.tar.xz
fastboot: Re-initialize gadget mode if connection is loststabilize-7202.B
If USB cable is disconnected and re-connected, re-initialize USB gadget mode. This fixes the issue that depthcharge is stuck in a tight loop trying to recv packets from the host even if connection is lost. On re-connecting the cable, device re-initializes the connection. CQ-DEPEND=CL:281066 BUG=chrome-os-partner:41687 BRANCH=None TEST=Compiles successfully. fastboot works fine on disconnecting and reconnecting cable between host and device. Change-Id: Icd8a0eb2556acd2849fab34806ed1fd60506ed3c Signed-off-by: Furquan Shaikh <furquan@google.com> Reviewed-on: https://chromium-review.googlesource.com/281067 Tested-by: Furquan Shaikh <furquan@chromium.org> Reviewed-by: Patrick Georgi <pgeorgi@chromium.org> Commit-Queue: Furquan Shaikh <furquan@chromium.org> Trybot-Ready: Furquan Shaikh <furquan@chromium.org>
-rw-r--r--src/fastboot/fastboot.c25
-rw-r--r--src/fastboot/fastboot.h1
-rw-r--r--src/fastboot/udc.c16
3 files changed, 38 insertions, 4 deletions
diff --git a/src/fastboot/fastboot.c b/src/fastboot/fastboot.c
index 4caca8e..e0decc4 100644
--- a/src/fastboot/fastboot.c
+++ b/src/fastboot/fastboot.c
@@ -141,6 +141,9 @@ static void fb_execute_send(struct fb_cmd *cmd)
[FB_OKAY] = "OKAY",
};
+ if (cmd->type == FB_NONE)
+ return;
+
fb_send(&cmd->output, prefix[cmd->type]);
}
@@ -598,16 +601,26 @@ static void alloc_image_space(size_t bytes)
* Desc: Download data from host and store it in image_addr
*
*/
-static void fb_recv_data(struct fb_cmd *cmd)
+static int fb_recv_data(struct fb_cmd *cmd)
{
size_t curr_len = 0;
while (curr_len < image_size) {
void *curr = (uint8_t *)image_addr + curr_len;
- curr_len += usb_gadget_recv(curr, image_size - curr_len);
+
+ size_t ret = usb_gadget_recv(curr, image_size - curr_len);
+
+ if (ret == 0) {
+ curr_len = 0;
+ cmd->type = FB_NONE;
+ return curr_len;
+ }
+
+ curr_len += ret;
}
cmd->type = FB_OKAY;
+ return curr_len;
}
/*
@@ -646,7 +659,10 @@ static fb_ret_type fb_download(struct fb_cmd *cmd)
fb_add_number(output, "%08lx", bytes);
fb_execute_send(cmd);
- fb_recv_data(cmd);
+ if (fb_recv_data(cmd) == 0) {
+ FB_LOG("Freeing memory.. failed to download data\n");
+ free_image_space();
+ }
return FB_SUCCESS;
}
@@ -1013,6 +1029,9 @@ fb_ret_type device_mode_enter(void)
/* Receive a packet from the host */
len = usb_gadget_recv(pkt, MAX_COMMAND_LENGTH);
+ if (len == 0)
+ continue;
+
fb_buffer_push(&cmd.input, len);
print_input(&cmd);
diff --git a/src/fastboot/fastboot.h b/src/fastboot/fastboot.h
index 36bc360..2c573d9 100644
--- a/src/fastboot/fastboot.h
+++ b/src/fastboot/fastboot.h
@@ -60,6 +60,7 @@ typedef enum fb_ret {
*/
#define PREFIX_LEN 4
typedef enum fb_rsp {
+ FB_NONE,
FB_DATA,
FB_FAIL,
FB_INFO,
diff --git a/src/fastboot/udc.c b/src/fastboot/udc.c
index d083746..948d7fb 100644
--- a/src/fastboot/udc.c
+++ b/src/fastboot/udc.c
@@ -162,6 +162,11 @@ size_t usb_gadget_send(const char *msg, size_t size)
return size;
}
+static void usb_gadget_force_shutdown(void)
+{
+ udc->force_shutdown(udc);
+}
+
size_t usb_gadget_recv(void *pkt, size_t size)
{
/* max 64 packets at once */
@@ -183,7 +188,16 @@ size_t usb_gadget_recv(void *pkt, size_t size)
size = remaining;
udc->enqueue_packet(udc, 1, 0, tmp, size, 0, 0);
- while (out_length == 0) udc->poll(udc);
+ while ((out_length == 0) && udc->initialized)
+ udc->poll(udc);
+
+ /* If lost connection, re-initialize gadget mode. */
+ if (!udc->initialized) {
+ usb_gadget_force_shutdown();
+ usb_gadget_init();
+ return 0;
+ }
+
memcpy(pkt, tmp, out_length);
total += out_length;