ftdi: address ftdi_usb_purge_buffers() deprecation in libftdi 1.5
authorGerhard Sittig <gerhard.sittig@gmx.net>
Wed, 22 Dec 2021 11:22:48 +0000 (12:22 +0100)
committerGerhard Sittig <gerhard.sittig@gmx.net>
Wed, 22 Dec 2021 19:06:02 +0000 (20:06 +0100)
The ftdi_usb_purge_buffers() implementation suffered from an incorrect
implementation (inverse semantics). Library version 1.5 introduced a set
of substitute routines, and deprecated the existing purge API. Parameters
are identical, so we get away with a mere replacement of the routine name
which gets invoked. Which simplifies call sites, and concentrates all the
version dependency cruft in a central spot. The fact that all drivers
always flushed RX and TX and never individually also helped.

configure.ac
src/hardware/asix-sigma/protocol.c
src/hardware/chronovu-la/api.c
src/hardware/chronovu-la/protocol.c
src/hardware/ftdi-la/api.c
src/hardware/ikalogic-scanaplus/api.c
src/hardware/pipistrello-ols/protocol.c
src/libsigrok-internal.h

index 90291772580af6fd3dd7cb8e9218bc4531dcd28c..424b00022729e4ba70671bfdc17518c3b8646ed0 100644 (file)
@@ -616,6 +616,7 @@ AM_COND_IF([BINDINGS_CXX], [
 ])
 
 # Check for specific libusb features, now that we know the CFLAGS.
+# Also check for version dependent libftdi features.
 AC_LANG([C])
 sr_save_cflags=$CFLAGS
 sr_save_libs=$LIBS
@@ -625,6 +626,7 @@ AC_CHECK_TYPES([libusb_os_handle],
        [sr_have_libusb_os_handle=yes], [sr_have_libusb_os_handle=no],
        [[#include <libusb.h>]])
 AC_CHECK_FUNCS([zip_discard])
+AC_CHECK_FUNCS([ftdi_tciflush ftdi_tcoflush ftdi_tcioflush])
 LIBS=$sr_save_libs
 CFLAGS=$sr_save_cflags
 
index df59693db0e62841368ed10637db209ac853c02a..142316514c7ceab0ebda7fc8a157fa66cc495302 100644 (file)
@@ -625,7 +625,7 @@ static int sigma_fpga_init_bitbang_once(struct dev_context *devc)
        if (ret != SR_OK)
                return ret;
        g_usleep(10 * 1000);
-       ftdi_usb_purge_buffers(&devc->ftdi.ctx);
+       PURGE_FTDI_BOTH(&devc->ftdi.ctx);
 
        /*
         * Wait until the FPGA asserts INIT_B. Check in a maximum number
@@ -889,7 +889,7 @@ static int upload_firmware(struct sr_context *ctx, struct dev_context *devc,
                        ftdi_get_error_string(&devc->ftdi.ctx));
                return SR_ERR;
        }
-       ftdi_usb_purge_buffers(&devc->ftdi.ctx);
+       PURGE_FTDI_BOTH(&devc->ftdi.ctx);
        while (sigma_read_raw(devc, &pins, sizeof(pins)) > 0)
                ;
 
index 694bd54ac84fb91f0f864cefa67d9d31eb2a641c..d35a4f5377d2b8d8bc943cfbf893b2a043340444 100644 (file)
@@ -243,7 +243,7 @@ static int dev_open(struct sr_dev_inst *sdi)
                goto err_ftdi_free;
        }
 
-       if ((ret = ftdi_usb_purge_buffers(devc->ftdic)) < 0) {
+       if ((ret = PURGE_FTDI_BOTH(devc->ftdic)) < 0) {
                sr_err("Failed to purge FTDI buffers (%d): %s.",
                       ret, ftdi_get_error_string(devc->ftdic));
                goto err_ftdi_free;
index da772f5b1d8f5ffcdb1d3ab46227dad39dc2922d..ae8f427a7e9af002e6069382493be45375e47728 100644 (file)
@@ -202,7 +202,7 @@ static int close_usb_reset_sequencer(struct dev_context *devc)
                sr_dbg("Purging buffers, resetting+closing FTDI device.");
 
                /* Log errors, but ignore them (i.e., don't abort). */
-               if ((ret = ftdi_usb_purge_buffers(devc->ftdic)) < 0)
+               if ((ret = PURGE_FTDI_BOTH(devc->ftdic)) < 0)
                        sr_err("Failed to purge FTDI buffers (%d): %s.",
                               ret, ftdi_get_error_string(devc->ftdic));
                if ((ret = ftdi_usb_reset(devc->ftdic)) < 0)
index 8bb67121cc6c71051b279b200ffc6a6d95e2372d..2e7e59f49324c4b63310e4fb6c03ced6f229ed29 100644 (file)
@@ -325,7 +325,7 @@ static int dev_open(struct sr_dev_inst *sdi)
                goto err_ftdi_free;
        }
 
-       ret = ftdi_usb_purge_buffers(devc->ftdic);
+       ret = PURGE_FTDI_BOTH(devc->ftdic);
        if (ret < 0) {
                sr_err("Failed to purge FTDI RX/TX buffers (%d): %s.",
                       ret, ftdi_get_error_string(devc->ftdic));
index f29e5c39ae327c24b37a4ade4047cecc4410bc98..fb3b137f3fc36f7ad620295494607cd0185aa0e5 100644 (file)
@@ -141,7 +141,7 @@ static int dev_open(struct sr_dev_inst *sdi)
                return SR_ERR;
        }
 
-       if ((ret = ftdi_usb_purge_buffers(devc->ftdic)) < 0) {
+       if ((ret = PURGE_FTDI_BOTH(devc->ftdic)) < 0) {
                sr_err("Failed to purge FTDI RX/TX buffers (%d): %s.",
                       ret, ftdi_get_error_string(devc->ftdic));
                goto err_dev_open_close_ftdic;
index f0ef680527abc48d925f9dae6b9bbcb1adeb5add..1b54dd164e23075f4fb3c77c53fb3a810d5bf081 100644 (file)
@@ -90,7 +90,7 @@ SR_PRIV int p_ols_open(struct dev_context *devc)
                return SR_ERR;
        }
 
-       if ((ret = ftdi_usb_purge_buffers(devc->ftdic)) < 0) {
+       if ((ret = PURGE_FTDI_BOTH(devc->ftdic)) < 0) {
                sr_err("Failed to purge FTDI RX/TX buffers (%d): %s.",
                       ret, ftdi_get_error_string(devc->ftdic));
                goto err_open_close_ftdic;
index 25297f4c9386561d8583494cf9e2c2c75e7cd3f6..a2350e02ddf3aed2c48c89bcab2ac8eb8f59dfae 100644 (file)
@@ -32,6 +32,9 @@
 #ifdef HAVE_LIBUSB_1_0
 #include <libusb.h>
 #endif
+#ifdef HAVE_LIBFTDI
+#include <ftdi.h>
+#endif
 #include <stdarg.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -981,6 +984,21 @@ static inline void write_dblle_inc(uint8_t **p, double x)
        libusb_handle_events_timeout(ctx, tv)
 #endif
 
+/*
+ * Convenience for FTDI library version dependency.
+ * - Version 1.5 introduced ftdi_tciflush(), ftdi_tcoflush(), and
+ *   ftdi_tcioflush() all within the same commit, and deprecated
+ *   ftdi_usb_purge_buffers() which suffered from inverse semantics.
+ *   The API is drop-in compatible (arguments count and data types are
+ *   identical). The libsigrok source code always flushes RX and TX at
+ *   the same time, never individually.
+ */
+#if defined HAVE_FTDI_TCIOFLUSH && HAVE_FTDI_TCIOFLUSH
+#  define PURGE_FTDI_BOTH ftdi_tcioflush
+#else
+#  define PURGE_FTDI_BOTH ftdi_usb_purge_buffers
+#endif
+
 /* Static definitions of structs ending with an all-zero entry are a
  * problem when compiling with -Wmissing-field-initializers: GCC
  * suppresses the warning only with { 0 }, clang wants { } */