On Tue, Jun 23, 2015 at 4:23 PM, Martin Pieuchot <m...@openbsd.org> wrote: > On 23/06/15(Tue) 14:04, Brandon Mercer wrote: >> On Tue, Jun 23, 2015 at 5:17 AM Martin Pieuchot <m...@openbsd.org> wrote: >> >> > On 22/06/15(Mon) 23:56, Jérémie Courrèges-Anglas wrote: >> > > Martin Pieuchot <m...@openbsd.org> writes: >> > > >> > > > Here's an update to the latest version. This diff is basically the >> > > > same as last year and hopefully the regression exposed in the 1.0.18 >> > > > are now gone. >> > > > >> > > > Please test with your favorite ports and report back. >> > > >> > > FWIW, the update looks sane ports-wise. >> > >> > Thanks. >> > >> > > If you're still looking for test reports then running a test bulk >> > > (on exopi) in the meantime would be a good idea to avoid any fallout. >> > >> > I doubt this will cause any breakage. But more importantly dcoppa@ told >> > me in private that the regression introduced in 1.0.18 is still present. >> > However is has been fixed in master. >> > >> > Since the changes are not trivial to backport I prefer to wait for the >> > next release. >> > >> >> Is this a good candidate for tracking their github repo? > > You can use the diff below if you want. But I'd prefer to stick to > stable releases. Thing is OpenBSD's backend is synchronous whereas > the libusb advertise synchronous transfer submission. This difference > does not really matter for the port ecosystem as most of the ports > use the synchronous libusb-compat wrapper. But this difference matters > as of the 1.0.18 release when libusbx started adding some locks that > trigger a deadlock with one application on OpenBSD. > > Now we currently have a GSoC student working on improving our kernel > interface to support asynchronous transfers so I'm not in a rush of > upgrading the current port.
I'm OK with the diff below, if you want to commit it. Ah... You forgot to "cvs rm -f patches/patch-libusb_os_openbsd_usb_c" btw Cheers! David > Index: Makefile > =================================================================== > RCS file: /cvs/ports/devel/libusb1/Makefile,v > retrieving revision 1.23 > diff -u -p -r1.23 Makefile > --- Makefile 16 Mar 2015 18:07:43 -0000 1.23 > +++ Makefile 18 Jun 2015 16:33:06 -0000 > @@ -2,15 +2,19 @@ > > COMMENT = library for USB device access from userspace > > -VERSION = 1.0.9 > +VERSION = 1.0.20 > DISTNAME = libusb-${VERSION} > PKGNAME = libusb1-${VERSION} > -REVISION = 9 > -SHARED_LIBS += usb-1.0 1.0 # 1.0 > + > +GH_ACCOUNT = libusb > +GH_PROJECT = libusb > +GH_COMMIT = c141457debff6156b83786eb69b46d873634e5bd > + > +SHARED_LIBS += usb-1.0 1.1 # 1.0 > > CATEGORIES = devel > > -HOMEPAGE = http://www.libusb.org > +HOMEPAGE = http://www.libusb.info > > MAINTAINER = Martin Pieuchot <m...@openbsd.org> > > @@ -19,8 +23,15 @@ PERMIT_PACKAGE_CDROM = Yes > > WANTLIB = pthread > > -MASTER_SITES = ${MASTER_SITE_SOURCEFORGE:=libusb/} > -EXTRACT_SUFX = .tar.bz2 > +#MASTER_SITES = ${MASTER_SITE_SOURCEFORGE:=libusb/} > +#EXTRACT_SUFX = .tar.bz2 > + > +BUILD_DEPENDS= devel/libtool \ > + ${MODGNU_AUTOCONF_DEPENDS} \ > + ${MODGNU_AUTOMAKE_DEPENDS} > + > +AUTOCONF_VERSION= 2.69 > +AUTOMAKE_VERSION= 1.11 > > CONFIGURE_STYLE = gnu > CONFIGURE_ARGS += ${CONFIGURE_SHARED} > @@ -29,5 +40,9 @@ CONFIGURE_ARGS += ${CONFIGURE_SHARED} > CONFIGURE_ARGS += --enable-debug-log \ > --enable-examples-build > .endif > + > +pre-configure: > + cd ${WRKSRC} && env AUTOCONF_VERSION=${AUTOCONF_VERSION} \ > + AUTOMAKE_VERSION=${AUTOMAKE_VERSION} sh ./bootstrap.sh > > .include <bsd.port.mk> > Index: distinfo > =================================================================== > RCS file: /cvs/ports/devel/libusb1/distinfo,v > retrieving revision 1.3 > diff -u -p -r1.3 distinfo > --- distinfo 18 Jan 2015 03:13:17 -0000 1.3 > +++ distinfo 18 Jun 2015 16:26:48 -0000 > @@ -1,2 +1,2 @@ > -SHA256 (libusb-1.0.9.tar.bz2) = 6SDu3C0GsJYGYRyZ7HMEQTxnhMum4zko54JD0yMZX5s= > -SIZE (libusb-1.0.9.tar.bz2) = 421971 > +SHA256 (libusb-1.0.20.tar.gz) = qs7ke/y3BBAm5JRbrOHGjFSm0bRrRD4JxlL1cJVDgxc= > +SIZE (libusb-1.0.20.tar.gz) = 361223 > Index: patches/patch-libusb_core_c > =================================================================== > RCS file: /cvs/ports/devel/libusb1/patches/patch-libusb_core_c,v > retrieving revision 1.3 > diff -u -p -r1.3 patch-libusb_core_c > --- patches/patch-libusb_core_c 19 Jun 2012 21:10:59 -0000 1.3 > +++ patches/patch-libusb_core_c 16 Jun 2015 11:45:17 -0000 > @@ -4,9 +4,9 @@ On OpenBSD USB controllers are shown as > itinial limit too small. On a recent machine this value is almost > always exceeded, so bump it. > > ---- libusb/core.c.orig Fri Apr 20 08:44:27 2012 > -+++ libusb/core.c Tue Jun 12 15:48:05 2012 > -@@ -468,7 +468,7 @@ libusb_free_device_list(list, 1); > +--- libusb/core.c.orig Sun Jan 26 00:06:33 2014 > ++++ libusb/core.c Mon Jan 27 10:08:37 2014 > +@@ -448,7 +448,7 @@ libusb_free_device_list(list, 1); > * which grows when required. it can be freed once discovery has completed, > * eliminating the need for a list node in the libusb_device structure > * itself. */ > Index: patches/patch-libusb_os_openbsd_usb_c > =================================================================== > RCS file: /cvs/ports/devel/libusb1/patches/patch-libusb_os_openbsd_usb_c,v > retrieving revision 1.5 > diff -u -p -r1.5 patch-libusb_os_openbsd_usb_c > --- patches/patch-libusb_os_openbsd_usb_c 22 Apr 2013 08:37:20 -0000 > 1.5 > +++ patches/patch-libusb_os_openbsd_usb_c 16 Jun 2015 11:45:17 -0000 > @@ -1,570 +0,0 @@ > -$OpenBSD: patch-libusb_os_openbsd_usb_c,v 1.5 2013/04/22 08:37:20 mpi Exp $ > - > -Add support for non ugen(4) attached devices through usb(4) buses. > - > ---- libusb/os/openbsd_usb.c.orig Fri Apr 20 08:44:27 2012 > -+++ libusb/os/openbsd_usb.c Sun Apr 21 12:39:40 2013 > -@@ -1,5 +1,5 @@ > - /* > -- * Copyright (c) 2011 Martin Pieuchot <m...@openbsd.org> > -+ * Copyright (c) 2011-2013 Martin Pieuchot <m...@openbsd.org> > - * > - * This library is free software; you can redistribute it and/or > - * modify it under the terms of the GNU Lesser General Public > -@@ -32,8 +32,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 */ > -@@ -82,11 +82,14 @@ static int obsd_clock_gettime(int, struct timespec *); > - * Private functions > - */ > - static int _errno_to_libusb(int); > --static int _cache_active_config_descriptor(struct libusb_device *, int); > -+static int _cache_active_config_descriptor(struct libusb_device *); > - static int _sync_control_transfer(struct usbi_transfer *); > - static int _sync_gen_transfer(struct usbi_transfer *); > - static int _access_endpoint(struct libusb_transfer *); > - > -+static int _bus_open(int); > -+ > -+ > - const struct usbi_os_backend openbsd_backend = { > - "Synchronous OpenBSD backend", > - NULL, /* init() */ > -@@ -128,75 +131,105 @@ const struct usbi_os_backend openbsd_backend = { > - 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 *ddd; > - struct libusb_device *dev; > - struct device_priv *dpriv; > - struct usb_device_info di; > -+ struct usb_device_ddesc dd; > - 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; > -+ bzero(devices, sizeof(devices)); > -+ for (addr = 1; addr < USB_MAX_DEVICES; addr++) { > -+ if (devices[addr]) > -+ continue; > - > -- session_id = (di.udi_bus << 8 | di.udi_addr); > -- dev = usbi_get_device_by_session_id(ctx, session_id); > -+ di.udi_addr = addr; > -+ if (ioctl(fd, USB_DEVICEINFO, &di) < 0) > -+ continue; > - > -- if (dev == NULL) { > -- dev = usbi_alloc_device(ctx, session_id); > -- if (dev == NULL) > -- return (LIBUSB_ERROR_NO_MEM); > -+ /* > -+ * 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; > -+ } > - > -- dev->bus_number = di.udi_bus; > -- dev->device_address = di.udi_addr; > -- dev->speed = di.udi_speed; > -+ session_id = (di.udi_bus << 8 | di.udi_addr); > -+ dev = usbi_get_device_by_session_id(ctx, session_id); > - > -- dpriv = (struct device_priv *)dev->os_priv; > -- strlcpy(dpriv->devnode, devnode, sizeof(devnode)); > -- dpriv->fd = -1; > -+ if (dev == NULL) { > -+ dev = usbi_alloc_device(ctx, session_id); > -+ if (dev == NULL) { > -+ close(fd); > -+ return (LIBUSB_ERROR_NO_MEM); > -+ } > - > -- if (ioctl(fd, USB_GET_DEVICE_DESC, &dpriv->ddesc) < > 0) { > -- err = errno; > -- goto error; > -+ 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; > -+ > -+ dd.udd_bus = di.udi_bus; > -+ dd.udd_addr = di.udi_addr; > -+ if (ioctl(fd, USB_DEVICE_GET_DDESC, &dd) < 0) > { > -+ libusb_unref_device(dev); > -+ continue; > -+ } > -+ dpriv->ddesc = dd.udd_desc; > -+ > -+ if (_cache_active_config_descriptor(dev)) { > -+ libusb_unref_device(dev); > -+ continue; > -+ } > -+ > -+ if (usbi_sanitize_device(dev)) > -+ libusb_unref_device(dev); > - } > - > -- dpriv->cdesc = NULL; > -- if (_cache_active_config_descriptor(dev, fd)) { > -- err = errno; > -- goto error; > -+ ddd = discovered_devs_append(*discdevs, dev); > -+ if (ddd == NULL) { > -+ close(fd); > -+ return (LIBUSB_ERROR_NO_MEM); > - } > - > -- if ((err = usbi_sanitize_device(dev))) > -- goto error; > -+ *discdevs = ddd; > -+ 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 > -@@ -204,16 +237,22 @@ obsd_open(struct libusb_device_handle *handle) > - { > - 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", devnode, dpriv->fd); > - } > - > -- usbi_dbg("open %s: fd %d", dpriv->devnode, dpriv->fd); > -- > - if (pipe(hpriv->pipe) < 0) > - return _errno_to_libusb(errno); > - > -@@ -226,10 +265,12 @@ obsd_close(struct libusb_device_handle *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]); > - > -@@ -257,9 +298,8 @@ obsd_get_active_config_descriptor(struct libusb_device > - unsigned char *buf, size_t len, int *host_endian) > - { > - struct device_priv *dpriv = (struct device_priv *)dev->os_priv; > -- usb_config_descriptor_t *ucd; > -+ usb_config_descriptor_t *ucd = (usb_config_descriptor_t > *)dpriv->cdesc; > - > -- ucd = (usb_config_descriptor_t *) dpriv->cdesc; > - len = MIN(len, UGETW(ucd->wTotalLength)); > - > - usbi_dbg("len %d", len); > -@@ -275,35 +315,27 @@ 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; > -+ struct usb_device_fdesc udf; > - int fd, err; > - > -- usbi_dbg("index %d, len %d", idx, len); > -+ if ((fd = _bus_open(dev->bus_number)) < 0) > -+ return _errno_to_libusb(errno); > - > -- /* 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); > -- } > -+ udf.udf_bus = dev->bus_number; > -+ udf.udf_addr = dev->device_address; > -+ udf.udf_config_index = idx; > -+ udf.udf_size = len; > -+ udf.udf_data = buf; > - > -- ufd.ufd_config_index = idx; > -- ufd.ufd_size = len; > -- ufd.ufd_data = buf; > -+ usbi_dbg("index %d, len %d", udf.udf_config_index, len); > - > -- if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) { > -+ if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) { > - err = errno; > -- if (dpriv->fd < 0) > -- close(fd); > -+ close(fd); > - return _errno_to_libusb(err); > - } > -+ close(fd); > - > -- if (dpriv->fd < 0) > -- close(fd); > -- > - *host_endian = 0; > - > - return (LIBUSB_SUCCESS); > -@@ -313,14 +345,12 @@ int > - obsd_get_configuration(struct libusb_device_handle *handle, int *config) > - { > - struct device_priv *dpriv = (struct device_priv > *)handle->dev->os_priv; > -+ usb_config_descriptor_t *ucd = (usb_config_descriptor_t > *)dpriv->cdesc; > - > -- usbi_dbg(""); > -+ *config = ucd->bConfigurationValue; > - > -- if (ioctl(dpriv->fd, USB_GET_CONFIG, config) < 0) > -- return _errno_to_libusb(errno); > -+ usbi_dbg("bConfigurationValue %d", *config); > - > -- usbi_dbg("configuration %d", *config); > -- > - return (LIBUSB_SUCCESS); > - } > - > -@@ -329,12 +359,15 @@ obsd_set_configuration(struct libusb_device_handle *ha > - { > - struct device_priv *dpriv = (struct device_priv > *)handle->dev->os_priv; > - > -- 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); > -+ return _cache_active_config_descriptor(handle->dev); > - } > - > - int > -@@ -369,6 +402,9 @@ obsd_set_interface_altsetting(struct libusb_device_han > - 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)); > -@@ -385,19 +421,27 @@ obsd_set_interface_altsetting(struct libusb_device_han > - 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); > - } > -@@ -418,6 +462,7 @@ obsd_destroy_device(struct libusb_device *dev) > - usbi_dbg(""); > - > - free(dpriv->cdesc); > -+ free(dpriv->devname); > - } > - > - int > -@@ -557,6 +602,8 @@ obsd_clock_gettime(int clkid, struct timespec *tp) > - int > - _errno_to_libusb(int err) > - { > -+ usbi_dbg("error: %s (%d)", strerror(err), err); > -+ > - switch (err) { > - case EIO: > - return (LIBUSB_ERROR_IO); > -@@ -566,52 +613,64 @@ _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) > - { > - struct device_priv *dpriv = (struct device_priv *)dev->os_priv; > -- struct usb_config_desc ucd; > -- struct usb_full_desc ufd; > -+ struct usb_device_cdesc udc; > -+ struct usb_device_fdesc udf; > - 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) > -+ udc.udc_bus = dev->bus_number; > -+ udc.udc_addr = dev->device_address; > -+ udc.udc_config_index = USB_CURRENT_CONFIG_INDEX; > -+ if (ioctl(fd, USB_DEVICE_GET_CDESC, &udc) < 0) { > -+ err = errno; > -+ close(fd); > - return _errno_to_libusb(errno); > -+ } > - > -- usbi_dbg("active bLength %d", ucd.ucd_desc.bLength); > -+ usbi_dbg("active bLength %d", udc.udc_desc.bLength); > - > -- len = UGETW(ucd.ucd_desc.wTotalLength); > -+ len = UGETW(udc.udc_desc.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; > -+ udf.udf_bus = dev->bus_number; > -+ udf.udf_addr = dev->device_address; > -+ udf.udf_config_index = udc.udc_config_index; > -+ udf.udf_size = len; > -+ udf.udf_data = buf; > - > -- usbi_dbg("index %d, len %d", ufd.ufd_config_index, len); > -+ usbi_dbg("index %d, len %d", udf.udf_config_index, len); > - > -- if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) { > -+ if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) { > -+ 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 > -@@ -626,12 +685,13 @@ _sync_control_transfer(struct usbi_transfer *itransfer > - 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 */ > -@@ -643,12 +703,31 @@ _sync_control_transfer(struct usbi_transfer *itransfer > - 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; > - > - usbi_dbg("transferred %d", itransfer->transferred); > -@@ -661,7 +740,7 @@ _access_endpoint(struct libusb_transfer *transfer) > - { > - struct handle_priv *hpriv; > - struct device_priv *dpriv; > -- char *s, devnode[16]; > -+ char devnode[16]; > - int fd, endpt; > - mode_t mode; > - > -@@ -674,10 +753,9 @@ _access_endpoint(struct libusb_transfer *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)) > -@@ -694,10 +772,15 @@ 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 > - * endpoint and thus the node to open. > -@@ -724,4 +807,14 @@ _sync_gen_transfer(struct usbi_transfer *itransfer) > - itransfer->transferred = nr; > - > - return (0); > -+} > -+ > -+int > -+_bus_open(int number) > -+{ > -+ char busnode[16]; > -+ > -+ snprintf(busnode, sizeof(busnode), USBDEV "%d", number); > -+ > -+ return open(busnode, O_RDWR); > - } > -- "If you try a few times and give up, you'll never get there. But if you keep at it... There's a lot of problems in the world which can really be solved by applying two or three times the persistence that other people will." -- Stewart Nelson