flash/nor/at91samd: Use 32-bit register writes for ST-Link compat
[fw/openocd] / src / jtag / drivers / mpsse.c
index a881803adfc10a0dc80f5a02008d503cf63cfd1f..18aeb38a480b79c1a873ac9e8de748e41e114199 100644 (file)
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
 /**************************************************************************
  *   Copyright (C) 2012 by Andreas Fritiofson                              *
  *   andreas.fritiofson@gmail.com                                          *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -22,6 +11,8 @@
 
 #include "mpsse.h"
 #include "helper/log.h"
+#include "helper/replacements.h"
+#include "helper/time_support.h"
 #include <libusb.h>
 
 /* Compatibility define for older libusb-1.0 */
@@ -61,8 +52,8 @@
 #define SIO_RESET_PURGE_TX 2
 
 struct mpsse_ctx {
-       libusb_context *usb_ctx;
-       libusb_device_handle *usb_dev;
+       struct libusb_context *usb_ctx;
+       struct libusb_device_handle *usb_dev;
        unsigned int usb_write_timeout;
        unsigned int usb_read_timeout;
        uint8_t in_ep;
@@ -84,7 +75,7 @@ struct mpsse_ctx {
 };
 
 /* Returns true if the string descriptor indexed by str_index in device matches string */
-static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_index,
+static bool string_descriptor_equal(struct libusb_device_handle *device, uint8_t str_index,
        const char *string)
 {
        int retval;
@@ -98,7 +89,7 @@ static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_in
        return strncmp(string, desc_string, sizeof(desc_string)) == 0;
 }
 
-static bool device_location_equal(libusb_device *device, const char *location)
+static bool device_location_equal(struct libusb_device *device, const char *location)
 {
        bool result = false;
 #ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
@@ -117,7 +108,7 @@ static bool device_location_equal(libusb_device *device, const char *location)
        LOG_DEBUG("device path has %i steps", path_len);
 
        ptr = strtok(loc, "-:");
-       if (ptr == NULL) {
+       if (!ptr) {
                LOG_DEBUG("no ':' in path");
                goto done;
        }
@@ -129,7 +120,7 @@ static bool device_location_equal(libusb_device *device, const char *location)
        path_step = 0;
        while (path_step < 7) {
                ptr = strtok(NULL, ".,");
-               if (ptr == NULL) {
+               if (!ptr) {
                        LOG_DEBUG("no more tokens in path at step %i", path_step);
                        break;
                }
@@ -160,7 +151,7 @@ static bool device_location_equal(libusb_device *device, const char *location)
 static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, const uint16_t *pid,
        const char *product, const char *serial, const char *location)
 {
-       libusb_device **list;
+       struct libusb_device **list;
        struct libusb_device_descriptor desc;
        struct libusb_config_descriptor *config0;
        int err;
@@ -170,7 +161,7 @@ static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, con
                LOG_ERROR("libusb_get_device_list() failed with %s", libusb_error_name(cnt));
 
        for (ssize_t i = 0; i < cnt; i++) {
-               libusb_device *device = list[i];
+               struct libusb_device *device = list[i];
 
                err = libusb_get_device_descriptor(device, &desc);
                if (err != LIBUSB_SUCCESS) {
@@ -403,13 +394,10 @@ void mpsse_close(struct mpsse_ctx *ctx)
        if (ctx->usb_ctx)
                libusb_exit(ctx->usb_ctx);
        bit_copy_discard(&ctx->read_queue);
-       if (ctx->write_buffer)
-               free(ctx->write_buffer);
-       if (ctx->read_buffer)
-               free(ctx->read_buffer);
-       if (ctx->read_chunk)
-               free(ctx->read_chunk);
 
+       free(ctx->write_buffer);
+       free(ctx->read_buffer);
+       free(ctx->read_chunk);
        free(ctx);
 }
 
@@ -888,6 +876,8 @@ int mpsse_flush(struct mpsse_ctx *ctx)
        }
 
        /* Polling loop, more or less taken from libftdi */
+       int64_t start = timeval_ms();
+       int64_t warn_after = 2000;
        while (!write_result.done || !read_result.done) {
                struct timeval timeout_usb;
 
@@ -910,6 +900,13 @@ int mpsse_flush(struct mpsse_ctx *ctx)
                                        break;
                        }
                }
+
+               int64_t now = timeval_ms();
+               if (now - start > warn_after) {
+                       LOG_WARNING("Haven't made progress in mpsse_flush() for %" PRId64
+                                       "ms.", now - start);
+                       warn_after *= 2;
+               }
        }
 
 error_check:
@@ -937,12 +934,12 @@ error_check:
                retval = ERROR_OK;
        }
 
+       if (retval != ERROR_OK)
+               mpsse_purge(ctx);
+
        libusb_free_transfer(write_transfer);
        if (read_transfer)
                libusb_free_transfer(read_transfer);
 
-       if (retval != ERROR_OK)
-               mpsse_purge(ctx);
-
        return retval;
 }