This is an automated email from Gerrit.

Stephen Tridgell (stephen.tridg...@exablaze.com) just uploaded a new patch set 
to Gerrit, which you can find at http://openocd.zylin.com/2547

-- gerrit

commit 1b86e37d3fdbfb0c361fd825f884ddfe6711d36f
Author: Stephen Tridgell <stephen.tridg...@exablaze.com>
Date:   Fri Feb 13 12:04:41 2015 +1100

    topic: Added a method to specify the device path for ftdi device
    
    I had an issue with two devices with the same PID and VID and varying
    serial numbers (swapping devices) but the position determined the
    purpose. Hence i use the libusb device path to specify which one
    
    Change-Id: I866bf7f2d2b8d12b018cb6ab0729066078938e48
    Signed-off-by: Stephen Tridgell <stephen.tridg...@exablaze.com>

diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c
index 7df6389..7da9f6b 100644
--- a/src/jtag/drivers/ftdi.c
+++ b/src/jtag/drivers/ftdi.c
@@ -83,6 +83,7 @@
 #include <assert.h>
 
 /* FTDI access library includes */
+#include <libusb.h>
 #include "mpsse.h"
 
 #define JTAG_MODE (LSB_FIRST | POS_EDGE_IN | NEG_EDGE_OUT)
@@ -90,6 +91,7 @@
 
 static char *ftdi_device_desc;
 static char *ftdi_serial;
+static char *ftdi_device_path;
 static uint8_t ftdi_channel;
 
 static bool swd_mode;
@@ -626,7 +628,11 @@ static int ftdi_initialize(void)
 
        for (int i = 0; ftdi_vid[i] || ftdi_pid[i]; i++) {
                mpsse_ctx = mpsse_open(&ftdi_vid[i], &ftdi_pid[i], 
ftdi_device_desc,
-                               ftdi_serial, ftdi_channel);
+                                      ftdi_serial,
+#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000102) /* 
require version libusb 1.0.16 */
+                                      ftdi_device_path,
+#endif
+                                      ftdi_channel);
                if (mpsse_ctx)
                        break;
        }
@@ -678,6 +684,24 @@ COMMAND_HANDLER(ftdi_handle_device_desc_command)
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(ftdi_handle_device_path_command)
+{
+#ifndef LIBUSB_API_VERSION
+       LOG_WARNING("ftdi_handle_device_path requires libusb >= 1.0.16");
+#elif LIBUSB_API_VERSION < 0x01000102
+       LOG_WARNING("ftdi_handle_device_path requires libusb >= 1.0.16");
+#endif
+       if (CMD_ARGC == 1) {
+               if (ftdi_device_path)
+                       free(ftdi_device_path);
+               ftdi_device_path = strdup(CMD_ARGV[0]);
+       } else {
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       return ERROR_OK;
+}
+
 COMMAND_HANDLER(ftdi_handle_serial_command)
 {
        if (CMD_ARGC == 1) {
@@ -876,7 +900,13 @@ static const struct command_registration 
ftdi_command_handlers[] = {
                .usage = "name (1|0|z)",
        },
        {
-               .name = "ftdi_vid_pid",
+               .name = "ftdi_device_path",
+               .handler = &ftdi_handle_device_path_command,
+               .mode = COMMAND_CONFIG,
+               .help = "set the device path of the FTDI device",
+               .usage = "device_path_string",
+       },
+       {               .name = "ftdi_vid_pid",
                .handler = &ftdi_handle_vid_pid_command,
                .mode = COMMAND_CONFIG,
                .help = "the vendor ID and product ID of the FTDI device",
diff --git a/src/jtag/drivers/mpsse.c b/src/jtag/drivers/mpsse.c
index d9f73a2..39abb1e 100644
--- a/src/jtag/drivers/mpsse.c
+++ b/src/jtag/drivers/mpsse.c
@@ -66,6 +66,8 @@
 #define SIO_RESET_PURGE_RX 1
 #define SIO_RESET_PURGE_TX 2
 
+#define USB_PORT_MAX 7 /* according to USB 3.0 specs */
+
 struct mpsse_ctx {
        libusb_context *usb_ctx;
        libusb_device_handle *usb_dev;
@@ -104,12 +106,52 @@ static bool string_descriptor_equal(libusb_device_handle 
*device, uint8_t str_in
        return strncmp(string, desc_string, sizeof(desc_string)) == 0;
 }
 
+#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000102) /* 
require version libusb 1.0.16 */
+/* Determines if a device path for the format bus-port.port.port (eg 1-1.2) 
matches the device */
+static bool device_path_match(libusb_device *device, const char * device_path)
+{
+       uint8_t ports[USB_PORT_MAX];
+       int req_ports[USB_PORT_MAX];
+       uint8_t bus_no = libusb_get_bus_number(device);
+       int req_bus_no;
+       int offset, no_read_chars, no_returned;
+       no_returned = sscanf(device_path, "%i%n", &req_bus_no, &no_read_chars);
+       offset = no_read_chars;
+       /* Invalid string or wrong bus */
+       if (req_bus_no < 1 || no_returned != 1 || req_bus_no != bus_no)
+         return false;
+       /* read port numbers */
+       int no_port = libusb_get_port_numbers(device, ports, USB_PORT_MAX);
+       int dev_path_len = strlen(device_path);
+       for (int i = 0; i < USB_PORT_MAX; i++) {
+         no_returned = sscanf((device_path + offset), "%*[-.]%i%n", 
&(req_ports[i]), &no_read_chars);
+         offset += no_read_chars;
+         if (no_returned != 1) {           /* Either end of string or bad 
format */
+           if (i == (no_port - 1))
+             return true;                 /* String matched -> end of string */
+           else
+             return false;                /* Not exact match as there is more 
to come */
+         }
+         if (req_ports[i] != ports[i])    /* Invalid string or wrong port */
+           return false;
+         if (offset >= (dev_path_len - 1))
+           break;
+       }
+       return true;
+}
+#endif
+
+
 /* Helper to open a libusb device that matches vid, pid, product string and/or 
serial string.
  * 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,
-       const char *product, const char *serial)
+       const char *product, const char *serial
+#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000102) /* 
require version libusb 1.0.16 */
+        , const char *device_path            /* Device path of same format as 
system ie bus-port.port.port */
+#endif
+       )
 {
        libusb_device **list;
        struct libusb_device_descriptor desc;
@@ -140,7 +182,12 @@ static bool open_matching_device(struct mpsse_ctx *ctx, 
const uint16_t *vid, con
                                  libusb_error_name(err));
                        continue;
                }
-
+#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000102) /* 
require version libusb 1.0.16 */
+               if (device_path && !device_path_match(device, device_path)) {
+                       libusb_close(ctx->usb_dev);
+                       continue;
+               }
+#endif
                if (product && !string_descriptor_equal(ctx->usb_dev, 
desc.iProduct, product)) {
                        libusb_close(ctx->usb_dev);
                        continue;
@@ -263,7 +310,11 @@ error:
 }
 
 struct mpsse_ctx *mpsse_open(const uint16_t *vid, const uint16_t *pid, const 
char *description,
-       const char *serial, int channel)
+       const char *serial,
+#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000102) /* 
require version libusb 1.0.16 */
+       const char *device_path,            /* Device path of same format as 
system ie bus-port.port.port */
+#endif
+       int channel)
 {
        struct mpsse_ctx *ctx = calloc(1, sizeof(*ctx));
        int err;
@@ -291,8 +342,11 @@ struct mpsse_ctx *mpsse_open(const uint16_t *vid, const 
uint16_t *pid, const cha
                LOG_ERROR("libusb_init() failed with %s", 
libusb_error_name(err));
                goto error;
        }
-
+#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000102) /* 
require version libusb 1.0.16 */
+       if (!open_matching_device(ctx, vid, pid, description, serial, 
device_path)) {
+#else
        if (!open_matching_device(ctx, vid, pid, description, serial)) {
+#endif
                /* Four hex digits plus terminating zero each */
                char vidstr[5];
                char pidstr[5];
diff --git a/src/jtag/drivers/mpsse.h b/src/jtag/drivers/mpsse.h
index 3e287f7..a5de4a6 100644
--- a/src/jtag/drivers/mpsse.h
+++ b/src/jtag/drivers/mpsse.h
@@ -23,6 +23,7 @@
 
 #include <stdbool.h>
 #include "helper/binarybuffer.h"
+#include <libusb.h>
 
 /* Mode flags */
 #define POS_EDGE_OUT 0x00
@@ -43,7 +44,11 @@ struct mpsse_ctx;
 
 /* Device handling */
 struct mpsse_ctx *mpsse_open(const uint16_t *vid, const uint16_t *pid, const 
char *description,
-       const char *serial, int channel);
+       const char *serial,
+#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000102) /* 
require version libusb 1.0.16 */
+       const char *device_path,            /* Device path of same format as 
system ie bus-port.port.port */
+#endif
+       int channel);
 void mpsse_close(struct mpsse_ctx *ctx);
 bool mpsse_is_high_speed(struct mpsse_ctx *ctx);
 

-- 

------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to