diff options
| author | Scott Anderson <saa@android.com> | 2012-05-01 18:34:22 -0700 |
|---|---|---|
| committer | Scott Anderson <saa@android.com> | 2012-05-01 18:34:22 -0700 |
| commit | a61bcad58ba1f7359183a333ee58303ed67e4a2f (patch) | |
| tree | c30d316882119d9acbc9fa9adaf3c0fce11d219b /fastboot | |
| parent | 048f24600f389bb756cf9c6ea93774f31fd588ad (diff) | |
| parent | 13081c6915220db03886b177f1a8e0b2c63467c9 (diff) | |
| download | system_core-a61bcad58ba1f7359183a333ee58303ed67e4a2f.zip system_core-a61bcad58ba1f7359183a333ee58303ed67e4a2f.tar.gz system_core-a61bcad58ba1f7359183a333ee58303ed67e4a2f.tar.bz2 | |
resolved conflicts for merge of 13081c69 to master
Change-Id: I631e466fc53e9b0f4a39f24f959b4ae9b626bdda
Diffstat (limited to 'fastboot')
| -rw-r--r-- | fastboot/engine.c | 7 | ||||
| -rw-r--r-- | fastboot/fastboot.c | 40 | ||||
| -rw-r--r-- | fastboot/fastboot.h | 1 | ||||
| -rw-r--r-- | fastboot/usb.h | 1 | ||||
| -rw-r--r-- | fastboot/usb_linux.c | 41 | ||||
| -rw-r--r-- | fastboot/usb_osx.c | 8 | ||||
| -rw-r--r-- | fastboot/usb_windows.c | 2 |
7 files changed, 89 insertions, 11 deletions
diff --git a/fastboot/engine.c b/fastboot/engine.c index 994eeae..a1b6539 100644 --- a/fastboot/engine.c +++ b/fastboot/engine.c @@ -520,6 +520,8 @@ int fb_execute_queue(usb_handle *usb) int status = 0; a = action_list; + if (!a) + return status; resp[FB_RESPONSE_SZ] = 0; double start = -1; @@ -556,3 +558,8 @@ int fb_execute_queue(usb_handle *usb) fprintf(stderr,"finished. total time: %.3fs\n", (now() - start)); return status; } + +int fb_queue_is_empty(void) +{ + return (action_list == NULL); +} diff --git a/fastboot/fastboot.c b/fastboot/fastboot.c index af61f88..b96d93b 100644 --- a/fastboot/fastboot.c +++ b/fastboot/fastboot.c @@ -58,6 +58,7 @@ static const char *product = 0; static const char *cmdline = 0; static int wipe_data = 0; static unsigned short vendor_id = 0; +static int long_listing = 0; static unsigned base_addr = 0x10000000; @@ -167,9 +168,10 @@ int match_fastboot(usb_ifc_info *info) if(info->ifc_class != 0xff) return -1; if(info->ifc_subclass != 0x42) return -1; if(info->ifc_protocol != 0x03) return -1; - // require matching serial number if a serial number is specified + // require matching serial number or device path if requested // at the command line with the -s option. - if (serial && strcmp(serial, info->serial_number) != 0) return -1; + if (serial && (strcmp(serial, info->serial_number) != 0 && + strcmp(serial, info->device_path) != 0)) return -1; return 0; } @@ -183,8 +185,16 @@ int list_devices_callback(usb_ifc_info *info) if (!serial[0]) { serial = "????????????"; } - // output compatible with "adb devices" - printf("%s\tfastboot\n", serial); + if (!long_listing) { + // output compatible with "adb devices" + printf("%s\tfastboot\n", serial); + } else { + char* device_path = info->device_path; + if (!device_path[0]) { + device_path = "????????????"; + } + printf("%s\t%s\tfastboot\n", serial, device_path); + } } return -1; @@ -238,7 +248,9 @@ void usage(void) "\n" "options:\n" " -w erase userdata and cache\n" - " -s <serial number> specify device serial number\n" + " -s <specific device> specify device serial number\n" + " or path to device port\n" + " -l with \"devices\", lists device paths\n" " -p <product> specify product name\n" " -c <cmdline> override kernel commandline\n" " -i <vendor id> specify a custom USB vendor id\n" @@ -571,6 +583,7 @@ int main(int argc, char **argv) int wants_wipe = 0; int wants_reboot = 0; int wants_reboot_bootloader = 0; + int wants_device_list = 0; void *data; unsigned sz; unsigned page_size = 2048; @@ -582,11 +595,6 @@ int main(int argc, char **argv) return 1; } - if (!strcmp(*argv, "devices")) { - list_devices(); - return 0; - } - if (!strcmp(*argv, "help")) { usage(); return 0; @@ -612,6 +620,9 @@ int main(int argc, char **argv) require(2); serial = argv[1]; skip(2); + } else if(!strcmp(*argv, "-l")) { + long_listing = 1; + skip(1); } else if(!strcmp(*argv, "-p")) { require(2); product = argv[1]; @@ -630,6 +641,9 @@ int main(int argc, char **argv) die("invalid vendor id '%s'", argv[1]); vendor_id = (unsigned short)val; skip(2); + } else if (!strcmp(*argv, "devices")) { + skip(1); + wants_device_list = 1; } else if(!strcmp(*argv, "getvar")) { require(2); fb_queue_display(argv[1], argv[1]); @@ -725,6 +739,9 @@ int main(int argc, char **argv) } } + if (wants_device_list) + list_devices(); + if (wants_wipe) { fb_queue_erase("userdata"); fb_queue_erase("cache"); @@ -735,6 +752,9 @@ int main(int argc, char **argv) fb_queue_command("reboot-bootloader", "rebooting into bootloader"); } + if (fb_queue_is_empty()) + return 0; + usb = open_device(); status = fb_execute_queue(usb); diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h index 7d56ecb..c249a8f 100644 --- a/fastboot/fastboot.h +++ b/fastboot/fastboot.h @@ -53,6 +53,7 @@ void fb_queue_command(const char *cmd, const char *msg); void fb_queue_download(const char *name, void *data, unsigned size); void fb_queue_notice(const char *notice); int fb_execute_queue(usb_handle *usb); +int fb_queue_is_empty(void); /* util stuff */ void die(const char *fmt, ...); diff --git a/fastboot/usb.h b/fastboot/usb.h index df9efde..d504ee2 100644 --- a/fastboot/usb.h +++ b/fastboot/usb.h @@ -53,6 +53,7 @@ struct usb_ifc_info unsigned char writable; char serial_number[256]; + char device_path[256]; }; typedef int (*ifc_match_func)(usb_ifc_info *ifc); diff --git a/fastboot/usb_linux.c b/fastboot/usb_linux.c index 83c6de9..b7a9ca3 100644 --- a/fastboot/usb_linux.c +++ b/fastboot/usb_linux.c @@ -32,6 +32,7 @@ #include <string.h> #include <sys/ioctl.h> +#include <sys/stat.h> #include <sys/types.h> #include <dirent.h> #include <fcntl.h> @@ -107,6 +108,9 @@ static int filter_usb_device(int fd, char *ptr, int len, int writable, int in, out; unsigned i; unsigned e; + + struct stat st; + int result; if(check(ptr, len, USB_DT_DEVICE, USB_DT_DEVICE_SIZE)) return -1; @@ -134,7 +138,6 @@ static int filter_usb_device(int fd, char *ptr, int len, int writable, // Keep it short enough because some bootloaders are borked if the URB len is > 255 // 128 is too big by 1. __u16 buffer[127]; - int result; memset(buffer, 0, sizeof(buffer)); @@ -158,6 +161,42 @@ static int filter_usb_device(int fd, char *ptr, int len, int writable, } } + /* We need to get a path that represents a particular port on a particular + * hub. We are passed an fd that was obtained by opening an entry under + * /dev/bus/usb. Unfortunately, the names of those entries change each + * time devices are plugged and unplugged. So how to get a repeatable + * path? udevadm provided the inspiration. We can get the major and + * minor of the device file, read the symlink that can be found here: + * /sys/dev/char/<major>:<minor> + * and then use the last element of that path. As a concrete example, I + * have an Android device at /dev/bus/usb/001/027 so working with bash: + * $ ls -l /dev/bus/usb/001/027 + * crw-rw-r-- 1 root plugdev 189, 26 Apr 9 11:03 /dev/bus/usb/001/027 + * $ ls -l /sys/dev/char/189:26 + * lrwxrwxrwx 1 root root 0 Apr 9 11:03 /sys/dev/char/189:26 -> + * ../../devices/pci0000:00/0000:00:1a.7/usb1/1-4/1-4.2/1-4.2.3 + * So our device_path would be 1-4.2.3 which says my device is connected + * to port 3 of a hub on port 2 of a hub on port 4 of bus 1 (per + * http://www.linux-usb.org/FAQ.html). + */ + info.device_path[0] = '\0'; + result = fstat(fd, &st); + if (!result && S_ISCHR(st.st_mode)) { + char cdev[128]; + char link[256]; + char *slash; + ssize_t link_len; + snprintf(cdev, sizeof(cdev), "/sys/dev/char/%d:%d", + major(st.st_rdev), minor(st.st_rdev)); + link_len = readlink(cdev, link, sizeof(link) - 1); + if (link_len > 0) { + link[link_len] = '\0'; + slash = strrchr(link, '/'); + if (slash) + snprintf(info.device_path, sizeof(info.device_path), "usb:%s", slash+1); + } + } + for(i = 0; i < cfg->bNumInterfaces; i++) { if(check(ptr, len, USB_DT_INTERFACE, USB_DT_INTERFACE_SIZE)) return -1; diff --git a/fastboot/usb_osx.c b/fastboot/usb_osx.c index cbce9bd..1548ba8 100644 --- a/fastboot/usb_osx.c +++ b/fastboot/usb_osx.c @@ -264,6 +264,7 @@ static int try_device(io_service_t device, usb_handle *handle) { SInt32 score; HRESULT result; UInt8 serialIndex; + UInt32 locationId; // Create an intermediate plugin. kr = IOCreatePlugInInterfaceForService(device, @@ -322,6 +323,13 @@ static int try_device(io_service_t device, usb_handle *handle) { goto error; } + kr = (*dev)->GetLocationID(dev, &locationId); + if (kr != 0) { + ERR("GetLocationId"); + goto error; + } + snprintf(handle->info.device_path, sizeof(handle->info.device_path), "usb:%lX", locationId); + kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex); if (serialIndex > 0) { diff --git a/fastboot/usb_windows.c b/fastboot/usb_windows.c index 99027cc..7aa36b2 100644 --- a/fastboot/usb_windows.c +++ b/fastboot/usb_windows.c @@ -311,6 +311,8 @@ int recognized_device(usb_handle* handle, ifc_match_func callback) { info.serial_number[0] = 0; } + info.device_path[0] = 0; + if (callback(&info) == 0) { return 1; } |
