On 02/08/2010 11:02 PM, Jie Zhang wrote:
Hi,

I have ported libftdi to libusb-1.0. The work is hosted in the following
repository:

git://developer.intra2net.com/libftdi-1.0

My work brought asynchronous transfer to libftdi. I explained how this
would help UrJTAG in this email:

http://developer.intra2net.com/mailarchive/html/libftdi/2010/msg00065.html

Now I propose a patch for UrJTAG to use this new libftdi to improve the
performance. When using the new libftdi, gdbproxy reads memory at about
110.2KB/s. Compared with previous 10.3KB/s, I would say it's a big
improvement.

This UrJTAG patch, which is attached in this email, does not change the
default settings. But it changes --with-libusb to to accept "1.0" and
"0.1". This patch also checks if libftdi is the new one. It will check
if the combination of libusb version and libftdi version is good. For
example, libusb-1.0 cannot be used with the old libftdi. libusb-0.1
cannot be used with the new libftdi. It changes usbconn_ftdi_flush to
utilize the asynchronous mode of the new libftdi. So we can enlarge the
receive buffer to (63 * 64). See the email on the above URL for further
explanation.

Since this patch does not change the default settings of UrJTAG, it's
not intrusive. I'm going to commit it in 24 ~ 48 hours if no one objects.

Here is an update of the patch. The new patch will error out when the specified libusb does not exist. Otherwise, it's same as previous one.


Jie
  * src/tap/usbconn/libftdx.h (URJ_USBCONN_FTDI_MAXRECV): Define
    to be (63 * 64) if HAVE_LIBFTDI_ASYNC_MODE defined.
  * src/tap/usbconn/libftdi.c (usbconn_ftdi_flush): Use async
    mode libftdi if HAVE_LIBFTDI_ASYNC_MODE defined.
  * configure.ac: Check libusb-1.0 and libftdi async mode.

Index: src/tap/usbconn/libftdx.h
===================================================================
--- src/tap/usbconn/libftdx.h	(revision 1768)
+++ src/tap/usbconn/libftdx.h	(working copy)
@@ -30,7 +30,11 @@
    Larger values might speed up comm, but there's an upper limit
    when too many bytes are sent and the underlying libftdi or libftd2xx
    don't fetch the returned data in time -> deadlock */
+#ifdef HAVE_LIBFTDI_ASYNC_MODE
+#define URJ_USBCONN_FTDI_MAXRECV   (63 * 64)
+#else
 #define URJ_USBCONN_FTDI_MAXRECV   ( 4 * 64)
+#endif
 #define URJ_USBCONN_FTD2XX_MAXRECV (63 * 64)
 #define URJ_USBCONN_FTDX_MAXRECV   (URJ_USBCONN_FTD2XX_MAXRECV < URJ_USBCONN_FTDI_MAXRECV ? URJ_USBCONN_FTD2XX_MAXRECV : URJ_USBCONN_FTDI_MAXRECV)
 
Index: src/tap/usbconn/libftdi.c
===================================================================
--- src/tap/usbconn/libftdi.c	(revision 1768)
+++ src/tap/usbconn/libftdi.c	(working copy)
@@ -68,6 +68,9 @@ usbconn_ftdi_flush (ftdi_param_t *p)
 {
     int xferred;
     int recvd = 0;
+#ifdef HAVE_LIBFTDI_ASYNC_MODE
+    struct ftdi_transfer_control *tc;
+#endif
 
     if (!p->fc)
         return -1;
@@ -75,6 +78,7 @@ usbconn_ftdi_flush (ftdi_param_t *p)
     if (p->send_buffered == 0)
         return 0;
 
+#ifndef HAVE_LIBFTDI_ASYNC_MODE
     if ((xferred = ftdi_write_data (p->fc, p->send_buf, p->send_buffered)) < 0)
         urj_error_set (URJ_ERROR_FTD, _("ftdi_write_data() failed: %s"),
                        ftdi_get_error_string (p->fc));
@@ -87,6 +91,7 @@ usbconn_ftdi_flush (ftdi_param_t *p)
     }
 
     p->send_buffered = 0;
+#endif
 
     /* now read all scheduled receive bytes */
     if (p->to_recv)
@@ -106,6 +111,30 @@ usbconn_ftdi_flush (ftdi_param_t *p)
             return -1;
         }
 
+#ifdef HAVE_LIBFTDI_ASYNC_MODE
+        if ((tc = ftdi_read_data_submit (p->fc,
+                                         &(p->recv_buf[p->recv_write_idx]),
+                                         p->to_recv)) == NULL)
+            urj_error_set (URJ_ERROR_FTD,
+                           _("Error from ftdi_read_data_submit(): %s"),
+                           ftdi_get_error_string (p->fc));
+    }
+
+    if ((xferred = ftdi_write_data (p->fc, p->send_buf, p->send_buffered)) < 0)
+        perror (ftdi_get_error_string (p->fc));
+
+    if (xferred < p->send_buffered)
+    {
+        urj_error_set (URJ_ERROR_FTD, _("Written fewer bytes than requested."));
+        return -1;
+    }
+
+    p->send_buffered = 0;
+
+    if (p->to_recv)
+    {
+        recvd = ftdi_transfer_data_done (tc);
+#else
         while (recvd == 0)
             if ((recvd = ftdi_read_data (p->fc,
                                          &(p->recv_buf[p->recv_write_idx]),
@@ -113,6 +142,7 @@ usbconn_ftdi_flush (ftdi_param_t *p)
                 urj_error_set (URJ_ERROR_FTD,
                                _("Error from ftdi_read_data(): %s"),
                                ftdi_get_error_string (p->fc));
+#endif
 
         if (recvd < p->to_recv)
             urj_log (URJ_LOG_LEVEL_NORMAL,
Index: configure.ac
===================================================================
--- configure.ac	(revision 1768)
+++ configure.ac	(working copy)
@@ -150,7 +150,7 @@ AC_ARG_WITH([libusb],
     [with_libusb=check])
 
 HAVELIBUSB=no
-AS_IF([test "x$with_libusb" != xno], [
+AS_IF([test "x$with_libusb" != xno -a "x$with_libusb" != x1.0], [
   save_LIBS=$LIBS
   save_CPPFLAGS=$CPPFLAGS
   PKG_CHECK_MODULES(LIBUSB, libusb, [:;], [dnl
@@ -161,7 +161,7 @@ AS_IF([test "x$with_libusb" != xno], [
         LIBUSB_CFLAGS="-I$with_libusb/include"
         ;;
       *)
-        LIBUSB_LIBS="-Lwith_libusb -lusb"
+        LIBUSB_LIBS="-L$with_libusb -lusb"
         LIBUSB_CFLAGS="-I$with_libusb"
         ;;
       esac
@@ -179,7 +179,11 @@ AS_IF([test "x$with_libusb" != xno], [
     AC_DEFINE(HAVE_LIBUSB, 1, [Define if you have libusb])
     HAVELIBUSB=yes
   ],[
-    AC_MSG_WARN([*** libusb not detected. No support for USB JTAG cables via libusb.])
+    AS_IF([test "x$with_libusb" = x0.1], [
+      AC_MSG_ERROR([*** libusb-0.1 not detected.])
+    ],[
+      AC_MSG_WARN([*** libusb not detected. No support for USB JTAG cables via libusb.])
+    ])
     LIBS=$save_LIBS
     CPPFLAGS=$save_CPPFLAGS
   ])
@@ -187,6 +191,35 @@ AS_IF([test "x$with_libusb" != xno], [
 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"], [
+  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"
+  ],)
+  LIBS="$LIBS $LIBUSB1_LIBS"
+  CPPFLAGS="$CPPFLAGS $LIBUSB1_CFLAGS"
+  AC_CHECK_FUNC([libusb_get_device_list], [
+    AC_DEFINE(HAVE_LIBUSB1, 1, [Define if you have libusb-1.0])
+    HAVELIBUSB1=yes
+  ],[
+    AS_IF([test "x$with_libusb" = x1.0], [
+      AC_MSG_ERROR([*** libusb-1.0 not detected.])
+    ],[
+      AC_MSG_WARN([*** libusb-1.0 not detected. No support for async mode for FTDI cables.])
+    ])
+    LIBS=$save_LIBS
+    CPPFLAGS=$save_CPPFLAGS
+  ])
+],)
+AM_CONDITIONAL(HAVE_LIBUSB1, [test "x$HAVELIBUSB1" = "xyes"])
+
+
 dnl Use FTDI library?
 
 AC_ARG_WITH([libftdi],
@@ -220,8 +253,20 @@ AS_IF([test "x$with_libftdi" != xno], [
     LIBS=$save_LIBS
     CPPFLAGS=$save_CPPFLAGS
   ])
+  AC_CHECK_FUNC([ftdi_read_data_submit], [
+    AS_IF([test "x$HAVELIBUSB" = "xyes"], [
+      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"], [
+      AC_MSG_ERROR([this libftdi cannot be used with libusb-1.0, libusb-0.1 is needed])
+    ],)
+  ])
 ],)
 AM_CONDITIONAL(HAVE_LIBFTDI, [test "x$HAVELIBFTDI" = "xyes"])
+AM_CONDITIONAL(HAVE_LIBFTDI_ASYNC_MODE, [test "x$HAVELIBFTDI_ASYNCMODE" = "xyes"])
 
 
 dnl Use FTDI ftd2xx library?
@@ -682,6 +727,20 @@ 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
+  ])
+])
+AS_IF([test "x$HAVELIBFTDI_ASYNCMODE" = "xyes"], [
+  FLAG_HAVELIBFTDI_ASYNCMODE="(have async mode)"
+],[
+  FLAG_HAVELIBFTDI_ASYNCMODE="(no async mode)"
+])
 AC_DEFUN([MAKE_YESNO_VAR],[dnl
   AS_IF([test ${$1:-$2} != $2], [dnl
      FLAG_$1=yes
@@ -690,7 +749,6 @@ AC_DEFUN([MAKE_YESNO_VAR],[dnl
   ])
 ])
 MAKE_YESNO_VAR([HAVELIBFTDI], [no])
-MAKE_YESNO_VAR([HAVELIBUSB], [no])
 MAKE_YESNO_VAR([HAVELIBFTD2XX], [no])
 MAKE_YESNO_VAR([HAVE_INPOUTXX], [no])
 MAKE_YESNO_VAR([svf], [false])
@@ -700,7 +758,7 @@ AC_MSG_NOTICE([
 jtag is now configured for
 
   Detected libusb      : $FLAG_HAVELIBUSB
-  Detected libftdi     : $FLAG_HAVELIBFTDI
+  Detected libftdi     : $FLAG_HAVELIBFTDI $FLAG_HAVELIBFTDI_ASYNCMODE
   Detected libftd2xx   : $FLAG_HAVELIBFTD2XX
   Detected inpout32    : $FLAG_HAVE_INPOUTXX
   Build SVF player     : $FLAG_svf
------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
UrJTAG-development mailing list
UrJTAG-development@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/urjtag-development

Reply via email to