libftdi Archives

Subject: [PATCH] Fixed first device failure in open_desc function

From: Harrison Marcks <hmarcks@xxxxxxxxxxxxxxxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Cc: amurray@xxxxxxxxxxxxxxxxxxxx, Harrison Marcks <hmarcks@xxxxxxxxxxxxxxxxxxxx>
Date: Thu, 7 Jul 2022 14:30:47 +0100
The ftdi_usb_open_desc_index function would fail immediately in the case of a
first failed device which is undesireable if several devices are present
that share ids but might not be accessible. This specific edge case fixes an 
issue
in containers that sees devices not passed through but still being seen by 
libusb
failing when they can't be accessed in the container by moving onto the next 
device
until a device is found it can open and check correctly.
---
 src/ftdi.c | 35 +++++++++++++++++++++++++++++------
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/src/ftdi.c b/src/ftdi.c
index 0a7fb27..c64fd8e 100644
--- a/src/ftdi.c
+++ b/src/ftdi.c
@@ -763,7 +763,7 @@ int ftdi_usb_open_desc(struct ftdi_context *ftdi, int 
vendor, int product,
     \retval -1: usb_find_busses() failed
     \retval -2: usb_find_devices() failed
     \retval -3: usb device not found
-    \retval -4: unable to open device
+    \retval -4: unable to open device. We made at least one match and it 
failed to open.
     \retval -5: unable to claim device
     \retval -6: reset failed
     \retval -7: set baudrate failed
@@ -780,6 +780,8 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int 
vendor, int product,
     libusb_device **devs;
     char string[256];
     int i = 0;
+    int error_code = -3;
+    int open_counter = 0, open_fail_counter = 0;
 
     if (ftdi == NULL)
         ftdi_error_return(-11, "ftdi context invalid");
@@ -797,8 +799,13 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, 
int vendor, int product,
 
         if (desc.idVendor == vendor && desc.idProduct == product)
         {
+            open_counter++;
             if (libusb_open(dev, &ftdi->usb_dev) < 0)
-                ftdi_error_return_free_device_list(-4, "usb_open() failed", 
devs);
+            {
+                open_fail_counter++;
+                error_code = -4;
+                continue;
+            }
 
             if (description != NULL)
             {
@@ -810,6 +817,7 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int 
vendor, int product,
                 if (strncmp(string, description, sizeof(string)) != 0)
                 {
                     ftdi_usb_close_internal (ftdi);
+                    error_code = -3;
                     continue;
                 }
             }
@@ -823,12 +831,12 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, 
int vendor, int product,
                 if (strncmp(string, serial, sizeof(string)) != 0)
                 {
                     ftdi_usb_close_internal (ftdi);
+                    error_code = -3;
                     continue;
                 }
             }
 
             ftdi_usb_close_internal (ftdi);
-
             if (index > 0)
             {
                 index--;
@@ -836,13 +844,28 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, 
int vendor, int product,
             }
 
             res = ftdi_usb_open_dev(ftdi, dev);
-            libusb_free_device_list(devs,1);
+            libusb_free_device_list(devs, 1);
             return res;
         }
     }
 
-    // device not found
-    ftdi_error_return_free_device_list(-3, "device not found", devs);
+    switch(error_code)
+    {
+        case -3:
+            // device not found
+            ftdi_error_return_free_device_list(-3, "device not found", devs);
+        break;
+        case -4:
+        {
+            // Failure to open any devices. We made at least one match and it 
failed to open.
+            char buf [256];
+            sprintf(buf, "usb_open() ran %d times and failed %d times.", 
open_counter, open_fail_counter);
+            ftdi_error_return_free_device_list(-4, buf, devs);
+        }
+        break;
+    }
+
+    return error_code;
 }
 
 /**
-- 
2.34.1


--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx   

Current Thread