blob: 31fd167aedd433aa34e469b780a0240e3f029f01 [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
Dan Albertdb6fe642015-03-19 15:21:08 -070017#define TRACE_TAG TRACE_USB
18
19#include "sysdeps.h"
20
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080021#include <ctype.h>
Dan Albertb302d122015-02-24 15:51:19 -080022#include <dirent.h>
23#include <errno.h>
24#include <fcntl.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080025#include <linux/usbdevice_fs.h>
26#include <linux/version.h>
Dan Albertb302d122015-02-24 15:51:19 -080027#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <sys/ioctl.h>
31#include <sys/time.h>
32#include <sys/types.h>
33#include <unistd.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080034#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20)
35#include <linux/usb/ch9.h>
36#else
37#include <linux/usb_ch9.h>
38#endif
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080039
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080040#include "adb.h"
Dan Albertb302d122015-02-24 15:51:19 -080041#include "transport.h"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080042
43/* usb scan debugging is waaaay too verbose */
44#define DBGX(x...)
45
JP Abgrall2e5dd6e2011-03-16 15:57:42 -070046ADB_MUTEX_DEFINE( usb_lock );
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080047
48struct usb_handle
49{
50 usb_handle *prev;
51 usb_handle *next;
52
53 char fname[64];
54 int desc;
55 unsigned char ep_in;
56 unsigned char ep_out;
57
58 unsigned zero_mask;
Mike Lockwoode45583f2009-08-08 12:37:44 -040059 unsigned writeable;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080060
61 struct usbdevfs_urb urb_in;
62 struct usbdevfs_urb urb_out;
63
64 int urb_in_busy;
65 int urb_out_busy;
66 int dead;
67
68 adb_cond_t notify;
69 adb_mutex_t lock;
70
71 // for garbage collecting disconnected devices
72 int mark;
73
74 // ID of thread currently in REAPURB
75 pthread_t reaper_thread;
76};
77
78static usb_handle handle_list = {
79 .prev = &handle_list,
80 .next = &handle_list,
81};
82
83static int known_device(const char *dev_name)
84{
85 usb_handle *usb;
86
87 adb_mutex_lock(&usb_lock);
88 for(usb = handle_list.next; usb != &handle_list; usb = usb->next){
89 if(!strcmp(usb->fname, dev_name)) {
90 // set mark flag to indicate this device is still alive
91 usb->mark = 1;
92 adb_mutex_unlock(&usb_lock);
93 return 1;
94 }
95 }
96 adb_mutex_unlock(&usb_lock);
97 return 0;
98}
99
100static void kick_disconnected_devices()
101{
102 usb_handle *usb;
103
104 adb_mutex_lock(&usb_lock);
105 // kick any devices in the device list that were not found in the device scan
106 for(usb = handle_list.next; usb != &handle_list; usb = usb->next){
107 if (usb->mark == 0) {
108 usb_kick(usb);
109 } else {
110 usb->mark = 0;
111 }
112 }
113 adb_mutex_unlock(&usb_lock);
114
115}
116
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800117static inline int badname(const char *name)
118{
119 while(*name) {
120 if(!isdigit(*name++)) return 1;
121 }
122 return 0;
123}
124
Mike Lockwoode45583f2009-08-08 12:37:44 -0400125static void find_usb_device(const char *base,
126 void (*register_device_callback)
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700127 (const char *, const char *, unsigned char, unsigned char, int, int, unsigned))
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800128{
129 char busname[32], devname[32];
130 unsigned char local_ep_in, local_ep_out;
131 DIR *busdir , *devdir ;
132 struct dirent *de;
133 int fd ;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800134
135 busdir = opendir(base);
Mike Lockwoode45583f2009-08-08 12:37:44 -0400136 if(busdir == 0) return;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800137
138 while((de = readdir(busdir)) != 0) {
139 if(badname(de->d_name)) continue;
140
141 snprintf(busname, sizeof busname, "%s/%s", base, de->d_name);
142 devdir = opendir(busname);
143 if(devdir == 0) continue;
144
145// DBGX("[ scanning %s ]\n", busname);
146 while((de = readdir(devdir))) {
Mike Lockwoodf1667712011-01-07 23:18:14 -0500147 unsigned char devdesc[4096];
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800148 unsigned char* bufptr = devdesc;
Mike Lockwood31175d62010-01-17 00:52:27 -0500149 unsigned char* bufend;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800150 struct usb_device_descriptor* device;
151 struct usb_config_descriptor* config;
152 struct usb_interface_descriptor* interface;
153 struct usb_endpoint_descriptor *ep1, *ep2;
154 unsigned zero_mask = 0;
155 unsigned vid, pid;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800156 size_t desclength;
157
158 if(badname(de->d_name)) continue;
159 snprintf(devname, sizeof devname, "%s/%s", busname, de->d_name);
160
161 if(known_device(devname)) {
162 DBGX("skipping %s\n", devname);
163 continue;
164 }
165
166// DBGX("[ scanning %s ]\n", devname);
Nick Kralevich777523e2014-07-18 20:57:35 -0700167 if((fd = unix_open(devname, O_RDONLY | O_CLOEXEC)) < 0) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800168 continue;
169 }
170
171 desclength = adb_read(fd, devdesc, sizeof(devdesc));
Mike Lockwood31175d62010-01-17 00:52:27 -0500172 bufend = bufptr + desclength;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800173
174 // should have device and configuration descriptors, and atleast two endpoints
175 if (desclength < USB_DT_DEVICE_SIZE + USB_DT_CONFIG_SIZE) {
Elliott Hughes9c0d9402014-01-16 10:53:11 -0800176 D("desclength %zu is too small\n", desclength);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800177 adb_close(fd);
178 continue;
179 }
180
181 device = (struct usb_device_descriptor*)bufptr;
182 bufptr += USB_DT_DEVICE_SIZE;
183
184 if((device->bLength != USB_DT_DEVICE_SIZE) || (device->bDescriptorType != USB_DT_DEVICE)) {
185 adb_close(fd);
186 continue;
187 }
188
Marcus Comstedt3d2f5182010-09-22 20:09:44 +0200189 vid = device->idVendor;
190 pid = device->idProduct;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800191 DBGX("[ %s is V:%04x P:%04x ]\n", devname, vid, pid);
192
193 // should have config descriptor next
194 config = (struct usb_config_descriptor *)bufptr;
195 bufptr += USB_DT_CONFIG_SIZE;
196 if (config->bLength != USB_DT_CONFIG_SIZE || config->bDescriptorType != USB_DT_CONFIG) {
197 D("usb_config_descriptor not found\n");
198 adb_close(fd);
199 continue;
200 }
201
Mike Lockwood31175d62010-01-17 00:52:27 -0500202 // loop through all the descriptors and look for the ADB interface
203 while (bufptr < bufend) {
204 unsigned char length = bufptr[0];
205 unsigned char type = bufptr[1];
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800206
Mike Lockwood31175d62010-01-17 00:52:27 -0500207 if (type == USB_DT_INTERFACE) {
208 interface = (struct usb_interface_descriptor *)bufptr;
209 bufptr += length;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800210
Mike Lockwood31175d62010-01-17 00:52:27 -0500211 if (length != USB_DT_INTERFACE_SIZE) {
212 D("interface descriptor has wrong size\n");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800213 break;
214 }
215
Mike Lockwood31175d62010-01-17 00:52:27 -0500216 DBGX("bInterfaceClass: %d, bInterfaceSubClass: %d,"
217 "bInterfaceProtocol: %d, bNumEndpoints: %d\n",
218 interface->bInterfaceClass, interface->bInterfaceSubClass,
219 interface->bInterfaceProtocol, interface->bNumEndpoints);
220
221 if (interface->bNumEndpoints == 2 &&
222 is_adb_interface(vid, pid, interface->bInterfaceClass,
223 interface->bInterfaceSubClass, interface->bInterfaceProtocol)) {
224
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700225 struct stat st;
226 char pathbuf[128];
227 char link[256];
228 char *devpath = NULL;
229
Mike Lockwood31175d62010-01-17 00:52:27 -0500230 DBGX("looking for bulk endpoints\n");
231 // looks like ADB...
232 ep1 = (struct usb_endpoint_descriptor *)bufptr;
233 bufptr += USB_DT_ENDPOINT_SIZE;
Ingo Rohloff5b276632014-05-16 21:51:41 +0200234 // For USB 3.0 SuperSpeed devices, skip potential
235 // USB 3.0 SuperSpeed Endpoint Companion descriptor
236 if (bufptr+2 <= devdesc + desclength &&
237 bufptr[0] == USB_DT_SS_EP_COMP_SIZE &&
238 bufptr[1] == USB_DT_SS_ENDPOINT_COMP) {
239 bufptr += USB_DT_SS_EP_COMP_SIZE;
240 }
Mike Lockwood31175d62010-01-17 00:52:27 -0500241 ep2 = (struct usb_endpoint_descriptor *)bufptr;
242 bufptr += USB_DT_ENDPOINT_SIZE;
Ingo Rohloff5b276632014-05-16 21:51:41 +0200243 if (bufptr+2 <= devdesc + desclength &&
244 bufptr[0] == USB_DT_SS_EP_COMP_SIZE &&
245 bufptr[1] == USB_DT_SS_ENDPOINT_COMP) {
246 bufptr += USB_DT_SS_EP_COMP_SIZE;
247 }
Mike Lockwood31175d62010-01-17 00:52:27 -0500248
249 if (bufptr > devdesc + desclength ||
250 ep1->bLength != USB_DT_ENDPOINT_SIZE ||
251 ep1->bDescriptorType != USB_DT_ENDPOINT ||
252 ep2->bLength != USB_DT_ENDPOINT_SIZE ||
253 ep2->bDescriptorType != USB_DT_ENDPOINT) {
254 D("endpoints not found\n");
255 break;
256 }
257
258 // both endpoints should be bulk
259 if (ep1->bmAttributes != USB_ENDPOINT_XFER_BULK ||
260 ep2->bmAttributes != USB_ENDPOINT_XFER_BULK) {
261 D("bulk endpoints not found\n");
262 continue;
263 }
264 /* aproto 01 needs 0 termination */
265 if(interface->bInterfaceProtocol == 0x01) {
266 zero_mask = ep1->wMaxPacketSize - 1;
267 }
268
269 // we have a match. now we just need to figure out which is in and which is out.
270 if (ep1->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
271 local_ep_in = ep1->bEndpointAddress;
272 local_ep_out = ep2->bEndpointAddress;
273 } else {
274 local_ep_in = ep2->bEndpointAddress;
275 local_ep_out = ep1->bEndpointAddress;
276 }
277
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700278 // Determine the device path
279 if (!fstat(fd, &st) && S_ISCHR(st.st_mode)) {
280 char *slash;
281 ssize_t link_len;
282 snprintf(pathbuf, sizeof(pathbuf), "/sys/dev/char/%d:%d",
283 major(st.st_rdev), minor(st.st_rdev));
284 link_len = readlink(pathbuf, link, sizeof(link) - 1);
285 if (link_len > 0) {
286 link[link_len] = '\0';
287 slash = strrchr(link, '/');
288 if (slash) {
289 snprintf(pathbuf, sizeof(pathbuf),
290 "usb:%s", slash + 1);
291 devpath = pathbuf;
292 }
293 }
294 }
295
296 register_device_callback(devname, devpath,
297 local_ep_in, local_ep_out,
Mike Lockwood31175d62010-01-17 00:52:27 -0500298 interface->bInterfaceNumber, device->iSerialNumber, zero_mask);
299 break;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800300 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800301 } else {
Mike Lockwood31175d62010-01-17 00:52:27 -0500302 bufptr += length;
303 }
304 } // end of while
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800305
306 adb_close(fd);
307 } // end of devdir while
308 closedir(devdir);
309 } //end of busdir while
310 closedir(busdir);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800311}
312
313void usb_cleanup()
314{
315}
316
317static int usb_bulk_write(usb_handle *h, const void *data, int len)
318{
319 struct usbdevfs_urb *urb = &h->urb_out;
320 int res;
Mike Lockwood09024d62010-02-19 17:45:57 -0500321 struct timeval tv;
322 struct timespec ts;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800323
324 memset(urb, 0, sizeof(*urb));
325 urb->type = USBDEVFS_URB_TYPE_BULK;
326 urb->endpoint = h->ep_out;
327 urb->status = -1;
328 urb->buffer = (void*) data;
329 urb->buffer_length = len;
330
331 D("++ write ++\n");
332
333 adb_mutex_lock(&h->lock);
334 if(h->dead) {
335 res = -1;
336 goto fail;
337 }
338 do {
339 res = ioctl(h->desc, USBDEVFS_SUBMITURB, urb);
340 } while((res < 0) && (errno == EINTR));
341
342 if(res < 0) {
343 goto fail;
344 }
345
346 res = -1;
347 h->urb_out_busy = 1;
348 for(;;) {
Mike Lockwood09024d62010-02-19 17:45:57 -0500349 /* time out after five seconds */
350 gettimeofday(&tv, NULL);
351 ts.tv_sec = tv.tv_sec + 5;
352 ts.tv_nsec = tv.tv_usec * 1000L;
353 res = pthread_cond_timedwait(&h->notify, &h->lock, &ts);
354 if(res < 0 || h->dead) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800355 break;
356 }
357 if(h->urb_out_busy == 0) {
358 if(urb->status == 0) {
359 res = urb->actual_length;
360 }
361 break;
362 }
363 }
364fail:
365 adb_mutex_unlock(&h->lock);
366 D("-- write --\n");
367 return res;
368}
369
370static int usb_bulk_read(usb_handle *h, void *data, int len)
371{
372 struct usbdevfs_urb *urb = &h->urb_in;
373 struct usbdevfs_urb *out = NULL;
374 int res;
375
Nanik Tolaramc624a7e2015-02-18 22:53:37 +1100376 D("++ usb_bulk_read ++\n");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800377 memset(urb, 0, sizeof(*urb));
378 urb->type = USBDEVFS_URB_TYPE_BULK;
379 urb->endpoint = h->ep_in;
380 urb->status = -1;
381 urb->buffer = data;
382 urb->buffer_length = len;
383
384
385 adb_mutex_lock(&h->lock);
386 if(h->dead) {
387 res = -1;
388 goto fail;
389 }
390 do {
391 res = ioctl(h->desc, USBDEVFS_SUBMITURB, urb);
392 } while((res < 0) && (errno == EINTR));
393
394 if(res < 0) {
395 goto fail;
396 }
397
398 h->urb_in_busy = 1;
399 for(;;) {
400 D("[ reap urb - wait ]\n");
401 h->reaper_thread = pthread_self();
402 adb_mutex_unlock(&h->lock);
403 res = ioctl(h->desc, USBDEVFS_REAPURB, &out);
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700404 int saved_errno = errno;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800405 adb_mutex_lock(&h->lock);
406 h->reaper_thread = 0;
407 if(h->dead) {
408 res = -1;
409 break;
410 }
411 if(res < 0) {
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700412 if(saved_errno == EINTR) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800413 continue;
414 }
415 D("[ reap urb - error ]\n");
416 break;
417 }
418 D("[ urb @%p status = %d, actual = %d ]\n",
419 out, out->status, out->actual_length);
420
421 if(out == &h->urb_in) {
422 D("[ reap urb - IN complete ]\n");
423 h->urb_in_busy = 0;
424 if(urb->status == 0) {
425 res = urb->actual_length;
426 } else {
427 res = -1;
428 }
429 break;
430 }
431 if(out == &h->urb_out) {
432 D("[ reap urb - OUT compelete ]\n");
433 h->urb_out_busy = 0;
434 adb_cond_broadcast(&h->notify);
435 }
436 }
437fail:
438 adb_mutex_unlock(&h->lock);
Nanik Tolaramc624a7e2015-02-18 22:53:37 +1100439 D("-- usb_bulk_read --\n");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800440 return res;
441}
442
443
444int usb_write(usb_handle *h, const void *_data, int len)
445{
446 unsigned char *data = (unsigned char*) _data;
447 int n;
448 int need_zero = 0;
449
Nanik Tolaramc624a7e2015-02-18 22:53:37 +1100450 D("++ usb_write ++\n");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800451 if(h->zero_mask) {
452 /* if we need 0-markers and our transfer
453 ** is an even multiple of the packet size,
454 ** we make note of it
455 */
456 if(!(len & h->zero_mask)) {
457 need_zero = 1;
458 }
459 }
460
461 while(len > 0) {
462 int xfer = (len > 4096) ? 4096 : len;
463
464 n = usb_bulk_write(h, data, xfer);
465 if(n != xfer) {
466 D("ERROR: n = %d, errno = %d (%s)\n",
467 n, errno, strerror(errno));
468 return -1;
469 }
470
471 len -= xfer;
472 data += xfer;
473 }
474
475 if(need_zero){
476 n = usb_bulk_write(h, _data, 0);
477 return n;
478 }
479
Nanik Tolaramc624a7e2015-02-18 22:53:37 +1100480 D("-- usb_write --\n");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800481 return 0;
482}
483
484int usb_read(usb_handle *h, void *_data, int len)
485{
486 unsigned char *data = (unsigned char*) _data;
487 int n;
488
489 D("++ usb_read ++\n");
490 while(len > 0) {
491 int xfer = (len > 4096) ? 4096 : len;
492
493 D("[ usb read %d fd = %d], fname=%s\n", xfer, h->desc, h->fname);
494 n = usb_bulk_read(h, data, xfer);
495 D("[ usb read %d ] = %d, fname=%s\n", xfer, n, h->fname);
496 if(n != xfer) {
497 if((errno == ETIMEDOUT) && (h->desc != -1)) {
498 D("[ timeout ]\n");
499 if(n > 0){
500 data += n;
501 len -= n;
502 }
503 continue;
504 }
505 D("ERROR: n = %d, errno = %d (%s)\n",
506 n, errno, strerror(errno));
507 return -1;
508 }
509
510 len -= xfer;
511 data += xfer;
512 }
513
514 D("-- usb_read --\n");
515 return 0;
516}
517
518void usb_kick(usb_handle *h)
519{
520 D("[ kicking %p (fd = %d) ]\n", h, h->desc);
521 adb_mutex_lock(&h->lock);
522 if(h->dead == 0) {
523 h->dead = 1;
524
Mike Lockwoode45583f2009-08-08 12:37:44 -0400525 if (h->writeable) {
526 /* HACK ALERT!
527 ** Sometimes we get stuck in ioctl(USBDEVFS_REAPURB).
528 ** This is a workaround for that problem.
529 */
530 if (h->reaper_thread) {
531 pthread_kill(h->reaper_thread, SIGALRM);
532 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800533
Mike Lockwoode45583f2009-08-08 12:37:44 -0400534 /* cancel any pending transactions
535 ** these will quietly fail if the txns are not active,
536 ** but this ensures that a reader blocked on REAPURB
537 ** will get unblocked
538 */
539 ioctl(h->desc, USBDEVFS_DISCARDURB, &h->urb_in);
540 ioctl(h->desc, USBDEVFS_DISCARDURB, &h->urb_out);
541 h->urb_in.status = -ENODEV;
542 h->urb_out.status = -ENODEV;
543 h->urb_in_busy = 0;
544 h->urb_out_busy = 0;
545 adb_cond_broadcast(&h->notify);
546 } else {
547 unregister_usb_transport(h);
548 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800549 }
550 adb_mutex_unlock(&h->lock);
551}
552
553int usb_close(usb_handle *h)
554{
Nanik Tolaramc624a7e2015-02-18 22:53:37 +1100555 D("++ usb close ++\n");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800556 adb_mutex_lock(&usb_lock);
557 h->next->prev = h->prev;
558 h->prev->next = h->next;
559 h->prev = 0;
560 h->next = 0;
561
562 adb_close(h->desc);
Nanik Tolaramc624a7e2015-02-18 22:53:37 +1100563 D("-- usb closed %p (fd = %d) --\n", h, h->desc);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800564 adb_mutex_unlock(&usb_lock);
565
566 free(h);
567 return 0;
568}
569
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700570static void register_device(const char *dev_name, const char *devpath,
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800571 unsigned char ep_in, unsigned char ep_out,
Mike Lockwoode45583f2009-08-08 12:37:44 -0400572 int interface, int serial_index, unsigned zero_mask)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800573{
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800574 int n = 0;
Mike Lockwoode45583f2009-08-08 12:37:44 -0400575 char serial[256];
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800576
577 /* Since Linux will not reassign the device ID (and dev_name)
578 ** as long as the device is open, we can add to the list here
579 ** once we open it and remove from the list when we're finally
580 ** closed and everything will work out fine.
581 **
582 ** If we have a usb_handle on the list 'o handles with a matching
583 ** name, we have no further work to do.
584 */
585 adb_mutex_lock(&usb_lock);
Elliott Hughes5d504372015-04-25 14:44:23 -0700586 for (usb_handle* usb = handle_list.next; usb != &handle_list; usb = usb->next) {
Dan Albertf30d73c2015-02-25 17:51:28 -0800587 if (!strcmp(usb->fname, dev_name)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800588 adb_mutex_unlock(&usb_lock);
589 return;
590 }
591 }
592 adb_mutex_unlock(&usb_lock);
593
Elliott Hughes5d504372015-04-25 14:44:23 -0700594 D("[ usb located new device %s (%d/%d/%d) ]\n", dev_name, ep_in, ep_out, interface);
Elliott Hughesd0269c92015-04-21 19:39:52 -0700595 usb_handle* usb = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle)));
596 if (usb == nullptr) fatal("couldn't allocate usb_handle");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800597 strcpy(usb->fname, dev_name);
598 usb->ep_in = ep_in;
599 usb->ep_out = ep_out;
600 usb->zero_mask = zero_mask;
Mike Lockwoode45583f2009-08-08 12:37:44 -0400601 usb->writeable = 1;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800602
603 adb_cond_init(&usb->notify, 0);
604 adb_mutex_init(&usb->lock, 0);
605 /* initialize mark to 1 so we don't get garbage collected after the device scan */
606 usb->mark = 1;
607 usb->reaper_thread = 0;
608
Nick Kralevich777523e2014-07-18 20:57:35 -0700609 usb->desc = unix_open(usb->fname, O_RDWR | O_CLOEXEC);
Elliott Hughes5d504372015-04-25 14:44:23 -0700610 if (usb->desc == -1) {
611 // Opening RW failed, so see if we have RO access.
Nick Kralevich777523e2014-07-18 20:57:35 -0700612 usb->desc = unix_open(usb->fname, O_RDONLY | O_CLOEXEC);
Elliott Hughes5d504372015-04-25 14:44:23 -0700613 if (usb->desc == -1) {
614 D("[ usb open %s failed: %s]\n", usb->fname, strerror(errno));
615 free(usb);
616 return;
617 }
Mike Lockwoode45583f2009-08-08 12:37:44 -0400618 usb->writeable = 0;
Elliott Hughes5d504372015-04-25 14:44:23 -0700619 }
620
621 D("[ usb opened %s%s, fd=%d]\n", usb->fname, (usb->writeable ? "" : " (read-only)"), usb->desc);
622
623 if (usb->writeable) {
Mike Lockwoode45583f2009-08-08 12:37:44 -0400624 n = ioctl(usb->desc, USBDEVFS_CLAIMINTERFACE, &interface);
Elliott Hughes5d504372015-04-25 14:44:23 -0700625 if (n != 0) {
626 D("[ usb ioctl(%d, USBDEVFS_CLAIMINTERFACE) failed: %s]\n", usb->desc, strerror(errno));
627 adb_close(usb->desc);
628 free(usb);
629 return;
630 }
Mike Lockwoode45583f2009-08-08 12:37:44 -0400631 }
632
633 /* read the device's serial number */
634 serial[0] = 0;
635 memset(serial, 0, sizeof(serial));
636 if (serial_index) {
637 struct usbdevfs_ctrltransfer ctrl;
638 __u16 buffer[128];
639 __u16 languages[128];
640 int i, result;
641 int languageCount = 0;
642
643 memset(languages, 0, sizeof(languages));
644 memset(&ctrl, 0, sizeof(ctrl));
645
646 // read list of supported languages
647 ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE;
648 ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
649 ctrl.wValue = (USB_DT_STRING << 8) | 0;
650 ctrl.wIndex = 0;
651 ctrl.wLength = sizeof(languages);
652 ctrl.data = languages;
Omari Stephenseac8a182011-05-09 18:45:06 -0700653 ctrl.timeout = 1000;
Mike Lockwoode45583f2009-08-08 12:37:44 -0400654
655 result = ioctl(usb->desc, USBDEVFS_CONTROL, &ctrl);
656 if (result > 0)
657 languageCount = (result - 2) / 2;
658
659 for (i = 1; i <= languageCount; i++) {
660 memset(buffer, 0, sizeof(buffer));
661 memset(&ctrl, 0, sizeof(ctrl));
662
663 ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE;
664 ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
665 ctrl.wValue = (USB_DT_STRING << 8) | serial_index;
Marcus Comstedt3d2f5182010-09-22 20:09:44 +0200666 ctrl.wIndex = __le16_to_cpu(languages[i]);
Mike Lockwoode45583f2009-08-08 12:37:44 -0400667 ctrl.wLength = sizeof(buffer);
668 ctrl.data = buffer;
Omari Stephenseac8a182011-05-09 18:45:06 -0700669 ctrl.timeout = 1000;
Mike Lockwoode45583f2009-08-08 12:37:44 -0400670
671 result = ioctl(usb->desc, USBDEVFS_CONTROL, &ctrl);
672 if (result > 0) {
673 int i;
674 // skip first word, and copy the rest to the serial string, changing shorts to bytes.
675 result /= 2;
676 for (i = 1; i < result; i++)
Marcus Comstedt3d2f5182010-09-22 20:09:44 +0200677 serial[i - 1] = __le16_to_cpu(buffer[i]);
Mike Lockwoode45583f2009-08-08 12:37:44 -0400678 serial[i - 1] = 0;
679 break;
680 }
681 }
682 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800683
684 /* add to the end of the active handles */
685 adb_mutex_lock(&usb_lock);
686 usb->next = &handle_list;
687 usb->prev = handle_list.prev;
688 usb->prev->next = usb;
689 usb->next->prev = usb;
690 adb_mutex_unlock(&usb_lock);
691
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700692 register_usb_transport(usb, serial, devpath, usb->writeable);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800693}
694
695void* device_poll_thread(void* unused)
696{
697 D("Created device thread\n");
698 for(;;) {
699 /* XXX use inotify */
700 find_usb_device("/dev/bus/usb", register_device);
701 kick_disconnected_devices();
702 sleep(1);
703 }
704 return NULL;
705}
706
707static void sigalrm_handler(int signo)
708{
709 // don't need to do anything here
710}
711
712void usb_init()
713{
714 adb_thread_t tid;
715 struct sigaction actions;
716
717 memset(&actions, 0, sizeof(actions));
718 sigemptyset(&actions.sa_mask);
719 actions.sa_flags = 0;
720 actions.sa_handler = sigalrm_handler;
721 sigaction(SIGALRM,& actions, NULL);
722
723 if(adb_thread_create(&tid, device_poll_thread, NULL)){
724 fatal_errno("cannot create input thread");
725 }
726}