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.

Reply via email to