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