See https://github.com/linux-sunxi/sunxi-tools/issues/37
The patch introduces a "--dev" (-d) option to specify the desired FEL device. This is useful if multiple target devices are connected to the same host. --- fel.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 13 deletions(-) diff --git a/fel.c b/fel.c index 59f0f72..0c69d80 100644 --- a/fel.c +++ b/fel.c @@ -1270,12 +1270,56 @@ static unsigned int file_upload(libusb_device_handle *handle, size_t count, return i; // return number of files that were processed } +/* open libusb handle to desired FEL device */ +static void request_libusb_handle(libusb_device_handle **handle, + int busnum, int devnum, uint16_t vendor_id, uint16_t product_id) +{ + if (busnum < 0 || devnum < 0) + // With the default values (busnum -1, devnum -1) we don't care + // for a specific USB device; so let libusb open the first + // device that matches VID/PID. + *handle = libusb_open_device_with_vid_pid(NULL, vendor_id, product_id); + else { + // look for specific bus and device number + pr_info("Selecting USB Bus %03d Device %03d\n", busnum, devnum); + libusb_device **list; + size_t ndevs, i; + bool found = false; + + ndevs = libusb_get_device_list(NULL, &list); + for (i = 0; i < ndevs; i++) + if (libusb_get_bus_number(list[i]) == busnum + && libusb_get_device_address(list[i]) == devnum) { + found = true; // bus:devnum matched + struct libusb_device_descriptor desc; + libusb_get_device_descriptor(list[i], &desc); + if (desc.idVendor != vendor_id + || desc.idProduct != product_id) { + fprintf(stderr, "ERROR: Bus %03d Device %03d not a FEL device (expected %04x:%04x, got %04x:%04x)\n", + busnum, devnum, vendor_id, product_id, desc.idVendor, desc.idProduct); + exit(1); + } + // open handle to this specific device (incrementing its refcount) + libusb_open(list[i], handle); + break; + } + libusb_free_device_list(list, true); + + if (!found) { + fprintf(stderr, "ERROR: Bus %03d Device %03d not found in libusb device list\n", + busnum, devnum); + exit(1); + } + } +} + int main(int argc, char **argv) { bool uboot_autostart = false; /* flag for "uboot" command = U-Boot autostart */ bool pflag_active = false; /* -p switch, causing "write" to output progress */ int rc; libusb_device_handle *handle = NULL; + int busnum = -1, devnum = -1; int iface_detached = -1; rc = libusb_init(NULL); assert(rc == 0); @@ -1284,6 +1328,7 @@ int main(int argc, char **argv) printf("Usage: %s [options] command arguments... [command...]\n" " -v, --verbose Verbose logging\n" " -p, --progress \"write\" transfers show a progress bar\n" + " -d, --dev bus:devnum Use specific USB bus and device number\n" "\n" " spl file Load and execute U-Boot SPL\n" " If file additionally contains a main U-Boot binary\n" @@ -1316,7 +1361,29 @@ int main(int argc, char **argv) ); } - handle = libusb_open_device_with_vid_pid(NULL, 0x1f3a, 0xefe8); + /* process all "prefix"-type arguments first */ + while (argc > 1) { + if (strcmp(argv[1], "--verbose") == 0 || strcmp(argv[1], "-v") == 0) + verbose = true; + else if (strcmp(argv[1], "--progress") == 0 || strcmp(argv[1], "-p") == 0) + pflag_active = true; + else if (strncmp(argv[1], "--dev", 5) == 0 || strncmp(argv[1], "-d", 2) == 0) { + char *dev = argv[1]; + dev += strspn(argv[1], "-dev="); // skip option chars, ignore '=' + if (*dev == 0) { // at end of argument, use the next one instead + dev = argv[2]; + argc -= 1; + argv += 1; + } + busnum = strtoul(dev, &dev, 10); + devnum = strtoul(dev + 1, NULL, 10); + } else + break; /* no valid (prefix) option detected, exit loop */ + argc -= 1; + argv += 1; + } + + request_libusb_handle(&handle, busnum, devnum, 0x1f3a, 0xefe8); if (!handle) { switch (errno) { case EACCES: @@ -1343,18 +1410,6 @@ int main(int argc, char **argv) exit(1); } - /* process all "prefix"-type arguments first */ - while (argc > 1) { - if (strcmp(argv[1], "--verbose") == 0 || strcmp(argv[1], "-v") == 0) - verbose = true; - else if (strcmp(argv[1], "--progress") == 0 || strcmp(argv[1], "-p") == 0) - pflag_active = true; - else - break; /* no valid (prefix) option detected, exit loop */ - argc -= 1; - argv += 1; - } - while (argc > 1 ) { int skip = 1; -- 2.4.10 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.