usb_linux_client.c revision 35237d135807af84bf9b0e5b8d7f8633e58db6f5
14a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall/* 24a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * Copyright (C) 2007 The Android Open Source Project 34a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * 44a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * Licensed under the Apache License, Version 2.0 (the "License"); 54a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * you may not use this file except in compliance with the License. 64a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * You may obtain a copy of the License at 74a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * 84a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * http://www.apache.org/licenses/LICENSE-2.0 94a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * 104a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * Unless required by applicable law or agreed to in writing, software 114a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * distributed under the License is distributed on an "AS IS" BASIS, 124a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * See the License for the specific language governing permissions and 144a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * limitations under the License. 154a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall */ 164a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall 174a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#include <stdio.h> 184a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#include <stdlib.h> 194a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#include <unistd.h> 204a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#include <string.h> 21fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall 22db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall#include <sys/ioctl.h> 234a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#include <sys/types.h> 244a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#include <dirent.h> 25db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall#include <errno.h> 26db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall 27db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall#include "sysdeps.h" 28db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall 29db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall#define TRACE_TAG TRACE_USB 30db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall#include "adb.h" 31db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall 32db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall 33db7da58e8d2aa021060098057f944ef754be06e3JP Abgrallstruct usb_handle 34db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall{ 35db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall int fd; 36db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall adb_cond_t notify; 37db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall adb_mutex_t lock; 38db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall}; 39db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall 40db7da58e8d2aa021060098057f944ef754be06e3JP Abgrallvoid usb_cleanup() 41db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall{ 42db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall // nothing to do here 43db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall} 44db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall 45db7da58e8d2aa021060098057f944ef754be06e3JP Abgrallstatic void *usb_open_thread(void *x) 46db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall{ 47db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall struct usb_handle *usb = (struct usb_handle *)x; 48fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall int fd; 490031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall 500031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall while (1) { 510031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall // wait until the USB device needs opening 520031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall adb_mutex_lock(&usb->lock); 53fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall while (usb->fd != -1) 54fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall adb_cond_wait(&usb->notify, &usb->lock); 550dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall adb_mutex_unlock(&usb->lock); 568a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall 57fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall D("[ usb_thread - opening device ]\n"); 58fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall do { 590dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall /* XXX use inotify? */ 608a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall fd = unix_open("/dev/android_adb", O_RDWR); 610dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall if (fd < 0) { 620dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall // to support older kernels 63fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall fd = unix_open("/dev/android", O_RDWR); 64fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall } 654a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall if (fd < 0) { 668a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall adb_sleep_ms(1000); 678a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall } 68c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall } while (fd < 0); 69c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall D("[ opening device succeeded ]\n"); 708a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall 718a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall close_on_exec(fd); 728a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall usb->fd = fd; 738a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall 748a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall D("[ usb_thread - registering device ]\n"); 758a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall register_usb_transport(usb, 0); 760dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall } 77db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall 78db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall // never gets here 79db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall return 0; 80db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall} 81a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall 82db7da58e8d2aa021060098057f944ef754be06e3JP Abgrallint usb_write(usb_handle *h, const void *data, int len) 838e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey{ 848e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey int n; 858e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey 868e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey D("[ write %d ]\n", len); 878e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey n = adb_write(h->fd, data, len); 888e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey if(n != len) { 894a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall D("ERROR: n = %d, errno = %d (%s)\n", 908a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall n, errno, strerror(errno)); 918a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall return -1; 928a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall } 938a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall D("[ done ]\n"); 948a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall return 0; 958a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall} 968a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall 978a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrallint usb_read(usb_handle *h, void *data, int len) 98db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall{ 9926e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall int n; 10026e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall 10126e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall D("[ read %d ]\n", len); 10226e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall n = adb_read(h->fd, data, len); 10326e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall if(n != len) { 10426e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall D("ERROR: n = %d, errno = %d (%s)\n", 1051fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall n, errno, strerror(errno)); 1061fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall return -1; 1071fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall } 1081fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall return 0; 1091fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall} 11026e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall 1114a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrallvoid usb_init() 11226e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall{ 11326e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall usb_handle *h; 1140dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall adb_thread_t tid; 1150dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall int fd; 11626e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall 1170dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall h = calloc(1, sizeof(usb_handle)); 1188a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall h->fd = -1; 119c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall adb_cond_init(&h->notify, 0); 1208a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall adb_mutex_init(&h->lock, 0); 1210dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall 12226e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall // Open the file /dev/android_adb_enable to trigger 1230dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall // the enabling of the adb USB function in the kernel. 1241fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall // We never touch this file again - just leave it open 1251fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall // indefinitely so the kernel will know when we are running 1261fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall // and when we are not. 1271fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall fd = unix_open("/dev/android_adb_enable", O_RDWR); 1281fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall if (fd < 0) { 12926e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall D("failed to open /dev/android_adb_enable\n"); 13026e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall } else { 13126e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall close_on_exec(fd); 1320dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall } 1338a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall 1348a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall D("[ usb_init - starting thread ]\n"); 1358a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall if(adb_thread_create(&tid, usb_open_thread, h)){ 1368a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall fatal_errno("cannot create usb thread"); 1378a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall } 13811b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall} 139db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall 140db7da58e8d2aa021060098057f944ef754be06e3JP Abgrallvoid usb_kick(usb_handle *h) 141a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall{ 14211b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall D("usb_kick\n"); 143a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall adb_mutex_lock(&h->lock); 1440031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall adb_close(h->fd); 145db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall h->fd = -1; 146db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall 147db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall // notify usb_open_thread that we are disconnected 148db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall adb_cond_signal(&h->notify); 149db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall adb_mutex_unlock(&h->lock); 150db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall} 151db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall 152c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrallint usb_close(usb_handle *h) 153c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall{ 154c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall // nothing to do here 155c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall return 0; 156c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall} 157c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall