adb: Have device usb_handle return io size
Previously, read and write would return 0
on success. Now it will return the number
of bytes read/write. This is more consistent
with other usb handles and is needed in order
to handle partial packets (for fastbootd).
Update usb_write in other usb handles
to return amount written.
Change transport_usb accordingly.
Test: adb works
Bug: 78793464
Change-Id: If07ff05fbc8120343f20661475d34f4e5ff805de
diff --git a/adb/client/usb_libusb.cpp b/adb/client/usb_libusb.cpp
index 46c3f58..10b6090 100644
--- a/adb/client/usb_libusb.cpp
+++ b/adb/client/usb_libusb.cpp
@@ -589,7 +589,7 @@
int rc = perform_usb_transfer(h, info, std::move(lock));
LOG(DEBUG) << "usb_write(" << len << ") = " << rc;
- return rc;
+ return info->transfer->actual_length;
}
int usb_read(usb_handle* h, void* d, int len) {
diff --git a/adb/client/usb_linux.cpp b/adb/client/usb_linux.cpp
index 1f376a4..aace16d 100644
--- a/adb/client/usb_linux.cpp
+++ b/adb/client/usb_linux.cpp
@@ -418,11 +418,11 @@
if (h->zero_mask && !(len & h->zero_mask)) {
// If we need 0-markers and our transfer is an even multiple of the packet size,
// then send a zero marker.
- return usb_bulk_write(h, _data, 0);
+ return usb_bulk_write(h, _data, 0) == 0 ? n : -1;
}
D("-- usb_write --");
- return 0;
+ return n;
}
int usb_read(usb_handle *h, void *_data, int len)
diff --git a/adb/client/usb_osx.cpp b/adb/client/usb_osx.cpp
index 8a95a19..49baf36 100644
--- a/adb/client/usb_osx.cpp
+++ b/adb/client/usb_osx.cpp
@@ -497,8 +497,8 @@
}
}
- if (0 == result)
- return 0;
+ if (!result)
+ return len;
LOG(ERROR) << "usb_write failed with status: " << std::hex << result;
return -1;
diff --git a/adb/client/usb_windows.cpp b/adb/client/usb_windows.cpp
index f529e8f..d2aeb26 100644
--- a/adb/client/usb_windows.cpp
+++ b/adb/client/usb_windows.cpp
@@ -365,7 +365,7 @@
}
}
- return 0;
+ return written;
fail:
// Any failure should cause us to kick the device instead of leaving it a
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index 8c14955..5242718 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -368,6 +368,7 @@
D("about to write (fd=%d, len=%d)", h->bulk_in, len);
const char* buf = static_cast<const char*>(data);
+ int orig_len = len;
while (len > 0) {
int write_len = std::min(USB_FFS_BULK_SIZE, len);
int n = adb_write(h->bulk_in, buf, write_len);
@@ -380,13 +381,14 @@
}
D("[ done fd=%d ]", h->bulk_in);
- return 0;
+ return orig_len;
}
static int usb_ffs_read(usb_handle* h, void* data, int len) {
D("about to read (fd=%d, len=%d)", h->bulk_out, len);
char* buf = static_cast<char*>(data);
+ int orig_len = len;
while (len > 0) {
int read_len = std::min(USB_FFS_BULK_SIZE, len);
int n = adb_read(h->bulk_out, buf, read_len);
@@ -399,7 +401,7 @@
}
D("[ done fd=%d ]", h->bulk_out);
- return 0;
+ return orig_len;
}
static int usb_ffs_do_aio(usb_handle* h, const void* data, int len, bool read) {
@@ -447,6 +449,7 @@
if (num_bufs == 1 && aiob->events[0].res == -EINTR) {
continue;
}
+ int ret = 0;
for (int i = 0; i < num_bufs; i++) {
if (aiob->events[i].res < 0) {
errno = -aiob->events[i].res;
@@ -454,8 +457,9 @@
<< " total bufs " << num_bufs;
return -1;
}
+ ret += aiob->events[i].res;
}
- return 0;
+ return ret;
}
}
diff --git a/adb/transport_usb.cpp b/adb/transport_usb.cpp
index 94b2e37..602970c 100644
--- a/adb/transport_usb.cpp
+++ b/adb/transport_usb.cpp
@@ -122,7 +122,7 @@
// On Android devices, we rely on the kernel to provide buffered read.
// So we can recover automatically from EOVERFLOW.
static int remote_read(apacket* p, usb_handle* usb) {
- if (usb_read(usb, &p->msg, sizeof(amessage))) {
+ if (usb_read(usb, &p->msg, sizeof(amessage)) != sizeof(amessage)) {
PLOG(ERROR) << "remote usb: read terminated (message)";
return -1;
}
@@ -134,7 +134,8 @@
}
p->payload.resize(p->msg.data_length);
- if (usb_read(usb, &p->payload[0], p->payload.size())) {
+ if (usb_read(usb, &p->payload[0], p->payload.size())
+ != static_cast<int>(p->payload.size())) {
PLOG(ERROR) << "remote usb: terminated (data)";
return -1;
}
@@ -154,14 +155,14 @@
}
bool UsbConnection::Write(apacket* packet) {
- unsigned size = packet->msg.data_length;
+ int size = packet->msg.data_length;
- if (usb_write(handle_, &packet->msg, sizeof(packet->msg)) != 0) {
+ if (usb_write(handle_, &packet->msg, sizeof(packet->msg)) != sizeof(packet->msg)) {
PLOG(ERROR) << "remote usb: 1 - write terminated";
return false;
}
- if (packet->msg.data_length != 0 && usb_write(handle_, packet->payload.data(), size) != 0) {
+ if (packet->msg.data_length != 0 && usb_write(handle_, packet->payload.data(), size) != size) {
PLOG(ERROR) << "remote usb: 2 - write terminated";
return false;
}