X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Fmpsse.c;h=89248921ae46657cab6510557db4f5b964514682;hb=HEAD;hp=9ba1e2502de746474cda4ef2aef27126c51a41b2;hpb=87c90393fedc8bb278d189aa53bcd93f4892012b;p=openocd.git diff --git a/src/jtag/drivers/mpsse.c b/src/jtag/drivers/mpsse.c index 9ba1e2502d..f3499e3864 100644 --- a/src/jtag/drivers/mpsse.c +++ b/src/jtag/drivers/mpsse.c @@ -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 . * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -24,6 +13,7 @@ #include "helper/log.h" #include "helper/replacements.h" #include "helper/time_support.h" +#include "libusb_helper.h" #include /* Compatibility define for older libusb-1.0 */ @@ -119,7 +109,7 @@ static bool device_location_equal(struct libusb_device *device, const char *loca LOG_DEBUG("device path has %i steps", path_len); ptr = strtok(loc, "-:"); - if (ptr == NULL) { + if (!ptr) { LOG_DEBUG("no ':' in path"); goto done; } @@ -131,7 +121,7 @@ static bool device_location_equal(struct libusb_device *device, const char *loca 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; } @@ -159,7 +149,7 @@ static bool device_location_equal(struct libusb_device *device, const char *loca * Set any field to 0 as a wildcard. If the device is found true is returned, with ctx containing * the already opened handle. ctx->interface must be set to the desired interface (channel) number * prior to calling this function. */ -static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, const uint16_t *pid, +static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t vids[], const uint16_t pids[], const char *product, const char *serial, const char *location) { struct libusb_device **list; @@ -180,9 +170,7 @@ static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, con continue; } - if (vid && *vid != desc.idVendor) - continue; - if (pid && *pid != desc.idProduct) + if (!jtag_libusb_match_ids(&desc, vids, pids)) continue; err = libusb_open(device, &ctx->usb_dev); @@ -214,7 +202,7 @@ static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, con libusb_free_device_list(list, 1); if (!found) { - LOG_ERROR("no device found"); + /* The caller reports detailed error desc */ return false; } @@ -277,6 +265,24 @@ static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, con case 0x900: ctx->type = TYPE_FT232H; break; + case 0x2800: + ctx->type = TYPE_FT2233HP; + break; + case 0x2900: + ctx->type = TYPE_FT4233HP; + break; + case 0x3000: + ctx->type = TYPE_FT2232HP; + break; + case 0x3100: + ctx->type = TYPE_FT4232HP; + break; + case 0x3200: + ctx->type = TYPE_FT233HP; + break; + case 0x3300: + ctx->type = TYPE_FT232HP; + break; default: LOG_ERROR("unsupported FTDI chip type: 0x%04x", desc.bcdDevice); goto error; @@ -318,14 +324,14 @@ error: return false; } -struct mpsse_ctx *mpsse_open(const uint16_t *vid, const uint16_t *pid, const char *description, +struct mpsse_ctx *mpsse_open(const uint16_t vids[], const uint16_t pids[], const char *description, const char *serial, const char *location, int channel) { struct mpsse_ctx *ctx = calloc(1, sizeof(*ctx)); int err; if (!ctx) - return 0; + return NULL; bit_copy_queue_init(&ctx->read_queue); ctx->read_chunk_size = 16384; @@ -354,18 +360,13 @@ struct mpsse_ctx *mpsse_open(const uint16_t *vid, const uint16_t *pid, const cha goto error; } - if (!open_matching_device(ctx, vid, pid, description, serial, location)) { - /* Four hex digits plus terminating zero each */ - char vidstr[5]; - char pidstr[5]; - LOG_ERROR("unable to open ftdi device with vid %s, pid %s, description '%s', " + if (!open_matching_device(ctx, vids, pids, description, serial, location)) { + LOG_ERROR("unable to open ftdi device with description '%s', " "serial '%s' at bus location '%s'", - vid ? sprintf(vidstr, "%04x", *vid), vidstr : "*", - pid ? sprintf(pidstr, "%04x", *pid), pidstr : "*", description ? description : "*", serial ? serial : "*", location ? location : "*"); - ctx->usb_dev = 0; + ctx->usb_dev = NULL; goto error; } @@ -395,7 +396,7 @@ struct mpsse_ctx *mpsse_open(const uint16_t *vid, const uint16_t *pid, const cha return ctx; error: mpsse_close(ctx); - return 0; + return NULL; } void mpsse_close(struct mpsse_ctx *ctx) @@ -482,13 +483,13 @@ static unsigned buffer_add_read(struct mpsse_ctx *ctx, uint8_t *in, unsigned in_ void mpsse_clock_data_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, unsigned length, uint8_t mode) { - mpsse_clock_data(ctx, out, out_offset, 0, 0, length, mode); + mpsse_clock_data(ctx, out, out_offset, NULL, 0, length, mode); } void mpsse_clock_data_in(struct mpsse_ctx *ctx, uint8_t *in, unsigned in_offset, unsigned length, uint8_t mode) { - mpsse_clock_data(ctx, 0, 0, in, in_offset, length, mode); + mpsse_clock_data(ctx, NULL, 0, in, in_offset, length, mode); } void mpsse_clock_data(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in, @@ -565,7 +566,7 @@ void mpsse_clock_data(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_of void mpsse_clock_tms_cs_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, unsigned length, bool tdi, uint8_t mode) { - mpsse_clock_tms_cs(ctx, out, out_offset, 0, 0, length, tdi, mode); + mpsse_clock_tms_cs(ctx, out, out_offset, NULL, 0, length, tdi, mode); } void mpsse_clock_tms_cs(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in, @@ -859,7 +860,7 @@ int mpsse_flush(struct mpsse_ctx *ctx) if (ctx->write_count == 0) return retval; - struct libusb_transfer *read_transfer = 0; + struct libusb_transfer *read_transfer = NULL; struct transfer_result read_result = { .ctx = ctx, .done = true }; if (ctx->read_count) { buffer_write_byte(ctx, 0x87); /* SEND_IMMEDIATE */ @@ -897,20 +898,6 @@ int mpsse_flush(struct mpsse_ctx *ctx) retval = libusb_handle_events_timeout_completed(ctx->usb_ctx, &timeout_usb, NULL); keep_alive(); - if (retval == LIBUSB_ERROR_NO_DEVICE || retval == LIBUSB_ERROR_INTERRUPTED) - break; - - if (retval != LIBUSB_SUCCESS) { - libusb_cancel_transfer(write_transfer); - if (read_transfer) - libusb_cancel_transfer(read_transfer); - while (!write_result.done || !read_result.done) { - retval = libusb_handle_events_timeout_completed(ctx->usb_ctx, - &timeout_usb, NULL); - if (retval != LIBUSB_SUCCESS) - break; - } - } int64_t now = timeval_ms(); if (now - start > warn_after) { @@ -918,6 +905,15 @@ int mpsse_flush(struct mpsse_ctx *ctx) "ms.", now - start); warn_after *= 2; } + + if (retval == LIBUSB_ERROR_INTERRUPTED) + continue; + + if (retval != LIBUSB_SUCCESS) { + libusb_cancel_transfer(write_transfer); + if (read_transfer) + libusb_cancel_transfer(read_transfer); + } } error_check: @@ -945,12 +941,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; }