From 5f8b966d960ff9cb403a167768c48c2aa4d76710 Mon Sep 17 00:00:00 2001 From: "chihhao.chen" Date: Mon, 20 May 2019 16:55:55 +0800 Subject: [PATCH] Fix non-aio USB read issue for fastbootd non-aio USB read function was stuck in a loop waiting for more data because data length parameter is always set 64 for fastbootd commands. It should be a normal case to get less data than expected since lengths of these commands are usually less than 64. Add logic to check this and one more parameter to distinguish fastbootd from general adbd case. Bug: 133189029 Test: try various fastbootd commands Change-Id: I6690324840d78f3f1e04235040301520329976db --- adb/daemon/include/adbd/usb.h | 2 +- adb/daemon/usb_legacy.cpp | 17 ++++++++++++++--- fastboot/device/usb_client.cpp | 3 ++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/adb/daemon/include/adbd/usb.h b/adb/daemon/include/adbd/usb.h index 3213f6909..fca3c58e8 100644 --- a/adb/daemon/include/adbd/usb.h +++ b/adb/daemon/include/adbd/usb.h @@ -43,7 +43,7 @@ struct usb_handle { bool open_new_connection = true; int (*write)(usb_handle* h, const void* data, int len); - int (*read)(usb_handle* h, void* data, int len); + int (*read)(usb_handle* h, void* data, int len, bool allow_partial); void (*kick)(usb_handle* h); void (*close)(usb_handle* h); diff --git a/adb/daemon/usb_legacy.cpp b/adb/daemon/usb_legacy.cpp index b65727a0c..fe80e7d59 100644 --- a/adb/daemon/usb_legacy.cpp +++ b/adb/daemon/usb_legacy.cpp @@ -142,11 +142,12 @@ static int usb_ffs_write(usb_handle* h, const void* data, int len) { return orig_len; } -static int usb_ffs_read(usb_handle* h, void* data, int len) { +static int usb_ffs_read(usb_handle* h, void* data, int len, bool allow_partial) { D("about to read (fd=%d, len=%d)", h->bulk_out.get(), len); char* buf = static_cast(data); int orig_len = len; + unsigned count = 0; while (len > 0) { int read_len = std::min(USB_FFS_BULK_SIZE, len); int n = adb_read(h->bulk_out, buf, read_len); @@ -156,6 +157,16 @@ static int usb_ffs_read(usb_handle* h, void* data, int len) { } buf += n; len -= n; + count += n; + + // For fastbootd command such as "getvar all", len parameter is always set 64. + // But what we read is actually less than 64. + // For example, length 10 for "getvar all" command. + // If we get less data than expected, this means there should be no more data. + if (allow_partial && n < read_len) { + orig_len = count; + break; + } } D("[ done fd=%d ]", h->bulk_out.get()); @@ -221,7 +232,7 @@ static int usb_ffs_do_aio(usb_handle* h, const void* data, int len, bool read) { } } -static int usb_ffs_aio_read(usb_handle* h, void* data, int len) { +static int usb_ffs_aio_read(usb_handle* h, void* data, int len, bool allow_partial) { return usb_ffs_do_aio(h, data, len, true); } @@ -299,7 +310,7 @@ int usb_write(usb_handle* h, const void* data, int len) { } int usb_read(usb_handle* h, void* data, int len) { - return h->read(h, data, len); + return h->read(h, data, len, false /* allow_partial */); } int usb_close(usb_handle* h) { diff --git a/fastboot/device/usb_client.cpp b/fastboot/device/usb_client.cpp index fb51a900b..5921df958 100644 --- a/fastboot/device/usb_client.cpp +++ b/fastboot/device/usb_client.cpp @@ -255,7 +255,8 @@ ssize_t ClientUsbTransport::Read(void* data, size_t len) { size_t bytes_read_total = 0; while (bytes_read_total < len) { auto bytes_to_read = std::min(len - bytes_read_total, kFbFfsNumBufs * kFbFfsBufSize); - auto bytes_read_now = handle_->read(handle_.get(), char_data, bytes_to_read); + auto bytes_read_now = + handle_->read(handle_.get(), char_data, bytes_to_read, true /* allow_partial */); if (bytes_read_now < 0) { return bytes_read_total; }