On Tue, Jun 23, 2015 at 4:23 PM, Martin Pieuchot <[email protected]> wrote:
> On 23/06/15(Tue) 14:04, Brandon Mercer wrote:
>> On Tue, Jun 23, 2015 at 5:17 AM Martin Pieuchot <[email protected]> wrote:
>>
>> > On 22/06/15(Mon) 23:56, Jérémie Courrèges-Anglas wrote:
>> > > Martin Pieuchot <[email protected]> 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 <[email protected]>
>
> @@ -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 <[email protected]>
> -+ * Copyright (c) 2011-2013 Martin Pieuchot <[email protected]>
> - *
> - * 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