libusb-1.0 support
authorMauro Gamba <maurillo71@gmail.com>
Wed, 16 Nov 2011 14:01:04 +0000 (15:01 +0100)
committerSpencer Oliver <spen@spen-soft.co.uk>
Fri, 18 Nov 2011 17:00:58 +0000 (17:00 +0000)
The configuration script check for libusb-1.0 availability first and only
if not found check for libusb-0. So if both libraries are installed on the
system the build script will use libusb-1.0
It's possible to force compiling with libusb-0 with the --enable-libusb0 switch.
If the driver support only libusb0 the script check anly for it.

Change-Id: I7eb045d4e2bd553abefad53f3f4023ff46b0f5f6
Signed-off-by: Mauro Gamba <maurillo71@gmail.com>
Reviewed-on: http://openocd.zylin.com/33
Tested-by: jenkins
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
configure.ac
src/Makefile.am
src/jtag/drivers/Makefile.am
src/jtag/drivers/libusb0_common.c [new file with mode: 0644]
src/jtag/drivers/libusb0_common.h [new file with mode: 0644]
src/jtag/drivers/libusb1_common.c [new file with mode: 0644]
src/jtag/drivers/libusb1_common.h [new file with mode: 0644]
src/jtag/drivers/libusb_common.h [new file with mode: 0644]

index d0386bcfe1ad89fea298d1362af51f0c0a32ed99..f061170db47ef118284b5e06a9773cd243fc2e10 100644 (file)
@@ -486,6 +486,10 @@ AC_ARG_ENABLE(internal-jimtcl,
   AS_HELP_STRING([--disable-internal-jimtcl], [Disable building internal jimtcl]),
   [use_internal_jimtcl=$enableval], [use_internal_jimtcl=yes])
 
+AC_ARG_ENABLE(libusb0,
+  AS_HELP_STRING([--enable-libusb0], [Use libusb-0.1 library for USB JTAG devices]),
+  [check_libusb0=$enableval], [check_libusb0=no])
+
 build_minidriver=no
 AC_MSG_CHECKING([whether to enable ZY1000 minidriver])
 if test $build_zy1000 = yes; then
@@ -1055,11 +1059,28 @@ build_usb=no
 if test $build_jlink = yes -o $build_vsllink = yes -o $build_usbprog = yes -o \
   $build_rlink = yes -o $build_ulink = yes -o $build_armjtagew = yes
 then
-  AC_CHECK_HEADERS([usb.h],[],
-  [AC_MSG_ERROR([usb.h is required to build some OpenOCD driver(s)])])
   build_usb=yes
 fi
 
+# Check for libusb1 ported drivers.
+build_usb_ng=no
+
+# check for libusb library if necessary
+use_libusb0=no
+use_libusb1=no
+if test $build_usb = yes -o $build_usb_ng = yes; then
+  if test $check_libusb0 = no -a $build_usb_ng = yes; then
+       AC_CHECK_HEADERS(libusb-1.0/libusb.h,
+                       [AC_DEFINE(HAVE_LIBUSB1, 1, [Define if you have libusb-1.0]) check_libusb0=no use_libusb1=yes ],
+                       [ check_libusb0=yes use_libusb1=no ])
+  fi
+
+  if test $check_libusb0 = yes -o $build_usb = yes; then
+       AC_CHECK_HEADERS(usb.h, [use_libusb0=yes],
+                       [AC_MSG_ERROR([libusb or libusb-1.0 are required to build some OpenOCD driver(s)])])
+  fi
+fi
+
 AM_CONDITIONAL(RELEASE, test $build_release = yes)
 AM_CONDITIONAL(PARPORT, test $build_parport = yes)
 AM_CONDITIONAL(DUMMY, test $build_dummy = yes)
@@ -1089,6 +1110,9 @@ AM_CONDITIONAL(ARMJTAGEW, test $build_armjtagew = yes)
 AM_CONDITIONAL(REMOTE_BITBANG, test $build_remote_bitbang = yes)
 AM_CONDITIONAL(BUSPIRATE, test $build_buspirate = yes)
 AM_CONDITIONAL(USB, test $build_usb = yes)
+AM_CONDITIONAL(USB_NG, test $build_usb_ng = yes)
+AM_CONDITIONAL(USE_LIBUSB0, test $use_libusb0 = yes)
+AM_CONDITIONAL(USE_LIBUSB1, test $use_libusb1 = yes)
 AM_CONDITIONAL(IS_CYGWIN, test $is_cygwin = yes)
 AM_CONDITIONAL(IS_MINGW, test $is_mingw = yes)
 AM_CONDITIONAL(IS_WIN32, test $is_win32 = yes)
index 8375683d07e79dbfec6e16669df07d2512e00d36..3a92fffee3c43bd426a6f22c1001449fef026d7e 100644 (file)
@@ -81,26 +81,13 @@ endif
 endif
 endif
 
-if USBPROG
-LIBUSB = -lusb
-else
-if JLINK
-LIBUSB = -lusb
-else
-if RLINK
-LIBUSB = -lusb
-else
-if ULINK
-LIBUSB = -lusb
-else
-if VSLLINK
-LIBUSB = -lusb
-else
 LIBUSB =
+if USE_LIBUSB1
+LIBUSB += -lusb-1.0
 endif
-endif
-endif
-endif
+
+if USE_LIBUSB0
+LIBUSB += -lusb
 endif
 
 libopenocd_la_LIBADD = \
index 408ea8100936434ccef060d7ef56c29aaf2607c3..1f239b7b0e2042abb675c750e5562e0b418d5a15 100644 (file)
@@ -20,6 +20,16 @@ if USB
 DRIVERFILES += usb_common.c
 endif
 
+if USE_LIBUSB1
+DRIVERFILES += libusb1_common.c
+else
+
+if USE_LIBUSB0
+DRIVERFILES += libusb0_common.c
+endif
+
+endif
+
 if BITBANG
 DRIVERFILES += bitbang.c
 endif
diff --git a/src/jtag/drivers/libusb0_common.c b/src/jtag/drivers/libusb0_common.c
new file mode 100644 (file)
index 0000000..8ed60df
--- /dev/null
@@ -0,0 +1,109 @@
+/***************************************************************************
+ *   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, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "log.h"
+#include "libusb0_common.h"
+
+static bool jtag_libusb_match(struct jtag_libusb_device *dev,
+               const uint16_t vids[], const uint16_t pids[])
+{
+       for (unsigned i = 0; vids[i] && pids[i]; i++) {
+               if (dev->descriptor.idVendor == vids[i] &&
+                       dev->descriptor.idProduct == pids[i]) {
+                       return true;
+               }
+       }
+       return false;
+}
+
+int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[],
+               struct jtag_libusb_device_handle **out)
+{
+       usb_init();
+
+       usb_find_busses();
+       usb_find_devices();
+
+       struct usb_bus *busses = usb_get_busses();
+       for (struct usb_bus *bus = busses; bus; bus = bus->next) {
+               for (struct usb_device *dev = bus->devices;
+                    dev; dev = dev->next) {
+                       if (!jtag_libusb_match(dev, vids, pids))
+                               continue;
+
+                       *out = usb_open(dev);
+                       if (NULL == *out)
+                               return -errno;
+                       return 0;
+               }
+       }
+       return -ENODEV;
+}
+
+void jtag_libusb_close(jtag_libusb_device_handle *dev)
+{
+       /* Close device */
+       jtag_libusb_close(dev);
+}
+
+int jtag_libusb_bulk_write(jtag_libusb_device_handle *dev, int ep, char *bytes,
+                                               int size, int timeout)
+{
+       return usb_bulk_write(dev, ep, bytes, size, timeout);
+}
+
+int jtag_libusb_bulk_read(jtag_libusb_device_handle *dev, int ep, char *bytes,
+                                          int size, int timeout)
+{
+       return usb_bulk_read(dev, ep, bytes, size, timeout);
+}
+
+int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh,
+                                 int configuration)
+{
+       struct jtag_libusb_device *udev = jtag_libusb_get_device(devh);
+
+       return usb_set_configuration(devh,
+                       udev->config[configuration].bConfigurationValue);
+}
+
+int jtag_libusb_get_endpoints(struct jtag_libusb_device *udev,
+                                                  unsigned int *usb_read_ep,
+                                                  unsigned int *usb_write_ep)
+{
+       struct usb_interface *iface = udev->config->interface;
+       struct usb_interface_descriptor *desc = iface->altsetting;
+
+       for (int i = 0; i < desc->bNumEndpoints; i++) {
+               uint8_t epnum = desc->endpoint[i].bEndpointAddress;
+               bool is_input = epnum & 0x80;
+               LOG_DEBUG("usb ep %s %02x", is_input ? "in" : "out", epnum);
+               if (is_input)
+                       *usb_read_ep = epnum;
+               else
+                       *usb_write_ep = epnum;
+       }
+
+       return 0;
+}
diff --git a/src/jtag/drivers/libusb0_common.h b/src/jtag/drivers/libusb0_common.h
new file mode 100644 (file)
index 0000000..9cf235e
--- /dev/null
@@ -0,0 +1,58 @@
+/***************************************************************************
+ *   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, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef JTAG_LIBUSB_COMMON_H
+#define JTAG_LIBUSB_COMMON_H
+
+#include <helper/types.h>
+#include <usb.h>
+
+#define jtag_libusb_device                     usb_device
+#define jtag_libusb_device_handle              usb_dev_handle
+#define jtag_libusb_device_descriptor          usb_device_descriptor
+#define jtag_libusb_interface                  usb_interface
+#define jtag_libusb_interface_descriptor       usb_interface_descriptor
+#define jtag_libusb_endpoint_descriptor                usb_endpoint_descriptor
+#define jtag_libusb_config_descriptor          usb_config_descriptor
+
+#define jtag_libusb_reset_device(dev)          usb_reset(dev)
+#define jtag_libusb_get_device(devh)           usb_device(devh)
+
+inline int jtag_libusb_claim_interface(jtag_libusb_device_handle *devh,
+                                      int iface)
+{
+       return usb_claim_interface(devh, iface);
+};
+
+int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[],
+                    struct jtag_libusb_device_handle **out);
+void jtag_libusb_close(jtag_libusb_device_handle *dev);
+int jtag_libusb_bulk_write(struct jtag_libusb_device_handle *dev, int ep,
+                          char *bytes, int size, int timeout);
+int jtag_libusb_bulk_read(struct jtag_libusb_device_handle *dev, int ep,
+                         char *bytes, int size, int timeout);
+int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh,
+                                 int configuration);
+int jtag_libusb_get_endpoints(struct jtag_libusb_device *udev,
+                             unsigned int *usb_read_ep,
+                             unsigned int *usb_write_ep);
+
+#endif /* JTAG_USB_COMMON_H */
diff --git a/src/jtag/drivers/libusb1_common.c b/src/jtag/drivers/libusb1_common.c
new file mode 100644 (file)
index 0000000..c6cb494
--- /dev/null
@@ -0,0 +1,152 @@
+/***************************************************************************
+ *   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, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "log.h"
+#include "libusb1_common.h"
+
+static struct libusb_context *jtag_libusb_context; /**< Libusb context **/
+static libusb_device **devs; /**< The usb device list **/
+
+static bool jtag_libusb_match(struct jtag_libusb_device *dev,
+               const uint16_t vids[], const uint16_t pids[])
+{
+       struct libusb_device_descriptor dev_desc;
+
+       for (unsigned i = 0; vids[i] && pids[i]; i++) {
+               if (libusb_get_device_descriptor(dev, &dev_desc) == 0) {
+                       if (dev_desc.idVendor == vids[i] &&
+                               dev_desc.idProduct == pids[i])
+                               return true;
+               }
+       }
+       return false;
+}
+
+int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[],
+               struct jtag_libusb_device_handle **out)
+{
+       int cnt, idx, errCode;
+
+       if (libusb_init(&jtag_libusb_context) < 0)
+               return -ENODEV;
+
+       libusb_set_debug(jtag_libusb_context, 3);
+
+       cnt = libusb_get_device_list(jtag_libusb_context, &devs);
+
+       for (idx = 0; idx < cnt; idx++) {
+               if (!jtag_libusb_match(devs[idx], vids, pids))
+                       continue;
+
+               errCode = libusb_open(devs[idx], out);
+
+               /** Free the device list **/
+               libusb_free_device_list(devs, 1);
+
+               if (errCode < 0)
+                       return errCode;
+               return 0;
+       }
+       return -ENODEV;
+}
+
+void jtag_libusb_close(jtag_libusb_device_handle *dev)
+{
+       /* Close device */
+       jtag_libusb_close(dev);
+
+       libusb_exit(jtag_libusb_context);
+}
+
+int jtag_libusb_bulk_write(jtag_libusb_device_handle *dev, int ep, char *bytes,
+                          int size, int timeout)
+{
+       int transferred = 0;
+
+       libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size,
+                            &transferred, timeout);
+       return transferred;
+}
+
+int jtag_libusb_bulk_read(jtag_libusb_device_handle *dev, int ep, char *bytes,
+                         int size, int timeout)
+{
+       int transferred = 0;
+
+       libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size,
+                            &transferred, timeout);
+       return transferred;
+}
+
+int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh,
+                                 int configuration)
+{
+       struct jtag_libusb_device *udev = jtag_libusb_get_device(devh);
+       int retCode = -99;
+
+       struct libusb_config_descriptor *config;
+
+       libusb_get_config_descriptor(udev, configuration, &config);
+       retCode = libusb_set_configuration(devh, config->bConfigurationValue);
+
+       libusb_free_config_descriptor(config);
+
+       return retCode;
+}
+
+int jtag_libusb_get_endpoints(struct jtag_libusb_device *udev,
+                             unsigned int *usb_read_ep,
+                             unsigned int *usb_write_ep)
+{
+       const struct libusb_interface *inter;
+       const struct libusb_interface_descriptor *interdesc;
+       const struct libusb_endpoint_descriptor *epdesc;
+       struct libusb_config_descriptor *config;
+
+       libusb_get_config_descriptor(udev, 0, &config);
+       for (int i = 0; i < (int)config->bNumInterfaces; i++) {
+               inter = &config->interface[i];
+
+               for (int j = 0; j < inter->num_altsetting; j++) {
+                       interdesc = &inter->altsetting[j];
+                       for (int k = 0;
+                               k < (int)interdesc->bNumEndpoints; k++) {
+                               epdesc = &interdesc->endpoint[k];
+
+                               uint8_t epnum = epdesc->bEndpointAddress;
+                               bool is_input = epnum & 0x80;
+                               LOG_DEBUG("usb ep %s %02x",
+                                       is_input ? "in" : "out", epnum);
+
+                               if (is_input)
+                                       *usb_read_ep = epnum;
+                               else
+                                       *usb_write_ep = epnum;
+                       }
+               }
+       }
+       libusb_free_config_descriptor(config);
+
+       return 0;
+}
diff --git a/src/jtag/drivers/libusb1_common.h b/src/jtag/drivers/libusb1_common.h
new file mode 100644 (file)
index 0000000..89e8c1e
--- /dev/null
@@ -0,0 +1,58 @@
+/***************************************************************************
+ *   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, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef JTAG_LIBUSB_COMMON_H
+#define JTAG_LIBUSB_COMMON_H
+
+#include <helper/types.h>
+#include <libusb-1.0/libusb.h>
+
+#define jtag_libusb_device                     libusb_device
+#define jtag_libusb_device_handle              libusb_device_handle
+#define jtag_libusb_device_descriptor          libusb_device_descriptor
+#define jtag_libusb_interface                  libusb_interface
+#define jtag_libusb_interface_descriptor       libusb_interface_descriptor
+#define jtag_libusb_endpoint_descriptor                libusb_endpoint_descriptor
+#define jtag_libusb_config_descriptor          libusb_config_descriptor
+
+#define jtag_libusb_reset_device(dev)          libusb_reset_device(dev)
+#define jtag_libusb_get_device(devh)           libusb_get_device(devh)
+
+inline int jtag_libusb_claim_interface(jtag_libusb_device_handle *devh,
+                                      int iface)
+{
+       return libusb_claim_interface(devh, iface);
+};
+
+int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[],
+                    struct jtag_libusb_device_handle **out);
+void jtag_libusb_close(jtag_libusb_device_handle *dev);
+int jtag_libusb_bulk_write(struct jtag_libusb_device_handle *dev, int ep,
+                          char *bytes, int size, int timeout);
+int jtag_libusb_bulk_read(struct jtag_libusb_device_handle *dev, int ep,
+                         char *bytes, int size, int timeout);
+int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh,
+                                 int configuration);
+int jtag_libusb_get_endpoints(struct jtag_libusb_device *udev,
+                             unsigned int *usb_read_ep,
+                             unsigned int *usb_write_ep);
+
+#endif /* JTAG_USB_COMMON_H */
diff --git a/src/jtag/drivers/libusb_common.h b/src/jtag/drivers/libusb_common.h
new file mode 100644 (file)
index 0000000..7e172d6
--- /dev/null
@@ -0,0 +1,24 @@
+/***************************************************************************
+ *   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, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifdef HAVE_LIBUSB1
+#include <libusb1_common.h>
+#else
+#include <libusb0_common.h>
+#endif

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)