From 2c335db3bcfcc3fb411af96c14470e820ba430d0 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 25 Jun 2010 02:23:25 +0000 Subject: [PATCH] port to libusb-1.x (includes a small glue layer so libusb-0.x still works) git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@1801 b68d4a1b-bc3d-0410-92ed-d4ac073336b7 --- urjtag/ChangeLog | 11 ++ urjtag/configure.ac | 45 +++----- urjtag/src/tap/cable/ice100.c | 37 ++++--- urjtag/src/tap/cable/jlink.c | 57 +++++----- urjtag/src/tap/cable/xpc.c | 98 ++++++++-------- urjtag/src/tap/usbconn/libusb.c | 190 +++++++++++++++++++------------- urjtag/src/tap/usbconn/libusb.h | 85 +++++++++++++- 7 files changed, 328 insertions(+), 195 deletions(-) diff --git a/urjtag/ChangeLog b/urjtag/ChangeLog index fb031740..0c612657 100644 --- a/urjtag/ChangeLog +++ b/urjtag/ChangeLog @@ -1,3 +1,14 @@ +2010-06-24 Mike Frysinger + + * configure.ac: Merge libusb-0.x and libusb-1.x variables so that "libusb" + in the rest of the source tree isn't tied to a specific version. + * src/tap/cable/ice100.c: Convert API to libusb-1.x. + * src/tap/cable/jlink.c: Likewise. + * src/tap/cable/xpc.c: Likewise. + * src/tap/usbconn/libusb.c: Likewise. + * src/tap/usbconn/libusb.h: Create a small layer to convert the libusb-1.x + API to the older libusb-0.x API if we're building against that version. + 2010-06-23 Mike Frysinger * configure.ac (fmax): Drop fmax check as it is no longer used. diff --git a/urjtag/configure.ac b/urjtag/configure.ac index f890bf63..515ddeaa 100644 --- a/urjtag/configure.ac +++ b/urjtag/configure.ac @@ -163,7 +163,7 @@ AS_IF([test "x$ac_cv_header_windows_h" = "xyes"],[ VL_LIB_READLINE -dnl check for libusb +dnl check for libusb-0.x AC_ARG_WITH([libusb], [AS_HELP_STRING([--with-libusb], @@ -197,8 +197,7 @@ AS_IF([test "x$with_libusb" != xno -a "x$with_libusb" != x1.0], [ LIBS="$LIBS $LIBUSB_LIBS" CPPFLAGS="$CPPFLAGS $LIBUSB_CFLAGS" AC_CHECK_FUNC([usb_find_devices], [ - AC_DEFINE(HAVE_LIBUSB, 1, [Define if you have libusb]) - HAVELIBUSB=yes + HAVELIBUSB=0.1 ],[ AS_IF([test "x$with_libusb" = x0.1], [ AC_MSG_ERROR([*** libusb-0.1 not detected.]) @@ -209,25 +208,22 @@ AS_IF([test "x$with_libusb" != xno -a "x$with_libusb" != x1.0], [ CPPFLAGS=$save_CPPFLAGS ]) ],) -AM_CONDITIONAL(HAVE_LIBUSB, [test "x$HAVELIBUSB" = "xyes"]) - dnl check for libusb-1.0 -HAVELIBUSB1=no -AS_IF([test "x$with_libusb" != xno -a "x$with_libusb" != x0.1 -a "x$HAVELIBUSB" != "xyes"], [ +AS_IF([test "x$with_libusb" != xno -a "x$with_libusb" != x0.1 -a "x$HAVELIBUSB" = "xno"], [ save_LIBS=$LIBS save_CPPFLAGS=$CPPFLAGS - PKG_CHECK_MODULES(LIBUSB1, libusb-1.0, have_libusb1=yes, have_libusb1=no) - AS_IF([test "$have_libusb1" = "yes"],[ - LIBUSB_CFLAGS="$CFLAGS $LIBUSB1_CFLAGS" - LIBUSB_LIBS="$USB_LIBS $LIBUSB1_LIBS" + PKG_CHECK_MODULES(LIBUSB, libusb-1.0, have_libusb=yes, have_libusb=no) + AS_IF([test "$have_libusb" = "yes"],[ + LIBUSB_CFLAGS="$CFLAGS $LIBUSB_CFLAGS" + LIBUSB_LIBS="$USB_LIBS $LIBUSB_LIBS" ],) - LIBS="$LIBS $LIBUSB1_LIBS" - CPPFLAGS="$CPPFLAGS $LIBUSB1_CFLAGS" + LIBS="$LIBS $LIBUSB_LIBS" + CPPFLAGS="$CPPFLAGS $LIBUSB_CFLAGS" AC_CHECK_FUNC([libusb_get_device_list], [ AC_DEFINE(HAVE_LIBUSB1, 1, [Define if you have libusb-1.0]) - HAVELIBUSB1=yes + HAVELIBUSB=1.0 ],[ AS_IF([test "x$with_libusb" = x1.0], [ AC_MSG_ERROR([*** libusb-1.0 not detected.]) @@ -238,7 +234,10 @@ AS_IF([test "x$with_libusb" != xno -a "x$with_libusb" != x0.1 -a "x$HAVELIBUSB" CPPFLAGS=$save_CPPFLAGS ]) ],) -AM_CONDITIONAL(HAVE_LIBUSB1, [test "x$HAVELIBUSB1" = "xyes"]) +if test "x$HAVELIBUSB" != "xno"; then + AC_DEFINE(HAVE_LIBUSB, 1, [Define if you have libusb]) +fi +AM_CONDITIONAL(HAVE_LIBUSB, [test "x$HAVELIBUSB" != "xno"]) dnl Use FTDI library? @@ -275,13 +274,13 @@ AS_IF([test "x$with_libftdi" != xno], [ CPPFLAGS=$save_CPPFLAGS ]) AC_CHECK_FUNC([ftdi_read_data_submit], [ - AS_IF([test "x$HAVELIBUSB" = "xyes"], [ + AS_IF([test "x$HAVELIBUSB" = "x0.1"], [ AC_MSG_ERROR([this libftdi cannot be used with libusb-0.1, libusb-1.0 is needed]) ],) AC_DEFINE(HAVE_LIBFTDI_ASYNC_MODE, 1, [Define if libftdi support async mode]) HAVELIBFTDI_ASYNCMODE=yes ], [ - AS_IF([test "x$HAVELIBUSB1" = "xyes"], [ + AS_IF([test "x$HAVELIBUSB" = "x1.0"], [ AC_MSG_ERROR([this libftdi cannot be used with libusb-1.0, libusb-0.1 is needed. did you configure libftdi with --with-async-mode ?]) ],) @@ -665,7 +664,7 @@ URJ_DRIVER_SET([cable], [ AS_IF([test "x$HAVELIBFTDI" != "xyes" -a "x$HAVELIBFTD2XX" != "xyes"], [ drivers=`echo ${drivers} | $SED -e "s/ft2232//" -e "s/usbblaster//"` ]) - AS_IF([test "x$HAVELIBUSB" != "xyes"], [ + AS_IF([test "x$HAVELIBUSB" = "xno"], [ drivers=`echo ${drivers} | $SED -e "s/jlink//" -e "s/xpc//"` ]) ]) @@ -744,15 +743,7 @@ AC_OUTPUT dnl dnl Configuration summary dnl -AS_IF([test "x$HAVELIBUSB" = "xyes"], [ - FLAG_HAVELIBUSB=0.1 -], [ - AS_IF([test "x$HAVELIBUSB1" = "xyes"], [ - FLAG_HAVELIBUSB=1.0 - ],[ - FLAG_HAVELIBUSB=no - ]) -]) +FLAG_HAVELIBUSB=$HAVELIBUSB AS_IF([test "x$HAVELIBFTDI_ASYNCMODE" = "xyes"], [ FLAG_HAVELIBFTDI_ASYNCMODE="(have async mode)" ],[ diff --git a/urjtag/src/tap/cable/ice100.c b/urjtag/src/tap/cable/ice100.c index 23cac712..8014fad0 100644 --- a/urjtag/src/tap/cable/ice100.c +++ b/urjtag/src/tap/cable/ice100.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -183,7 +184,7 @@ static uint32_t do_single_reg_value (urj_cable_t *cable, uint8_t reg, int32_t r_ /* Ice USB controls */ #define ICE_100B_WRITE_ENDPOINT 0x06 -#define ICE_100B_READ_ENDPOINT 0x85 +#define ICE_100B_READ_ENDPOINT 0x05 #define ICE_100B_USB_WRITE_TIMEOUT 10000 #define ICE_100B_USB_READ_TIMEOUT 30000 #define ICE_100B_WRITE_BUFFER_SIZE 0x9800 @@ -191,7 +192,7 @@ static uint32_t do_single_reg_value (urj_cable_t *cable, uint8_t reg, int32_t r_ /* Kit 1.0 USB controls */ #define KIT_10_WRITE_ENDPOINT 0x02 -#define KIT_10_READ_ENDPOINT 0x86 +#define KIT_10_READ_ENDPOINT 0x06 #define KIT_10_USB_WRITE_TIMEOUT 50000 #define KIT_10_USB_READ_TIMEOUT 50000 #define KIT_10_WRITE_BUFFER_SIZE 0x40/*0x1000*/ @@ -199,7 +200,7 @@ static uint32_t do_single_reg_value (urj_cable_t *cable, uint8_t reg, int32_t r_ /* Kit 2.0 USB controls */ #define KIT_20_WRITE_ENDPOINT 0x01 -#define KIT_20_READ_ENDPOINT 0x82 +#define KIT_20_READ_ENDPOINT 0x02 #define KIT_20_USB_WRITE_TIMEOUT 50000 #define KIT_20_USB_READ_TIMEOUT 50000 #define KIT_20_WRITE_BUFFER_SIZE 0x2000 @@ -228,32 +229,34 @@ static bool kitInFastMode = false; #define adi_usb_read_or_ret(p, buf, len) \ do { \ - int __ret, __size = (len); \ - __ret = usb_bulk_read (((urj_usbconn_libusb_param_t *)p)->handle, \ - cable_params->r_ep, (char *)(buf), __size, \ - cable_params->r_timeout); \ - if (__ret != __size) \ + int __ret, __actual, __size = (len); \ + __ret = libusb_bulk_transfer (((urj_usbconn_libusb_param_t *)p)->handle, \ + cable_params->r_ep | LIBUSB_ENDPOINT_IN, \ + (unsigned char *)(buf), __size, \ + &__actual, cable_params->r_timeout); \ + if (__ret || __actual != __size) \ { \ urj_log (URJ_LOG_LEVEL_ERROR, \ - _("%s: unable to read from usb to " #buf ";" \ + _("%s: unable to read from usb to " #buf ": %i;" \ "wanted %i bytes but only received %i bytes"), \ - __func__, __size, __ret); \ + __func__, __ret, __size, __actual); \ return URJ_STATUS_FAIL; \ } \ } while (0) #define adi_usb_write_or_ret(p, buf, len) \ do { \ - int __ret, __size = (len); \ - __ret = usb_bulk_write (((urj_usbconn_libusb_param_t *)p)->handle, \ - cable_params->wr_ep, (char *)(buf), __size, \ - cable_params->wr_timeout); \ - if (__ret != __size) \ + int __ret, __actual, __size = (len); \ + __ret = libusb_bulk_transfer (((urj_usbconn_libusb_param_t *)p)->handle, \ + cable_params->wr_ep, \ + (unsigned char *)(buf), __size, \ + &__actual, cable_params->wr_timeout); \ + if (__ret || __actual != __size) \ { \ urj_log (URJ_LOG_LEVEL_ERROR, \ - _("%s: unable to write from " #buf " to usb;" \ + _("%s: unable to write from " #buf " to usb: %i;" \ "wanted %i bytes but only wrote %i bytes"), \ - __func__, __size, __ret); \ + __func__, __ret, __size, __actual); \ return URJ_STATUS_FAIL; \ } \ } while (0) diff --git a/urjtag/src/tap/cable/jlink.c b/urjtag/src/tap/cable/jlink.c index e41b2957..643d1635 100644 --- a/urjtag/src/tap/cable/jlink.c +++ b/urjtag/src/tap/cable/jlink.c @@ -31,6 +31,9 @@ #include +#include +#include + #include "generic.h" #include "generic_usbconn.h" @@ -44,11 +47,8 @@ #include "usbconn/libusb.h" -#include -#include - #define JLINK_WRITE_ENDPOINT 0x02 -#define JLINK_READ_ENDPOINT 0x81 +#define JLINK_READ_ENDPOINT (0x01 | LIBUSB_ENDPOINT_IN) #define JLINK_USB_TIMEOUT 100 @@ -61,8 +61,8 @@ typedef struct { /* Global USB buffers */ - char usb_in_buffer[JLINK_IN_BUFFER_SIZE]; - char usb_out_buffer[JLINK_OUT_BUFFER_SIZE]; + unsigned char usb_in_buffer[JLINK_IN_BUFFER_SIZE]; + unsigned char usb_out_buffer[JLINK_OUT_BUFFER_SIZE]; int tap_length; uint8_t tms_buffer[JLINK_TAP_BUFFER_SIZE]; @@ -109,7 +109,7 @@ static int jlink_usb_write (urj_usbconn_libusb_param_t *params, unsigned int); /** @return number of bytes read; -1 on error */ static int jlink_usb_read (urj_usbconn_libusb_param_t *params); -static void jlink_debug_buffer (char *buffer, int length); +static void jlink_debug_buffer (unsigned char *buffer, int length); /* API functions */ @@ -339,7 +339,7 @@ jlink_usb_message (urj_usbconn_libusb_param_t *params, int out_length, static int jlink_usb_write (urj_usbconn_libusb_param_t *params, unsigned int out_length) { - int result; + int result, actual; jlink_usbconn_data_t *data; data = params->data; @@ -353,16 +353,18 @@ jlink_usb_write (urj_usbconn_libusb_param_t *params, unsigned int out_length) return -1; } - result = usb_bulk_write (params->handle, - JLINK_WRITE_ENDPOINT, - data->usb_out_buffer, - out_length, JLINK_USB_TIMEOUT); + result = libusb_bulk_transfer (params->handle, + JLINK_WRITE_ENDPOINT, + data->usb_out_buffer, + out_length, &actual, + JLINK_USB_TIMEOUT); urj_log (URJ_LOG_LEVEL_DETAIL, - "jlink_usb_write, out_length = %d, result = %d\n", out_length, - result); + "jlink_usb_write, out_length = %d, result = %d, actual = %d\n", + out_length, result, actual); jlink_debug_buffer (data->usb_out_buffer, out_length); - return result; + + return actual; } /* ---------------------------------------------------------------------- */ @@ -373,15 +375,20 @@ jlink_usb_read (urj_usbconn_libusb_param_t *params) { jlink_usbconn_data_t *data = params->data; - int result = usb_bulk_read (params->handle, - JLINK_READ_ENDPOINT, - data->usb_in_buffer, - JLINK_IN_BUFFER_SIZE, - JLINK_USB_TIMEOUT); + int result, actual; - urj_log (URJ_LOG_LEVEL_DETAIL, "jlink_usb_read, result = %d\n", result); - jlink_debug_buffer (data->usb_in_buffer, result); - return result; + result = libusb_bulk_transfer (params->handle, + JLINK_READ_ENDPOINT, + data->usb_in_buffer, + JLINK_IN_BUFFER_SIZE, + &actual, + JLINK_USB_TIMEOUT); + + urj_log (URJ_LOG_LEVEL_DETAIL, "jlink_usb_read, result = %d, actual = %d\n", + result, actual); + jlink_debug_buffer (data->usb_in_buffer, actual); + + return actual; } /* ---------------------------------------------------------------------- */ @@ -389,7 +396,7 @@ jlink_usb_read (urj_usbconn_libusb_param_t *params) #define BYTES_PER_LINE 16 static void -jlink_debug_buffer (char *buffer, int length) +jlink_debug_buffer (unsigned char *buffer, int length) { char line[81]; char s[4]; @@ -448,7 +455,7 @@ jlink_init (urj_cable_t *cable) // retain error state urj_log (URJ_LOG_LEVEL_ERROR, "Resetting J-Link. Please retry the cable command.\n"); - usb_reset (params->handle); + libusb_reset_device (params->handle); return URJ_STATUS_FAIL; } diff --git a/urjtag/src/tap/cable/xpc.c b/urjtag/src/tap/cable/xpc.c index 3467416d..a46b0c4a 100644 --- a/urjtag/src/tap/cable/xpc.c +++ b/urjtag/src/tap/cable/xpc.c @@ -27,6 +27,9 @@ #include #include +#include +#include +#include #include #include @@ -37,9 +40,6 @@ #include #include "usbconn/libusb.h" -#include -#include - // #define VERBOSE 1 #undef VERBOSE typedef struct @@ -78,12 +78,12 @@ static int last_tdo; /* ---------------------------------------------------------------------- */ static int -xpcu_output_enable (struct usb_dev_handle *xpcu, int enable) +xpcu_output_enable (struct libusb_device_handle *xpcu, int enable) { - if (usb_control_msg + if (libusb_control_transfer (xpcu, 0x40, 0xB0, enable ? 0x18 : 0x10, 0, NULL, 0, 1000) < 0) { - urj_error_IO_set ("usb_control_msg(0x10/0x18)"); + urj_error_IO_set ("libusb_control_transfer(0x10/0x18)"); return URJ_STATUS_FAIL; } @@ -94,13 +94,13 @@ xpcu_output_enable (struct usb_dev_handle *xpcu, int enable) #ifdef UNUSED /* RFHH */ static int -xpcu_bit_reverse (struct usb_dev_handle *xpcu, uint8_t bits_in, +xpcu_bit_reverse (struct libusb_device_handle *xpcu, uint8_t bits_in, uint8_t *bits_out) { - if (usb_control_msg - (xpcu, 0xC0, 0xB0, 0x0020, bits_in, (char *) bits_out, 1, 1000) < 0) + if (libusb_control_transfer + (xpcu, 0xC0, 0xB0, 0x0020, bits_in, bits_out, 1, 1000) < 0) { - urj_error_IO_set ("usb_control_msg(0x20.x) (bit reverse)"); + urj_error_IO_set ("libusb_control_transfer(0x20.x) (bit reverse)"); return URJ_STATUS_FAIL; } @@ -111,13 +111,13 @@ xpcu_bit_reverse (struct usb_dev_handle *xpcu, uint8_t bits_in, /* ----------------------------------------------------------------- */ static int -xpcu_request_28 (struct usb_dev_handle *xpcu, int value) +xpcu_request_28 (struct libusb_device_handle *xpcu, int value) { /* Typical values seen during autodetection of chain configuration: 0x11, 0x12 */ - if (usb_control_msg (xpcu, 0x40, 0xB0, 0x0028, value, NULL, 0, 1000) < 0) + if (libusb_control_transfer (xpcu, 0x40, 0xB0, 0x0028, value, NULL, 0, 1000) < 0) { - urj_error_IO_set ("usb_control_msg(0x28.x)"); + urj_error_IO_set ("libusb_control_transfer(0x28.x)"); return URJ_STATUS_FAIL; } @@ -127,11 +127,11 @@ xpcu_request_28 (struct usb_dev_handle *xpcu, int value) /* ---------------------------------------------------------------------- */ static int -xpcu_write_gpio (struct usb_dev_handle *xpcu, uint8_t bits) +xpcu_write_gpio (struct libusb_device_handle *xpcu, uint8_t bits) { - if (usb_control_msg (xpcu, 0x40, 0xB0, 0x0030, bits, NULL, 0, 1000) < 0) + if (libusb_control_transfer (xpcu, 0x40, 0xB0, 0x0030, bits, NULL, 0, 1000) < 0) { - urj_error_IO_set ("usb_control_msg(0x30.0x00) (write port E)"); + urj_error_IO_set ("libusb_control_transfer(0x30.0x00) (write port E)"); return URJ_STATUS_FAIL; } @@ -141,12 +141,12 @@ xpcu_write_gpio (struct usb_dev_handle *xpcu, uint8_t bits) /* ---------------------------------------------------------------------- */ static int -xpcu_read_gpio (struct usb_dev_handle *xpcu, uint8_t *bits) +xpcu_read_gpio (struct libusb_device_handle *xpcu, uint8_t *bits) { - if (usb_control_msg (xpcu, 0xC0, 0xB0, 0x0038, 0, (char *) bits, 1, 1000) + if (libusb_control_transfer (xpcu, 0xC0, 0xB0, 0x0038, 0, bits, 1, 1000) < 0) { - urj_error_IO_set ("usb_control_msg(0x38.0x00) (read port E)"); + urj_error_IO_set ("libusb_control_transfer(0x38.0x00) (read port E)"); return URJ_STATUS_FAIL; } @@ -157,12 +157,12 @@ xpcu_read_gpio (struct usb_dev_handle *xpcu, uint8_t *bits) static int -xpcu_read_cpld_version (struct usb_dev_handle *xpcu, uint16_t *buf) +xpcu_read_cpld_version (struct libusb_device_handle *xpcu, uint16_t *buf) { - if (usb_control_msg - (xpcu, 0xC0, 0xB0, 0x0050, 0x0001, (char *) buf, 2, 1000) < 0) + if (libusb_control_transfer + (xpcu, 0xC0, 0xB0, 0x0050, 0x0001, (unsigned char *) buf, 2, 1000) < 0) { - urj_error_IO_set ("usb_control_msg(0x50.1) (read_cpld_version)"); + urj_error_IO_set ("libusb_control_transfer(0x50.1) (read_cpld_version)"); return URJ_STATUS_FAIL; } return URJ_STATUS_OK; @@ -171,12 +171,12 @@ xpcu_read_cpld_version (struct usb_dev_handle *xpcu, uint16_t *buf) /* ---------------------------------------------------------------------- */ static int -xpcu_read_firmware_version (struct usb_dev_handle *xpcu, uint16_t *buf) +xpcu_read_firmware_version (struct libusb_device_handle *xpcu, uint16_t *buf) { - if (usb_control_msg - (xpcu, 0xC0, 0xB0, 0x0050, 0x0000, (char *) buf, 2, 1000) < 0) + if (libusb_control_transfer + (xpcu, 0xC0, 0xB0, 0x0050, 0x0000, (unsigned char *) buf, 2, 1000) < 0) { - urj_error_IO_set ("usb_control_msg(0x50.0) (read_firmware_version)"); + urj_error_IO_set ("libusb_control_transfer(0x50.0) (read_firmware_version)"); return URJ_STATUS_FAIL; } @@ -186,12 +186,12 @@ xpcu_read_firmware_version (struct usb_dev_handle *xpcu, uint16_t *buf) /* ----------------------------------------------------------------- */ static int -xpcu_select_gpio (struct usb_dev_handle *xpcu, int int_or_ext) +xpcu_select_gpio (struct libusb_device_handle *xpcu, int int_or_ext) { - if (usb_control_msg (xpcu, 0x40, 0xB0, 0x0052, int_or_ext, NULL, 0, 1000) + if (libusb_control_transfer (xpcu, 0x40, 0xB0, 0x0052, int_or_ext, NULL, 0, 1000) < 0) { - urj_error_IO_set ("usb_control_msg(0x52.x) (select gpio)"); + urj_error_IO_set ("libusb_control_transfer(0x52.x) (select gpio)"); return URJ_STATUS_FAIL; } @@ -243,12 +243,14 @@ xpcu_select_gpio (struct usb_dev_handle *xpcu, int int_or_ext) /** @return 0 on success; -1 on error */ static int -xpcu_shift (struct usb_dev_handle *xpcu, int reqno, int bits, int in_len, +xpcu_shift (struct libusb_device_handle *xpcu, int reqno, int bits, int in_len, uint8_t *in, int out_len, uint8_t *out) { - if (usb_control_msg (xpcu, 0x40, 0xB0, reqno, bits, NULL, 0, 1000) < 0) + int ret, actual; + + if (libusb_control_transfer (xpcu, 0x40, 0xB0, reqno, bits, NULL, 0, 1000) < 0) { - urj_error_IO_set ("usb_control_msg(x.x) (shift)"); + urj_error_IO_set ("libusb_control_transfer(x.x) (shift)"); return -1; } @@ -268,17 +270,21 @@ xpcu_shift (struct usb_dev_handle *xpcu, int reqno, int bits, int in_len, } #endif - if (usb_bulk_write (xpcu, 0x02, (char *) in, in_len, 1000) < 0) + ret = libusb_bulk_transfer (xpcu, 0x02, in, in_len, &actual, 1000); + if (ret) { - urj_error_IO_set ("usb_bulk_write error(shift)"); + urj_error_IO_set ("usb_bulk_write error(shift): %i (transferred %i)", + ret, actual); return -1; } if (out_len > 0 && out != NULL) { - if (usb_bulk_read (xpcu, 0x86, (char *) out, out_len, 1000) < 0) + ret = libusb_bulk_transfer (xpcu, 0x06 | LIBUSB_ENDPOINT_IN, out, out_len, &actual, 1000); + if (ret) { - urj_error_IO_set ("usb_bulk_read error(shift)"); + urj_error_IO_set ("usb_bulk_read error(shift): %i (transferred %i)", + ret, actual); return -1; } } @@ -303,7 +309,7 @@ xpcu_common_init (urj_cable_t *cable) { int r; uint16_t buf; - struct usb_dev_handle *xpcu; + struct libusb_device_handle *xpcu; if (urj_tap_usbconn_open (cable->link.usb) != URJ_STATUS_OK) return URJ_STATUS_FAIL; @@ -342,7 +348,7 @@ xpcu_common_init (urj_cable_t *cable) if (r != URJ_STATUS_OK) { - usb_close (xpcu); + libusb_close (xpcu); } return r; @@ -351,7 +357,7 @@ xpcu_common_init (urj_cable_t *cable) static int xpc_int_init (urj_cable_t *cable) { - struct usb_dev_handle *xpcu; + struct libusb_device_handle *xpcu; if (xpcu_common_init (cable) == URJ_STATUS_FAIL) return URJ_STATUS_FAIL; @@ -366,7 +372,7 @@ xpc_int_init (urj_cable_t *cable) static int xpc_ext_init (urj_cable_t *cable) { - struct usb_dev_handle *xpcu; + struct libusb_device_handle *xpcu; uint8_t zero[2] = { 0, 0 }; int r; @@ -402,7 +408,7 @@ xpc_ext_init (urj_cable_t *cable) if (r != URJ_STATUS_OK) { - usb_close (xpcu); + libusb_close (xpcu); free (cable->params); cable->params = NULL; @@ -436,7 +442,7 @@ static void xpc_clock (urj_cable_t *cable, int tms, int tdi, int n) { int i; - struct usb_dev_handle *xpcu; + struct libusb_device_handle *xpcu; xpcu = ((urj_usbconn_libusb_param_t *) (cable->link.usb->params))->handle; tms = tms ? (1 << TMS) : 0; @@ -462,7 +468,7 @@ static int xpc_get_tdo (urj_cable_t *cable) { unsigned char d; - struct usb_dev_handle *xpcu; + struct libusb_device_handle *xpcu; xpcu = ((urj_usbconn_libusb_param_t *) (cable->link.usb->params))->handle; xpcu_read_gpio (xpcu, &d); @@ -485,7 +491,7 @@ xpc_ext_clock (urj_cable_t *cable, int tms, int tdi, int n) int i; uint8_t tdo[2]; uint8_t clock[2]; - struct usb_dev_handle *xpcu; + struct libusb_device_handle *xpcu; clock[0] = (tms ? 0x10 : 0) | (tdi ? 0x01 : 0); clock[1] = 0x11; /* clock'n read */ @@ -516,7 +522,7 @@ xpc_ext_get_tdo (urj_cable_t *cable) typedef struct { urj_cable_t *cable; - struct usb_dev_handle *xpcu; + struct libusb_device_handle *xpcu; int in_bits; int out_bits; int out_done; diff --git a/urjtag/src/tap/usbconn/libusb.c b/urjtag/src/tap/usbconn/libusb.c index edc1b3e2..bc28ccdd 100644 --- a/urjtag/src/tap/usbconn/libusb.c +++ b/urjtag/src/tap/usbconn/libusb.c @@ -33,69 +33,78 @@ #include #include #include -#include #include #include #include +#include "libusb.h" #include "../usbconn.h" -typedef struct +/* ---------------------------------------------------------------------- */ + +/* @return 1 when found, 0 when not */ +static int +libusb_match_desc (libusb_device_handle *handle, unsigned int id, const char *desc) { - struct usb_device *dev; - struct usb_dev_handle *handle; -} urj_usbconn_libusb_param_t; + int r; + char buf[256]; -/* ---------------------------------------------------------------------- */ + if (!id) + return 0; + r = libusb_get_string_descriptor_ascii (handle, id, (unsigned char *) buf, + sizeof (buf)); + if (r <= 0) + return 0; + + return strstr (buf, desc) ? 1 : 0; +} + +/* @return 1 when found, 0 when not */ static int -libusb_match_desc (struct usb_device *dev, const char *desc) +libusb_match (struct libusb_device *dev, urj_usbconn_cable_t *template) { int r = 0; - char buf[256]; - usb_dev_handle *handle; + struct libusb_device_descriptor *desc; + libusb_device_handle *handle; + +#ifdef HAVE_LIBUSB1 + struct libusb_device_descriptor _desc; + desc = &_desc; - if (desc == NULL) + if (libusb_get_device_descriptor (dev, desc)) + return 0; +#else + desc = &dev->descriptor; +#endif + + /* If VID specified but no match, return fail */ + if (template->vid >= 0 && desc->idVendor != template->vid) + return 0; + + /* If PID specified but no match, return fail */ + if (template->pid >= 0 && desc->idProduct != template->pid) + return 0; + + /* If desc not specified, then return pass */ + if (template->desc == NULL) return 1; - handle = usb_open (dev); - if (handle == NULL) + /* At this point, try to match the description */ + r = libusb_open (dev, &handle); + if (r) { - urj_error_set (URJ_ERROR_USB, "usb_open() failed: %s", usb_strerror()); + urj_error_set (URJ_ERROR_USB, "usb_open() failed: %i", r); errno = 0; return 0; } - if (dev->descriptor.iManufacturer) - { - r = usb_get_string_simple (handle, dev->descriptor.iManufacturer, buf, - sizeof (buf)); - if (r > 0) - { - if (strstr (buf, desc) == NULL) - r = 0; - } - } - if (r <= 0 && dev->descriptor.iProduct) - { - r = usb_get_string_simple (handle, dev->descriptor.iProduct, buf, - sizeof (buf)); - if (r > 0) - { - if (strstr (buf, desc) == NULL) - r = 0; - } - } - if (r <= 0 && dev->descriptor.iSerialNumber) - { - r = usb_get_string_simple (handle, dev->descriptor.iSerialNumber, buf, - sizeof (buf)); - if (r > 0) - { - if (strstr (buf, desc) == NULL) - r = 0; - } - } - usb_close (handle); + r = libusb_match_desc (handle, desc->iManufacturer, template->desc); + if (r <= 0) + r = libusb_match_desc (handle, desc->iProduct, template->desc); + if (r <= 0) + r = libusb_match_desc (handle, desc->iSerialNumber, template->desc); + libusb_close (handle); + return r > 0 ? 1 : 0; } @@ -106,44 +115,61 @@ static urj_usbconn_t * usbconn_libusb_connect (urj_usbconn_cable_t *template, const urj_param_t *params[]) { - struct usb_bus *bus; - struct usb_device *found_dev = NULL; + int ret; + struct libusb_device *found_dev = NULL; urj_usbconn_t *libusb_conn; urj_usbconn_libusb_param_t *libusb_params; + { /* Scope to make sure variables don't bleed across #ifdefs */ +#ifdef HAVE_LIBUSB1 + ssize_t num_devs, i; + libusb_device **list; + libusb_context *ctx; + + /* XXX: missing libusb_exit() */ + ret = libusb_init (&ctx); + if (ret) + { + urj_error_set (URJ_ERROR_USB, "libusb_init() failed: %i", ret); + errno = 0; + return NULL; + } + + num_devs = libusb_get_device_list (ctx, &list); + for (i = 0; i < num_devs; ++i) + { + struct libusb_device *dev = list[i]; + + if (libusb_match (dev, template)) + found_dev = libusb_ref_device (dev); + } + libusb_free_device_list (list, 0); +#else + struct usb_bus *bus; + usb_init (); - if (usb_find_busses () < 0) + if ((ret = usb_find_busses ()) < 0) { - urj_error_set (URJ_ERROR_USB, "usb_find_busses() failed: %s", - usb_strerror()); + urj_error_set (URJ_ERROR_USB, "usb_find_busses() failed: %i", ret); errno = 0; return NULL; } - if (usb_find_devices () < 0) + if ((ret = usb_find_devices ()) < 0) { - urj_error_set (URJ_ERROR_USB, "usb_find_devices() failed: %s", - usb_strerror()); + urj_error_set (URJ_ERROR_USB, "usb_find_devices() failed: %i", ret); errno = 0; return NULL; } for (bus = usb_get_busses (); bus && !found_dev; bus = bus->next) { - struct usb_device *dev; + struct libusb_device *dev; for (dev = bus->devices; dev && !found_dev; dev = dev->next) - { - if (((template->vid < 0) - || (dev->descriptor.idVendor == template->vid)) - && ((template->pid < 0) - || (dev->descriptor.idProduct == template->pid))) - { - if (libusb_match_desc (dev, template->desc)) - { - found_dev = dev; - } - } - } + if (libusb_match (dev, template)) + found_dev = dev; + } +#endif } if (!found_dev) @@ -182,32 +208,42 @@ usbconn_libusb_connect (urj_usbconn_cable_t *template, static int usbconn_libusb_open (urj_usbconn_t *conn) { + int ret; urj_usbconn_libusb_param_t *p = conn->params; - p->handle = usb_open (p->dev); - if (p->handle == NULL) + ret = libusb_open (p->dev, &p->handle); + if (ret) { - urj_error_set (URJ_ERROR_USB, "usb_open() failed: %s", usb_strerror()); + urj_error_set (URJ_ERROR_USB, "libusb_open() failed: %i", ret); errno = 0; } else { #if 1 - usb_set_configuration (p->handle, - p->dev->config[0].bConfigurationValue); + uint8_t configuration; +#ifdef HAVE_LIBUSB1 + struct libusb_config_descriptor *config; + libusb_get_active_config_descriptor (p->dev, &config); + configuration = config->bConfigurationValue; + libusb_free_config_descriptor (config); +#else + configuration = p->dev->config[0].bConfigurationValue; +#endif + libusb_set_configuration (p->handle, configuration); #endif - if (usb_claim_interface (p->handle, 0) != 0) + ret = libusb_claim_interface (p->handle, 0); + if (ret) { - usb_close (p->handle); - urj_error_set (URJ_ERROR_USB, "usb_claim_interface failed: %s", - usb_strerror()); + libusb_close (p->handle); + urj_error_set (URJ_ERROR_USB, "libusb_claim_interface failed: %i", + ret); errno = 0; p->handle = NULL; } #if 1 else { - usb_set_altinterface (p->handle, 0); + libusb_set_interface_alt_setting (p->handle, 0, 0); } #endif } @@ -229,8 +265,8 @@ usbconn_libusb_close (urj_usbconn_t *conn) urj_usbconn_libusb_param_t *p = conn->params; if (p->handle != NULL) { - usb_release_interface (p->handle, 0); - usb_close (p->handle); + libusb_release_interface (p->handle, 0); + libusb_close (p->handle); } p->handle = NULL; return URJ_STATUS_OK; diff --git a/urjtag/src/tap/usbconn/libusb.h b/urjtag/src/tap/usbconn/libusb.h index 6b447e94..636021c3 100644 --- a/urjtag/src/tap/usbconn/libusb.h +++ b/urjtag/src/tap/usbconn/libusb.h @@ -27,12 +27,91 @@ #ifndef URJ_USBCONN_LIBUSB_H #define URJ_USBCONN_LIBUSB_H 1 -#include +#ifdef HAVE_LIBUSB1 +# include +#else + +/* Glue the libusb-0.x API to the libusb-1.x API */ +# include + +# define LIBUSB_ENDPOINT_IN USB_ENDPOINT_IN + +# define libusb_device usb_device +# define libusb_device_handle usb_dev_handle +# define libusb_device_descriptor usb_device_descriptor + +# define libusb_reset_device(dev) usb_reset (dev) +# define libusb_close(dev) usb_close (dev) +# define libusb_set_configuration(dev, cfg) usb_set_configuration (dev, cfg) +# define libusb_claim_interface(dev, iface) usb_claim_interface (dev, iface) +# define libusb_set_interface_alt_setting(dev, prev, alt) usb_set_altinterface (dev, alt) +# define libusb_release_interface(dev, iface) usb_release_interface (dev, iface) + +static inline int +libusb_bulk_transfer (libusb_device_handle *dev_handle, unsigned char endpoint, + unsigned char *data, int length, int *actual_length, + unsigned int timeout) +{ + char *cdata = (char *)data; + int ret; + + if (endpoint & LIBUSB_ENDPOINT_IN) + ret = usb_bulk_read (dev_handle, endpoint, cdata, length, timeout); + else + ret = usb_bulk_write (dev_handle, endpoint, cdata, length, timeout); + + if (ret < 0) + { + *actual_length = 0; + return -ret; + } + else + { + *actual_length = ret; + return 0; + } +} + +static inline int +libusb_control_transfer (libusb_device_handle *dev_handle, uint8_t request_type, + uint8_t request, uint16_t value, uint16_t index, + unsigned char *data, uint16_t length, unsigned int timeout) +{ + char *cdata = (char *)data; + int ret; + + ret = usb_control_msg (dev_handle, request_type, request, value, index, + cdata, length, timeout); + + if (ret < 0) + return -ret; + else + return ret; +} + +static inline int +libusb_open (struct libusb_device *dev, libusb_device_handle **handle) +{ + *handle = usb_open (dev); + return *handle ? 0 : -99; +} + +static inline int +libusb_get_string_descriptor_ascii (libusb_device_handle *dev, uint8_t index, + unsigned char *data, int length) +{ + return usb_get_string_simple (dev, index, (char *) data, length); +} + +#endif + +/* XXX: libusb-1.x doesn't have a replacement ? :( */ +#define usb_strerror() dont_use_usb_strerror typedef struct { - struct usb_device *dev; - struct usb_dev_handle *handle; + struct libusb_device *dev; + struct libusb_device_handle *handle; void *data; } urj_usbconn_libusb_param_t;