jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / jtag / drivers / libusb_helper.c
index 18fe4bad4c668694ae78a1e0d73b5995b7b03f77..57ea8cd3fa0fe9fe85498f83f0e80a22d91975d3 100644 (file)
@@ -1,28 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
 /***************************************************************************
  *   Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net>          *
  *                                                                         *
  *   Copyright (C) 2011 by Mauro Gamba <maurillo71@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
 #include "config.h"
 #endif
-#include <jtag/drivers/jtag_usb_common.h>
+
+#include <string.h>
+
+#include <helper/log.h>
+#include <jtag/adapter.h>
 #include "libusb_helper.h"
-#include "log.h"
 
 /*
  * comment from libusb:
@@ -58,7 +50,7 @@ static int jtag_libusb_error(int err)
        }
 }
 
-static bool jtag_libusb_match_ids(struct libusb_device_descriptor *dev_desc,
+bool jtag_libusb_match_ids(struct libusb_device_descriptor *dev_desc,
                const uint16_t vids[], const uint16_t pids[])
 {
        for (unsigned i = 0; vids[i]; i++) {
@@ -85,7 +77,7 @@ static bool jtag_libusb_location_equal(struct libusb_device *device)
        }
        dev_bus = libusb_get_bus_number(device);
 
-       return jtag_usb_location_equal(dev_bus, port_path, path_len);
+       return adapter_usb_location_equal(dev_bus, port_path, path_len);
 }
 #else /* HAVE_LIBUSB_GET_PORT_NUMBERS */
 static bool jtag_libusb_location_equal(struct libusb_device *device)
@@ -138,7 +130,7 @@ static bool jtag_libusb_match_serial(struct libusb_device_handle *device,
        char *alternate_serial = adapter_get_alternate_serial(device, dev_desc);
 
        /* check possible failures */
-       if (alternate_serial == NULL)
+       if (!alternate_serial)
                return false;
 
        /* then compare and free the alternate serial */
@@ -154,14 +146,15 @@ static bool jtag_libusb_match_serial(struct libusb_device_handle *device,
 }
 
 int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[],
-               const char *serial,
-               struct libusb_device_handle **out,
+               const char *product, struct libusb_device_handle **out,
                adapter_get_alternate_serial_fn adapter_get_alternate_serial)
 {
-       int cnt, idx, errCode;
+       int cnt, idx, err_code;
        int retval = ERROR_FAIL;
        bool serial_mismatch = false;
+       bool product_mismatch = false;
        struct libusb_device_handle *libusb_handle = NULL;
+       const char *serial = adapter_get_required_serial();
 
        if (libusb_init(&jtag_libusb_context) < 0)
                return ERROR_FAIL;
@@ -177,29 +170,37 @@ int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[],
                if (!jtag_libusb_match_ids(&dev_desc, vids, pids))
                        continue;
 
-               if (jtag_usb_get_location() && !jtag_libusb_location_equal(devs[idx]))
+               if (adapter_usb_get_location() && !jtag_libusb_location_equal(devs[idx]))
                        continue;
 
-               errCode = libusb_open(devs[idx], &libusb_handle);
+               err_code = libusb_open(devs[idx], &libusb_handle);
 
-               if (errCode) {
+               if (err_code) {
                        LOG_ERROR("libusb_open() failed with %s",
-                                 libusb_error_name(errCode));
+                                 libusb_error_name(err_code));
                        continue;
                }
 
                /* Device must be open to use libusb_get_string_descriptor_ascii. */
-               if (serial != NULL &&
+               if (serial &&
                                !jtag_libusb_match_serial(libusb_handle, &dev_desc, serial, adapter_get_alternate_serial)) {
                        serial_mismatch = true;
                        libusb_close(libusb_handle);
                        continue;
                }
 
+               if (product &&
+                               !string_descriptor_equal(libusb_handle, dev_desc.iProduct, product)) {
+                       product_mismatch = true;
+                       libusb_close(libusb_handle);
+                       continue;
+               }
+
                /* Success. */
                *out = libusb_handle;
                retval = ERROR_OK;
                serial_mismatch = false;
+               product_mismatch = false;
                break;
        }
        if (cnt >= 0)
@@ -208,6 +209,9 @@ int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[],
        if (serial_mismatch)
                LOG_INFO("No device matches the serial string");
 
+       if (product_mismatch)
+               LOG_INFO("No device matches the product string");
+
        if (retval != ERROR_OK)
                libusb_exit(jtag_libusb_context);
 
@@ -222,19 +226,24 @@ void jtag_libusb_close(struct libusb_device_handle *dev)
        libusb_exit(jtag_libusb_context);
 }
 
-int jtag_libusb_control_transfer(struct libusb_device_handle *dev, uint8_t requestType,
-               uint8_t request, uint16_t wValue, uint16_t wIndex, char *bytes,
-               uint16_t size, unsigned int timeout)
+int jtag_libusb_control_transfer(struct libusb_device_handle *dev, uint8_t request_type,
+               uint8_t request, uint16_t value, uint16_t index, char *bytes,
+               uint16_t size, unsigned int timeout, int *transferred)
 {
-       int transferred = 0;
-
-       transferred = libusb_control_transfer(dev, requestType, request, wValue, wIndex,
+       int retval = libusb_control_transfer(dev, request_type, request, value, index,
                                (unsigned char *)bytes, size, timeout);
 
-       if (transferred < 0)
-               transferred = 0;
+       if (retval < 0) {
+               LOG_ERROR("libusb_control_transfer error: %s", libusb_error_name(retval));
+               if (transferred)
+                       *transferred = 0;
+               return jtag_libusb_error(retval);
+       }
 
-       return transferred;
+       if (transferred)
+               *transferred = retval;
+
+       return ERROR_OK;
 }
 
 int jtag_libusb_bulk_write(struct libusb_device_handle *dev, int ep, char *bytes,
@@ -275,28 +284,28 @@ int jtag_libusb_set_configuration(struct libusb_device_handle *devh,
                int configuration)
 {
        struct libusb_device *udev = libusb_get_device(devh);
-       int retCode = -99;
+       int retval = -99;
 
        struct libusb_config_descriptor *config = NULL;
        int current_config = -1;
 
-       retCode = libusb_get_configuration(devh, &current_config);
-       if (retCode != 0)
-               return retCode;
+       retval = libusb_get_configuration(devh, &current_config);
+       if (retval != 0)
+               return retval;
 
-       retCode = libusb_get_config_descriptor(udev, configuration, &config);
-       if (retCode != 0 || config == NULL)
-               return retCode;
+       retval = libusb_get_config_descriptor(udev, configuration, &config);
+       if (retval != 0 || !config)
+               return retval;
 
        /* Only change the configuration if it is not already set to the
           same one. Otherwise this issues a lightweight reset and hangs
           LPC-Link2 with JLink firmware. */
        if (current_config != config->bConfigurationValue)
-               retCode = libusb_set_configuration(devh, config->bConfigurationValue);
+               retval = libusb_set_configuration(devh, config->bConfigurationValue);
 
        libusb_free_config_descriptor(config);
 
-       return retCode;
+       return retval;
 }
 
 int jtag_libusb_choose_interface(struct libusb_device_handle *devh,
@@ -368,3 +377,59 @@ int jtag_libusb_handle_events_completed(int *completed)
 {
        return libusb_handle_events_completed(jtag_libusb_context, completed);
 }
+
+static enum {
+       DEV_MEM_NOT_YET_DECIDED,
+       DEV_MEM_AVAILABLE,
+       DEV_MEM_FALLBACK_MALLOC
+} dev_mem_allocation;
+
+/* Older libusb does not implement following API calls - define stubs instead */
+#if !defined(LIBUSB_API_VERSION) || (LIBUSB_API_VERSION < 0x01000105)
+static uint8_t *libusb_dev_mem_alloc(libusb_device_handle *devh, size_t length)
+{
+       return NULL;
+}
+
+static int libusb_dev_mem_free(libusb_device_handle *devh,
+                                                          uint8_t *buffer, size_t length)
+{
+       return LIBUSB_ERROR_NOT_SUPPORTED;
+}
+#endif
+
+uint8_t *oocd_libusb_dev_mem_alloc(libusb_device_handle *devh,
+                       size_t length)
+{
+       uint8_t *buffer = NULL;
+       if (dev_mem_allocation != DEV_MEM_FALLBACK_MALLOC)
+               buffer = libusb_dev_mem_alloc(devh, length);
+
+       if (dev_mem_allocation == DEV_MEM_NOT_YET_DECIDED)
+               dev_mem_allocation = buffer ? DEV_MEM_AVAILABLE : DEV_MEM_FALLBACK_MALLOC;
+
+       if (dev_mem_allocation == DEV_MEM_FALLBACK_MALLOC)
+               buffer = malloc(length);
+
+       return buffer;
+}
+
+int oocd_libusb_dev_mem_free(libusb_device_handle *devh,
+               uint8_t *buffer, size_t length)
+{
+       if (!buffer)
+               return ERROR_OK;
+
+       switch (dev_mem_allocation) {
+       case DEV_MEM_AVAILABLE:
+               return jtag_libusb_error(libusb_dev_mem_free(devh, buffer, length));
+
+       case DEV_MEM_FALLBACK_MALLOC:
+               free(buffer);
+               return ERROR_OK;
+
+       case DEV_MEM_NOT_YET_DECIDED:
+               return ERROR_FAIL;
+       }
+       return ERROR_FAIL;
+}

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)