usb_linux_client.c revision e109d266c12c5f537d429ca4b892f2719e02c2da
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/ioctl.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h> 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <dirent.h> 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "sysdeps.h" 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TRACE_TAG TRACE_USB 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb.h" 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct usb_handle 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_cond_t notify; 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_t lock; 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_cleanup() 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // nothing to do here 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *usb_open_thread(void *x) 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct usb_handle *usb = (struct usb_handle *)x; 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (1) { 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // wait until the USB device needs opening 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&usb->lock); 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (usb->fd != -1) 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_cond_wait(&usb->notify, &usb->lock); 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&usb->lock); 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("[ usb_thread - opening device ]\n"); 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* XXX use inotify? */ 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = unix_open("/dev/android_adb", O_RDWR); 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd < 0) { 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // to support older kernels 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = unix_open("/dev/android", O_RDWR); 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd < 0) { 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_sleep_ms(1000); 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (fd < 0); 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("[ opening device succeeded ]\n"); 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close_on_exec(fd); 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb->fd = fd; 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("[ usb_thread - registering device ]\n"); 75e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson register_usb_transport(usb, 0, 0, 1); 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // never gets here 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_write(usb_handle *h, const void *data, int len) 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int n; 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 86408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("about to write (fd=%d, len=%d)\n", h->fd, len); 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project n = adb_write(h->fd, data, len); 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(n != len) { 89408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("ERROR: fd = %d, n = %d, errno = %d (%s)\n", 90408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall h->fd, n, errno, strerror(errno)); 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 93408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("[ done fd=%d ]\n", h->fd); 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_read(usb_handle *h, void *data, int len) 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int n; 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 101408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("about to read (fd=%d, len=%d)\n", h->fd, len); 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project n = adb_read(h->fd, data, len); 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(n != len) { 104408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("ERROR: fd = %d, n = %d, errno = %d (%s)\n", 105408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall h->fd, n, errno, strerror(errno)); 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 108408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("[ done fd=%d ]\n", h->fd); 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_init() 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_handle *h; 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_thread_t tid; 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project h = calloc(1, sizeof(usb_handle)); 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project h->fd = -1; 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_cond_init(&h->notify, 0); 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_init(&h->lock, 0); 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Open the file /dev/android_adb_enable to trigger 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // the enabling of the adb USB function in the kernel. 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // We never touch this file again - just leave it open 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // indefinitely so the kernel will know when we are running 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // and when we are not. 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = unix_open("/dev/android_adb_enable", O_RDWR); 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd < 0) { 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("failed to open /dev/android_adb_enable\n"); 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close_on_exec(fd); 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("[ usb_init - starting thread ]\n"); 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(adb_thread_create(&tid, usb_open_thread, h)){ 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot create usb thread"); 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_kick(usb_handle *h) 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("usb_kick\n"); 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&h->lock); 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(h->fd); 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project h->fd = -1; 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // notify usb_open_thread that we are disconnected 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_cond_signal(&h->notify); 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&h->lock); 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_close(usb_handle *h) 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // nothing to do here 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 158