openocd: fix SPDX tag format for files .c
[fw/openocd] / src / jtag / drivers / usb_blaster / ublast2_access_libusb.c
index 6f15fa70a280115bdba86857924522859a257795..7f9781869c1de4a4d51a5ebe6ca24bb5e2d98260 100644 (file)
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
 /*
  *   Driver for USB-JTAG, Altera USB-Blaster II and compatibles
  *
  *   Copyright (C) 2013 Franck Jullien franck.jullien@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
@@ -23,6 +12,7 @@
 #endif
 #include <jtag/interface.h>
 #include <jtag/commands.h>
+#include "helper/system.h"
 #include <libusb_helper.h>
 #include <target/image.h>
 
@@ -133,13 +123,18 @@ static int load_usb_blaster_firmware(struct libusb_device_handle *libusb_dev,
                return ERROR_FAIL;
        }
 
+       if (libusb_claim_interface(libusb_dev, 0)) {
+               LOG_ERROR("unable to claim interface");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
        ublast2_firmware_image.base_address = 0;
        ublast2_firmware_image.base_address_set = false;
 
        int ret = image_open(&ublast2_firmware_image, low->firmware_path, "ihex");
        if (ret != ERROR_OK) {
                LOG_ERROR("Could not load firmware image");
-               return ret;
+               goto error_release_usb;
        }
 
        /** A host loader program must write 0x01 to the CPUCS register
@@ -167,7 +162,7 @@ static int load_usb_blaster_firmware(struct libusb_device_handle *libusb_dev,
                                                     &ublast2_firmware_image, i);
                if (ret != ERROR_OK) {
                        LOG_ERROR("Error while downloading the firmware");
-                       return ret;
+                       goto error_close_firmware;
                }
        }
 
@@ -182,9 +177,18 @@ static int load_usb_blaster_firmware(struct libusb_device_handle *libusb_dev,
                                     1,
                                     100);
 
+error_close_firmware:
        image_close(&ublast2_firmware_image);
 
-       return ERROR_OK;
+error_release_usb:
+       /*
+        * Release claimed interface. Most probably it is already disconnected
+        * and re-enumerated as new devices after firmware upload, so we do
+        * not need to care about errors.
+        */
+       libusb_release_interface(libusb_dev, 0);
+
+       return ret;
 }
 
 static int ublast2_libusb_init(struct ublast_lowlevel *low)
@@ -195,7 +199,7 @@ static int ublast2_libusb_init(struct ublast_lowlevel *low)
        bool renumeration = false;
        int ret;
 
-       if (jtag_libusb_open(vids, pids, NULL, &temp, NULL) == ERROR_OK) {
+       if (jtag_libusb_open(vids, pids, &temp, NULL) == ERROR_OK) {
                LOG_INFO("Altera USB-Blaster II (uninitialized) found");
                LOG_INFO("Loading firmware...");
                ret = load_usb_blaster_firmware(temp, low);
@@ -209,15 +213,13 @@ static int ublast2_libusb_init(struct ublast_lowlevel *low)
        const uint16_t pids_renum[] = { low->ublast_pid, 0 };
 
        if (renumeration == false) {
-               if (jtag_libusb_open(vids_renum, pids_renum, NULL,
-                               &low->libusb_dev, NULL) != ERROR_OK) {
+               if (jtag_libusb_open(vids_renum, pids_renum, &low->libusb_dev, NULL) != ERROR_OK) {
                        LOG_ERROR("Altera USB-Blaster II not found");
                        return ERROR_FAIL;
                }
        } else {
                int retry = 10;
-               while (jtag_libusb_open(vids_renum, pids_renum, NULL,
-                               &low->libusb_dev, NULL) != ERROR_OK && retry--) {
+               while (jtag_libusb_open(vids_renum, pids_renum, &low->libusb_dev, NULL) != ERROR_OK && retry--) {
                        usleep(1000000);
                        LOG_INFO("Waiting for reenumerate...");
                }
@@ -228,6 +230,12 @@ static int ublast2_libusb_init(struct ublast_lowlevel *low)
                }
        }
 
+       if (libusb_claim_interface(low->libusb_dev, 0)) {
+               LOG_ERROR("unable to claim interface");
+               jtag_libusb_close(low->libusb_dev);
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
        char buffer[5];
        jtag_libusb_control_transfer(low->libusb_dev,
                                     LIBUSB_REQUEST_TYPE_VENDOR |
@@ -246,6 +254,9 @@ static int ublast2_libusb_init(struct ublast_lowlevel *low)
 
 static int ublast2_libusb_quit(struct ublast_lowlevel *low)
 {
+       if (libusb_release_interface(low->libusb_dev, 0))
+               LOG_ERROR("usb release interface failed");
+
        jtag_libusb_close(low->libusb_dev);
        return ERROR_OK;
 };