blob: 70d2ad01d9aa8bd802e07337deb33a7c0475efcd [file] [log] [blame]
The Android Open Source Projectdd7bc332009-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
17#include <stdio.h>
18#include <stdlib.h>
19#include <unistd.h>
20#include <string.h>
21
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +010022#include <linux/usb/ch9.h>
23#include <linux/usb/functionfs.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080024#include <sys/ioctl.h>
25#include <sys/types.h>
26#include <dirent.h>
27#include <errno.h>
28
29#include "sysdeps.h"
30
31#define TRACE_TAG TRACE_USB
32#include "adb.h"
33
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +010034#define MAX_PACKET_SIZE_FS 64
35#define MAX_PACKET_SIZE_HS 512
Zhuang Jin Cand6ee9f22014-09-02 13:04:44 +080036#define MAX_PACKET_SIZE_SS 1024
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +010037
38#define cpu_to_le16(x) htole16(x)
39#define cpu_to_le32(x) htole32(x)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080040
41struct usb_handle
42{
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080043 adb_cond_t notify;
44 adb_mutex_t lock;
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +010045
46 int (*write)(usb_handle *h, const void *data, int len);
47 int (*read)(usb_handle *h, void *data, int len);
48 void (*kick)(usb_handle *h);
49
50 // Legacy f_adb
51 int fd;
52
53 // FunctionFS
54 int control;
55 int bulk_out; /* "out" from the host's perspective => source for adbd */
56 int bulk_in; /* "in" from the host's perspective => sink for adbd */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080057};
58
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +010059static const struct {
Zhuang Jin Cand6ee9f22014-09-02 13:04:44 +080060 __le32 magic;
61 __le32 length;
62 __le32 flags;
63 __le32 fs_count;
64 __le32 hs_count;
65 __le32 ss_count;
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +010066 struct {
67 struct usb_interface_descriptor intf;
68 struct usb_endpoint_descriptor_no_audio source;
69 struct usb_endpoint_descriptor_no_audio sink;
70 } __attribute__((packed)) fs_descs, hs_descs;
Zhuang Jin Cand6ee9f22014-09-02 13:04:44 +080071 struct {
72 struct usb_interface_descriptor intf;
73 struct usb_endpoint_descriptor_no_audio source;
74 struct usb_ss_ep_comp_descriptor source_comp;
75 struct usb_endpoint_descriptor_no_audio sink;
76 struct usb_ss_ep_comp_descriptor sink_comp;
77 } __attribute__((packed)) ss_descs;
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +010078} __attribute__((packed)) descriptors = {
Zhuang Jin Cand6ee9f22014-09-02 13:04:44 +080079 .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2),
80 .length = cpu_to_le32(sizeof(descriptors)),
81 .flags = cpu_to_le32(FUNCTIONFS_HAS_FS_DESC |
82 FUNCTIONFS_HAS_HS_DESC |
83 FUNCTIONFS_HAS_SS_DESC),
84 .fs_count = 3,
85 .hs_count = 3,
86 .ss_count = 5,
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +010087 .fs_descs = {
88 .intf = {
89 .bLength = sizeof(descriptors.fs_descs.intf),
90 .bDescriptorType = USB_DT_INTERFACE,
91 .bInterfaceNumber = 0,
92 .bNumEndpoints = 2,
93 .bInterfaceClass = ADB_CLASS,
94 .bInterfaceSubClass = ADB_SUBCLASS,
95 .bInterfaceProtocol = ADB_PROTOCOL,
96 .iInterface = 1, /* first string from the provided table */
97 },
98 .source = {
99 .bLength = sizeof(descriptors.fs_descs.source),
100 .bDescriptorType = USB_DT_ENDPOINT,
101 .bEndpointAddress = 1 | USB_DIR_OUT,
102 .bmAttributes = USB_ENDPOINT_XFER_BULK,
103 .wMaxPacketSize = MAX_PACKET_SIZE_FS,
104 },
105 .sink = {
106 .bLength = sizeof(descriptors.fs_descs.sink),
107 .bDescriptorType = USB_DT_ENDPOINT,
108 .bEndpointAddress = 2 | USB_DIR_IN,
109 .bmAttributes = USB_ENDPOINT_XFER_BULK,
110 .wMaxPacketSize = MAX_PACKET_SIZE_FS,
111 },
112 },
113 .hs_descs = {
114 .intf = {
115 .bLength = sizeof(descriptors.hs_descs.intf),
116 .bDescriptorType = USB_DT_INTERFACE,
117 .bInterfaceNumber = 0,
118 .bNumEndpoints = 2,
119 .bInterfaceClass = ADB_CLASS,
120 .bInterfaceSubClass = ADB_SUBCLASS,
121 .bInterfaceProtocol = ADB_PROTOCOL,
122 .iInterface = 1, /* first string from the provided table */
123 },
124 .source = {
125 .bLength = sizeof(descriptors.hs_descs.source),
126 .bDescriptorType = USB_DT_ENDPOINT,
127 .bEndpointAddress = 1 | USB_DIR_OUT,
128 .bmAttributes = USB_ENDPOINT_XFER_BULK,
129 .wMaxPacketSize = MAX_PACKET_SIZE_HS,
130 },
131 .sink = {
132 .bLength = sizeof(descriptors.hs_descs.sink),
133 .bDescriptorType = USB_DT_ENDPOINT,
134 .bEndpointAddress = 2 | USB_DIR_IN,
135 .bmAttributes = USB_ENDPOINT_XFER_BULK,
136 .wMaxPacketSize = MAX_PACKET_SIZE_HS,
137 },
138 },
Zhuang Jin Cand6ee9f22014-09-02 13:04:44 +0800139 .ss_descs = {
140 .intf = {
141 .bLength = sizeof(descriptors.ss_descs.intf),
142 .bDescriptorType = USB_DT_INTERFACE,
143 .bInterfaceNumber = 0,
144 .bNumEndpoints = 2,
145 .bInterfaceClass = ADB_CLASS,
146 .bInterfaceSubClass = ADB_SUBCLASS,
147 .bInterfaceProtocol = ADB_PROTOCOL,
148 .iInterface = 1, /* first string from the provided table */
149 },
150 .source = {
151 .bLength = sizeof(descriptors.ss_descs.source),
152 .bDescriptorType = USB_DT_ENDPOINT,
153 .bEndpointAddress = 1 | USB_DIR_OUT,
154 .bmAttributes = USB_ENDPOINT_XFER_BULK,
155 .wMaxPacketSize = MAX_PACKET_SIZE_SS,
156 },
157 .source_comp = {
158 .bLength = sizeof(descriptors.ss_descs.source_comp),
159 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
160 },
161 .sink = {
162 .bLength = sizeof(descriptors.ss_descs.sink),
163 .bDescriptorType = USB_DT_ENDPOINT,
164 .bEndpointAddress = 2 | USB_DIR_IN,
165 .bmAttributes = USB_ENDPOINT_XFER_BULK,
166 .wMaxPacketSize = MAX_PACKET_SIZE_SS,
167 },
168 .sink_comp = {
169 .bLength = sizeof(descriptors.ss_descs.sink_comp),
170 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
171 },
172 },
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100173};
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800174
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100175#define STR_INTERFACE_ "ADB Interface"
176
177static const struct {
178 struct usb_functionfs_strings_head header;
179 struct {
180 __le16 code;
181 const char str1[sizeof(STR_INTERFACE_)];
182 } __attribute__((packed)) lang0;
183} __attribute__((packed)) strings = {
184 .header = {
185 .magic = cpu_to_le32(FUNCTIONFS_STRINGS_MAGIC),
186 .length = cpu_to_le32(sizeof(strings)),
187 .str_count = cpu_to_le32(1),
188 .lang_count = cpu_to_le32(1),
189 },
190 .lang0 = {
191 cpu_to_le16(0x0409), /* en-us */
192 STR_INTERFACE_,
193 },
194};
195
196
197
198static void *usb_adb_open_thread(void *x)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800199{
200 struct usb_handle *usb = (struct usb_handle *)x;
201 int fd;
202
203 while (1) {
204 // wait until the USB device needs opening
205 adb_mutex_lock(&usb->lock);
206 while (usb->fd != -1)
207 adb_cond_wait(&usb->notify, &usb->lock);
208 adb_mutex_unlock(&usb->lock);
209
210 D("[ usb_thread - opening device ]\n");
211 do {
212 /* XXX use inotify? */
213 fd = unix_open("/dev/android_adb", O_RDWR);
214 if (fd < 0) {
215 // to support older kernels
216 fd = unix_open("/dev/android", O_RDWR);
217 }
218 if (fd < 0) {
219 adb_sleep_ms(1000);
220 }
221 } while (fd < 0);
222 D("[ opening device succeeded ]\n");
223
224 close_on_exec(fd);
225 usb->fd = fd;
226
227 D("[ usb_thread - registering device ]\n");
Scott Andersone109d262012-04-20 11:21:14 -0700228 register_usb_transport(usb, 0, 0, 1);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800229 }
230
231 // never gets here
232 return 0;
233}
234
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100235static int usb_adb_write(usb_handle *h, const void *data, int len)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800236{
237 int n;
238
JP Abgrall408fa572011-03-16 15:57:42 -0700239 D("about to write (fd=%d, len=%d)\n", h->fd, len);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800240 n = adb_write(h->fd, data, len);
241 if(n != len) {
JP Abgrall408fa572011-03-16 15:57:42 -0700242 D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
243 h->fd, n, errno, strerror(errno));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800244 return -1;
245 }
JP Abgrall408fa572011-03-16 15:57:42 -0700246 D("[ done fd=%d ]\n", h->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800247 return 0;
248}
249
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100250static int usb_adb_read(usb_handle *h, void *data, int len)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800251{
252 int n;
253
JP Abgrall408fa572011-03-16 15:57:42 -0700254 D("about to read (fd=%d, len=%d)\n", h->fd, len);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800255 n = adb_read(h->fd, data, len);
256 if(n != len) {
JP Abgrall408fa572011-03-16 15:57:42 -0700257 D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
258 h->fd, n, errno, strerror(errno));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800259 return -1;
260 }
JP Abgrall408fa572011-03-16 15:57:42 -0700261 D("[ done fd=%d ]\n", h->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800262 return 0;
263}
264
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100265static void usb_adb_kick(usb_handle *h)
266{
267 D("usb_kick\n");
268 adb_mutex_lock(&h->lock);
269 adb_close(h->fd);
270 h->fd = -1;
271
272 // notify usb_adb_open_thread that we are disconnected
273 adb_cond_signal(&h->notify);
274 adb_mutex_unlock(&h->lock);
275}
276
277static void usb_adb_init()
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800278{
279 usb_handle *h;
280 adb_thread_t tid;
281 int fd;
282
283 h = calloc(1, sizeof(usb_handle));
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100284
285 h->write = usb_adb_write;
286 h->read = usb_adb_read;
287 h->kick = usb_adb_kick;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800288 h->fd = -1;
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100289
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800290 adb_cond_init(&h->notify, 0);
291 adb_mutex_init(&h->lock, 0);
292
293 // Open the file /dev/android_adb_enable to trigger
294 // the enabling of the adb USB function in the kernel.
295 // We never touch this file again - just leave it open
296 // indefinitely so the kernel will know when we are running
297 // and when we are not.
298 fd = unix_open("/dev/android_adb_enable", O_RDWR);
299 if (fd < 0) {
300 D("failed to open /dev/android_adb_enable\n");
301 } else {
302 close_on_exec(fd);
303 }
304
305 D("[ usb_init - starting thread ]\n");
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100306 if(adb_thread_create(&tid, usb_adb_open_thread, h)){
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800307 fatal_errno("cannot create usb thread");
308 }
309}
310
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800311
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100312static void init_functionfs(struct usb_handle *h)
313{
314 ssize_t ret;
315
Jack Pham4cbf1d82013-12-23 17:46:10 -0800316 if (h->control < 0) { // might have already done this before
317 D("OPENING %s\n", USB_FFS_ADB_EP0);
318 h->control = adb_open(USB_FFS_ADB_EP0, O_RDWR);
319 if (h->control < 0) {
320 D("[ %s: cannot open control endpoint: errno=%d]\n", USB_FFS_ADB_EP0, errno);
321 goto err;
322 }
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100323
Jack Pham4cbf1d82013-12-23 17:46:10 -0800324 ret = adb_write(h->control, &descriptors, sizeof(descriptors));
325 if (ret < 0) {
326 D("[ %s: write descriptors failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno);
327 goto err;
328 }
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100329
Jack Pham4cbf1d82013-12-23 17:46:10 -0800330 ret = adb_write(h->control, &strings, sizeof(strings));
331 if (ret < 0) {
332 D("[ %s: writing strings failed: errno=%d]\n", USB_FFS_ADB_EP0, errno);
333 goto err;
334 }
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100335 }
336
337 h->bulk_out = adb_open(USB_FFS_ADB_OUT, O_RDWR);
338 if (h->bulk_out < 0) {
339 D("[ %s: cannot open bulk-out ep: errno=%d ]\n", USB_FFS_ADB_OUT, errno);
340 goto err;
341 }
342
343 h->bulk_in = adb_open(USB_FFS_ADB_IN, O_RDWR);
344 if (h->bulk_in < 0) {
345 D("[ %s: cannot open bulk-in ep: errno=%d ]\n", USB_FFS_ADB_IN, errno);
346 goto err;
347 }
348
349 return;
350
351err:
352 if (h->bulk_in > 0) {
353 adb_close(h->bulk_in);
354 h->bulk_in = -1;
355 }
356 if (h->bulk_out > 0) {
357 adb_close(h->bulk_out);
358 h->bulk_out = -1;
359 }
360 if (h->control > 0) {
361 adb_close(h->control);
362 h->control = -1;
363 }
364 return;
365}
366
367static void *usb_ffs_open_thread(void *x)
368{
369 struct usb_handle *usb = (struct usb_handle *)x;
370
371 while (1) {
372 // wait until the USB device needs opening
373 adb_mutex_lock(&usb->lock);
Jack Pham4cbf1d82013-12-23 17:46:10 -0800374 while (usb->control != -1 && usb->bulk_in != -1 && usb->bulk_out != -1)
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100375 adb_cond_wait(&usb->notify, &usb->lock);
376 adb_mutex_unlock(&usb->lock);
377
378 while (1) {
379 init_functionfs(usb);
380
Jack Pham4cbf1d82013-12-23 17:46:10 -0800381 if (usb->control >= 0 && usb->bulk_in >= 0 && usb->bulk_out >= 0)
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100382 break;
383
384 adb_sleep_ms(1000);
385 }
386
387 D("[ usb_thread - registering device ]\n");
388 register_usb_transport(usb, 0, 0, 1);
389 }
390
391 // never gets here
392 return 0;
393}
394
395static int bulk_write(int bulk_in, const char *buf, size_t length)
396{
397 size_t count = 0;
398 int ret;
399
400 do {
401 ret = adb_write(bulk_in, buf + count, length - count);
402 if (ret < 0) {
403 if (errno != EINTR)
404 return ret;
405 } else {
406 count += ret;
407 }
408 } while (count < length);
409
410 D("[ bulk_write done fd=%d ]\n", bulk_in);
411 return count;
412}
413
414static int usb_ffs_write(usb_handle *h, const void *data, int len)
415{
416 int n;
417
418 D("about to write (fd=%d, len=%d)\n", h->bulk_in, len);
419 n = bulk_write(h->bulk_in, data, len);
420 if (n != len) {
421 D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
422 h->bulk_in, n, errno, strerror(errno));
423 return -1;
424 }
425 D("[ done fd=%d ]\n", h->bulk_in);
426 return 0;
427}
428
429static int bulk_read(int bulk_out, char *buf, size_t length)
430{
431 size_t count = 0;
432 int ret;
433
434 do {
435 ret = adb_read(bulk_out, buf + count, length - count);
436 if (ret < 0) {
437 if (errno != EINTR) {
Elliott Hughesccecf142014-01-16 10:53:11 -0800438 D("[ bulk_read failed fd=%d length=%zu count=%zu ]\n",
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100439 bulk_out, length, count);
440 return ret;
441 }
442 } else {
443 count += ret;
444 }
445 } while (count < length);
446
447 return count;
448}
449
450static int usb_ffs_read(usb_handle *h, void *data, int len)
451{
452 int n;
453
454 D("about to read (fd=%d, len=%d)\n", h->bulk_out, len);
455 n = bulk_read(h->bulk_out, data, len);
456 if (n != len) {
457 D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
458 h->bulk_out, n, errno, strerror(errno));
459 return -1;
460 }
461 D("[ done fd=%d ]\n", h->bulk_out);
462 return 0;
463}
464
465static void usb_ffs_kick(usb_handle *h)
466{
467 int err;
468
469 err = ioctl(h->bulk_in, FUNCTIONFS_CLEAR_HALT);
470 if (err < 0)
471 D("[ kick: source (fd=%d) clear halt failed (%d) ]", h->bulk_in, errno);
472
473 err = ioctl(h->bulk_out, FUNCTIONFS_CLEAR_HALT);
474 if (err < 0)
475 D("[ kick: sink (fd=%d) clear halt failed (%d) ]", h->bulk_out, errno);
476
477 adb_mutex_lock(&h->lock);
Jack Pham4cbf1d82013-12-23 17:46:10 -0800478
479 // don't close ep0 here, since we may not need to reinitialize it with
480 // the same descriptors again. if however ep1/ep2 fail to re-open in
481 // init_functionfs, only then would we close and open ep0 again.
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100482 adb_close(h->bulk_out);
483 adb_close(h->bulk_in);
Jack Pham4cbf1d82013-12-23 17:46:10 -0800484 h->bulk_out = h->bulk_in = -1;
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100485
486 // notify usb_ffs_open_thread that we are disconnected
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800487 adb_cond_signal(&h->notify);
488 adb_mutex_unlock(&h->lock);
489}
490
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100491static void usb_ffs_init()
492{
493 usb_handle *h;
494 adb_thread_t tid;
495
496 D("[ usb_init - using FunctionFS ]\n");
497
498 h = calloc(1, sizeof(usb_handle));
499
500 h->write = usb_ffs_write;
501 h->read = usb_ffs_read;
502 h->kick = usb_ffs_kick;
503
504 h->control = -1;
505 h->bulk_out = -1;
506 h->bulk_out = -1;
507
508 adb_cond_init(&h->notify, 0);
509 adb_mutex_init(&h->lock, 0);
510
511 D("[ usb_init - starting thread ]\n");
512 if (adb_thread_create(&tid, usb_ffs_open_thread, h)){
513 fatal_errno("[ cannot create usb thread ]\n");
514 }
515}
516
517void usb_init()
518{
519 if (access(USB_FFS_ADB_EP0, F_OK) == 0)
520 usb_ffs_init();
521 else
522 usb_adb_init();
523}
524
525void usb_cleanup()
526{
527}
528
529int usb_write(usb_handle *h, const void *data, int len)
530{
531 return h->write(h, data, len);
532}
533
534int usb_read(usb_handle *h, void *data, int len)
535{
536 return h->read(h, data, len);
537}
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800538int usb_close(usb_handle *h)
539{
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800540 return 0;
541}
Andrzej Pietrasiewiczfd96db12012-01-13 15:13:46 +0100542
543void usb_kick(usb_handle *h)
544{
545 h->kick(h);
546}