summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPete Batard <pbatard@gmail.com>2011-03-07 19:02:27 +0000
committerPete Batard <pbatard@gmail.com>2011-03-07 19:02:27 +0000
commit00d3fa801e1778d79c1bce079e3b4e01daa0ef7b (patch)
tree74690352d40d144e8c97b93ed3eed99eeee763ab
parentc11ede2913803ec2ac27ff5c2288406f22720d1a (diff)
downloadlibusb-00d3fa801e1778d79c1bce079e3b4e01daa0ef7b.tar.gz
[integration] merged latest from -stuge branch
* also switched to using POLL_NFDS_TYPE in windows_usb.c
-rw-r--r--configure.ac103
-rw-r--r--libusb/Makefile.am2
-rw-r--r--libusb/io.c63
-rw-r--r--libusb/libusb-1.0.def20
-rw-r--r--libusb/libusbi.h6
-rw-r--r--libusb/os/darwin_usb.c57
-rw-r--r--libusb/os/darwin_usb.h2
-rw-r--r--libusb/os/linux_usbfs.c162
-rw-r--r--libusb/os/poll_posix.h2
-rw-r--r--libusb/os/poll_windows.h2
-rw-r--r--libusb/os/windows_usb.c4
-rw-r--r--libusb/sync.c8
-rw-r--r--msvc/config.h10
13 files changed, 187 insertions, 254 deletions
diff --git a/configure.ac b/configure.ac
index 630d76b..e6e085e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -17,11 +17,11 @@ AC_SUBST([LIBUSB_VERSION_NANO], [LIBUSB_NANO])
lt_current="1"
lt_revision="0"
lt_age="1"
-AC_SUBST(lt_current)
-AC_SUBST(lt_revision)
-AC_SUBST(lt_age)
+LTLDFLAGS="-version-info ${lt_current}:${lt_revision}:${lt_age}"
AM_INIT_AUTOMAKE
+AM_MAINTAINER_MODE
+
AC_CONFIG_SRCDIR([libusb/core.c])
AC_CONFIG_MACRO_DIR([m4])
AM_CONFIG_HEADER([config.h])
@@ -32,75 +32,71 @@ AC_PROG_CC
AC_PROG_LIBTOOL
AC_C_INLINE
AM_PROG_CC_C_O
-AC_DEFINE([_GNU_SOURCE], [], [Use GNU extensions])
+AC_DEFINE([_GNU_SOURCE], 1, [Use GNU extensions])
-AM_MAINTAINER_MODE
+LTLDFLAGS="${LTLDFLAGS} -no-undefined"
AC_MSG_CHECKING([operating system])
-PC_LIBS_PRIVATE=
case $host in
*-linux*)
- AC_DEFINE(OS_LINUX, [], [Linux backend])
+ AC_DEFINE(OS_LINUX, 1, [Linux backend])
AC_SUBST(OS_LINUX)
- AC_DEFINE([THREADS_POSIX], [], [Use Posix Threads])
AC_MSG_RESULT([Linux])
backend="linux"
AC_CHECK_LIB(rt, clock_gettime, PC_LIBS_PRIVATE="-lrt")
- LIBS="${LIBS} ${PC_LIBS_PRIVATE}"
threads="posix"
THREAD_CFLAGS="-pthread"
PC_LIBS_PRIVATE="${PC_LIBS_PRIVATE} -pthread"
- AM_CFLAGS="-std=gnu99"
- AM_LDFLAGS=""
+ AC_CHECK_HEADERS([poll.h])
+ AC_DEFINE([POLL_NFDS_TYPE],[nfds_t],[type of second poll() argument])
;;
*-darwin*)
- AC_DEFINE(OS_DARWIN, [], [Darwin backend])
+ AC_DEFINE(OS_DARWIN, 1, [Darwin backend])
AC_SUBST(OS_DARWIN)
- AC_DEFINE([THREADS_POSIX], [], [Use Posix Threads])
- AC_MSG_RESULT([Darwin/MacOS X])
+ AC_MSG_RESULT([Darwin/Mac OS X])
backend="darwin"
threads="posix"
- THREAD_CFLAGS="-pthread"
- AM_CFLAGS="-std=gnu99"
- PC_LIBS_PRIVATE="-Wl,-framework,IOKit -Wl,-framework,CoreFoundation -Wl,-prebind -no-undefined -pthread"
- AM_LDFLAGS=${PC_LIBS_PRIVATE}
+ PC_LIBS_PRIVATE="-Wl,-framework,IOKit -Wl,-framework,CoreFoundation"
+ LTLDFLAGS="${LTLDFLAGS} -Wl,-prebind"
+ AC_CHECK_HEADERS([poll.h])
+ AC_CHECK_TYPE([nfds_t],
+ [AC_DEFINE([POLL_NFDS_TYPE],[nfds_t],[type of second poll() argument])],
+ [AC_DEFINE([POLL_NFDS_TYPE],[unsigned int],[type of second poll() argument])],
+ [#include <poll.h>])
;;
*-mingw*)
- AC_DEFINE(OS_WINDOWS, [], [Windows backend])
- AC_SUBST(OS_WINDOWS)
AC_MSG_RESULT([Windows])
backend="windows"
- threads="windows"
- create_import_lib="yes"
- LIBS="${LIBS} ${PC_LIBS_PRIVATE}"
- # -avoid-version to avoid a naming scheme such as libusb-0.dll
- AM_LDFLAGS="-no-undefined -avoid-version -Wl,--add-stdcall-alias"
- AM_CFLAGS="-std=gnu99"
- AC_CHECK_TOOL(RC, windres, no)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
;;
*-cygwin*)
- AC_DEFINE(OS_WINDOWS, [], [Windows backend])
- AC_SUBST(OS_WINDOWS)
- AC_DEFINE([THREADS_POSIX], [], [Use Posix Threads])
- AC_MSG_RESULT([Windows])
+ AC_MSG_RESULT([Cygwin (using Windows backend)])
backend="windows"
threads="posix"
- LIBS="${LIBS} ${PC_LIBS_PRIVATE}"
- AM_CFLAGS="-std=gnu99"
- AM_LDFLAGS="-no-undefined -avoid-version"
- AC_CHECK_TOOL(RC, windres, no)
;;
*)
AC_MSG_ERROR([unsupported operating system])
esac
+if test "$backend" = windows; then
+ AC_DEFINE(OS_WINDOWS, 1, [Windows backend])
+ AC_SUBST(OS_WINDOWS)
+ PC_LIBS_PRIVATE="-lsetupapi -lole32 -ladvapi32"
+ LTLDFLAGS="${LTLDFLAGS} -avoid-version -Wl,--add-stdcall-alias"
+ AC_CHECK_TOOL(RC, windres, no)
+ AC_DEFINE([POLL_NFDS_TYPE],[unsigned int],[type of second poll() argument])
+fi
+AC_SUBST(THREAD_CFLAGS)
AC_SUBST(PC_LIBS_PRIVATE)
-
-AM_CONDITIONAL([OS_LINUX], [test "x$backend" = "xlinux"])
-AM_CONDITIONAL([OS_DARWIN], [test "x$backend" = "xdarwin"])
-AM_CONDITIONAL([OS_WINDOWS], [test "x$backend" = "xwindows"])
-AM_CONDITIONAL([THREADS_POSIX], [test "x$threads" = "xposix"])
-AM_CONDITIONAL([CREATE_IMPORT_LIB], [test "x$create_import_lib" = "xyes"])
+LIBS="${LIBS} ${PC_LIBS_PRIVATE}"
+
+AM_CONDITIONAL(OS_LINUX, test "x$backend" = xlinux)
+AM_CONDITIONAL(OS_DARWIN, test "x$backend" = xdarwin)
+AM_CONDITIONAL(OS_WINDOWS, test "x$backend" = xwindows)
+AM_CONDITIONAL(THREADS_POSIX, test "x$threads" = xposix)
+AM_CONDITIONAL(CREATE_IMPORT_LIB, test "x$create_import_lib" = "xyes")
+if test "$threads" = posix; then
+ AC_DEFINE(THREADS_POSIX, 1, [Use POSIX Threads])
+fi
# timerfd
AC_CHECK_HEADER([sys/timerfd.h], [timerfd_h=1], [timerfd_h=0])
@@ -124,7 +120,7 @@ if test "x$use_timerfd" = "xno"; then
else
if test "x$timerfd_h" = "x1" -a "x$tfd_hdr_ok" = "xyes"; then
AC_MSG_RESULT([yes])
- AC_DEFINE(USBI_TIMERFD_AVAILABLE, [], [timerfd headers available])
+ AC_DEFINE(USBI_TIMERFD_AVAILABLE, 1, [timerfd headers available])
else
AC_MSG_RESULT([no (header not available)])
fi
@@ -168,14 +164,14 @@ AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$build_examples" != "xno"])
# Restore gnu89 inline semantics on gcc 4.3 and newer
saved_cflags="$CFLAGS"
CFLAGS="$CFLAGS -fgnu89-inline"
-AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]), inline_cflags="-fgnu89-inline", inline_cflags="")
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], inline_cflags="-fgnu89-inline", inline_cflags="")
CFLAGS="$saved_cflags"
# check for -fvisibility=hidden compiler support (GCC >= 3.4)
saved_cflags="$CFLAGS"
# -Werror required for cygwin
CFLAGS="$CFLAGS -Werror -fvisibility=hidden"
-AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]),
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
[VISIBILITY_CFLAGS="-fvisibility=hidden"
AC_DEFINE([DEFAULT_VISIBILITY], [__attribute__((visibility("default")))], [Default visibility]) ],
[ VISIBILITY_CFLAGS=""
@@ -186,7 +182,7 @@ CFLAGS="$saved_cflags"
# check for -Wno-pointer-sign compiler support (GCC >= 4)
saved_cflags="$CFLAGS"
CFLAGS="$CFLAGS -Wno-pointer-sign"
-AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]),
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
nopointersign_cflags="-Wno-pointer-sign", nopointersign_cflags="")
CFLAGS="$saved_cflags"
@@ -197,14 +193,17 @@ AM_CONDITIONAL([HAVE_SIGACTION], [test "x$have_sigaction" = "xyes"])
# headers not available on all platforms but required on others
AC_CHECK_HEADERS([sys/time.h])
-AC_SUBST([THREAD_CFLAGS])
-
-AM_CFLAGS="$AM_CFLAGS $inline_cflags -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration $nopointersign_cflags -Wshadow"
+AM_CFLAGS="-std=gnu99 $inline_cflags -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration $nopointersign_cflags -Wshadow"
AC_SUBST(VISIBILITY_CFLAGS)
AC_SUBST(AM_CFLAGS)
-AC_SUBST(AM_LDFLAGS)
-
-AC_CONFIG_FILES([libusb-1.0.pc] [Makefile] [libusb/Makefile] [libusb/libusb_version.h] [examples/Makefile] [doc/Makefile] [doc/doxygen.cfg])
+AC_SUBST(LTLDFLAGS)
+
+AC_CONFIG_FILES([libusb-1.0.pc])
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([libusb/Makefile])
+AC_CONFIG_FILES([libusb/libusb_version.h])
+AC_CONFIG_FILES([examples/Makefile])
+AC_CONFIG_FILES([doc/Makefile])
+AC_CONFIG_FILES([doc/doxygen.cfg])
AC_OUTPUT
-
diff --git a/libusb/Makefile.am b/libusb/Makefile.am
index b7890b1..2b6ca7b 100644
--- a/libusb/Makefile.am
+++ b/libusb/Makefile.am
@@ -34,7 +34,7 @@ endif
endif
libusb_1_0_la_CFLAGS = $(VISIBILITY_CFLAGS) $(AM_CFLAGS) $(THREAD_CFLAGS)
-libusb_1_0_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(lt_current):$(lt_revision):$(lt_age)
+libusb_1_0_la_LDFLAGS = $(LTLDFLAGS)
libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c sync.c $(OS_SRC) \
os/linux_usbfs.h os/darwin_usb.h os/windows_usb.h \
os/threads_posix.h os/threads_windows.h \
diff --git a/libusb/io.c b/libusb/io.c
index b23c76b..dd56857 100644
--- a/libusb/io.c
+++ b/libusb/io.c
@@ -1793,7 +1793,7 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
{
int r;
struct usbi_pollfd *ipollfd;
- nfds_t nfds = 0;
+ POLL_NFDS_TYPE nfds = 0;
struct pollfd *fds;
int i = -1;
int timeout_ms;
@@ -1937,8 +1937,8 @@ static int get_next_timeout(libusb_context *ctx, struct timeval *tv,
* non-blocking mode
* \returns 0 on success, or a LIBUSB_ERROR code on failure
*/
-int API_EXPORTED libusb_handle_events_timeout_check(libusb_context *ctx,
- struct timeval *tv, int *completed)
+int API_EXPORTED libusb_handle_events_timeout(libusb_context *ctx,
+ struct timeval *tv)
{
int r;
struct timeval poll_timeout;
@@ -1952,12 +1952,8 @@ int API_EXPORTED libusb_handle_events_timeout_check(libusb_context *ctx,
retry:
if (libusb_try_lock_events(ctx) == 0) {
- r = 0;
- if (completed == NULL || !*completed) {
- /* we obtained the event lock: do our own event handling */
- usbi_dbg("doing our own event handling");
- r = handle_events(ctx, &poll_timeout);
- }
+ /* we obtained the event lock: do our own event handling */
+ r = handle_events(ctx, &poll_timeout);
libusb_unlock_events(ctx);
return r;
}
@@ -1966,18 +1962,16 @@ retry:
* notify event completion. */
libusb_lock_event_waiters(ctx);
- if (completed == NULL || !*completed) {
- if (!libusb_event_handler_active(ctx)) {
- /* we hit a race: whoever was event handling earlier finished in the
- * time it took us to reach this point. try the cycle again. */
- libusb_unlock_event_waiters(ctx);
- usbi_dbg("event handler was active but went away, retrying");
- goto retry;
- }
-
- usbi_dbg("another thread is doing event handling, wait for notification");
- r = libusb_wait_for_event(ctx, &poll_timeout);
+ if (!libusb_event_handler_active(ctx)) {
+ /* we hit a race: whoever was event handling earlier finished in the
+ * time it took us to reach this point. try the cycle again. */
+ libusb_unlock_event_waiters(ctx);
+ usbi_dbg("event handler was active but went away, retrying");
+ goto retry;
}
+
+ usbi_dbg("another thread is doing event handling");
+ r = libusb_wait_for_event(ctx, &poll_timeout);
libusb_unlock_event_waiters(ctx);
if (r < 0)
@@ -1988,21 +1982,6 @@ retry:
return 0;
}
-int API_EXPORTED libusb_handle_events_timeout(libusb_context *ctx,
- struct timeval *tv)
-{
- return libusb_handle_events_timeout_check(ctx, tv, NULL);
-}
-
-int API_EXPORTED libusb_handle_events_check(libusb_context *ctx,
- int *completed)
-{
- struct timeval tv;
- tv.tv_sec = 60;
- tv.tv_usec = 0;
- return libusb_handle_events_timeout_check(ctx, &tv, completed);
-}
-
/** \ingroup poll
* Handle any pending events in blocking mode. There is currently a timeout
* hardcoded at 60 seconds but we plan to make it unlimited in future. For
@@ -2017,7 +1996,7 @@ int API_EXPORTED libusb_handle_events(libusb_context *ctx)
struct timeval tv;
tv.tv_sec = 60;
tv.tv_usec = 0;
- return libusb_handle_events_timeout_check(ctx, &tv, NULL);
+ return libusb_handle_events_timeout(ctx, &tv);
}
/** \ingroup poll
@@ -2145,24 +2124,22 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
if (transfer->flags & (USBI_TRANSFER_TIMED_OUT | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
continue;
+ /* no timeout for this transfer? */
+ if (!timerisset(&transfer->timeout))
+ continue;
+
found = 1;
break;
}
usbi_mutex_unlock(&ctx->flying_transfers_lock);
if (!found) {
- usbi_dbg("all URBs have already been processed for timeouts");
+ usbi_dbg("no URB with timeout or all handled by OS; no timeout!");
return 0;
}
next_timeout = &transfer->timeout;
- /* no timeout for next transfer */
- if (!timerisset(next_timeout)) {
- usbi_dbg("no URBs with timeouts, no timeout!");
- return 0;
- }
-
r = usbi_backend->clock_gettime(USBI_CLOCK_MONOTONIC, &cur_ts);
if (r < 0) {
usbi_err(ctx, "failed to read monotonic clock, errno=%d", errno);
diff --git a/libusb/libusb-1.0.def b/libusb/libusb-1.0.def
index bce31fb..1ae2756 100644
--- a/libusb/libusb-1.0.def
+++ b/libusb/libusb-1.0.def
@@ -340,16 +340,6 @@ EXPORTS
libusb_handle_events@32 = libusb_handle_events
libusb_handle_events@4 = libusb_handle_events
libusb_handle_events@8 = libusb_handle_events
- libusb_handle_events_check
- libusb_handle_events_check@0 = libusb_handle_events_check
- libusb_handle_events_check@12 = libusb_handle_events_check
- libusb_handle_events_check@16 = libusb_handle_events_check
- libusb_handle_events_check@20 = libusb_handle_events_check
- libusb_handle_events_check@24 = libusb_handle_events_check
- libusb_handle_events_check@28 = libusb_handle_events_check
- libusb_handle_events_check@32 = libusb_handle_events_check
- libusb_handle_events_check@4 = libusb_handle_events_check
- libusb_handle_events_check@8 = libusb_handle_events_check
libusb_handle_events_locked
libusb_handle_events_locked@0 = libusb_handle_events_locked
libusb_handle_events_locked@12 = libusb_handle_events_locked
@@ -370,16 +360,6 @@ EXPORTS
libusb_handle_events_timeout@32 = libusb_handle_events_timeout
libusb_handle_events_timeout@4 = libusb_handle_events_timeout
libusb_handle_events_timeout@8 = libusb_handle_events_timeout
- libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@0 = libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@12 = libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@16 = libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@20 = libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@24 = libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@28 = libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@32 = libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@4 = libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@8 = libusb_handle_events_timeout_check
libusb_init
libusb_init@0 = libusb_init
libusb_init@12 = libusb_init
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
index 8ade9c7..322ebbc 100644
--- a/libusb/libusbi.h
+++ b/libusb/libusbi.h
@@ -26,6 +26,9 @@
#include <stddef.h>
#include <stdint.h>
#include <time.h>
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
#include <libusb.h>
#include "libusb_version.h"
@@ -194,6 +197,7 @@ static inline void usbi_dbg(const char *format, ...)
#endif
#if defined(OS_LINUX) || defined(OS_DARWIN)
+#include <unistd.h>
#include <os/poll_posix.h>
#elif defined(OS_WINDOWS)
#include <os/poll_windows.h>
@@ -831,7 +835,7 @@ struct usbi_os_backend {
* Return 0 on success, or a LIBUSB_ERROR code on failure.
*/
int (*handle_events)(struct libusb_context *ctx,
- struct pollfd *fds, nfds_t nfds, int num_ready);
+ struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready);
/* Get time from specified clock. At least two clocks must be implemented
by the backend: USBI_CLOCK_REALTIME, and USBI_CLOCK_MONOTONIC.
diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c
index 37b8e2c..169fa1a 100644
--- a/libusb/os/darwin_usb.c
+++ b/libusb/os/darwin_usb.c
@@ -672,10 +672,19 @@ static int darwin_open (struct libusb_device_handle *dev_handle) {
return darwin_to_libusb (kresult);
}
} else {
- priv->is_open = 1;
-
/* create async event source */
kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
+ if (kresult != kIOReturnSuccess) {
+ usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
+
+ (*(dpriv->device))->USBDeviceClose (dpriv->device);
+ (*(dpriv->device))->Release (dpriv->device);
+
+ dpriv->device = NULL;
+ return darwin_to_libusb (kresult);
+ }
+
+ priv->is_open = 1;
CFRetain (libusb_darwin_acfl);
@@ -1173,10 +1182,18 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) {
/* are we reading or writing? */
is_read = transfer->endpoint & LIBUSB_ENDPOINT_IN;
- /* construct an array of IOUSBIsocFrames */
- tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc (transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
- if (!tpriv->isoc_framelist)
- return LIBUSB_ERROR_NO_MEM;
+ /* construct an array of IOUSBIsocFrames, reuse the old one if possible */
+ if (tpriv->isoc_framelist && tpriv->num_iso_packets != transfer->num_iso_packets) {
+ free(tpriv->isoc_framelist);
+ tpriv->isoc_framelist = NULL;
+ }
+
+ if (!tpriv->isoc_framelist) {
+ tpriv->num_iso_packets = transfer->num_iso_packets;
+ tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc (transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
+ if (!tpriv->isoc_framelist)
+ return LIBUSB_ERROR_NO_MEM;
+ }
/* copy the frame list from the libusb descriptor (the structures differ only is member order) */
for (i = 0 ; i < transfer->num_iso_packets ; i++)
@@ -1202,7 +1219,10 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) {
}
/* schedule for a frame a little in the future */
- frame += 2;
+ frame += 4;
+
+ if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
+ frame = cInterface->frames[transfer->endpoint];
/* submit the request */
if (is_read)
@@ -1214,6 +1234,8 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) {
transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
itransfer);
+ cInterface->frames[transfer->endpoint] = frame + transfer->num_iso_packets / 8;
+
if (kresult != kIOReturnSuccess) {
usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", is_read ? "In" : "Out",
darwin_error_str(kresult));
@@ -1228,6 +1250,7 @@ static int submit_control_transfer(struct usbi_transfer *itransfer) {
struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
struct darwin_device_priv *dpriv = (struct darwin_device_priv *)transfer->dev_handle->dev->os_priv;
+ struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
IOReturn kresult;
@@ -1249,7 +1272,23 @@ static int submit_control_transfer(struct usbi_transfer *itransfer) {
itransfer->flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
/* all transfers in libusb-1.0 are async */
- kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
+
+ if (transfer->endpoint) {
+ struct __darwin_interface *cInterface;
+ uint8_t pipeRef, iface;
+
+ if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
+ usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
+
+ return LIBUSB_ERROR_NOT_FOUND;
+ }
+
+ cInterface = &priv->interfaces[iface];
+
+ kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
+ } else
+ /* control request on endpoint 0 */
+ kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
if (kresult != kIOReturnSuccess)
usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
@@ -1421,7 +1460,7 @@ static void darwin_handle_callback (struct usbi_transfer *itransfer, kern_return
usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, result));
}
-static int op_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds, int num_ready) {
+static int op_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready) {
struct usbi_transfer *itransfer;
UInt32 io_size;
IOReturn kresult;
diff --git a/libusb/os/darwin_usb.h b/libusb/os/darwin_usb.h
index a71d464..9ffd6df 100644
--- a/libusb/os/darwin_usb.h
+++ b/libusb/os/darwin_usb.h
@@ -139,6 +139,7 @@ struct darwin_device_handle_priv {
usb_interface_t **interface;
uint8_t num_endpoints;
CFRunLoopSourceRef cfSource;
+ uint64_t frames[256];
uint8_t endpoint_addrs[USB_MAXENDPOINTS];
} interfaces[USB_MAXINTERFACES];
};
@@ -146,6 +147,7 @@ struct darwin_device_handle_priv {
struct darwin_transfer_priv {
/* Isoc */
IOUSBIsocFrame *isoc_framelist;
+ size_t num_iso_packets;
/* Control */
#if !defined (LIBUSB_NO_TIMEOUT_DEVICE)
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index 867893c..72db57a 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -363,7 +363,7 @@ static int sysfs_get_active_config(struct libusb_device *dev, int *config)
char tmp[4] = {0, 0, 0, 0};
long num;
int fd;
- size_t r;
+ ssize_t r;
fd = __open_sysfs_attr(dev, "bConfigurationValue");
if (fd < 0)
@@ -407,7 +407,7 @@ static int seek_to_next_config(struct libusb_context *ctx, int fd,
struct libusb_config_descriptor config;
unsigned char tmp[6];
off_t off;
- int r;
+ ssize_t r;
/* read first 6 bytes of descriptor */
r = read(fd, tmp, sizeof(tmp));
@@ -1331,6 +1331,39 @@ static void op_destroy_device(struct libusb_device *dev)
free(priv->sysfs_dir);
}
+/* URBs are discarded in reverse order of submission to avoid races. */
+static int discard_urbs(struct usbi_transfer *itransfer, int first, int last_plus_one)
+{
+ struct libusb_transfer *transfer =
+ __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
+ struct linux_transfer_priv *tpriv =
+ usbi_transfer_get_os_priv(itransfer);
+ struct linux_device_handle_priv *dpriv =
+ __device_handle_priv(transfer->dev_handle);
+ int i, ret = 0;
+ struct usbfs_urb *urb;
+
+ for (i = last_plus_one - 1; i >= first; i--) {
+ if (LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type)
+ urb = tpriv->iso_urbs[i];
+ else
+ urb = &tpriv->urbs[i];
+
+ if (0 == ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, urb))
+ continue;
+
+ if (EINVAL == errno) {
+ usbi_dbg("URB not found --> assuming ready to be reaped");
+ ret = LIBUSB_ERROR_NOT_FOUND;
+ } else {
+ usbi_warn(TRANSFER_CTX(transfer),
+ "unrecognised discard errno %d", errno);
+ ret = LIBUSB_ERROR_OTHER;
+ }
+ }
+ return ret;
+}
+
static void free_iso_urbs(struct linux_transfer_priv *tpriv)
{
int i;
@@ -1409,8 +1442,6 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer,
r = ioctl(dpriv->fd, IOCTL_USBFS_SUBMITURB, urb);
if (r < 0) {
- int j;
-
if (errno == ENODEV) {
r = LIBUSB_ERROR_NO_DEVICE;
} else {
@@ -1454,14 +1485,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer,
if (COMPLETED_EARLY == tpriv->reap_action)
return 0;
- /* The URBs are discarded in reverse order of
- * submission, to avoid races. */
- for (j = i - 1; j >= 0; j--) {
- int tmp = ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, &urbs[j]);
- if (tmp && errno != EINVAL)
- usbi_warn(TRANSFER_CTX(transfer),
- "unrecognised discard errno %d", errno);
- }
+ discard_urbs(itransfer, 0, i);
usbi_dbg("reporting successful submission but waiting for %d "
"discards before reporting error", i);
@@ -1577,8 +1601,6 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
for (i = 0; i < num_urbs; i++) {
int r = ioctl(dpriv->fd, IOCTL_USBFS_SUBMITURB, urbs[i]);
if (r < 0) {
- int j;
-
if (errno == ENODEV) {
r = LIBUSB_ERROR_NO_DEVICE;
} else {
@@ -1613,12 +1635,7 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
/* The URBs we haven't submitted yet we count as already
* retired. */
tpriv->num_retired = num_urbs - i;
- for (j = i - 1; j >= 0; j--) {
- int tmp = ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, urbs[j]);
- if (tmp && errno != EINVAL)
- usbi_warn(TRANSFER_CTX(transfer),
- "unrecognised discard errno %d", errno);
- }
+ discard_urbs(itransfer, 0, i);
usbi_dbg("reporting successful submission but waiting for %d "
"discards before reporting error", i);
@@ -1650,6 +1667,7 @@ static int submit_control_transfer(struct usbi_transfer *itransfer)
return LIBUSB_ERROR_NO_MEM;
memset(urb, 0, sizeof(struct usbfs_urb));
tpriv->urbs = urb;
+ tpriv->num_urbs = 1;
tpriv->reap_action = NORMAL;
urb->usercontext = itransfer;
@@ -1693,98 +1711,32 @@ static int op_submit_transfer(struct usbi_transfer *itransfer)
}
}
-static int cancel_control_transfer(struct usbi_transfer *itransfer)
-{
- struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
- struct libusb_transfer *transfer =
- __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
- struct linux_device_handle_priv *dpriv =
- __device_handle_priv(transfer->dev_handle);
- int r;
-
- if (!tpriv->urbs)
- return LIBUSB_ERROR_NOT_FOUND;
-
- tpriv->reap_action = CANCELLED;
- r = ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, tpriv->urbs);
- if(r) {
- if (errno == EINVAL) {
- usbi_dbg("URB not found --> assuming ready to be reaped");
- return 0;
- } else {
- usbi_err(TRANSFER_CTX(transfer),
- "unrecognised DISCARD code %d", errno);
- return LIBUSB_ERROR_OTHER;
- }
- }
-
- return 0;
-}
-
-static int cancel_bulk_transfer(struct usbi_transfer *itransfer)
-{
- struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
- struct libusb_transfer *transfer =
- __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
- struct linux_device_handle_priv *dpriv =
- __device_handle_priv(transfer->dev_handle);
- int i;
-
- if (!tpriv->urbs)
- return LIBUSB_ERROR_NOT_FOUND;
-
- if (tpriv->reap_action != ERROR)
- tpriv->reap_action = CANCELLED;
-
- for (i = tpriv->num_urbs - 1; i >= 0; i--) {
- int tmp = ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, &tpriv->urbs[i]);
- if (tmp && errno != EINVAL)
- usbi_warn(TRANSFER_CTX(transfer),
- "unrecognised discard errno %d", errno);
- }
- return 0;
-}
-
-static int cancel_iso_transfer(struct usbi_transfer *itransfer)
-{
- struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
- struct libusb_transfer *transfer =
- __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
- struct linux_device_handle_priv *dpriv =
- __device_handle_priv(transfer->dev_handle);
- int i;
-
- if (!tpriv->iso_urbs)
- return LIBUSB_ERROR_NOT_FOUND;
-
- tpriv->reap_action = CANCELLED;
- for (i = tpriv->num_urbs - 1; i >= 0; i--) {
- int tmp = ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, tpriv->iso_urbs[i]);
- if (tmp && errno != EINVAL)
- usbi_warn(TRANSFER_CTX(transfer),
- "unrecognised discard errno %d", errno);
- }
- return 0;
-}
-
static int op_cancel_transfer(struct usbi_transfer *itransfer)
{
+ struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
struct libusb_transfer *transfer =
__USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
switch (transfer->type) {
- case LIBUSB_TRANSFER_TYPE_CONTROL:
- return cancel_control_transfer(itransfer);
case LIBUSB_TRANSFER_TYPE_BULK:
+ if (tpriv->reap_action == ERROR)
+ break;
+ /* else, fall through */
+ case LIBUSB_TRANSFER_TYPE_CONTROL:
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
- return cancel_bulk_transfer(itransfer);
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
- return cancel_iso_transfer(itransfer);
+ tpriv->reap_action = CANCELLED;
+ break;
default:
usbi_err(TRANSFER_CTX(transfer),
"unknown endpoint type %d", transfer->type);
return LIBUSB_ERROR_INVALID_PARAM;
}
+
+ if (!tpriv->urbs)
+ return LIBUSB_ERROR_NOT_FOUND;
+
+ return discard_urbs(itransfer, 0, tpriv->num_urbs);
}
static void op_clear_transfer_priv(struct usbi_transfer *itransfer)
@@ -1814,7 +1766,6 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer,
{
struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
- struct linux_device_handle_priv *dpriv = __device_handle_priv(transfer->dev_handle);
int urb_idx = urb - tpriv->urbs;
usbi_mutex_lock(&itransfer->lock);
@@ -1928,16 +1879,7 @@ cancel_remaining:
/* cancel remaining urbs and wait for their completion before
* reporting results */
- for (int i = tpriv->num_urbs - 1; i > urb_idx; i--) {
- /* remaining URBs with continuation flag are
- * automatically cancelled by the kernel */
- if (tpriv->urbs[i].flags & USBFS_URB_BULK_CONTINUATION)
- continue;
- int tmp = ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, &tpriv->urbs[i]);
- if (tmp && errno != EINVAL)
- usbi_warn(TRANSFER_CTX(transfer),
- "unrecognised discard errno %d", errno);
- }
+ discard_urbs(itransfer, urb_idx + 1, tpriv->num_urbs);
out_unlock:
usbi_mutex_unlock(&itransfer->lock);
@@ -2142,7 +2084,7 @@ static int reap_for_handle(struct libusb_device_handle *handle)
}
static int op_handle_events(struct libusb_context *ctx,
- struct pollfd *fds, nfds_t nfds, int num_ready)
+ struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
{
int r;
int i = 0;
diff --git a/libusb/os/poll_posix.h b/libusb/os/poll_posix.h
index 17298a5..f8c9e21 100644
--- a/libusb/os/poll_posix.h
+++ b/libusb/os/poll_posix.h
@@ -1,8 +1,6 @@
#ifndef __LIBUSB_POLL_POSIX_H__
#define __LIBUSB_POLL_POSIX_H__
-#include <unistd.h>
-#include <poll.h>
#define usbi_write write
#define usbi_read read
#define usbi_close close
diff --git a/libusb/os/poll_windows.h b/libusb/os/poll_windows.h
index 36e3915..fee89f5 100644
--- a/libusb/os/poll_windows.h
+++ b/libusb/os/poll_windows.h
@@ -63,8 +63,6 @@ struct pollfd {
short revents; /* returned events */
};
-typedef unsigned int nfds_t;
-
// access modes
enum rw_type {
RW_NONE,
diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c
index 8001a9a..38704ac 100644
--- a/libusb/os/windows_usb.c
+++ b/libusb/os/windows_usb.c
@@ -1970,10 +1970,10 @@ static void windows_handle_callback (struct usbi_transfer *itransfer, uint32_t i
}
}
-static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds, int num_ready)
+static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
{
struct windows_transfer_priv* transfer_priv = NULL;
- nfds_t i = 0;
+ POLL_NFDS_TYPE i = 0;
bool found = false;
struct usbi_transfer *transfer;
DWORD io_size, io_result;
diff --git a/libusb/sync.c b/libusb/sync.c
index d040d98..f6dc2a7 100644
--- a/libusb/sync.c
+++ b/libusb/sync.c
@@ -102,13 +102,13 @@ int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle,
}
while (!completed) {
- r = libusb_handle_events_check(HANDLE_CTX(dev_handle), &completed);
+ r = libusb_handle_events(HANDLE_CTX(dev_handle));
if (r < 0) {
if (r == LIBUSB_ERROR_INTERRUPTED)
continue;
libusb_cancel_transfer(transfer);
while (!completed)
- if (libusb_handle_events_check(HANDLE_CTX(dev_handle), &completed) < 0)
+ if (libusb_handle_events(HANDLE_CTX(dev_handle)) < 0)
break;
libusb_free_transfer(transfer);
return r;
@@ -172,13 +172,13 @@ static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle,
}
while (!completed) {
- r = libusb_handle_events_check(HANDLE_CTX(dev_handle), &completed);
+ r = libusb_handle_events(HANDLE_CTX(dev_handle));
if (r < 0) {
if (r == LIBUSB_ERROR_INTERRUPTED)
continue;
libusb_cancel_transfer(transfer);
while (!completed)
- if (libusb_handle_events_check(HANDLE_CTX(dev_handle), &completed) < 0)
+ if (libusb_handle_events(HANDLE_CTX(dev_handle)) < 0)
break;
libusb_free_transfer(transfer);
return r;
diff --git a/msvc/config.h b/msvc/config.h
index 29261fe..0430858 100644
--- a/msvc/config.h
+++ b/msvc/config.h
@@ -20,11 +20,5 @@
/* Windows backend */
#define OS_WINDOWS /**/
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Backend handles timeout */
-/* #undef USBI_OS_HANDLES_TIMEOUT */
-
-/* timerfd headers available */
-/* #undef USBI_TIMERFD_AVAILABLE */
+/* type of second poll() argument */
+#define POLL_NFDS_TYPE unsigned int