Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5f8b966d authored by chihhao.chen's avatar chihhao.chen Committed by Hridya Valsaraju
Browse files

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
parent 20b0bd9c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);

+14 −3
Original line number Diff line number Diff line
@@ -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<char*>(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) {
+2 −1
Original line number Diff line number Diff line
@@ -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;
        }