Added ftdi_transfer_data_cancel for cancelation of a submitted transfer, avoided...
authorEugene Hutorny <eugene@hutorny.in.ua>
Sat, 23 Jan 2016 04:41:30 +0000 (06:41 +0200)
committerThomas Jarosch <thomas.jarosch@intra2net.com>
Sat, 26 Mar 2016 12:01:50 +0000 (13:01 +0100)
AUTHORS
ChangeLog
src/ftdi.c
src/ftdi.h

diff --git a/AUTHORS b/AUTHORS
index ac74557..0200e22 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -22,6 +22,7 @@ see Changelog for full details:
   Davide Michelizza <dmichelizza@gmail.com>
   Denis Sirotkin <reg.libftdi@demitel.ru>
   Emil <emil@datel.co.uk>
+  Eugene Hutorny <eugene@hutorny.in.ua>
   Evan Nemerson <evan@coeus-group.com>
   Evgeny Sinelnikov <sin@geoft.ru>
   Flynn Marquardt <ftdi@flynnux.de>
index aaae78b..82c5a9c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+New in 1.3 - 2016-04-xx
+-----------------------
+* Added ftdi_transfer_data_cancel for cancelation of a submitted transfer,
+  avoided resubmittion of a cancelled transfer in the callbacks, replaced calls
+  to libusb_handle_events with libusb_handle_events_timeout_completed
+  (Eugene Hutorny, eugene@hutorny.in.ua)
+
+Note: All other changes are not listed yet
+
 New in 1.2 - 2014-11-21
 -----------------------
 * Support for FT230X devices (Uwe Bonnes)
index aa4b4ec..573080a 100644 (file)
@@ -1470,9 +1470,15 @@ static void LIBUSB_CALL ftdi_read_data_cb(struct libusb_transfer *transfer)
             }
         }
     }
-    ret = libusb_submit_transfer (transfer);
-    if (ret < 0)
-        tc->completed = 1;
+
+    if (transfer->status == LIBUSB_TRANSFER_CANCELLED)
+        tc->completed = LIBUSB_TRANSFER_CANCELLED;
+    else
+    {
+        ret = libusb_submit_transfer (transfer);
+        if (ret < 0)
+            tc->completed = 1;
+    }
 }
 
 
@@ -1497,9 +1503,15 @@ static void LIBUSB_CALL ftdi_write_data_cb(struct libusb_transfer *transfer)
 
         transfer->length = write_size;
         transfer->buffer = tc->buf + tc->offset;
-        ret = libusb_submit_transfer (transfer);
-        if (ret < 0)
-            tc->completed = 1;
+
+        if (transfer->status == LIBUSB_TRANSFER_CANCELLED)
+            tc->completed = LIBUSB_TRANSFER_CANCELLED;
+        else
+        {
+            ret = libusb_submit_transfer (transfer);
+            if (ret < 0)
+                tc->completed = 1;
+        }
     }
 }
 
@@ -1662,17 +1674,19 @@ struct ftdi_transfer_control *ftdi_read_data_submit(struct ftdi_context *ftdi, u
 int ftdi_transfer_data_done(struct ftdi_transfer_control *tc)
 {
     int ret;
-
+    struct timeval to = { 0, 0 };
     while (!tc->completed)
     {
-        ret = libusb_handle_events(tc->ftdi->usb_ctx);
+        ret = libusb_handle_events_timeout_completed(tc->ftdi->usb_ctx,
+                &to, &tc->completed);
         if (ret < 0)
         {
             if (ret == LIBUSB_ERROR_INTERRUPTED)
                 continue;
             libusb_cancel_transfer(tc->transfer);
             while (!tc->completed)
-                if (libusb_handle_events(tc->ftdi->usb_ctx) < 0)
+                if (libusb_handle_events_timeout_completed(tc->ftdi->usb_ctx,
+                        &to, &tc->completed) < 0)
                     break;
             libusb_free_transfer(tc->transfer);
             free (tc);
@@ -1696,6 +1710,39 @@ int ftdi_transfer_data_done(struct ftdi_transfer_control *tc)
 }
 
 /**
+    Cancel transfer and wait for completion.
+
+    Use libusb 1.0 asynchronous API.
+
+    \param tc pointer to ftdi_transfer_control
+    \param to pointer to timeout value or NULL for infinite
+*/
+
+void ftdi_transfer_data_cancel(struct ftdi_transfer_control *tc,
+                               struct timeval * to)
+{
+    struct timeval tv = { 0, 0 };
+
+    if (!tc->completed && tc->transfer != NULL)
+    {
+        if (to == NULL)
+            to = &tv;
+
+        libusb_cancel_transfer(tc->transfer);
+        while (!tc->completed)
+        {
+            if (libusb_handle_events_timeout_completed(tc->ftdi->usb_ctx, to, &tc->completed) < 0)
+                break;
+        }
+    }
+
+    if (tc->transfer)
+        libusb_free_transfer(tc->transfer);
+
+    free (tc);
+}
+
+/**
     Configure write buffer chunk size.
     Default is 4096.
 
index 9a6ec79..fa53b29 100644 (file)
@@ -521,6 +521,7 @@ extern "C"
 
     struct ftdi_transfer_control *ftdi_read_data_submit(struct ftdi_context *ftdi, unsigned char *buf, int size);
     int ftdi_transfer_data_done(struct ftdi_transfer_control *tc);
+    void ftdi_transfer_data_cancel(struct ftdi_transfer_control *tc, struct timeval * to);
 
     int ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned char bitmask, unsigned char mode);
     int ftdi_disable_bitbang(struct ftdi_context *ftdi);