summaryrefslogtreecommitdiff
path: root/devel/libusb1
diff options
context:
space:
mode:
authorleot <leot>2015-08-22 21:23:46 +0000
committerleot <leot>2015-08-22 21:23:46 +0000
commit2a83fec9e7f7480371cf470d189aaaf6170a07fd (patch)
tree3611efb2161427ddfbcdbb0035fa60ab7769adb1 /devel/libusb1
parentf04e3143abad3346134c6443d58cb9097ed5ece5 (diff)
downloadpkgsrc-2a83fec9e7f7480371cf470d189aaaf6170a07fd.tar.gz
Update devel/libusb1 to libusb1-1.0.19.
ok wiz@. pkgsrc changes: * Delete a patch that is now imported upstream * Add test target support Changes: 2014-05-30: v1.0.19 * Add support for USB bulk streams on Linux and Mac OS X (#11) * Windows: Add AMD and Intel USB-3.0 root hub support * Windows: Fix USB 3.0 speed detection on Windows 8 or later (#10) * Added Russian translation for libusb_strerror strings * All: Various small fixes and cleanups The (#xx) numbers are libusb issue numbers, see ie: https://github.com/libusb/libusb/issues/11 2014-01-25: v1.0.18 * Fix multiple memory leaks * Fix a crash when HID transfers return no data on Windows * Ensure all pending events are consumed * Improve Android and ucLinux support * Multiple Windows improvements (error logging, VS2013, VIA xHCI support) * Multiple OS X improvements (broken compilation, SIGFPE, 64bit support) 2013-09-06: v1.0.17 * Hotplug callbacks now always get passed a libusb_context, even if it is the default context. Previously NULL would be passed for the default context, but since the first context created is the default context, and most apps use only 1 context, this meant that apps explicitly creating a context would still get passed NULL * Android: Add .mk files to build with the Android NDK * Darwin: Add Xcode project * Darwin: Fix crash on unplug (#121) * Linux: Fix hang (deadlock) on libusb_exit * Linux: Fix libusb build failure with --disable-udev (#124) * Linux: Fix libusb_get_device_list() hang with --disable-udev (#130) * OpenBSD: Update OpenBSD backend with support for control transfers to non-ugen(4) devices and make get_configuration() no longer generate I/O. Note that using this libusb version on OpenBSD requires using OpenBSD 5.3-current or later. Users of older OpenBSD versions are advised to stay with the libusb shipped with OpenBSD (mpi) * Windows: fix libusb_dll_2010.vcxproj link errors (#129) * Various other bug fixes and improvements 2013-07-11: v1.0.16 * Add hotplug support for Darwin and Linux (#9) * Add superspeed endpoint companion descriptor support (#15) * Add BOS descriptor support (#15) * Make descriptor parsing code more robust * New libusb_get_port_numbers API, this is libusb_get_port_path without the unnecessary context parameter, libusb_get_port_path is now deprecated * New libusb_strerror API (#14) * New libusb_set_auto_detach_kernel_driver API (#17) * Improve topology API docs (#95) * Logging now use a single write call per log-message, avoiding log-message "interlacing" when using multiple threads. * Android: use Android logging when building on Android (#101) * Darwin: make libusb_reset reenumerate device on descriptors change (#89) * Darwin: add support for the LIBUSB_TRANSFER_ADD_ZERO_PACKET flag (#91) * Darwin: add a device cache (#112, #114) * Examples: Add sam3u_benchmark isochronous example by Harald Welte (#109) * Many other bug fixes and improvements The (#xx) numbers are libusbx issue numbers, see ie: https://github.com/libusbx/libusbx/issues/9 2013-04-15: v1.0.15 * Improve transfer cancellation and avoid short read failures on broken descriptors * Filter out 8-bit characters in libusb_get_string_descriptor_ascii() * Add WinCE support * Add library stress tests * Add Cypress FX3 firmware upload support for fxload sample * Add HID and kernel driver detach support capabilities detection * Add SuperSpeed detection on OS X * Fix bInterval value interpretation on OS X * Fix issues with autoclaim, composite HID devices, interface autoclaim and early abort in libusb_close() on Windows. Also add VS2012 solution files. * Improve fd event handling on Linux * Other bug fixes and improvements 2012-09-26: v1.0.14 * Reverts the previous API change with regards to bMaxPower. If this doesn't matter to you, you are encouraged to keep using v1.0.13, as it will use the same attribute as v2.0, to be released soon. * Note that LIBUSB_API_VERSION is *decreased* to 0x010000FF and the previous guidelines with regards to concurrent use of MaxPower/bMaxPower still apply. 2012-09-20: v1.0.13 * [MAJOR] Fix a typo in the API with struct libusb_config_descriptor where MaxPower was used instead of bMaxPower, as defined in the specs. If your application was accessing the MaxPower attribute, and you need to maintain compatibility with libusb or older versions, see APPENDIX A below. * Fix broken support for the 0.1 -> 1.0 libusb-compat layer * Fix unwanted cancellation of pending timeouts as well as major timeout related bugs * Fix handling of HID and composite devices on Windows * Introduce LIBUSB_API_VERSION macro * Add Cypress FX/FX2 firmware upload sample, based on fxload from http://linux-hotplug.sourceforge.net * Add libusb0 (libusb-win32) and libusbK driver support on Windows. Note that while the drivers allow it, isochronous transfers are not supported yet in libusb. Also not supported yet is the use of libusb-win32 filter drivers on composite interfaces * Add support for the new get_capabilities ioctl on Linux and avoid unnecessary splitting of bulk transfers * Improve support for newer Intel and Renesas USB 3.0 controllers on Windows * Harmonize the device number for root hubs across platforms * Other bug fixes and improvements 2012-06-15: v1.0.12 * Fix a potential major regression with pthread on Linux * Fix missing thread ID from debug log output on cygwin * Fix possible crash when using longjmp and MinGW's gcc 4.6 * Add topology calls: libusb_get_port_number(), libusb_get_parent() & libusb_get_port_path() * Add toggleable debug, using libusb_set_debug() or the LIBUSB_DEBUG environment variable * Define log levels in libusb.h and set timestamp origin to first libusb_init() call * All logging is now sent to to stderr (info was sent to stdout previously) * Update log messages severity and avoid polluting log output on OS-X * Add HID driver support on Windows * Enable interchangeability of MSVC and MinGW DLLs * Additional bug fixes and improvements 2012-05-08: v1.0.11 * Revert removal of critical Windows event handling that was introduced in 1.0.10 * Fix a possible deadlock in Windows when submitting transfers * Add timestamped logging * Add NetBSD support (experimental) and BSD libusb_get_device_speed() data * Add bootstrap.sh alongside autogen.sh (bootstrap.sh doesn't invoke configure) * Search for device nodes in /dev for Android support * Other bug fixes 2012-04-17: v1.0.10 * Public release * Add libusb_get_version * Add Visual Studio 2010 project files * Some Windows code cleanup * Fix xusb sample warnings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ APPENDIX A - How to maintain code compatibility with versions of libusb and libusb that use MaxPower: If you must to maintain compatibility with versions of the library that aren't using the bMaxPower attribute in struct libusb_config_descriptor, the recommended way is to use the new LIBUSB_API_VERSION macro with an #ifdef. For instance, if your code was written as follows: if (dev->config[0].MaxPower < 250) Then you should modify it to have: #if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000100) if (dev->config[0].bMaxPower < 250) #else if (dev->config[0].MaxPower < 250) #endif
Diffstat (limited to 'devel/libusb1')
-rw-r--r--devel/libusb1/Makefile10
-rw-r--r--devel/libusb1/distinfo13
-rw-r--r--devel/libusb1/patches/patch-configure12
-rw-r--r--devel/libusb1/patches/patch-configure.ac12
-rw-r--r--devel/libusb1/patches/patch-libusb_os_openbsd__usb.c626
5 files changed, 25 insertions, 648 deletions
diff --git a/devel/libusb1/Makefile b/devel/libusb1/Makefile
index b968a1798d9..0624c879eb0 100644
--- a/devel/libusb1/Makefile
+++ b/devel/libusb1/Makefile
@@ -1,8 +1,7 @@
-# $NetBSD: Makefile,v 1.11 2015/03/11 22:28:35 tnn Exp $
+# $NetBSD: Makefile,v 1.12 2015/08/22 21:23:46 leot Exp $
-DISTNAME= libusb-1.0.9
+DISTNAME= libusb-1.0.19
PKGNAME= ${DISTNAME:S/libusb/libusb1/}
-PKGREVISION= 1
CATEGORIES= devel
MASTER_SITES= ${MASTER_SITE_SOURCEFORGE:=libusb/}
EXTRACT_SUFX= .tar.bz2
@@ -23,7 +22,12 @@ USE_TOOLS+= pkg-config
PKGCONFIG_OVERRIDE+= libusb-1.0.pc.in
+CONFIGURE_ARGS+= --enable-tests-build
+
CONFLICTS= libusbx-[0-9]*
+do-test:
+ cd ${WRKSRC}/tests && ./stress
+
.include "../../mk/pthread.buildlink3.mk"
.include "../../mk/bsd.pkg.mk"
diff --git a/devel/libusb1/distinfo b/devel/libusb1/distinfo
index 2fd871bb562..8f31feea865 100644
--- a/devel/libusb1/distinfo
+++ b/devel/libusb1/distinfo
@@ -1,8 +1,7 @@
-$NetBSD: distinfo,v 1.4 2012/11/20 13:01:47 pettai Exp $
+$NetBSD: distinfo,v 1.5 2015/08/22 21:23:46 leot Exp $
-SHA1 (libusb-1.0.9.tar.bz2) = 025582ff2f6216e2dbc2610ae16b2e073e1b3346
-RMD160 (libusb-1.0.9.tar.bz2) = 5410570f8ce31783044eb04aebaae7ade3b21a61
-Size (libusb-1.0.9.tar.bz2) = 421971 bytes
-SHA1 (patch-configure) = 16945e970e356009d1022d9832ef3ee532435422
-SHA1 (patch-configure.ac) = 3d8234d368409a23da0f346822bea276c6081e8b
-SHA1 (patch-libusb_os_openbsd__usb.c) = be31799029f8e2acf7abb6be566a51c78026479d
+SHA1 (libusb-1.0.19.tar.bz2) = c5d14ced155233ceeb5107c7eb3b94b16649ae05
+RMD160 (libusb-1.0.19.tar.bz2) = 0b6818be6bb2c36628ad22e332c39dcab6c762b9
+Size (libusb-1.0.19.tar.bz2) = 521496 bytes
+SHA1 (patch-configure) = bef1f2108e35aa5cbddd25857dff25cdb9065388
+SHA1 (patch-configure.ac) = 1cc779623ce05635d8ce8fde03fde3fbeef1ce84
diff --git a/devel/libusb1/patches/patch-configure b/devel/libusb1/patches/patch-configure
index 8aecb371153..b11f4ebbcc5 100644
--- a/devel/libusb1/patches/patch-configure
+++ b/devel/libusb1/patches/patch-configure
@@ -1,12 +1,12 @@
-$NetBSD: patch-configure,v 1.2 2012/10/08 16:59:26 dholland Exp $
+$NetBSD: patch-configure,v 1.3 2015/08/22 21:23:46 leot Exp $
Recognize Dragonfly.
---- configure.orig 2012-10-06 07:29:32.285323000 +0000
+--- configure.orig 2014-06-13 18:28:18.000000000 +0000
+++ configure
-@@ -11108,6 +11108,11 @@ $as_echo "Darwin/Mac OS X" >&6; }
- $as_echo "OpenBSD" >&6; }
+@@ -11933,6 +11933,11 @@ $as_echo "OpenBSD" >&6; }
backend="openbsd"
+ threads="posix"
;;
+*-dragonfly*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: DragonflyBSD (using OpenBSD backend)" >&5
@@ -14,5 +14,5 @@ Recognize Dragonfly.
+ backend="openbsd"
+ ;;
*-netbsd*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: NetBSD (using OpenBSD backend)" >&5
- $as_echo "NetBSD (using OpenBSD backend)" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: NetBSD" >&5
+ $as_echo "NetBSD" >&6; }
diff --git a/devel/libusb1/patches/patch-configure.ac b/devel/libusb1/patches/patch-configure.ac
index f1e52341ded..c573c752d10 100644
--- a/devel/libusb1/patches/patch-configure.ac
+++ b/devel/libusb1/patches/patch-configure.ac
@@ -1,17 +1,17 @@
-$NetBSD: patch-configure.ac,v 1.2 2012/10/08 16:59:26 dholland Exp $
+$NetBSD: patch-configure.ac,v 1.3 2015/08/22 21:23:46 leot Exp $
Recognize Dragonfly.
---- configure.ac.orig 2012-04-20 06:44:27.000000000 +0000
+--- configure.ac.orig 2014-04-22 12:19:42.000000000 +0000
+++ configure.ac
-@@ -58,6 +58,10 @@ case $host in
- AC_MSG_RESULT([OpenBSD])
+@@ -72,6 +72,10 @@ case $host in
backend="openbsd"
+ threads="posix"
;;
+*-dragonfly*)
+ AC_MSG_RESULT([DragonflyBSD (using OpenBSD backend)])
+ backend="openbsd"
+ ;;
*-netbsd*)
- AC_MSG_RESULT([NetBSD (using OpenBSD backend)])
- backend="openbsd"
+ AC_MSG_RESULT([NetBSD])
+ backend="netbsd"
diff --git a/devel/libusb1/patches/patch-libusb_os_openbsd__usb.c b/devel/libusb1/patches/patch-libusb_os_openbsd__usb.c
deleted file mode 100644
index 116e0e1c688..00000000000
--- a/devel/libusb1/patches/patch-libusb_os_openbsd__usb.c
+++ /dev/null
@@ -1,626 +0,0 @@
-$NetBSD: patch-libusb_os_openbsd__usb.c,v 1.3 2012/11/20 13:01:47 pettai Exp $
-
-Fix build on Dragonfly.
-Add support for non ugen(4) attached devices through usb(4) buses.
-
---- libusb/os/openbsd_usb.c.orig 2012-11-20 11:50:40.000000000 +0000
-+++ libusb/os/openbsd_usb.c
-@@ -1,5 +1,5 @@
- /*
-- * Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
-+ * Copyright (c) 2011-2012 Martin Pieuchot <mpi@openbsd.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
-@@ -36,8 +36,8 @@
- #include "libusbi.h"
-
- struct device_priv {
-- char devnode[16];
-- int fd;
-+ char *devname; /* name of the ugen(4) node */
-+ int fd; /* device file descriptor */
-
- unsigned char *cdesc; /* active config descriptor */
- usb_device_descriptor_t ddesc; /* usb device descriptor */
-@@ -91,6 +91,13 @@ static int _sync_control_transfer(struct
- static int _sync_gen_transfer(struct usbi_transfer *);
- static int _access_endpoint(struct libusb_transfer *);
-
-+static int _bus_open(int);
-+static int _bus_get_config(int, int, int *);
-+static int _bus_get_device_desc(int, int, usb_device_descriptor_t *);
-+static int _bus_get_full_desc(int, int, int, int, void *);
-+static int _bus_get_config_desc(int, int, int, usb_config_descriptor_t *);
-+
-+
- const struct usbi_os_backend openbsd_backend = {
- "Synchronous OpenBSD backend",
- NULL, /* init() */
-@@ -132,75 +139,102 @@ const struct usbi_os_backend openbsd_bac
- 0, /* add_iso_packet_size */
- };
-
-+#define DEVPATH "/dev/"
-+#define USBDEV DEVPATH "usb"
-+
- int
- obsd_get_device_list(struct libusb_context * ctx,
- struct discovered_devs **discdevs)
- {
-+ struct discovered_devs *dd;
- struct libusb_device *dev;
- struct device_priv *dpriv;
- struct usb_device_info di;
- unsigned long session_id;
-- char devnode[16];
-- int fd, err, i;
-+ char devices[USB_MAX_DEVICES];
-+ char busnode[16];
-+ char *udevname;
-+ int fd, addr, i, j;
-
- usbi_dbg("");
-
-- /* Only ugen(4) is supported */
-- for (i = 0; i < USB_MAX_DEVICES; i++) {
-- /* Control endpoint is always .00 */
-- snprintf(devnode, sizeof(devnode), "/dev/ugen%d.00", i);
-+ for (i = 0; i < 8; i++) {
-+ snprintf(busnode, sizeof(busnode), USBDEV "%d", i);
-
-- if ((fd = open(devnode, O_RDONLY)) < 0) {
-+ if ((fd = open(busnode, O_RDWR)) < 0) {
- if (errno != ENOENT && errno != ENXIO)
-- usbi_err(ctx, "could not open %s", devnode);
-+ usbi_err(ctx, "could not open %s", busnode);
- continue;
- }
-
-- if (ioctl(fd, USB_GET_DEVICEINFO, &di) < 0)
-- continue;
--
-- session_id = (di.udi_bus << 8 | di.udi_addr);
-- dev = usbi_get_device_by_session_id(ctx, session_id);
--
-- if (dev == NULL) {
-- dev = usbi_alloc_device(ctx, session_id);
-- if (dev == NULL)
-- return (LIBUSB_ERROR_NO_MEM);
-+ bzero(devices, sizeof(devices));
-+ for (addr = 1; addr < USB_MAX_DEVICES; addr++) {
-+ if (devices[addr])
-+ continue;
-+
-+ di.udi_addr = addr;
-+ if (ioctl(fd, USB_DEVICEINFO, &di) < 0)
-+ continue;
-+
-+ /*
-+ * XXX If ugen(4) is attached to the USB device
-+ * it will be used.
-+ */
-+ udevname = NULL;
-+ for (j = 0; j < USB_MAX_DEVNAMES; j++)
-+ if (!strncmp("ugen", di.udi_devnames[j], 4)) {
-+ udevname = strdup(di.udi_devnames[j]);
-+ break;
-+ }
-+
-+ session_id = (di.udi_bus << 8 | di.udi_addr);
-+ dev = usbi_get_device_by_session_id(ctx, session_id);
-+
-+ if (dev == NULL) {
-+ dev = usbi_alloc_device(ctx, session_id);
-+ if (dev == NULL) {
-+ close(fd);
-+ return (LIBUSB_ERROR_NO_MEM);
-+ }
-+
-+ dev->bus_number = di.udi_bus;
-+ dev->device_address = di.udi_addr;
-+ dev->speed = di.udi_speed;
-+
-+ dpriv = (struct device_priv *)dev->os_priv;
-+ dpriv->fd = -1;
-+ dpriv->cdesc = NULL;
-+ dpriv->devname = udevname;
-+
-+ if (_bus_get_device_desc(fd, addr, &dpriv->ddesc)) {
-+ libusb_unref_device(dev);
-+ continue;
-+ }
-+
-+ /* XXX Assume the active config is at index 0 */
-+ if (_cache_active_config_descriptor(dev, 0)) {
-+ libusb_unref_device(dev);
-+ continue;
-+ }
-
-- dev->bus_number = di.udi_bus;
-- dev->device_address = di.udi_addr;
-- dev->speed = di.udi_speed;
--
-- dpriv = (struct device_priv *)dev->os_priv;
-- strlcpy(dpriv->devnode, devnode, sizeof(devnode));
-- dpriv->fd = -1;
--
-- if (ioctl(fd, USB_GET_DEVICE_DESC, &dpriv->ddesc) < 0) {
-- err = errno;
-- goto error;
-+ if (usbi_sanitize_device(dev))
-+ libusb_unref_device(dev);
- }
-
-- dpriv->cdesc = NULL;
-- if (_cache_active_config_descriptor(dev, fd)) {
-- err = errno;
-- goto error;
-+ dd = discovered_devs_append(*discdevs, dev);
-+ if (dd == NULL) {
-+ close(fd);
-+ return (LIBUSB_ERROR_NO_MEM);
- }
-
-- if ((err = usbi_sanitize_device(dev)))
-- goto error;
-+ *discdevs = dd;
-+ devices[addr] = 1;
- }
-- close(fd);
-
-- if (discovered_devs_append(*discdevs, dev) == NULL)
-- return (LIBUSB_ERROR_NO_MEM);
-+ close(fd);
- }
-
- return (LIBUSB_SUCCESS);
--
--error:
-- close(fd);
-- libusb_unref_device(dev);
-- return _errno_to_libusb(err);
- }
-
- int
-@@ -208,15 +242,21 @@ obsd_open(struct libusb_device_handle *h
- {
- struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
- struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
-+ char devnode[16];
-
-- dpriv->fd = open(dpriv->devnode, O_RDWR);
-- if (dpriv->fd < 0) {
-- dpriv->fd = open(dpriv->devnode, O_RDONLY);
-+ if (dpriv->devname) {
-+ /*
-+ * Only open ugen(4) attached devices read-write, all
-+ * read-only operations are done through the bus node.
-+ */
-+ snprintf(devnode, sizeof(devnode), DEVPATH "%s.00",
-+ dpriv->devname);
-+ dpriv->fd = open(devnode, O_RDWR);
- if (dpriv->fd < 0)
- return _errno_to_libusb(errno);
-- }
-
-- usbi_dbg("open %s: fd %d", dpriv->devnode, dpriv->fd);
-+ usbi_dbg("open %s: fd %d", devnode, dpriv->fd);
-+ }
-
- if (pipe(hpriv->pipe) < 0)
- return _errno_to_libusb(errno);
-@@ -230,10 +270,12 @@ obsd_close(struct libusb_device_handle *
- struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
- struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
-
-- usbi_dbg("close: fd %d", dpriv->fd);
-+ if (dpriv->devname) {
-+ usbi_dbg("close: fd %d", dpriv->fd);
-
-- close(dpriv->fd);
-- dpriv->fd = -1;
-+ close(dpriv->fd);
-+ dpriv->fd = -1;
-+ }
-
- usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
-
-@@ -279,34 +321,19 @@ int
- obsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx,
- unsigned char *buf, size_t len, int *host_endian)
- {
-- struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
-- struct usb_full_desc ufd;
- int fd, err;
-
-- usbi_dbg("index %d, len %d", idx, len);
--
-- /* A config descriptor may be requested before opening the device */
-- if (dpriv->fd >= 0) {
-- fd = dpriv->fd;
-- } else {
-- fd = open(dpriv->devnode, O_RDONLY);
-- if (fd < 0)
-- return _errno_to_libusb(errno);
-- }
-+ if ((fd = _bus_open(dev->bus_number)) < 0)
-+ return _errno_to_libusb(errno);
-
-- ufd.ufd_config_index = idx;
-- ufd.ufd_size = len;
-- ufd.ufd_data = buf;
-+ usbi_dbg("index %d, len %d", idx, len);
-
-- if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) {
-+ if (_bus_get_full_desc(fd, dev->device_address, idx, len, buf)) {
- err = errno;
-- if (dpriv->fd < 0)
-- close(fd);
-+ close(fd);
- return _errno_to_libusb(err);
- }
--
-- if (dpriv->fd < 0)
-- close(fd);
-+ close(fd);
-
- *host_endian = 0;
-
-@@ -316,14 +343,19 @@ obsd_get_config_descriptor(struct libusb
- int
- obsd_get_configuration(struct libusb_device_handle *handle, int *config)
- {
-- struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
--
-- usbi_dbg("");
-+ int fd, err;
-
-- if (ioctl(dpriv->fd, USB_GET_CONFIG, config) < 0)
-+ if ((fd = _bus_open(handle->dev->bus_number)) < 0)
- return _errno_to_libusb(errno);
-
-- usbi_dbg("configuration %d", *config);
-+ if (_bus_get_config(fd, handle->dev->device_address, config)) {
-+ err = errno;
-+ close(fd);
-+ return _errno_to_libusb(err);
-+ }
-+ close(fd);
-+
-+ usbi_dbg("bConfigurationValue %d", *config);
-
- return (LIBUSB_SUCCESS);
- }
-@@ -332,13 +364,23 @@ int
- obsd_set_configuration(struct libusb_device_handle *handle, int config)
- {
- struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
-+ int idx;
-
-- usbi_dbg("configuration %d", config);
-+ if (dpriv->devname == NULL)
-+ return (LIBUSB_ERROR_NOT_SUPPORTED);
-+
-+ usbi_dbg("bConfigurationValue %d", config);
-
- if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0)
- return _errno_to_libusb(errno);
-
-- return _cache_active_config_descriptor(handle->dev, dpriv->fd);
-+ /*
-+ * XXX Instead of assuming that the index is at bConfigurationValue
-+ * minus one, we should iterate against the possible configurations.
-+ */
-+ idx = config - 1;
-+
-+ return _cache_active_config_descriptor(handle->dev, idx);
- }
-
- int
-@@ -373,6 +415,9 @@ obsd_set_interface_altsetting(struct lib
- struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
- struct usb_alt_interface intf;
-
-+ if (dpriv->devname == NULL)
-+ return (LIBUSB_ERROR_NOT_SUPPORTED);
-+
- usbi_dbg("iface %d, setting %d", iface, altsetting);
-
- memset(&intf, 0, sizeof(intf));
-@@ -389,19 +434,27 @@ obsd_set_interface_altsetting(struct lib
- int
- obsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint)
- {
-- struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
- struct usb_ctl_request req;
-+ int fd, err;
-+
-+ if ((fd = _bus_open(handle->dev->bus_number)) < 0)
-+ return _errno_to_libusb(errno);
-
- usbi_dbg("");
-
-+ req.ucr_addr = handle->dev->device_address;
- req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT;
- req.ucr_request.bRequest = UR_CLEAR_FEATURE;
- USETW(req.ucr_request.wValue, UF_ENDPOINT_HALT);
- USETW(req.ucr_request.wIndex, endpoint);
- USETW(req.ucr_request.wLength, 0);
-
-- if (ioctl(dpriv->fd, USB_DO_REQUEST, &req) < 0)
-- return _errno_to_libusb(errno);
-+ if (ioctl(fd, USB_REQUEST, &req) < 0) {
-+ err = errno;
-+ close(fd);
-+ return _errno_to_libusb(err);
-+ }
-+ close(fd);
-
- return (LIBUSB_SUCCESS);
- }
-@@ -422,6 +475,7 @@ obsd_destroy_device(struct libusb_device
- usbi_dbg("");
-
- free(dpriv->cdesc);
-+ free(dpriv->devname);
- }
-
- int
-@@ -561,6 +615,8 @@ obsd_clock_gettime(int clkid, struct tim
- int
- _errno_to_libusb(int err)
- {
-+ usbi_dbg("error: %s (%d)", strerror(err), err);
-+
- switch (err) {
- case EIO:
- return (LIBUSB_ERROR_IO);
-@@ -570,52 +626,52 @@ _errno_to_libusb(int err)
- return (LIBUSB_ERROR_NO_DEVICE);
- case ENOMEM:
- return (LIBUSB_ERROR_NO_MEM);
-+ case ETIMEDOUT:
-+ return (LIBUSB_ERROR_TIMEOUT);
- }
-
-- usbi_dbg("error: %s", strerror(err));
--
- return (LIBUSB_ERROR_OTHER);
- }
-
- int
--_cache_active_config_descriptor(struct libusb_device *dev, int fd)
-+_cache_active_config_descriptor(struct libusb_device *dev, int idx)
- {
- struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
-- struct usb_config_desc ucd;
-- struct usb_full_desc ufd;
-+ usb_config_descriptor_t cdesc;
- unsigned char* buf;
-- int len;
-+ int fd, len, err;
-
-- usbi_dbg("fd %d", fd);
-+ if ((fd = _bus_open(dev->bus_number)) < 0)
-+ return _errno_to_libusb(errno);
-
-- ucd.ucd_config_index = USB_CURRENT_CONFIG_INDEX;
-+ usbi_dbg("fd %d, addr %d", fd, dev->device_address);
-
-- if ((ioctl(fd, USB_GET_CONFIG_DESC, &ucd)) < 0)
-+ if (_bus_get_config_desc(fd, dev->device_address, idx, &cdesc)) {
-+ err = errno;
-+ close(fd);
- return _errno_to_libusb(errno);
-+ }
-
-- usbi_dbg("active bLength %d", ucd.ucd_desc.bLength);
-+ usbi_dbg("active bLength %d", cdesc.bLength);
-
-- len = UGETW(ucd.ucd_desc.wTotalLength);
-+ len = UGETW(cdesc.wTotalLength);
- buf = malloc(len);
- if (buf == NULL)
- return (LIBUSB_ERROR_NO_MEM);
-
-- ufd.ufd_config_index = ucd.ucd_config_index;
-- ufd.ufd_size = len;
-- ufd.ufd_data = buf;
--
-- usbi_dbg("index %d, len %d", ufd.ufd_config_index, len);
--
-- if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) {
-+ if (_bus_get_full_desc(fd, dev->device_address, idx, len, buf)) {
-+ err = errno;
-+ close(fd);
- free(buf);
-- return _errno_to_libusb(errno);
-+ return _errno_to_libusb(err);
- }
-+ close(fd);
-
- if (dpriv->cdesc)
- free(dpriv->cdesc);
- dpriv->cdesc = buf;
-
-- return (0);
-+ return (LIBUSB_SUCCESS);
- }
-
- int
-@@ -630,12 +686,13 @@ _sync_control_transfer(struct usbi_trans
- dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
- setup = (struct libusb_control_setup *)transfer->buffer;
-
-- usbi_dbg("type %d request %d value %d index %d length %d timeout %d",
-+ usbi_dbg("type %x request %x value %x index %d length %d timeout %d",
- setup->bmRequestType, setup->bRequest,
- libusb_le16_to_cpu(setup->wValue),
- libusb_le16_to_cpu(setup->wIndex),
- libusb_le16_to_cpu(setup->wLength), transfer->timeout);
-
-+ req.ucr_addr = transfer->dev_handle->dev->device_address;
- req.ucr_request.bmRequestType = setup->bmRequestType;
- req.ucr_request.bRequest = setup->bRequest;
- /* Don't use USETW, libusb already deals with the endianness */
-@@ -647,11 +704,30 @@ _sync_control_transfer(struct usbi_trans
- if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0)
- req.ucr_flags = USBD_SHORT_XFER_OK;
-
-- if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0)
-- return _errno_to_libusb(errno);
-+ if (dpriv->devname == NULL) {
-+ /*
-+ * XXX If the device is not attached to ugen(4) it is
-+ * XXX still possible to submit a control transfer but
-+ * XXX with the default timeout only.
-+ */
-+ int fd, err;
-
-- if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0)
-- return _errno_to_libusb(errno);
-+ if ((fd = _bus_open(transfer->dev_handle->dev->bus_number)) < 0)
-+ return _errno_to_libusb(errno);
-+
-+ if ((ioctl(fd, USB_REQUEST, &req)) < 0) {
-+ err = errno;
-+ close(fd);
-+ return _errno_to_libusb(err);
-+ }
-+ close(fd);
-+ } else {
-+ if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0)
-+ return _errno_to_libusb(errno);
-+
-+ if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0)
-+ return _errno_to_libusb(errno);
-+ }
-
- itransfer->transferred = req.ucr_actlen;
-
-@@ -665,7 +741,7 @@ _access_endpoint(struct libusb_transfer
- {
- struct handle_priv *hpriv;
- struct device_priv *dpriv;
-- char *s, devnode[16];
-+ char devnode[16];
- int fd, endpt;
- mode_t mode;
-
-@@ -678,10 +754,9 @@ _access_endpoint(struct libusb_transfer
- usbi_dbg("endpoint %d mode %d", endpt, mode);
-
- if (hpriv->endpoints[endpt] < 0) {
-- /* Pick the right node given the control one */
-- strlcpy(devnode, dpriv->devnode, sizeof(devnode));
-- s = strchr(devnode, '.');
-- snprintf(s, 4, ".%02d", endpt);
-+ /* Pick the right endpoint node */
-+ snprintf(devnode, sizeof(devnode), DEVPATH "%s.%02d",
-+ dpriv->devname, endpt);
-
- /* We may need to read/write to the same endpoint later. */
- if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO))
-@@ -698,9 +773,14 @@ int
- _sync_gen_transfer(struct usbi_transfer *itransfer)
- {
- struct libusb_transfer *transfer;
-+ struct device_priv *dpriv;
- int fd, nr = 1;
-
- transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
-+ dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
-+
-+ if (dpriv->devname == NULL)
-+ return (LIBUSB_ERROR_NOT_SUPPORTED);
-
- /*
- * Bulk, Interrupt or Isochronous transfer depends on the
-@@ -729,3 +809,86 @@ _sync_gen_transfer(struct usbi_transfer
-
- return (0);
- }
-+
-+int
-+_bus_open(int number)
-+{
-+ char busnode[16];
-+
-+ snprintf(busnode, sizeof(busnode), USBDEV "%d", number);
-+
-+ return open(busnode, O_RDWR);
-+}
-+
-+int
-+_bus_get_config(int fd, int addr, int *config)
-+{
-+ struct usb_ctl_request req;
-+ uint8_t conf;
-+ int err;
-+
-+ usbi_dbg("");
-+
-+ req.ucr_addr = addr;
-+ req.ucr_request.bmRequestType = UT_READ_DEVICE;
-+ req.ucr_request.bRequest = UR_GET_CONFIG;
-+ USETW(req.ucr_request.wValue, 0);
-+ USETW(req.ucr_request.wIndex, 0);
-+ USETW(req.ucr_request.wLength, 1);
-+ req.ucr_data = &conf;
-+ req.ucr_flags = 0;
-+
-+ err = ioctl(fd, USB_REQUEST, &req);
-+
-+ *config = conf;
-+
-+ return (err);
-+}
-+
-+static int
-+_bus_get_desc(int fd, int addr, uint8_t type, uint8_t idx, int len, void *desc)
-+{
-+ struct usb_ctl_request req;
-+
-+ usbi_dbg("addr %d type %d index %d len %d", addr, type, idx, len);
-+
-+ req.ucr_addr = addr;
-+ req.ucr_request.bmRequestType = UT_READ_DEVICE;
-+ req.ucr_request.bRequest = UR_GET_DESCRIPTOR;
-+ USETW2(req.ucr_request.wValue, type, idx);
-+ USETW(req.ucr_request.wIndex, 0);
-+ USETW(req.ucr_request.wLength, len);
-+ req.ucr_data = desc;
-+ req.ucr_flags = 0;
-+
-+ if (ioctl(fd, USB_REQUEST, &req) < 0)
-+ return _errno_to_libusb(errno);
-+
-+ return (0);
-+}
-+
-+int
-+_bus_get_device_desc(int fd, int addr, usb_device_descriptor_t *ddesc)
-+{
-+ usbi_dbg("");
-+
-+ return _bus_get_desc(fd, addr, UDESC_DEVICE, 0,
-+ USB_DEVICE_DESCRIPTOR_SIZE, ddesc);
-+}
-+
-+int
-+_bus_get_config_desc(int fd, int addr, int idx, usb_config_descriptor_t *cdesc)
-+{
-+ usbi_dbg("config index %d", idx);
-+
-+ return _bus_get_desc(fd, addr, UDESC_CONFIG, idx,
-+ USB_CONFIG_DESCRIPTOR_SIZE, cdesc);
-+}
-+
-+int
-+_bus_get_full_desc(int fd, int addr, int idx, int size, void *desc)
-+{
-+ usbi_dbg("config index %d size %d", idx, size);
-+
-+ return _bus_get_desc(fd, addr, UDESC_CONFIG, idx, size, desc);
-+}