Merge changes I31e444f3,If07ff05f,If3ba190d

* changes:
  adb: Add io size and zero packet to usb_handle
  adb: Have device usb_handle return io size
  adb: Expose device usb_handle through libadbd
This commit is contained in:
Jerry Zhang 2018-07-17 22:35:36 +00:00 committed by Gerrit Code Review
commit cb140c04c9
8 changed files with 50 additions and 38 deletions

View file

@ -299,6 +299,10 @@ cc_library_static {
"libqemu_pipe", "libqemu_pipe",
"libbase", "libbase",
], ],
export_include_dirs: [
"daemon/include",
],
} }
cc_binary { cc_binary {

View file

@ -589,7 +589,7 @@ int usb_write(usb_handle* h, const void* d, int len) {
int rc = perform_usb_transfer(h, info, std::move(lock)); int rc = perform_usb_transfer(h, info, std::move(lock));
LOG(DEBUG) << "usb_write(" << len << ") = " << rc; LOG(DEBUG) << "usb_write(" << len << ") = " << rc;
return rc; return info->transfer->actual_length;
} }
int usb_read(usb_handle* h, void* d, int len) { int usb_read(usb_handle* h, void* d, int len) {

View file

@ -418,11 +418,11 @@ int usb_write(usb_handle *h, const void *_data, int len)
if (h->zero_mask && !(len & h->zero_mask)) { if (h->zero_mask && !(len & h->zero_mask)) {
// If we need 0-markers and our transfer is an even multiple of the packet size, // If we need 0-markers and our transfer is an even multiple of the packet size,
// then send a zero marker. // 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 --"); D("-- usb_write --");
return 0; return n;
} }
int usb_read(usb_handle *h, void *_data, int len) int usb_read(usb_handle *h, void *_data, int len)

View file

@ -497,8 +497,8 @@ int usb_write(usb_handle *handle, const void *buf, int len)
} }
} }
if (0 == result) if (!result)
return 0; return len;
LOG(ERROR) << "usb_write failed with status: " << std::hex << result; LOG(ERROR) << "usb_write failed with status: " << std::hex << result;
return -1; return -1;

View file

@ -365,7 +365,7 @@ int usb_write(usb_handle* handle, const void* data, int len) {
} }
} }
return 0; return written;
fail: fail:
// Any failure should cause us to kick the device instead of leaving it a // Any failure should cause us to kick the device instead of leaving it a

View file

@ -19,6 +19,7 @@
#include <atomic> #include <atomic>
#include <condition_variable> #include <condition_variable>
#include <mutex> #include <mutex>
#include <vector>
#include <asyncio/AsyncIO.h> #include <asyncio/AsyncIO.h>
@ -54,5 +55,9 @@ struct usb_handle {
// read and write threads. // read and write threads.
struct aio_block read_aiob; struct aio_block read_aiob;
struct aio_block write_aiob; struct aio_block write_aiob;
bool reads_zero_packets;
size_t io_size;
}; };
usb_handle *create_usb_handle(unsigned num_bufs, unsigned io_size);

View file

@ -41,7 +41,7 @@
#include <android-base/properties.h> #include <android-base/properties.h>
#include "adb.h" #include "adb.h"
#include "daemon/usb.h" #include "adbd/usb.h"
#include "transport.h" #include "transport.h"
using namespace std::chrono_literals; using namespace std::chrono_literals;
@ -53,7 +53,7 @@ using namespace std::chrono_literals;
#define USB_FFS_BULK_SIZE 16384 #define USB_FFS_BULK_SIZE 16384
// Number of buffers needed to fit MAX_PAYLOAD, with an extra for ZLPs. // Number of buffers needed to fit MAX_PAYLOAD, with an extra for ZLPs.
#define USB_FFS_NUM_BUFS ((MAX_PAYLOAD / USB_FFS_BULK_SIZE) + 1) #define USB_FFS_NUM_BUFS ((4 * MAX_PAYLOAD / USB_FFS_BULK_SIZE) + 1)
#define cpu_to_le16(x) htole16(x) #define cpu_to_le16(x) htole16(x)
#define cpu_to_le32(x) htole32(x) #define cpu_to_le32(x) htole32(x)
@ -226,16 +226,16 @@ static const struct {
}, },
}; };
static void aio_block_init(aio_block* aiob) { static void aio_block_init(aio_block* aiob, unsigned num_bufs) {
aiob->iocb.resize(USB_FFS_NUM_BUFS); aiob->iocb.resize(num_bufs);
aiob->iocbs.resize(USB_FFS_NUM_BUFS); aiob->iocbs.resize(num_bufs);
aiob->events.resize(USB_FFS_NUM_BUFS); aiob->events.resize(num_bufs);
aiob->num_submitted = 0; aiob->num_submitted = 0;
for (unsigned i = 0; i < USB_FFS_NUM_BUFS; i++) { for (unsigned i = 0; i < num_bufs; i++) {
aiob->iocbs[i] = &aiob->iocb[i]; aiob->iocbs[i] = &aiob->iocb[i];
} }
memset(&aiob->ctx, 0, sizeof(aiob->ctx)); memset(&aiob->ctx, 0, sizeof(aiob->ctx));
if (io_setup(USB_FFS_NUM_BUFS, &aiob->ctx)) { if (io_setup(num_bufs, &aiob->ctx)) {
D("[ aio: got error on io_setup (%d) ]", errno); D("[ aio: got error on io_setup (%d) ]", errno);
} }
} }
@ -250,7 +250,7 @@ static int getMaxPacketSize(int ffs_fd) {
} }
} }
bool init_functionfs(struct usb_handle* h) { static bool init_functionfs(struct usb_handle* h) {
LOG(INFO) << "initializing functionfs"; LOG(INFO) << "initializing functionfs";
ssize_t ret; ssize_t ret;
@ -318,6 +318,7 @@ bool init_functionfs(struct usb_handle* h) {
h->read_aiob.fd = h->bulk_out; h->read_aiob.fd = h->bulk_out;
h->write_aiob.fd = h->bulk_in; h->write_aiob.fd = h->bulk_in;
h->reads_zero_packets = true;
return true; return true;
err: err:
@ -336,9 +337,7 @@ err:
return false; return false;
} }
static void usb_ffs_open_thread(void* x) { static void usb_ffs_open_thread(usb_handle *usb) {
struct usb_handle* usb = (struct usb_handle*)x;
adb_thread_setname("usb ffs open"); adb_thread_setname("usb ffs open");
while (true) { while (true) {
@ -370,6 +369,7 @@ static int usb_ffs_write(usb_handle* h, const void* data, int len) {
D("about to write (fd=%d, len=%d)", h->bulk_in, len); D("about to write (fd=%d, len=%d)", h->bulk_in, len);
const char* buf = static_cast<const char*>(data); const char* buf = static_cast<const char*>(data);
int orig_len = len;
while (len > 0) { while (len > 0) {
int write_len = std::min(USB_FFS_BULK_SIZE, len); int write_len = std::min(USB_FFS_BULK_SIZE, len);
int n = adb_write(h->bulk_in, buf, write_len); int n = adb_write(h->bulk_in, buf, write_len);
@ -382,13 +382,14 @@ static int usb_ffs_write(usb_handle* h, const void* data, int len) {
} }
D("[ done fd=%d ]", h->bulk_in); D("[ done fd=%d ]", h->bulk_in);
return 0; 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) {
D("about to read (fd=%d, len=%d)", h->bulk_out, len); D("about to read (fd=%d, len=%d)", h->bulk_out, len);
char* buf = static_cast<char*>(data); char* buf = static_cast<char*>(data);
int orig_len = len;
while (len > 0) { while (len > 0) {
int read_len = std::min(USB_FFS_BULK_SIZE, len); int read_len = std::min(USB_FFS_BULK_SIZE, len);
int n = adb_read(h->bulk_out, buf, read_len); int n = adb_read(h->bulk_out, buf, read_len);
@ -401,14 +402,14 @@ static int usb_ffs_read(usb_handle* h, void* data, int len) {
} }
D("[ done fd=%d ]", h->bulk_out); 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) { static int usb_ffs_do_aio(usb_handle* h, const void* data, int len, bool read) {
aio_block* aiob = read ? &h->read_aiob : &h->write_aiob; aio_block* aiob = read ? &h->read_aiob : &h->write_aiob;
bool zero_packet = false; bool zero_packet = false;
int num_bufs = len / USB_FFS_BULK_SIZE + (len % USB_FFS_BULK_SIZE == 0 ? 0 : 1); int num_bufs = len / h->io_size + (len % h->io_size == 0 ? 0 : 1);
const char* cur_data = reinterpret_cast<const char*>(data); const char* cur_data = reinterpret_cast<const char*>(data);
int packet_size = getMaxPacketSize(aiob->fd); int packet_size = getMaxPacketSize(aiob->fd);
@ -418,7 +419,7 @@ static int usb_ffs_do_aio(usb_handle* h, const void* data, int len, bool read) {
} }
for (int i = 0; i < num_bufs; i++) { for (int i = 0; i < num_bufs; i++) {
int buf_len = std::min(len, USB_FFS_BULK_SIZE); int buf_len = std::min(len, static_cast<int>(h->io_size));
io_prep(&aiob->iocb[i], aiob->fd, cur_data, buf_len, 0, read); io_prep(&aiob->iocb[i], aiob->fd, cur_data, buf_len, 0, read);
len -= buf_len; len -= buf_len;
@ -427,7 +428,7 @@ static int usb_ffs_do_aio(usb_handle* h, const void* data, int len, bool read) {
if (len == 0 && buf_len % packet_size == 0 && read) { if (len == 0 && buf_len % packet_size == 0 && read) {
// adb does not expect the device to send a zero packet after data transfer, // adb does not expect the device to send a zero packet after data transfer,
// but the host *does* send a zero packet for the device to read. // but the host *does* send a zero packet for the device to read.
zero_packet = true; zero_packet = h->reads_zero_packets;
} }
} }
if (zero_packet) { if (zero_packet) {
@ -449,6 +450,7 @@ static int usb_ffs_do_aio(usb_handle* h, const void* data, int len, bool read) {
if (num_bufs == 1 && aiob->events[0].res == -EINTR) { if (num_bufs == 1 && aiob->events[0].res == -EINTR) {
continue; continue;
} }
int ret = 0;
for (int i = 0; i < num_bufs; i++) { for (int i = 0; i < num_bufs; i++) {
if (aiob->events[i].res < 0) { if (aiob->events[i].res < 0) {
errno = -aiob->events[i].res; errno = -aiob->events[i].res;
@ -456,8 +458,9 @@ static int usb_ffs_do_aio(usb_handle* h, const void* data, int len, bool read) {
<< " total bufs " << num_bufs; << " total bufs " << num_bufs;
return -1; return -1;
} }
ret += aiob->events[i].res;
} }
return 0; return ret;
} }
} }
@ -505,9 +508,7 @@ static void usb_ffs_close(usb_handle* h) {
h->notify.notify_one(); h->notify.notify_one();
} }
static void usb_ffs_init() { usb_handle *create_usb_handle(unsigned num_bufs, unsigned io_size) {
D("[ usb_init - using FunctionFS ]");
usb_handle* h = new usb_handle(); usb_handle* h = new usb_handle();
if (android::base::GetBoolProperty("sys.usb.ffs.aio_compat", false)) { if (android::base::GetBoolProperty("sys.usb.ffs.aio_compat", false)) {
@ -518,20 +519,21 @@ static void usb_ffs_init() {
} else { } else {
h->write = usb_ffs_aio_write; h->write = usb_ffs_aio_write;
h->read = usb_ffs_aio_read; h->read = usb_ffs_aio_read;
aio_block_init(&h->read_aiob); aio_block_init(&h->read_aiob, num_bufs);
aio_block_init(&h->write_aiob); aio_block_init(&h->write_aiob, num_bufs);
} }
h->io_size = io_size;
h->kick = usb_ffs_kick; h->kick = usb_ffs_kick;
h->close = usb_ffs_close; h->close = usb_ffs_close;
return h;
D("[ usb_init - starting thread ]");
std::thread(usb_ffs_open_thread, h).detach();
} }
void usb_init() { void usb_init() {
D("[ usb_init - using FunctionFS ]");
dummy_fd = adb_open("/dev/null", O_WRONLY); dummy_fd = adb_open("/dev/null", O_WRONLY);
CHECK_NE(dummy_fd, -1); CHECK_NE(dummy_fd, -1);
usb_ffs_init();
std::thread(usb_ffs_open_thread, create_usb_handle(USB_FFS_NUM_BUFS, USB_FFS_BULK_SIZE)).detach();
} }
int usb_write(usb_handle* h, const void* data, int len) { int usb_write(usb_handle* h, const void* data, int len) {

View file

@ -122,7 +122,7 @@ static int remote_read(apacket* p, usb_handle* usb) {
// On Android devices, we rely on the kernel to provide buffered read. // On Android devices, we rely on the kernel to provide buffered read.
// So we can recover automatically from EOVERFLOW. // So we can recover automatically from EOVERFLOW.
static int remote_read(apacket* p, usb_handle* usb) { 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)"; PLOG(ERROR) << "remote usb: read terminated (message)";
return -1; return -1;
} }
@ -134,7 +134,8 @@ static int remote_read(apacket* p, usb_handle* usb) {
} }
p->payload.resize(p->msg.data_length); 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)"; PLOG(ERROR) << "remote usb: terminated (data)";
return -1; return -1;
} }
@ -154,14 +155,14 @@ bool UsbConnection::Read(apacket* packet) {
} }
bool UsbConnection::Write(apacket* packet) { 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"; PLOG(ERROR) << "remote usb: 1 - write terminated";
return false; 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"; PLOG(ERROR) << "remote usb: 2 - write terminated";
return false; return false;
} }