summaryrefslogtreecommitdiff
path: root/fastboot/engine.cpp
diff options
context:
space:
mode:
authorChris Fries <cfries@google.com>2017-04-12 10:25:57 -0500
committerChris Fries <cfries@google.com>2017-04-17 09:22:49 -0500
commit0ea946c007cf76a96d867ba3e96505f72639960e (patch)
treea67c7252fdc8a3c16b588ee6fc1e1155b00fb69b /fastboot/engine.cpp
parent6a99971096a9c5a6752f494db1d9b57d4ab77af2 (diff)
fastboot: Support larger transfers during flash
Adding methods to queue and download flashable images by fd instead of by pointer, so that we can deal with sending large (up to 4GB) files on windows and linux. This gets past limitations on linux to read more than 2GB from a file at a time, as well as memory limitations on win32, in order to download up to 4GB in a single transfer. Test: fastboot -w Test: "flash-all" from nexus factory images site (incl. fastboot -w update) Test: fastboot flash with large and small image, large and small max-download-size Test: Sanity check flashing on win32, darwin, linux. Test: Sanity check 3GB image download (with 3GB max-download-size) on win32, darwin, linux. Bug: 36810152 Change-Id: I528d739d344eb080d59d721dadf3b3b34d4b375e
Diffstat (limited to 'fastboot/engine.cpp')
-rw-r--r--fastboot/engine.cpp27
1 files changed, 23 insertions, 4 deletions
diff --git a/fastboot/engine.cpp b/fastboot/engine.cpp
index 9f7d22657..bf887c9e9 100644
--- a/fastboot/engine.cpp
+++ b/fastboot/engine.cpp
@@ -44,6 +44,7 @@
#define OP_NOTICE 4
#define OP_DOWNLOAD_SPARSE 5
#define OP_WAIT_FOR_DISCONNECT 6
+#define OP_DOWNLOAD_FD 7
typedef struct Action Action;
@@ -56,6 +57,7 @@ struct Action {
char cmd[CMD_SIZE];
const char* prod;
void* data;
+ int fd;
// The protocol only supports 32-bit sizes, so you'll have to break
// anything larger into chunks.
@@ -142,7 +144,20 @@ void fb_queue_erase(const char *ptn)
a->msg = mkmsg("erasing '%s'", ptn);
}
-void fb_queue_flash(const char *ptn, void *data, unsigned sz)
+void fb_queue_flash_fd(const char *ptn, int fd, uint32_t sz)
+{
+ Action *a;
+
+ a = queue_action(OP_DOWNLOAD_FD, "");
+ a->fd = fd;
+ a->size = sz;
+ a->msg = mkmsg("sending '%s' (%d KB)", ptn, sz / 1024);
+
+ a = queue_action(OP_COMMAND, "flash:%s", ptn);
+ a->msg = mkmsg("writing '%s'", ptn);
+}
+
+void fb_queue_flash(const char *ptn, void *data, uint32_t sz)
{
Action *a;
@@ -155,7 +170,7 @@ void fb_queue_flash(const char *ptn, void *data, unsigned sz)
a->msg = mkmsg("writing '%s'", ptn);
}
-void fb_queue_flash_sparse(const char* ptn, struct sparse_file* s, unsigned sz, size_t current,
+void fb_queue_flash_sparse(const char* ptn, struct sparse_file* s, uint32_t sz, size_t current,
size_t total) {
Action *a;
@@ -282,7 +297,7 @@ static int cb_save(Action* a, int status, const char* resp) {
return 0;
}
-void fb_queue_query_save(const char *var, char *dest, unsigned dest_size)
+void fb_queue_query_save(const char *var, char *dest, uint32_t dest_size)
{
Action *a;
a = queue_action(OP_QUERY, "getvar:%s", var);
@@ -309,7 +324,7 @@ void fb_queue_command(const char *cmd, const char *msg)
a->msg = msg;
}
-void fb_queue_download(const char *name, void *data, unsigned size)
+void fb_queue_download(const char *name, void *data, uint32_t size)
{
Action *a = queue_action(OP_DOWNLOAD, "");
a->data = data;
@@ -351,6 +366,10 @@ int64_t fb_execute_queue(Transport* transport)
status = fb_download_data(transport, a->data, a->size);
status = a->func(a, status, status ? fb_get_error().c_str() : "");
if (status) break;
+ } else if (a->op == OP_DOWNLOAD_FD) {
+ status = fb_download_data_fd(transport, a->fd, a->size);
+ status = a->func(a, status, status ? fb_get_error().c_str() : "");
+ if (status) break;
} else if (a->op == OP_COMMAND) {
status = fb_command(transport, a->cmd);
status = a->func(a, status, status ? fb_get_error().c_str() : "");