resolved conflicts for merge of 13081c69
to master
Change-Id: I631e466fc53e9b0f4a39f24f959b4ae9b626bdda
This commit is contained in:
commit
a61bcad58b
7 changed files with 89 additions and 11 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, ...);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue