blob: c863ed2055bacf78a403f4d95c3fbdc723c5bf9d [file] [log] [blame]
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001/*
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
Yabin Cui19bec5b2015-09-22 15:52:57 -070017#define TRACE_TAG USB
Dan Albertdb6fe642015-03-19 15:21:08 -070018
19#include "sysdeps.h"
20
Badhri Jagan Sridharane1febe92015-04-21 11:09:32 -070021#include <cutils/properties.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080022#include <dirent.h>
23#include <errno.h>
Dan Albertb302d122015-02-24 15:51:19 -080024#include <linux/usb/ch9.h>
25#include <linux/usb/functionfs.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <sys/ioctl.h>
30#include <sys/types.h>
31#include <unistd.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080032
Josh Gaoc95bb3d2015-12-17 13:45:18 -080033#include <algorithm>
34
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080035#include "adb.h"
Dan Albertb302d122015-02-24 15:51:19 -080036#include "transport.h"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080037
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +010038#define MAX_PACKET_SIZE_FS 64
39#define MAX_PACKET_SIZE_HS 512
Zhuang Jin Can1fc58c52014-09-02 13:04:44 +080040#define MAX_PACKET_SIZE_SS 1024
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +010041
Josh Gaoc95bb3d2015-12-17 13:45:18 -080042// Writes larger than 16k fail on some devices (seed with 3.10.49-g209ea2f in particular).
43#define USB_FFS_MAX_WRITE 16384
44
45// The kernel allocates a contiguous buffer for reads, which can fail for large ones due to
46// fragmentation. 16k chosen arbitrarily to match the write limit.
47#define USB_FFS_MAX_READ 16384
48
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +010049#define cpu_to_le16(x) htole16(x)
50#define cpu_to_le32(x) htole32(x)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080051
52struct usb_handle
53{
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080054 adb_cond_t notify;
55 adb_mutex_t lock;
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +010056
57 int (*write)(usb_handle *h, const void *data, int len);
58 int (*read)(usb_handle *h, void *data, int len);
59 void (*kick)(usb_handle *h);
60
61 // Legacy f_adb
62 int fd;
63
64 // FunctionFS
65 int control;
66 int bulk_out; /* "out" from the host's perspective => source for adbd */
67 int bulk_in; /* "in" from the host's perspective => sink for adbd */
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080068};
69
Badhri Jagan Sridharand6a63732014-10-27 18:26:17 -070070struct func_desc {
71 struct usb_interface_descriptor intf;
72 struct usb_endpoint_descriptor_no_audio source;
73 struct usb_endpoint_descriptor_no_audio sink;
74} __attribute__((packed));
75
Jack Phamb64ab092015-06-02 10:36:43 -070076struct ss_func_desc {
77 struct usb_interface_descriptor intf;
78 struct usb_endpoint_descriptor_no_audio source;
79 struct usb_ss_ep_comp_descriptor source_comp;
80 struct usb_endpoint_descriptor_no_audio sink;
81 struct usb_ss_ep_comp_descriptor sink_comp;
82} __attribute__((packed));
83
Badhri Jagan Sridharand6a63732014-10-27 18:26:17 -070084struct desc_v1 {
85 struct usb_functionfs_descs_head_v1 {
86 __le32 magic;
87 __le32 length;
88 __le32 fs_count;
89 __le32 hs_count;
90 } __attribute__((packed)) header;
91 struct func_desc fs_descs, hs_descs;
92} __attribute__((packed));
93
94struct desc_v2 {
Christopher Ferrisf7555b12015-01-23 17:09:56 -080095 struct usb_functionfs_descs_head_v2 header;
96 // The rest of the structure depends on the flags in the header.
97 __le32 fs_count;
98 __le32 hs_count;
Jack Phamb64ab092015-06-02 10:36:43 -070099 __le32 ss_count;
Badhri Jagan Sridharanf1500ca2015-10-05 13:04:03 -0700100 __le32 os_count;
Badhri Jagan Sridharand6a63732014-10-27 18:26:17 -0700101 struct func_desc fs_descs, hs_descs;
Jack Phamb64ab092015-06-02 10:36:43 -0700102 struct ss_func_desc ss_descs;
Badhri Jagan Sridharanf1500ca2015-10-05 13:04:03 -0700103 struct usb_os_desc_header os_header;
104 struct usb_ext_compat_desc os_desc;
Badhri Jagan Sridharand6a63732014-10-27 18:26:17 -0700105} __attribute__((packed));
106
Elliott Hughes712416a2015-05-05 18:26:10 -0700107static struct func_desc fs_descriptors = {
Badhri Jagan Sridharand6a63732014-10-27 18:26:17 -0700108 .intf = {
109 .bLength = sizeof(fs_descriptors.intf),
110 .bDescriptorType = USB_DT_INTERFACE,
111 .bInterfaceNumber = 0,
112 .bNumEndpoints = 2,
113 .bInterfaceClass = ADB_CLASS,
114 .bInterfaceSubClass = ADB_SUBCLASS,
115 .bInterfaceProtocol = ADB_PROTOCOL,
116 .iInterface = 1, /* first string from the provided table */
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100117 },
Badhri Jagan Sridharand6a63732014-10-27 18:26:17 -0700118 .source = {
119 .bLength = sizeof(fs_descriptors.source),
120 .bDescriptorType = USB_DT_ENDPOINT,
121 .bEndpointAddress = 1 | USB_DIR_OUT,
122 .bmAttributes = USB_ENDPOINT_XFER_BULK,
123 .wMaxPacketSize = MAX_PACKET_SIZE_FS,
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100124 },
Badhri Jagan Sridharand6a63732014-10-27 18:26:17 -0700125 .sink = {
126 .bLength = sizeof(fs_descriptors.sink),
127 .bDescriptorType = USB_DT_ENDPOINT,
128 .bEndpointAddress = 2 | USB_DIR_IN,
129 .bmAttributes = USB_ENDPOINT_XFER_BULK,
130 .wMaxPacketSize = MAX_PACKET_SIZE_FS,
131 },
132};
133
Elliott Hughes712416a2015-05-05 18:26:10 -0700134static struct func_desc hs_descriptors = {
Badhri Jagan Sridharand6a63732014-10-27 18:26:17 -0700135 .intf = {
136 .bLength = sizeof(hs_descriptors.intf),
137 .bDescriptorType = USB_DT_INTERFACE,
138 .bInterfaceNumber = 0,
139 .bNumEndpoints = 2,
140 .bInterfaceClass = ADB_CLASS,
141 .bInterfaceSubClass = ADB_SUBCLASS,
142 .bInterfaceProtocol = ADB_PROTOCOL,
143 .iInterface = 1, /* first string from the provided table */
144 },
145 .source = {
146 .bLength = sizeof(hs_descriptors.source),
147 .bDescriptorType = USB_DT_ENDPOINT,
148 .bEndpointAddress = 1 | USB_DIR_OUT,
149 .bmAttributes = USB_ENDPOINT_XFER_BULK,
150 .wMaxPacketSize = MAX_PACKET_SIZE_HS,
151 },
152 .sink = {
153 .bLength = sizeof(hs_descriptors.sink),
154 .bDescriptorType = USB_DT_ENDPOINT,
155 .bEndpointAddress = 2 | USB_DIR_IN,
156 .bmAttributes = USB_ENDPOINT_XFER_BULK,
157 .wMaxPacketSize = MAX_PACKET_SIZE_HS,
Zhuang Jin Can1fc58c52014-09-02 13:04:44 +0800158 },
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100159};
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800160
Jack Phamb64ab092015-06-02 10:36:43 -0700161static struct ss_func_desc ss_descriptors = {
162 .intf = {
163 .bLength = sizeof(ss_descriptors.intf),
164 .bDescriptorType = USB_DT_INTERFACE,
165 .bInterfaceNumber = 0,
166 .bNumEndpoints = 2,
167 .bInterfaceClass = ADB_CLASS,
168 .bInterfaceSubClass = ADB_SUBCLASS,
169 .bInterfaceProtocol = ADB_PROTOCOL,
170 .iInterface = 1, /* first string from the provided table */
171 },
172 .source = {
173 .bLength = sizeof(ss_descriptors.source),
174 .bDescriptorType = USB_DT_ENDPOINT,
175 .bEndpointAddress = 1 | USB_DIR_OUT,
176 .bmAttributes = USB_ENDPOINT_XFER_BULK,
177 .wMaxPacketSize = MAX_PACKET_SIZE_SS,
178 },
179 .source_comp = {
180 .bLength = sizeof(ss_descriptors.source_comp),
181 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
182 },
183 .sink = {
184 .bLength = sizeof(ss_descriptors.sink),
185 .bDescriptorType = USB_DT_ENDPOINT,
186 .bEndpointAddress = 2 | USB_DIR_IN,
187 .bmAttributes = USB_ENDPOINT_XFER_BULK,
188 .wMaxPacketSize = MAX_PACKET_SIZE_SS,
189 },
190 .sink_comp = {
191 .bLength = sizeof(ss_descriptors.sink_comp),
192 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
193 },
194};
195
Badhri Jagan Sridharanf1500ca2015-10-05 13:04:03 -0700196struct usb_ext_compat_desc os_desc_compat = {
197 .bFirstInterfaceNumber = 0,
198 .Reserved1 = cpu_to_le32(1),
199 .CompatibleID = {0},
200 .SubCompatibleID = {0},
201 .Reserved2 = {0},
202};
203
204static struct usb_os_desc_header os_desc_header = {
205 .interface = cpu_to_le32(1),
206 .dwLength = cpu_to_le32(sizeof(os_desc_header) + sizeof(os_desc_compat)),
207 .bcdVersion = cpu_to_le32(1),
208 .wIndex = cpu_to_le32(4),
209 .bCount = cpu_to_le32(1),
210 .Reserved = cpu_to_le32(0),
211};
212
213
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100214#define STR_INTERFACE_ "ADB Interface"
215
216static const struct {
217 struct usb_functionfs_strings_head header;
218 struct {
219 __le16 code;
220 const char str1[sizeof(STR_INTERFACE_)];
221 } __attribute__((packed)) lang0;
222} __attribute__((packed)) strings = {
223 .header = {
224 .magic = cpu_to_le32(FUNCTIONFS_STRINGS_MAGIC),
225 .length = cpu_to_le32(sizeof(strings)),
226 .str_count = cpu_to_le32(1),
227 .lang_count = cpu_to_le32(1),
228 },
229 .lang0 = {
230 cpu_to_le16(0x0409), /* en-us */
231 STR_INTERFACE_,
232 },
233};
234
Josh Gao7d405252016-02-12 14:31:15 -0800235static void usb_adb_open_thread(void* x) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800236 struct usb_handle *usb = (struct usb_handle *)x;
237 int fd;
238
Siva Velusamy2669cf92015-08-28 16:37:29 -0700239 adb_thread_setname("usb open");
240
Elliott Hughes7cf35752015-04-17 17:03:59 -0700241 while (true) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800242 // wait until the USB device needs opening
243 adb_mutex_lock(&usb->lock);
244 while (usb->fd != -1)
245 adb_cond_wait(&usb->notify, &usb->lock);
246 adb_mutex_unlock(&usb->lock);
247
Yabin Cui815ad882015-09-02 17:44:28 -0700248 D("[ usb_thread - opening device ]");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800249 do {
250 /* XXX use inotify? */
251 fd = unix_open("/dev/android_adb", O_RDWR);
252 if (fd < 0) {
253 // to support older kernels
254 fd = unix_open("/dev/android", O_RDWR);
255 }
256 if (fd < 0) {
257 adb_sleep_ms(1000);
258 }
259 } while (fd < 0);
Yabin Cui815ad882015-09-02 17:44:28 -0700260 D("[ opening device succeeded ]");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800261
262 close_on_exec(fd);
263 usb->fd = fd;
264
Yabin Cui815ad882015-09-02 17:44:28 -0700265 D("[ usb_thread - registering device ]");
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700266 register_usb_transport(usb, 0, 0, 1);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800267 }
268
269 // never gets here
Josh Gao7d405252016-02-12 14:31:15 -0800270 abort();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800271}
272
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100273static int usb_adb_write(usb_handle *h, const void *data, int len)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800274{
275 int n;
276
Yabin Cui815ad882015-09-02 17:44:28 -0700277 D("about to write (fd=%d, len=%d)", h->fd, len);
Spencer Low3a2421b2015-05-22 20:09:06 -0700278 n = unix_write(h->fd, data, len);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800279 if(n != len) {
Yabin Cui815ad882015-09-02 17:44:28 -0700280 D("ERROR: fd = %d, n = %d, errno = %d (%s)",
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700281 h->fd, n, errno, strerror(errno));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800282 return -1;
283 }
Yabin Cui815ad882015-09-02 17:44:28 -0700284 D("[ done fd=%d ]", h->fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800285 return 0;
286}
287
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100288static int usb_adb_read(usb_handle *h, void *data, int len)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800289{
Yabin Cui815ad882015-09-02 17:44:28 -0700290 D("about to read (fd=%d, len=%d)", h->fd, len);
Tamas Berghammera1c60c02015-07-13 19:12:28 +0100291 while (len > 0) {
292 // The kernel implementation of adb_read in f_adb.c doesn't support
293 // reads larger then 4096 bytes. Read the data in 4096 byte chunks to
294 // avoid the issue. (The ffs implementation doesn't have this limit.)
295 int bytes_to_read = len < 4096 ? len : 4096;
296 int n = unix_read(h->fd, data, bytes_to_read);
297 if (n != bytes_to_read) {
Yabin Cui815ad882015-09-02 17:44:28 -0700298 D("ERROR: fd = %d, n = %d, errno = %d (%s)",
Tamas Berghammera1c60c02015-07-13 19:12:28 +0100299 h->fd, n, errno, strerror(errno));
300 return -1;
301 }
302 len -= n;
303 data = ((char*)data) + n;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800304 }
Yabin Cui815ad882015-09-02 17:44:28 -0700305 D("[ done fd=%d ]", h->fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800306 return 0;
307}
308
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100309static void usb_adb_kick(usb_handle *h)
310{
Yabin Cui815ad882015-09-02 17:44:28 -0700311 D("usb_kick");
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100312 adb_mutex_lock(&h->lock);
Spencer Low3a2421b2015-05-22 20:09:06 -0700313 unix_close(h->fd);
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100314 h->fd = -1;
315
316 // notify usb_adb_open_thread that we are disconnected
317 adb_cond_signal(&h->notify);
318 adb_mutex_unlock(&h->lock);
319}
320
321static void usb_adb_init()
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800322{
Elliott Hughes392692c2015-04-16 14:12:50 -0700323 usb_handle* h = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle)));
Elliott Hughesd0269c92015-04-21 19:39:52 -0700324 if (h == nullptr) fatal("couldn't allocate usb_handle");
325
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100326 h->write = usb_adb_write;
327 h->read = usb_adb_read;
328 h->kick = usb_adb_kick;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800329 h->fd = -1;
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100330
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800331 adb_cond_init(&h->notify, 0);
332 adb_mutex_init(&h->lock, 0);
333
Elliott Hughes392692c2015-04-16 14:12:50 -0700334 // Open the file /dev/android_adb_enable to trigger
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800335 // the enabling of the adb USB function in the kernel.
336 // We never touch this file again - just leave it open
337 // indefinitely so the kernel will know when we are running
338 // and when we are not.
Elliott Hughes392692c2015-04-16 14:12:50 -0700339 int fd = unix_open("/dev/android_adb_enable", O_RDWR);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800340 if (fd < 0) {
Yabin Cui815ad882015-09-02 17:44:28 -0700341 D("failed to open /dev/android_adb_enable");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800342 } else {
343 close_on_exec(fd);
344 }
345
Yabin Cui815ad882015-09-02 17:44:28 -0700346 D("[ usb_init - starting thread ]");
Elliott Hughesf2517142015-05-05 13:41:21 -0700347 if (!adb_thread_create(usb_adb_open_thread, h)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800348 fatal_errno("cannot create usb thread");
349 }
350}
351
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800352
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100353static void init_functionfs(struct usb_handle *h)
354{
355 ssize_t ret;
Badhri Jagan Sridharand6a63732014-10-27 18:26:17 -0700356 struct desc_v1 v1_descriptor;
357 struct desc_v2 v2_descriptor;
358
359 v2_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
360 v2_descriptor.header.length = cpu_to_le32(sizeof(v2_descriptor));
Jack Phamb64ab092015-06-02 10:36:43 -0700361 v2_descriptor.header.flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC |
Badhri Jagan Sridharanf1500ca2015-10-05 13:04:03 -0700362 FUNCTIONFS_HAS_SS_DESC | FUNCTIONFS_HAS_MS_OS_DESC;
Christopher Ferrisf7555b12015-01-23 17:09:56 -0800363 v2_descriptor.fs_count = 3;
364 v2_descriptor.hs_count = 3;
Jack Phamb64ab092015-06-02 10:36:43 -0700365 v2_descriptor.ss_count = 5;
Badhri Jagan Sridharanf1500ca2015-10-05 13:04:03 -0700366 v2_descriptor.os_count = 1;
Badhri Jagan Sridharand6a63732014-10-27 18:26:17 -0700367 v2_descriptor.fs_descs = fs_descriptors;
368 v2_descriptor.hs_descs = hs_descriptors;
Jack Phamb64ab092015-06-02 10:36:43 -0700369 v2_descriptor.ss_descs = ss_descriptors;
Badhri Jagan Sridharanf1500ca2015-10-05 13:04:03 -0700370 v2_descriptor.os_header = os_desc_header;
371 v2_descriptor.os_desc = os_desc_compat;
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100372
Jack Pham6c3cef52013-12-23 17:46:10 -0800373 if (h->control < 0) { // might have already done this before
Yabin Cui815ad882015-09-02 17:44:28 -0700374 D("OPENING %s", USB_FFS_ADB_EP0);
Jack Pham6c3cef52013-12-23 17:46:10 -0800375 h->control = adb_open(USB_FFS_ADB_EP0, O_RDWR);
376 if (h->control < 0) {
Yabin Cui815ad882015-09-02 17:44:28 -0700377 D("[ %s: cannot open control endpoint: errno=%d]", USB_FFS_ADB_EP0, errno);
Jack Pham6c3cef52013-12-23 17:46:10 -0800378 goto err;
379 }
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100380
Badhri Jagan Sridharand6a63732014-10-27 18:26:17 -0700381 ret = adb_write(h->control, &v2_descriptor, sizeof(v2_descriptor));
Jack Pham6c3cef52013-12-23 17:46:10 -0800382 if (ret < 0) {
Badhri Jagan Sridharand6a63732014-10-27 18:26:17 -0700383 v1_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC);
384 v1_descriptor.header.length = cpu_to_le32(sizeof(v1_descriptor));
385 v1_descriptor.header.fs_count = 3;
386 v1_descriptor.header.hs_count = 3;
387 v1_descriptor.fs_descs = fs_descriptors;
388 v1_descriptor.hs_descs = hs_descriptors;
Yabin Cui815ad882015-09-02 17:44:28 -0700389 D("[ %s: Switching to V1_descriptor format errno=%d ]", USB_FFS_ADB_EP0, errno);
Badhri Jagan Sridharand6a63732014-10-27 18:26:17 -0700390 ret = adb_write(h->control, &v1_descriptor, sizeof(v1_descriptor));
391 if (ret < 0) {
Yabin Cui815ad882015-09-02 17:44:28 -0700392 D("[ %s: write descriptors failed: errno=%d ]", USB_FFS_ADB_EP0, errno);
Badhri Jagan Sridharand6a63732014-10-27 18:26:17 -0700393 goto err;
394 }
Jack Pham6c3cef52013-12-23 17:46:10 -0800395 }
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100396
Jack Pham6c3cef52013-12-23 17:46:10 -0800397 ret = adb_write(h->control, &strings, sizeof(strings));
398 if (ret < 0) {
Yabin Cui815ad882015-09-02 17:44:28 -0700399 D("[ %s: writing strings failed: errno=%d]", USB_FFS_ADB_EP0, errno);
Jack Pham6c3cef52013-12-23 17:46:10 -0800400 goto err;
401 }
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100402 }
403
404 h->bulk_out = adb_open(USB_FFS_ADB_OUT, O_RDWR);
405 if (h->bulk_out < 0) {
Yabin Cui815ad882015-09-02 17:44:28 -0700406 D("[ %s: cannot open bulk-out ep: errno=%d ]", USB_FFS_ADB_OUT, errno);
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100407 goto err;
408 }
409
410 h->bulk_in = adb_open(USB_FFS_ADB_IN, O_RDWR);
411 if (h->bulk_in < 0) {
Yabin Cui815ad882015-09-02 17:44:28 -0700412 D("[ %s: cannot open bulk-in ep: errno=%d ]", USB_FFS_ADB_IN, errno);
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100413 goto err;
414 }
415
416 return;
417
418err:
419 if (h->bulk_in > 0) {
420 adb_close(h->bulk_in);
421 h->bulk_in = -1;
422 }
423 if (h->bulk_out > 0) {
424 adb_close(h->bulk_out);
425 h->bulk_out = -1;
426 }
427 if (h->control > 0) {
428 adb_close(h->control);
429 h->control = -1;
430 }
431 return;
432}
433
Josh Gao7d405252016-02-12 14:31:15 -0800434static void usb_ffs_open_thread(void* x) {
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100435 struct usb_handle *usb = (struct usb_handle *)x;
436
Siva Velusamy2669cf92015-08-28 16:37:29 -0700437 adb_thread_setname("usb ffs open");
438
Elliott Hughes7cf35752015-04-17 17:03:59 -0700439 while (true) {
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100440 // wait until the USB device needs opening
441 adb_mutex_lock(&usb->lock);
Jack Pham6c3cef52013-12-23 17:46:10 -0800442 while (usb->control != -1 && usb->bulk_in != -1 && usb->bulk_out != -1)
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100443 adb_cond_wait(&usb->notify, &usb->lock);
444 adb_mutex_unlock(&usb->lock);
445
Elliott Hughes7cf35752015-04-17 17:03:59 -0700446 while (true) {
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100447 init_functionfs(usb);
448
Jack Pham6c3cef52013-12-23 17:46:10 -0800449 if (usb->control >= 0 && usb->bulk_in >= 0 && usb->bulk_out >= 0)
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100450 break;
451
452 adb_sleep_ms(1000);
453 }
Badhri Jagan Sridharane1febe92015-04-21 11:09:32 -0700454 property_set("sys.usb.ffs.ready", "1");
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100455
Yabin Cui815ad882015-09-02 17:44:28 -0700456 D("[ usb_thread - registering device ]");
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100457 register_usb_transport(usb, 0, 0, 1);
458 }
459
460 // never gets here
Josh Gao7d405252016-02-12 14:31:15 -0800461 abort();
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100462}
463
Josh Gao8e701252015-12-02 17:30:58 -0800464static int usb_ffs_write(usb_handle* h, const void* data, int len) {
Yabin Cui815ad882015-09-02 17:44:28 -0700465 D("about to write (fd=%d, len=%d)", h->bulk_in, len);
Josh Gao8e701252015-12-02 17:30:58 -0800466
Josh Gao8e701252015-12-02 17:30:58 -0800467 const char* buf = static_cast<const char*>(data);
468 while (len > 0) {
Josh Gaoc95bb3d2015-12-17 13:45:18 -0800469 int write_len = std::min(USB_FFS_MAX_WRITE, len);
Josh Gao8e701252015-12-02 17:30:58 -0800470 int n = adb_write(h->bulk_in, buf, write_len);
471 if (n < 0) {
472 D("ERROR: fd = %d, n = %d: %s", h->bulk_in, n, strerror(errno));
473 return -1;
474 }
475 buf += n;
476 len -= n;
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100477 }
Josh Gao8e701252015-12-02 17:30:58 -0800478
Yabin Cui815ad882015-09-02 17:44:28 -0700479 D("[ done fd=%d ]", h->bulk_in);
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100480 return 0;
481}
482
Josh Gao8e701252015-12-02 17:30:58 -0800483static int usb_ffs_read(usb_handle* h, void* data, int len) {
484 D("about to read (fd=%d, len=%d)", h->bulk_out, len);
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100485
Josh Gao8e701252015-12-02 17:30:58 -0800486 char* buf = static_cast<char*>(data);
487 while (len > 0) {
Josh Gaoc95bb3d2015-12-17 13:45:18 -0800488 int read_len = std::min(USB_FFS_MAX_READ, len);
Josh Gao83e329e2015-12-16 11:00:08 -0800489 int n = adb_read(h->bulk_out, buf, read_len);
Josh Gao8e701252015-12-02 17:30:58 -0800490 if (n < 0) {
491 D("ERROR: fd = %d, n = %d: %s", h->bulk_out, n, strerror(errno));
Elliott Hughes0bd85872015-08-25 10:59:45 -0700492 return -1;
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100493 }
Josh Gao8e701252015-12-02 17:30:58 -0800494 buf += n;
495 len -= n;
Elliott Hughes0bd85872015-08-25 10:59:45 -0700496 }
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100497
Yabin Cui815ad882015-09-02 17:44:28 -0700498 D("[ done fd=%d ]", h->bulk_out);
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100499 return 0;
500}
501
502static void usb_ffs_kick(usb_handle *h)
503{
504 int err;
505
506 err = ioctl(h->bulk_in, FUNCTIONFS_CLEAR_HALT);
Yabin Cui19bec5b2015-09-22 15:52:57 -0700507 if (err < 0) {
Yabin Cui815ad882015-09-02 17:44:28 -0700508 D("[ kick: source (fd=%d) clear halt failed (%d) ]", h->bulk_in, errno);
Yabin Cui19bec5b2015-09-22 15:52:57 -0700509 }
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100510
511 err = ioctl(h->bulk_out, FUNCTIONFS_CLEAR_HALT);
Yabin Cui19bec5b2015-09-22 15:52:57 -0700512 if (err < 0) {
Yabin Cui815ad882015-09-02 17:44:28 -0700513 D("[ kick: sink (fd=%d) clear halt failed (%d) ]", h->bulk_out, errno);
Yabin Cui19bec5b2015-09-22 15:52:57 -0700514 }
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100515
516 adb_mutex_lock(&h->lock);
Jack Pham6c3cef52013-12-23 17:46:10 -0800517
518 // don't close ep0 here, since we may not need to reinitialize it with
519 // the same descriptors again. if however ep1/ep2 fail to re-open in
520 // init_functionfs, only then would we close and open ep0 again.
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100521 adb_close(h->bulk_out);
522 adb_close(h->bulk_in);
Jack Pham6c3cef52013-12-23 17:46:10 -0800523 h->bulk_out = h->bulk_in = -1;
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100524
525 // notify usb_ffs_open_thread that we are disconnected
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800526 adb_cond_signal(&h->notify);
527 adb_mutex_unlock(&h->lock);
528}
529
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100530static void usb_ffs_init()
531{
Yabin Cui815ad882015-09-02 17:44:28 -0700532 D("[ usb_init - using FunctionFS ]");
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100533
Elliott Hughes392692c2015-04-16 14:12:50 -0700534 usb_handle* h = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle)));
Elliott Hughesd0269c92015-04-21 19:39:52 -0700535 if (h == nullptr) fatal("couldn't allocate usb_handle");
536
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100537 h->write = usb_ffs_write;
538 h->read = usb_ffs_read;
539 h->kick = usb_ffs_kick;
Elliott Hughes392692c2015-04-16 14:12:50 -0700540 h->control = -1;
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100541 h->bulk_out = -1;
542 h->bulk_out = -1;
543
544 adb_cond_init(&h->notify, 0);
545 adb_mutex_init(&h->lock, 0);
546
Yabin Cui815ad882015-09-02 17:44:28 -0700547 D("[ usb_init - starting thread ]");
Elliott Hughesf2517142015-05-05 13:41:21 -0700548 if (!adb_thread_create(usb_ffs_open_thread, h)) {
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100549 fatal_errno("[ cannot create usb thread ]\n");
550 }
551}
552
553void usb_init()
554{
555 if (access(USB_FFS_ADB_EP0, F_OK) == 0)
556 usb_ffs_init();
557 else
558 usb_adb_init();
559}
560
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100561int usb_write(usb_handle *h, const void *data, int len)
562{
563 return h->write(h, data, len);
564}
565
566int usb_read(usb_handle *h, void *data, int len)
567{
568 return h->read(h, data, len);
569}
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800570int usb_close(usb_handle *h)
571{
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800572 return 0;
573}
Andrzej Pietrasiewiczd7270f22012-01-13 15:13:46 +0100574
575void usb_kick(usb_handle *h)
576{
577 h->kick(h);
578}