• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "usb.h"
18 
19 #include <dirent.h>
20 #include <errno.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/ioctl.h>
25 #include <sys/mman.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 
29 #include <linux/usb/ch9.h>
30 #include <linux/usb/functionfs.h>
31 
32 #include <algorithm>
33 #include <atomic>
34 #include <chrono>
35 #include <condition_variable>
36 #include <mutex>
37 #include <thread>
38 
39 #include <android-base/logging.h>
40 #include <android-base/properties.h>
41 
42 using namespace std::chrono_literals;
43 
44 #define D(...)
45 #define MAX_PACKET_SIZE_FS 64
46 #define MAX_PACKET_SIZE_HS 512
47 #define MAX_PACKET_SIZE_SS 1024
48 
49 #define USB_FFS_BULK_SIZE 16384
50 
51 // Number of buffers needed to fit MAX_PAYLOAD, with an extra for ZLPs.
52 #define USB_FFS_NUM_BUFS ((4 * MAX_PAYLOAD / USB_FFS_BULK_SIZE) + 1)
53 
aio_block_init(aio_block * aiob,unsigned num_bufs)54 static void aio_block_init(aio_block* aiob, unsigned num_bufs) {
55     aiob->iocb.resize(num_bufs);
56     aiob->iocbs.resize(num_bufs);
57     aiob->events.resize(num_bufs);
58     aiob->num_submitted = 0;
59     for (unsigned i = 0; i < num_bufs; i++) {
60         aiob->iocbs[i] = &aiob->iocb[i];
61     }
62     memset(&aiob->ctx, 0, sizeof(aiob->ctx));
63     if (io_setup(num_bufs, &aiob->ctx)) {
64         D("[ aio: got error on io_setup (%d) ]", errno);
65     }
66 }
67 
getMaxPacketSize(int ffs_fd)68 static int getMaxPacketSize(int ffs_fd) {
69     usb_endpoint_descriptor desc;
70     if (ioctl(ffs_fd, FUNCTIONFS_ENDPOINT_DESC, reinterpret_cast<unsigned long>(&desc))) {
71         D("[ could not get endpoint descriptor! (%d) ]", errno);
72         return MAX_PACKET_SIZE_HS;
73     } else {
74         return desc.wMaxPacketSize;
75     }
76 }
77 
usb_ffs_write(usb_handle * h,const void * data,int len)78 static int usb_ffs_write(usb_handle* h, const void* data, int len) {
79     D("about to write (fd=%d, len=%d)", h->bulk_in.get(), len);
80 
81     const char* buf = static_cast<const char*>(data);
82     int orig_len = len;
83     while (len > 0) {
84         int write_len = std::min(USB_FFS_BULK_SIZE, len);
85         int n = write(h->bulk_in.get(), buf, write_len);
86         if (n < 0) {
87             D("ERROR: fd = %d, n = %d: %s", h->bulk_in.get(), n, strerror(errno));
88             return -1;
89         }
90         buf += n;
91         len -= n;
92     }
93 
94     D("[ done fd=%d ]", h->bulk_in.get());
95     return orig_len;
96 }
97 
usb_ffs_read(usb_handle * h,void * data,int len,bool allow_partial)98 static int usb_ffs_read(usb_handle* h, void* data, int len, bool allow_partial) {
99     D("about to read (fd=%d, len=%d)", h->bulk_out.get(), len);
100 
101     char* buf = static_cast<char*>(data);
102     int orig_len = len;
103     unsigned count = 0;
104     while (len > 0) {
105         int read_len = std::min(USB_FFS_BULK_SIZE, len);
106         int n = read(h->bulk_out.get(), buf, read_len);
107         if (n < 0) {
108             D("ERROR: fd = %d, n = %d: %s", h->bulk_out.get(), n, strerror(errno));
109             return -1;
110         }
111         buf += n;
112         len -= n;
113         count += n;
114 
115         // For fastbootd command such as "getvar all", len parameter is always set 64.
116         // But what we read is actually less than 64.
117         // For example, length 10 for "getvar all" command.
118         // If we get less data than expected, this means there should be no more data.
119         if (allow_partial && n < read_len) {
120             orig_len = count;
121             break;
122         }
123     }
124 
125     D("[ done fd=%d ]", h->bulk_out.get());
126     return orig_len;
127 }
128 
usb_ffs_do_aio(usb_handle * h,const void * data,int len,bool read)129 static int usb_ffs_do_aio(usb_handle* h, const void* data, int len, bool read) {
130     aio_block* aiob = read ? &h->read_aiob : &h->write_aiob;
131     bool zero_packet = false;
132 
133     int num_bufs = len / h->io_size + (len % h->io_size == 0 ? 0 : 1);
134     const char* cur_data = reinterpret_cast<const char*>(data);
135     int packet_size = getMaxPacketSize(aiob->fd);
136 
137     if (posix_madvise(const_cast<void*>(data), len, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED) <
138         0) {
139         D("[ Failed to madvise: %d ]", errno);
140     }
141 
142     for (int i = 0; i < num_bufs; i++) {
143         int buf_len = std::min(len, static_cast<int>(h->io_size));
144         io_prep(&aiob->iocb[i], aiob->fd, cur_data, buf_len, 0, read);
145 
146         len -= buf_len;
147         cur_data += buf_len;
148 
149         if (len == 0 && buf_len % packet_size == 0 && read) {
150             // adb does not expect the device to send a zero packet after data transfer,
151             // but the host *does* send a zero packet for the device to read.
152             zero_packet = h->reads_zero_packets;
153         }
154     }
155     if (zero_packet) {
156         io_prep(&aiob->iocb[num_bufs], aiob->fd, reinterpret_cast<const void*>(cur_data),
157                 packet_size, 0, read);
158         num_bufs += 1;
159     }
160 
161     while (true) {
162         if (TEMP_FAILURE_RETRY(io_submit(aiob->ctx, num_bufs, aiob->iocbs.data())) < num_bufs) {
163             PLOG(ERROR) << "aio: got error submitting " << (read ? "read" : "write");
164             return -1;
165         }
166         if (TEMP_FAILURE_RETRY(io_getevents(aiob->ctx, num_bufs, num_bufs, aiob->events.data(),
167                                             nullptr)) < num_bufs) {
168             PLOG(ERROR) << "aio: got error waiting " << (read ? "read" : "write");
169             return -1;
170         }
171         if (num_bufs == 1 && aiob->events[0].res == -EINTR) {
172             continue;
173         }
174         int ret = 0;
175         for (int i = 0; i < num_bufs; i++) {
176             if (aiob->events[i].res < 0) {
177                 errno = -aiob->events[i].res;
178                 PLOG(ERROR) << "aio: got error event on " << (read ? "read" : "write")
179                             << " total bufs " << num_bufs;
180                 return -1;
181             }
182             ret += aiob->events[i].res;
183         }
184         return ret;
185     }
186 }
187 
usb_ffs_aio_read(usb_handle * h,void * data,int len,bool)188 static int usb_ffs_aio_read(usb_handle* h, void* data, int len, bool /* allow_partial */) {
189     return usb_ffs_do_aio(h, data, len, true);
190 }
191 
usb_ffs_aio_write(usb_handle * h,const void * data,int len)192 static int usb_ffs_aio_write(usb_handle* h, const void* data, int len) {
193     return usb_ffs_do_aio(h, data, len, false);
194 }
195 
usb_ffs_close(usb_handle * h)196 static void usb_ffs_close(usb_handle* h) {
197     LOG(INFO) << "closing functionfs transport";
198 
199     h->bulk_out.reset();
200     h->bulk_in.reset();
201 
202     // Notify usb_adb_open_thread to open a new connection.
203     h->lock.lock();
204     h->open_new_connection = true;
205     h->lock.unlock();
206     h->notify.notify_one();
207 }
208 
create_usb_handle(unsigned num_bufs,unsigned io_size)209 usb_handle* create_usb_handle(unsigned num_bufs, unsigned io_size) {
210     usb_handle* h = new usb_handle();
211 
212     if (android::base::GetBoolProperty("sys.usb.ffs.aio_compat", false)) {
213         // Devices on older kernels (< 3.18) will not have aio support for ffs
214         // unless backported. Fall back on the non-aio functions instead.
215         h->write = usb_ffs_write;
216         h->read = usb_ffs_read;
217     } else {
218         h->write = usb_ffs_aio_write;
219         h->read = usb_ffs_aio_read;
220         aio_block_init(&h->read_aiob, num_bufs);
221         aio_block_init(&h->write_aiob, num_bufs);
222     }
223     h->io_size = io_size;
224     h->close = usb_ffs_close;
225     return h;
226 }
227