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 <stdio.h> 18#include <stdlib.h> 19#include <unistd.h> 20#include <string.h> 21 22#include <sys/ioctl.h> 23#include <sys/types.h> 24#include <dirent.h> 25#include <errno.h> 26 27#include "sysdeps.h" 28 29#define TRACE_TAG TRACE_USB 30#include "adb.h" 31 32 33struct usb_handle 34{ 35 int fd; 36 adb_cond_t notify; 37 adb_mutex_t lock; 38}; 39 40void usb_cleanup() 41{ 42 // nothing to do here 43} 44 45static void *usb_open_thread(void *x) 46{ 47 struct usb_handle *usb = (struct usb_handle *)x; 48 int fd; 49 50 while (1) { 51 // wait until the USB device needs opening 52 adb_mutex_lock(&usb->lock); 53 while (usb->fd != -1) 54 adb_cond_wait(&usb->notify, &usb->lock); 55 adb_mutex_unlock(&usb->lock); 56 57 D("[ usb_thread - opening device ]\n"); 58 do { 59 /* XXX use inotify? */ 60 fd = unix_open("/dev/android_adb", O_RDWR); 61 if (fd < 0) { 62 // to support older kernels 63 fd = unix_open("/dev/android", O_RDWR); 64 } 65 if (fd < 0) { 66 adb_sleep_ms(1000); 67 } 68 } while (fd < 0); 69 D("[ opening device succeeded ]\n"); 70 71 close_on_exec(fd); 72 usb->fd = fd; 73 74 D("[ usb_thread - registering device ]\n"); 75 register_usb_transport(usb, 0, 1); 76 } 77 78 // never gets here 79 return 0; 80} 81 82int usb_write(usb_handle *h, const void *data, int len) 83{ 84 int n; 85 86 D("[ write %d ]\n", len); 87 n = adb_write(h->fd, data, len); 88 if(n != len) { 89 D("ERROR: n = %d, errno = %d (%s)\n", 90 n, errno, strerror(errno)); 91 return -1; 92 } 93 D("[ done ]\n"); 94 return 0; 95} 96 97int usb_read(usb_handle *h, void *data, int len) 98{ 99 int n; 100 101 D("[ read %d ]\n", len); 102 n = adb_read(h->fd, data, len); 103 if(n != len) { 104 D("ERROR: n = %d, errno = %d (%s)\n", 105 n, errno, strerror(errno)); 106 return -1; 107 } 108 return 0; 109} 110 111void usb_init() 112{ 113 usb_handle *h; 114 adb_thread_t tid; 115 int fd; 116 117 h = calloc(1, sizeof(usb_handle)); 118 h->fd = -1; 119 adb_cond_init(&h->notify, 0); 120 adb_mutex_init(&h->lock, 0); 121 122 // Open the file /dev/android_adb_enable to trigger 123 // the enabling of the adb USB function in the kernel. 124 // We never touch this file again - just leave it open 125 // indefinitely so the kernel will know when we are running 126 // and when we are not. 127 fd = unix_open("/dev/android_adb_enable", O_RDWR); 128 if (fd < 0) { 129 D("failed to open /dev/android_adb_enable\n"); 130 } else { 131 close_on_exec(fd); 132 } 133 134 D("[ usb_init - starting thread ]\n"); 135 if(adb_thread_create(&tid, usb_open_thread, h)){ 136 fatal_errno("cannot create usb thread"); 137 } 138} 139 140void usb_kick(usb_handle *h) 141{ 142 D("usb_kick\n"); 143 adb_mutex_lock(&h->lock); 144 adb_close(h->fd); 145 h->fd = -1; 146 147 // notify usb_open_thread that we are disconnected 148 adb_cond_signal(&h->notify); 149 adb_mutex_unlock(&h->lock); 150} 151 152int usb_close(usb_handle *h) 153{ 154 // nothing to do here 155 return 0; 156} 157