usb_linux.c revision 5957c1ffe79b34d8b1859f9f11644d1007193cbc
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <stdio.h> 30#include <stdlib.h> 31#include <unistd.h> 32#include <string.h> 33 34#include <sys/ioctl.h> 35#include <sys/stat.h> 36#include <sys/types.h> 37#include <dirent.h> 38#include <fcntl.h> 39#include <errno.h> 40#include <pthread.h> 41#include <ctype.h> 42 43#include <linux/usbdevice_fs.h> 44#include <linux/usbdevice_fs.h> 45#include <linux/version.h> 46#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) 47#include <linux/usb/ch9.h> 48#else 49#include <linux/usb_ch9.h> 50#endif 51#include <asm/byteorder.h> 52 53#include "fastboot.h" 54#include "usb.h" 55 56#define MAX_RETRIES 5 57 58/* Timeout in seconds for usb_wait_for_disconnect. 59 * It doesn't usually take long for a device to disconnect (almost always 60 * under 2 seconds) but we'll time out after 3 seconds just in case. 61 */ 62#define WAIT_FOR_DISCONNECT_TIMEOUT 3 63 64#ifdef TRACE_USB 65#define DBG1(x...) fprintf(stderr, x) 66#define DBG(x...) fprintf(stderr, x) 67#else 68#define DBG(x...) 69#define DBG1(x...) 70#endif 71 72/* The max bulk size for linux is 16384 which is defined 73 * in drivers/usb/core/devio.c. 74 */ 75#define MAX_USBFS_BULK_SIZE (16 * 1024) 76 77struct usb_handle 78{ 79 char fname[64]; 80 int desc; 81 unsigned char ep_in; 82 unsigned char ep_out; 83}; 84 85/* True if name isn't a valid name for a USB device in /sys/bus/usb/devices. 86 * Device names are made up of numbers, dots, and dashes, e.g., '7-1.5'. 87 * We reject interfaces (e.g., '7-1.5:1.0') and host controllers (e.g. 'usb1'). 88 * The name must also start with a digit, to disallow '.' and '..' 89 */ 90static inline int badname(const char *name) 91{ 92 if (!isdigit(*name)) 93 return 1; 94 while(*++name) { 95 if(!isdigit(*name) && *name != '.' && *name != '-') 96 return 1; 97 } 98 return 0; 99} 100 101static int check(void *_desc, int len, unsigned type, int size) 102{ 103 unsigned char *desc = _desc; 104 105 if(len < size) return -1; 106 if(desc[0] < size) return -1; 107 if(desc[0] > len) return -1; 108 if(desc[1] != type) return -1; 109 110 return 0; 111} 112 113static int filter_usb_device(char* sysfs_name, 114 char *ptr, int len, int writable, 115 ifc_match_func callback, 116 int *ept_in_id, int *ept_out_id, int *ifc_id) 117{ 118 struct usb_device_descriptor *dev; 119 struct usb_config_descriptor *cfg; 120 struct usb_interface_descriptor *ifc; 121 struct usb_endpoint_descriptor *ept; 122 struct usb_ifc_info info; 123 124 int in, out; 125 unsigned i; 126 unsigned e; 127 128 if(check(ptr, len, USB_DT_DEVICE, USB_DT_DEVICE_SIZE)) 129 return -1; 130 dev = (void*) ptr; 131 len -= dev->bLength; 132 ptr += dev->bLength; 133 134 if(check(ptr, len, USB_DT_CONFIG, USB_DT_CONFIG_SIZE)) 135 return -1; 136 cfg = (void*) ptr; 137 len -= cfg->bLength; 138 ptr += cfg->bLength; 139 140 info.dev_vendor = dev->idVendor; 141 info.dev_product = dev->idProduct; 142 info.dev_class = dev->bDeviceClass; 143 info.dev_subclass = dev->bDeviceSubClass; 144 info.dev_protocol = dev->bDeviceProtocol; 145 info.writable = writable; 146 147 snprintf(info.device_path, sizeof(info.device_path), "usb:%s", sysfs_name); 148 149 /* Read device serial number (if there is one). 150 * We read the serial number from sysfs, since it's faster and more 151 * reliable than issuing a control pipe read, and also won't 152 * cause problems for devices which don't like getting descriptor 153 * requests while they're in the middle of flashing. 154 */ 155 info.serial_number[0] = '\0'; 156 if (dev->iSerialNumber) { 157 char path[80]; 158 int fd; 159 160 snprintf(path, sizeof(path), 161 "/sys/bus/usb/devices/%s/serial", sysfs_name); 162 path[sizeof(path) - 1] = '\0'; 163 164 fd = open(path, O_RDONLY); 165 if (fd >= 0) { 166 int chars_read = read(fd, info.serial_number, 167 sizeof(info.serial_number) - 1); 168 close(fd); 169 170 if (chars_read <= 0) 171 info.serial_number[0] = '\0'; 172 else if (info.serial_number[chars_read - 1] == '\n') { 173 // strip trailing newline 174 info.serial_number[chars_read - 1] = '\0'; 175 } 176 } 177 } 178 179 for(i = 0; i < cfg->bNumInterfaces; i++) { 180 if(check(ptr, len, USB_DT_INTERFACE, USB_DT_INTERFACE_SIZE)) 181 return -1; 182 ifc = (void*) ptr; 183 len -= ifc->bLength; 184 ptr += ifc->bLength; 185 186 in = -1; 187 out = -1; 188 info.ifc_class = ifc->bInterfaceClass; 189 info.ifc_subclass = ifc->bInterfaceSubClass; 190 info.ifc_protocol = ifc->bInterfaceProtocol; 191 192 for(e = 0; e < ifc->bNumEndpoints; e++) { 193 if(check(ptr, len, USB_DT_ENDPOINT, USB_DT_ENDPOINT_SIZE)) 194 return -1; 195 ept = (void*) ptr; 196 len -= ept->bLength; 197 ptr += ept->bLength; 198 199 if((ept->bmAttributes & 0x03) != 0x02) 200 continue; 201 202 if(ept->bEndpointAddress & 0x80) { 203 in = ept->bEndpointAddress; 204 } else { 205 out = ept->bEndpointAddress; 206 } 207 } 208 209 info.has_bulk_in = (in != -1); 210 info.has_bulk_out = (out != -1); 211 212 if(callback(&info) == 0) { 213 *ept_in_id = in; 214 *ept_out_id = out; 215 *ifc_id = ifc->bInterfaceNumber; 216 return 0; 217 } 218 } 219 220 return -1; 221} 222 223static int read_sysfs_string(const char *sysfs_name, const char *sysfs_node, 224 char* buf, int bufsize) 225{ 226 char path[80]; 227 int fd, n; 228 229 snprintf(path, sizeof(path), 230 "/sys/bus/usb/devices/%s/%s", sysfs_name, sysfs_node); 231 path[sizeof(path) - 1] = '\0'; 232 233 fd = open(path, O_RDONLY); 234 if (fd < 0) 235 return -1; 236 237 n = read(fd, buf, bufsize - 1); 238 close(fd); 239 240 if (n < 0) 241 return -1; 242 243 buf[n] = '\0'; 244 245 return n; 246} 247 248static int read_sysfs_number(const char *sysfs_name, const char *sysfs_node) 249{ 250 char buf[16]; 251 int value; 252 253 if (read_sysfs_string(sysfs_name, sysfs_node, buf, sizeof(buf)) < 0) 254 return -1; 255 256 if (sscanf(buf, "%d", &value) != 1) 257 return -1; 258 259 return value; 260} 261 262/* Given the name of a USB device in sysfs, get the name for the same 263 * device in devfs. Returns 0 for success, -1 for failure. 264 */ 265static int convert_to_devfs_name(const char* sysfs_name, 266 char* devname, int devname_size) 267{ 268 int busnum, devnum; 269 270 busnum = read_sysfs_number(sysfs_name, "busnum"); 271 if (busnum < 0) 272 return -1; 273 274 devnum = read_sysfs_number(sysfs_name, "devnum"); 275 if (devnum < 0) 276 return -1; 277 278 snprintf(devname, devname_size, "/dev/bus/usb/%03d/%03d", busnum, devnum); 279 return 0; 280} 281 282static usb_handle *find_usb_device(const char *base, ifc_match_func callback) 283{ 284 usb_handle *usb = 0; 285 char devname[64]; 286 char desc[1024]; 287 int n, in, out, ifc; 288 289 DIR *busdir; 290 struct dirent *de; 291 int fd; 292 int writable; 293 294 busdir = opendir(base); 295 if(busdir == 0) return 0; 296 297 while((de = readdir(busdir)) && (usb == 0)) { 298 if(badname(de->d_name)) continue; 299 300 if(!convert_to_devfs_name(de->d_name, devname, sizeof(devname))) { 301 302// DBG("[ scanning %s ]\n", devname); 303 writable = 1; 304 if((fd = open(devname, O_RDWR)) < 0) { 305 // Check if we have read-only access, so we can give a helpful 306 // diagnostic like "adb devices" does. 307 writable = 0; 308 if((fd = open(devname, O_RDONLY)) < 0) { 309 continue; 310 } 311 } 312 313 n = read(fd, desc, sizeof(desc)); 314 315 if(filter_usb_device(de->d_name, desc, n, writable, callback, 316 &in, &out, &ifc) == 0) { 317 usb = calloc(1, sizeof(usb_handle)); 318 strcpy(usb->fname, devname); 319 usb->ep_in = in; 320 usb->ep_out = out; 321 usb->desc = fd; 322 323 n = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &ifc); 324 if(n != 0) { 325 close(fd); 326 free(usb); 327 usb = 0; 328 continue; 329 } 330 } else { 331 close(fd); 332 } 333 } 334 } 335 closedir(busdir); 336 337 return usb; 338} 339 340int usb_write(usb_handle *h, const void *_data, int len) 341{ 342 unsigned char *data = (unsigned char*) _data; 343 unsigned count = 0; 344 struct usbdevfs_bulktransfer bulk; 345 int n; 346 347 if(h->ep_out == 0 || h->desc == -1) { 348 return -1; 349 } 350 351 do { 352 int xfer; 353 xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len; 354 355 bulk.ep = h->ep_out; 356 bulk.len = xfer; 357 bulk.data = data; 358 bulk.timeout = 0; 359 360 n = ioctl(h->desc, USBDEVFS_BULK, &bulk); 361 if(n != xfer) { 362 DBG("ERROR: n = %d, errno = %d (%s)\n", 363 n, errno, strerror(errno)); 364 return -1; 365 } 366 367 count += xfer; 368 len -= xfer; 369 data += xfer; 370 } while(len > 0); 371 372 return count; 373} 374 375int usb_read(usb_handle *h, void *_data, int len) 376{ 377 unsigned char *data = (unsigned char*) _data; 378 unsigned count = 0; 379 struct usbdevfs_bulktransfer bulk; 380 int n, retry; 381 382 if(h->ep_in == 0 || h->desc == -1) { 383 return -1; 384 } 385 386 while(len > 0) { 387 int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len; 388 389 bulk.ep = h->ep_in; 390 bulk.len = xfer; 391 bulk.data = data; 392 bulk.timeout = 0; 393 retry = 0; 394 395 do{ 396 DBG("[ usb read %d fd = %d], fname=%s\n", xfer, h->desc, h->fname); 397 n = ioctl(h->desc, USBDEVFS_BULK, &bulk); 398 DBG("[ usb read %d ] = %d, fname=%s, Retry %d \n", xfer, n, h->fname, retry); 399 400 if( n < 0 ) { 401 DBG1("ERROR: n = %d, errno = %d (%s)\n",n, errno, strerror(errno)); 402 if ( ++retry > MAX_RETRIES ) return -1; 403 sleep( 1 ); 404 } 405 } 406 while( n < 0 ); 407 408 count += n; 409 len -= n; 410 data += n; 411 412 if(n < xfer) { 413 break; 414 } 415 } 416 417 return count; 418} 419 420void usb_kick(usb_handle *h) 421{ 422 int fd; 423 424 fd = h->desc; 425 h->desc = -1; 426 if(fd >= 0) { 427 close(fd); 428 DBG("[ usb closed %d ]\n", fd); 429 } 430} 431 432int usb_close(usb_handle *h) 433{ 434 int fd; 435 436 fd = h->desc; 437 h->desc = -1; 438 if(fd >= 0) { 439 close(fd); 440 DBG("[ usb closed %d ]\n", fd); 441 } 442 443 return 0; 444} 445 446usb_handle *usb_open(ifc_match_func callback) 447{ 448 return find_usb_device("/sys/bus/usb/devices", callback); 449} 450 451/* Wait for the system to notice the device is gone, so that a subsequent 452 * fastboot command won't try to access the device before it's rebooted. 453 * Returns 0 for success, -1 for timeout. 454 */ 455int usb_wait_for_disconnect(usb_handle *usb) 456{ 457 double deadline = now() + WAIT_FOR_DISCONNECT_TIMEOUT; 458 while (now() < deadline) { 459 if (access(usb->fname, F_OK)) 460 return 0; 461 usleep(50000); 462 } 463 return -1; 464} 465