[Midnightbsd-cvs] src [12299] trunk/lib/libusb: sync libusb with freebsd 10 stable

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun Feb 2 16:27:12 EST 2020


Revision: 12299
          http://svnweb.midnightbsd.org/src/?rev=12299
Author:   laffer1
Date:     2020-02-02 16:27:11 -0500 (Sun, 02 Feb 2020)
Log Message:
-----------
sync libusb with freebsd 10 stable

Modified Paths:
--------------
    trunk/lib/libusb/Makefile
    trunk/lib/libusb/libusb-0.1.pc
    trunk/lib/libusb/libusb-1.0.pc
    trunk/lib/libusb/libusb-2.0.pc
    trunk/lib/libusb/libusb10.c
    trunk/lib/libusb/libusb10.h
    trunk/lib/libusb/libusb10_hotplug.c
    trunk/lib/libusb/libusb10_io.c
    trunk/lib/libusb/libusb20.3
    trunk/lib/libusb/libusb20.c
    trunk/lib/libusb/libusb20.h
    trunk/lib/libusb/libusb20_int.h
    trunk/lib/libusb/libusb20_ugen20.c

Modified: trunk/lib/libusb/Makefile
===================================================================
--- trunk/lib/libusb/Makefile	2020-02-02 21:21:47 UTC (rev 12298)
+++ trunk/lib/libusb/Makefile	2020-02-02 21:27:11 UTC (rev 12299)
@@ -1,6 +1,6 @@
 # $MidnightBSD$
 #
-# $FreeBSD: stable/10/lib/libusb/Makefile 302275 2016-06-29 10:58:36Z hselasky $
+# $FreeBSD: stable/10/lib/libusb/Makefile 356399 2020-01-06 09:22:33Z hselasky $
 #
 # Makefile for the FreeBSD specific LibUSB 2.0
 #
@@ -223,6 +223,7 @@
 MLINKS += libusb20.3 libusb20_dev_get_info.3
 MLINKS += libusb20.3 libusb20_dev_get_iface_desc.3
 MLINKS += libusb20.3 libusb20_dev_get_desc.3
+MLINKS += libusb20.3 libusb20_dev_get_stats.3
 MLINKS += libusb20.3 libusb20_dev_close.3
 MLINKS += libusb20.3 libusb20_dev_detach_kernel_driver.3
 MLINKS += libusb20.3 libusb20_dev_set_config_index.3

Modified: trunk/lib/libusb/libusb-0.1.pc
===================================================================
--- trunk/lib/libusb/libusb-0.1.pc	2020-02-02 21:21:47 UTC (rev 12298)
+++ trunk/lib/libusb/libusb-0.1.pc	2020-02-02 21:27:11 UTC (rev 12299)
@@ -1,5 +1,4 @@
 # $MidnightBSD$
-# $FreeBSD: stable/10/lib/libusb/libusb-0.1.pc 253637 2013-07-25 03:54:08Z rpaulo $
 prefix=/usr
 exec_prefix=${prefix}
 libdir=${exec_prefix}/lib

Modified: trunk/lib/libusb/libusb-1.0.pc
===================================================================
--- trunk/lib/libusb/libusb-1.0.pc	2020-02-02 21:21:47 UTC (rev 12298)
+++ trunk/lib/libusb/libusb-1.0.pc	2020-02-02 21:27:11 UTC (rev 12299)
@@ -1,5 +1,4 @@
 # $MidnightBSD$
-# $FreeBSD: stable/10/lib/libusb/libusb-1.0.pc 253637 2013-07-25 03:54:08Z rpaulo $
 prefix=/usr
 exec_prefix=${prefix}
 libdir=${exec_prefix}/lib

Modified: trunk/lib/libusb/libusb-2.0.pc
===================================================================
--- trunk/lib/libusb/libusb-2.0.pc	2020-02-02 21:21:47 UTC (rev 12298)
+++ trunk/lib/libusb/libusb-2.0.pc	2020-02-02 21:27:11 UTC (rev 12299)
@@ -1,5 +1,4 @@
 # $MidnightBSD$
-# $FreeBSD: stable/10/lib/libusb/libusb-2.0.pc 253637 2013-07-25 03:54:08Z rpaulo $
 prefix=/usr
 exec_prefix=${prefix}
 libdir=${exec_prefix}/lib

Modified: trunk/lib/libusb/libusb10.c
===================================================================
--- trunk/lib/libusb/libusb10.c	2020-02-02 21:21:47 UTC (rev 12298)
+++ trunk/lib/libusb/libusb10.c	2020-02-02 21:27:11 UTC (rev 12299)
@@ -1,5 +1,5 @@
 /* $MidnightBSD$ */
-/* $FreeBSD: stable/10/lib/libusb/libusb10.c 302275 2016-06-29 10:58:36Z hselasky $ */
+/* $FreeBSD: stable/10/lib/libusb/libusb10.c 345541 2019-03-26 13:46:47Z hselasky $ */
 /*-
  * Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
  * Copyright (c) 2009 Hans Petter Selasky. All rights reserved.
@@ -113,6 +113,19 @@
 	fcntl(f, F_SETFL, flags);
 }
 
+static void
+libusb10_wakeup_event_loop(libusb_context *ctx)
+{
+	uint8_t dummy = 0;
+	int err;
+
+	err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
+	if (err < (int)sizeof(dummy)) {
+		/* ignore error, if any */
+		DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "Waking up event loop failed!");
+	}
+}
+
 int
 libusb_init(libusb_context **context)
 {
@@ -483,7 +496,6 @@
 {
 	libusb_context *ctx = dev->ctx;
 	struct libusb20_device *pdev = dev->os_priv;
-	uint8_t dummy;
 	int err;
 
 	if (devh == NULL)
@@ -505,12 +517,8 @@
 	    POLLOUT | POLLRDNORM | POLLWRNORM);
 
 	/* make sure our event loop detects the new device */
-	dummy = 0;
-	err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
-	if (err < (int)sizeof(dummy)) {
-		/* ignore error, if any */
-		DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open write failed!");
-	}
+	libusb10_wakeup_event_loop(ctx);
+
 	*devh = pdev;
 
 	return (0);
@@ -530,7 +538,7 @@
 	if (ctx == NULL)
 		return (NULL);		/* be NULL safe */
 
-	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid enter");
+	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_with_vid_pid enter");
 
 	if ((i = libusb_get_device_list(ctx, &devs)) < 0)
 		return (NULL);
@@ -554,7 +562,7 @@
 	}
 
 	libusb_free_device_list(devs, 1);
-	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid leave");
+	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_with_vid_pid leave");
 	return (pdev);
 }
 
@@ -563,8 +571,6 @@
 {
 	libusb_context *ctx;
 	struct libusb_device *dev;
-	uint8_t dummy;
-	int err;
 
 	if (pdev == NULL)
 		return;			/* be NULL safe */
@@ -580,12 +586,7 @@
 	libusb_unref_device(dev);
 
 	/* make sure our event loop detects the closed device */
-	dummy = 0;
-	err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
-	if (err < (int)sizeof(dummy)) {
-		/* ignore error, if any */
-		DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close write failed!");
-	}
+	libusb10_wakeup_event_loop(ctx);
 }
 
 libusb_device *
@@ -1320,7 +1321,6 @@
 	int buffsize;
 	int maxframe;
 	int temp;
-	uint8_t dummy;
 
 	dev = libusb_get_device(pdev);
 
@@ -1421,10 +1421,8 @@
 
 failure:
 	libusb10_complete_transfer(pxfer0, sxfer, LIBUSB_TRANSFER_ERROR);
-
 	/* make sure our event loop spins the done handler */
-	dummy = 0;
-	err = write(dev->ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
+	libusb10_wakeup_event_loop(dev->ctx);
 }
 
 /* The following function must be called unlocked */
@@ -1465,6 +1463,8 @@
 	    (libusb20_tr_get_priv_sc1(pxfer0) == sxfer) ||
 	    (libusb20_tr_get_priv_sc1(pxfer1) == sxfer)) {
 		err = LIBUSB_ERROR_BUSY;
+	} else if (dev->device_is_gone != 0) {
+		err = LIBUSB_ERROR_NO_DEVICE;
 	} else {
 
 		/* set pending state */
@@ -1496,6 +1496,7 @@
 	struct libusb20_transfer *pxfer1;
 	struct libusb_super_transfer *sxfer;
 	struct libusb_device *dev;
+	struct libusb_device_handle *devh;
 	uint8_t endpoint;
 	int retval;
 
@@ -1503,12 +1504,12 @@
 		return (LIBUSB_ERROR_INVALID_PARAM);
 
 	/* check if not initialised */
-	if (uxfer->dev_handle == NULL)
+	if ((devh = uxfer->dev_handle) == NULL)
 		return (LIBUSB_ERROR_NOT_FOUND);
 
 	endpoint = uxfer->endpoint;
 
-	dev = libusb_get_device(uxfer->dev_handle);
+	dev = libusb_get_device(devh);
 
 	DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer enter");
 
@@ -1519,8 +1520,8 @@
 
 	CTX_LOCK(dev->ctx);
 
-	pxfer0 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 0);
-	pxfer1 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 1);
+	pxfer0 = libusb10_get_transfer(devh, endpoint, 0);
+	pxfer1 = libusb10_get_transfer(devh, endpoint, 1);
 
 	if (sxfer->state != LIBUSB_SUPER_XFER_ST_PEND) {
 		/* only update the transfer status */
@@ -1532,6 +1533,8 @@
 		sxfer->entry.tqe_prev = NULL;
 		libusb10_complete_transfer(NULL,
 		    sxfer, LIBUSB_TRANSFER_CANCELLED);
+		/* make sure our event loop spins the done handler */
+		libusb10_wakeup_event_loop(dev->ctx);
 	} else if (pxfer0 == NULL || pxfer1 == NULL) {
 		/* not started */
 		retval = LIBUSB_ERROR_NOT_FOUND;
@@ -1538,17 +1541,30 @@
 	} else if (libusb20_tr_get_priv_sc1(pxfer0) == sxfer) {
 		libusb10_complete_transfer(pxfer0,
 		    sxfer, LIBUSB_TRANSFER_CANCELLED);
-		libusb20_tr_stop(pxfer0);
-		/* make sure the queue doesn't stall */
-		libusb10_submit_transfer_sub(
-		    uxfer->dev_handle, endpoint);
+		if (dev->device_is_gone != 0) {
+			/* clear transfer pointer */
+			libusb20_tr_set_priv_sc1(pxfer0, NULL);
+			/* make sure our event loop spins the done handler */
+			libusb10_wakeup_event_loop(dev->ctx);
+		} else {
+			libusb20_tr_stop(pxfer0);
+			/* make sure the queue doesn't stall */
+			libusb10_submit_transfer_sub(devh, endpoint);
+		}
 	} else if (libusb20_tr_get_priv_sc1(pxfer1) == sxfer) {
 		libusb10_complete_transfer(pxfer1,
 		    sxfer, LIBUSB_TRANSFER_CANCELLED);
-		libusb20_tr_stop(pxfer1);
-		/* make sure the queue doesn't stall */
-		libusb10_submit_transfer_sub(
-		    uxfer->dev_handle, endpoint);
+		/* check if handle is still active */
+		if (dev->device_is_gone != 0) {
+			/* clear transfer pointer */
+			libusb20_tr_set_priv_sc1(pxfer1, NULL);
+			/* make sure our event loop spins the done handler */
+			libusb10_wakeup_event_loop(dev->ctx);
+		} else {
+			libusb20_tr_stop(pxfer1);
+			/* make sure the queue doesn't stall */
+			libusb10_submit_transfer_sub(devh, endpoint);
+		}
 	} else {
 		/* not started */
 		retval = LIBUSB_ERROR_NOT_FOUND;
@@ -1577,6 +1593,35 @@
 	}
 }
 
+UNEXPORTED void
+libusb10_cancel_all_transfer_locked(struct libusb20_device *pdev, struct libusb_device *dev)
+{
+	struct libusb_super_transfer *sxfer;
+	unsigned x;
+
+	for (x = 0; x != LIBUSB_NUM_SW_ENDPOINTS; x++) {
+		struct libusb20_transfer *xfer;
+
+		xfer = libusb20_tr_get_pointer(pdev, x);
+		if (xfer == NULL)
+			continue;
+		if (libusb20_tr_pending(xfer) == 0)
+			continue;
+		sxfer = libusb20_tr_get_priv_sc1(xfer);
+		if (sxfer == NULL)
+			continue;
+		/* complete pending transfer */
+		libusb10_complete_transfer(xfer, sxfer, LIBUSB_TRANSFER_ERROR);
+	}
+
+	while ((sxfer = TAILQ_FIRST(&dev->tr_head))) {
+		TAILQ_REMOVE(&dev->tr_head, sxfer, entry);
+
+		/* complete pending transfer */
+		libusb10_complete_transfer(NULL, sxfer, LIBUSB_TRANSFER_ERROR);
+	}
+}
+
 uint16_t
 libusb_cpu_to_le16(uint16_t x)
 {

Modified: trunk/lib/libusb/libusb10.h
===================================================================
--- trunk/lib/libusb/libusb10.h	2020-02-02 21:21:47 UTC (rev 12298)
+++ trunk/lib/libusb/libusb10.h	2020-02-02 21:27:11 UTC (rev 12299)
@@ -1,5 +1,5 @@
 /* $MidnightBSD$ */
-/* $FreeBSD: stable/10/lib/libusb/libusb10.h 302275 2016-06-29 10:58:36Z hselasky $ */
+/* $FreeBSD: stable/10/lib/libusb/libusb10.h 349669 2019-07-03 18:26:07Z hselasky $ */
 /*-
  * Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
  *
@@ -40,22 +40,24 @@
 #define	HOTPLUG_LOCK(ctx) pthread_mutex_lock(&(ctx)->hotplug_lock)
 #define	HOTPLUG_UNLOCK(ctx) pthread_mutex_unlock(&(ctx)->hotplug_lock)
 
-#define	DPRINTF(ctx, dbg, format, args...) do {	\
-    if ((ctx)->debug == dbg) {			\
-	switch (dbg) {				\
-	case LIBUSB_DEBUG_FUNCTION:		\
-		printf("LIBUSB_FUNCTION: "	\
-		    format "\n", ## args);	\
-		break;				\
-	case LIBUSB_DEBUG_TRANSFER:		\
-		printf("LIBUSB_TRANSFER: "	\
-		    format "\n", ## args);	\
-		break;				\
-	default:				\
-		break;				\
-	}					\
-    }						\
-} while(0)
+#define	DPRINTF(ctx, dbg, format, ...) do {			\
+	switch (dbg) {						\
+	case LIBUSB_DEBUG_FUNCTION:				\
+		if ((ctx)->debug & LIBUSB_DEBUG_FUNCTION) {	\
+			printf("LIBUSB_FUNCTION: "		\
+			       format "\n", ## __VA_ARGS__);	\
+		}						\
+		break;						\
+	case LIBUSB_DEBUG_TRANSFER:				\
+		if ((ctx)->debug & LIBUSB_DEBUG_TRANSFER) { 	\
+			printf("LIBUSB_TRANSFER: "		\
+			       format "\n", ## __VA_ARGS__);	\
+		}						\
+		break;						\
+	default:						\
+		break;						\
+	}							\
+} while (0)
 
 /* internal structures */
 
@@ -86,6 +88,8 @@
 	void *user_data;
 };
 
+TAILQ_HEAD(libusb_device_head, libusb_device);
+
 struct libusb_context {
 	int	debug;
 	int	debug_fixed;
@@ -103,7 +107,7 @@
 	TAILQ_HEAD(, libusb_super_pollfd) pollfds;
 	TAILQ_HEAD(, libusb_super_transfer) tr_done;
 	TAILQ_HEAD(, libusb_hotplug_callback_handle_struct) hotplug_cbh;
-  	TAILQ_HEAD(, libusb_device) hotplug_devs;
+	struct libusb_device_head hotplug_devs;
 
 	struct libusb_super_pollfd ctx_poll;
 
@@ -115,6 +119,8 @@
 struct libusb_device {
 	int	refcnt;
 
+	int	device_is_gone;
+
 	uint32_t claimed_interfaces;
 
 	struct libusb_super_pollfd dev_poll;
@@ -133,5 +139,6 @@
 void	libusb10_add_pollfd(libusb_context *ctx, struct libusb_super_pollfd *pollfd, struct libusb20_device *pdev, int fd, short events);
 void	libusb10_remove_pollfd(libusb_context *ctx, struct libusb_super_pollfd *pollfd);
 void	libusb10_cancel_all_transfer(libusb_device *dev);
+void	libusb10_cancel_all_transfer_locked(struct libusb20_device *pdev, struct libusb_device *dev);
 
 #endif					/* __LIBUSB10_H__ */

Modified: trunk/lib/libusb/libusb10_hotplug.c
===================================================================
--- trunk/lib/libusb/libusb10_hotplug.c	2020-02-02 21:21:47 UTC (rev 12298)
+++ trunk/lib/libusb/libusb10_hotplug.c	2020-02-02 21:27:11 UTC (rev 12299)
@@ -1,7 +1,7 @@
 /* $MidnightBSD$ */
-/* $FreeBSD: stable/10/lib/libusb/libusb10_hotplug.c 302275 2016-06-29 10:58:36Z hselasky $ */
+/* $FreeBSD: stable/10/lib/libusb/libusb10_hotplug.c 349669 2019-07-03 18:26:07Z hselasky $ */
 /*-
- * Copyright (c) 2016 Hans Petter Selasky. All rights reserved.
+ * Copyright (c) 2016-2019 Hans Petter Selasky. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -86,20 +86,35 @@
 	return (pcbh->fn(ctx, dev, event, pcbh->user_data));
 }
 
+static int
+libusb_hotplug_enumerate(libusb_context *ctx, struct libusb_device_head *phead)
+{
+	libusb_device **ppdev;
+	ssize_t count;
+	ssize_t x;
+
+	count = libusb_get_device_list(ctx, &ppdev);
+	if (count < 0)
+		return (-1);
+
+	for (x = 0; x != count; x++)
+		TAILQ_INSERT_TAIL(phead, ppdev[x], hotplug_entry);
+
+	libusb_free_device_list(ppdev, 0);
+	return (0);
+}
+
 static void *
 libusb_hotplug_scan(void *arg)
 {
-	TAILQ_HEAD(, libusb_device) hotplug_devs;
+	struct libusb_device_head hotplug_devs;
 	libusb_hotplug_callback_handle acbh;
 	libusb_hotplug_callback_handle bcbh;
 	libusb_context *ctx = arg;
-	libusb_device **ppdev;
 	libusb_device *temp;
 	libusb_device *adev;
 	libusb_device *bdev;
 	unsigned do_loop = 1;
-	ssize_t count;
-	ssize_t x;
 
 	while (do_loop) {
 		usleep(4000000);
@@ -109,14 +124,8 @@
 		TAILQ_INIT(&hotplug_devs);
 
 		if (ctx->hotplug_handler != NO_THREAD) {
-			count = libusb_get_device_list(ctx, &ppdev);
-			if (count < 0)
+			if (libusb_hotplug_enumerate(ctx, &hotplug_devs) < 0)
 				continue;
-			for (x = 0; x != count; x++) {
-				TAILQ_INSERT_TAIL(&hotplug_devs, ppdev[x],
-				    hotplug_entry);
-			}
-			libusb_free_device_list(ppdev, 0);
 		} else {
 			do_loop = 0;
 		}
@@ -192,6 +201,8 @@
 
 	HOTPLUG_LOCK(ctx);
 	if (ctx->hotplug_handler == NO_THREAD) {
+	  	libusb_hotplug_enumerate(ctx, &ctx->hotplug_devs);
+
 		if (pthread_create(&ctx->hotplug_handler, NULL,
 		    &libusb_hotplug_scan, ctx) != 0)
 			ctx->hotplug_handler = NO_THREAD;

Modified: trunk/lib/libusb/libusb10_io.c
===================================================================
--- trunk/lib/libusb/libusb10_io.c	2020-02-02 21:21:47 UTC (rev 12298)
+++ trunk/lib/libusb/libusb10_io.c	2020-02-02 21:27:11 UTC (rev 12299)
@@ -1,5 +1,5 @@
 /* $MidnightBSD$ */
-/* $FreeBSD: stable/10/lib/libusb/libusb10_io.c 302275 2016-06-29 10:58:36Z hselasky $ */
+/* $FreeBSD: stable/10/lib/libusb/libusb10_io.c 339190 2018-10-05 07:50:44Z hselasky $ */
 /*-
  * Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
  *
@@ -160,17 +160,19 @@
 		if (ppdev[i] != NULL) {
 			dev = libusb_get_device(ppdev[i]);
 
-			if (fds[i].revents == 0)
-				err = 0;	/* nothing to do */
-			else
+			if (fds[i].revents != 0) {
 				err = libusb20_dev_process(ppdev[i]);
 
-			if (err) {
-				/* cancel all transfers - device is gone */
-				libusb10_cancel_all_transfer(dev);
+				if (err) {
+					/* set device is gone */
+					dev->device_is_gone = 1;
 
-				/* remove USB device from polling loop */
-				libusb10_remove_pollfd(dev->ctx, &dev->dev_poll);
+					/* remove USB device from polling loop */
+					libusb10_remove_pollfd(dev->ctx, &dev->dev_poll);
+
+					/* cancel all pending transfers */
+					libusb10_cancel_all_transfer_locked(ppdev[i], dev);
+				}
 			}
 			CTX_UNLOCK(ctx);
 			libusb_unref_device(dev);
@@ -179,10 +181,8 @@
 		} else {
 			uint8_t dummy;
 
-			while (1) {
-				if (read(fds[i].fd, &dummy, 1) != 1)
-					break;
-			}
+			while (read(fds[i].fd, &dummy, 1) == 1)
+				;
 		}
 	}
 
@@ -311,6 +311,9 @@
 	if (tv == NULL) {
 		pthread_cond_wait(&ctx->ctx_cond,
 		    &ctx->ctx_lock);
+		/* try to grab polling of actual events, if any */
+		if (ctx->ctx_handler == NO_THREAD)
+			ctx->ctx_handler = pthread_self();
 		return (0);
 	}
 	err = clock_gettime(CLOCK_MONOTONIC, &ts);
@@ -329,6 +332,9 @@
 	}
 	err = pthread_cond_timedwait(&ctx->ctx_cond,
 	    &ctx->ctx_lock, &ts);
+	/* try to grab polling of actual events, if any */
+	if (ctx->ctx_handler == NO_THREAD)
+		ctx->ctx_handler = pthread_self();
 
 	if (err == ETIMEDOUT)
 		return (1);
@@ -488,6 +494,19 @@
 	return (actlen);
 }
 
+static libusb_context *
+libusb10_get_context_by_device_handle(libusb_device_handle *devh)
+{
+	libusb_context *ctx;
+
+	if (devh != NULL)
+		ctx = libusb_get_device(devh)->ctx;
+	else
+		ctx = NULL;
+
+	return (GET_CONTEXT(ctx));
+}
+
 static void
 libusb10_do_transfer_cb(struct libusb_transfer *transfer)
 {
@@ -494,7 +513,7 @@
 	libusb_context *ctx;
 	int *pdone;
 
-	ctx = GET_CONTEXT(NULL);
+	ctx = libusb10_get_context_by_device_handle(transfer->dev_handle);
 
 	DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "sync I/O done");
 
@@ -584,7 +603,8 @@
 	libusb_context *ctx;
 	int ret;
 
-	ctx = GET_CONTEXT(NULL);
+	ctx = libusb10_get_context_by_device_handle(devh);
+
 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer enter");
 
 	ret = libusb10_do_transfer(devh, endpoint, data, length, transferred,
@@ -602,7 +622,8 @@
 	libusb_context *ctx;
 	int ret;
 
-	ctx = GET_CONTEXT(NULL);
+	ctx = libusb10_get_context_by_device_handle(devh);
+
 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer enter");
 
 	ret = libusb10_do_transfer(devh, endpoint, data, length, transferred,

Modified: trunk/lib/libusb/libusb20.3
===================================================================
--- trunk/lib/libusb/libusb20.3	2020-02-02 21:21:47 UTC (rev 12298)
+++ trunk/lib/libusb/libusb20.3	2020-02-02 21:27:11 UTC (rev 12299)
@@ -1,6 +1,6 @@
 .\" $MidnightBSD$
 .\"
-.\" Copyright (c) 2008 Hans Petter Selasky
+.\" Copyright (c) 2008-2019 Hans Petter Selasky
 .\"
 .\" All rights reserved.
 .\"
@@ -25,9 +25,9 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: stable/10/lib/libusb/libusb20.3 250582 2013-05-12 22:22:12Z joel $
+.\" $FreeBSD: stable/10/lib/libusb/libusb20.3 356399 2020-01-06 09:22:33Z hselasky $
 .\"
-.Dd May 3, 2013
+.Dd December 27, 2019
 .Dt LIBUSB20 3
 .Os
 .Sh NAME
@@ -123,6 +123,8 @@
 .Ft const char *
 .Fn libusb20_dev_get_desc "struct libusb20_device *pdev"
 .Ft int
+.Fn libusb20_dev_get_stats "struct libusb20_device *pdev" "struct libusb20_device_stats *pstats"
+.Ft int
 .Fn libusb20_dev_close "struct libusb20_device *pdev"
 .Ft int
 .Fn libusb20_dev_detach_kernel_driver "struct libusb20_device *pdev" "uint8_t iface_index"
@@ -598,6 +600,14 @@
 .
 .Pp
 .
+.Fn libusb20_dev_get_stats
+retrieves the device statistics into the structure pointed to by the
+.Fa pstats
+argument.
+This function returns zero on success else a LIBUSB20_ERROR value is returned.
+.
+.Pp
+.
 .Fn libusb20_dev_close
 will close the given USB device.
 .

Modified: trunk/lib/libusb/libusb20.c
===================================================================
--- trunk/lib/libusb/libusb20.c	2020-02-02 21:21:47 UTC (rev 12298)
+++ trunk/lib/libusb/libusb20.c	2020-02-02 21:27:11 UTC (rev 12299)
@@ -1,5 +1,5 @@
 /* $MidnightBSD$ */
-/* $FreeBSD: stable/10/lib/libusb/libusb20.c 305641 2016-09-09 06:27:25Z hselasky $ */
+/* $FreeBSD: stable/10/lib/libusb/libusb20.c 356399 2020-01-06 09:22:33Z hselasky $ */
 /*-
  * Copyright (c) 2008-2009 Hans Petter Selasky. All rights reserved.
  *
@@ -78,6 +78,7 @@
 #define	dummy_get_power_mode (void *)dummy_int
 #define	dummy_get_port_path (void *)dummy_int
 #define	dummy_get_power_usage (void *)dummy_int
+#define	dummy_get_stats (void *)dummy_int
 #define	dummy_kernel_driver_active (void *)dummy_int
 #define	dummy_detach_kernel_driver (void *)dummy_int
 #define	dummy_do_request_sync (void *)dummy_int
@@ -795,6 +796,7 @@
 {
 	struct LIBUSB20_CONTROL_SETUP_DECODED req;
 	int error;
+	int flags;
 
 	/* make sure memory is initialised */
 	memset(ptr, 0, len);
@@ -821,22 +823,24 @@
 	error = libusb20_dev_request_sync(pdev, &req,
 	    ptr, NULL, 1000, LIBUSB20_TRANSFER_SINGLE_SHORT_NOT_OK);
 	if (error) {
-		return (error);
+		/* try to request full string */
+		req.wLength = 255;
+		flags = 0;
+	} else {
+		/* extract length and request full string */
+		req.wLength = *(uint8_t *)ptr;
+		flags = LIBUSB20_TRANSFER_SINGLE_SHORT_NOT_OK;
 	}
-	req.wLength = *(uint8_t *)ptr;	/* bytes */
 	if (req.wLength > len) {
 		/* partial string read */
 		req.wLength = len;
 	}
-	error = libusb20_dev_request_sync(pdev, &req,
-	    ptr, NULL, 1000, LIBUSB20_TRANSFER_SINGLE_SHORT_NOT_OK);
+	error = libusb20_dev_request_sync(pdev, &req, ptr, NULL, 1000, flags);
+	if (error)
+		return (error);
 
-	if (error) {
-		return (error);
-	}
-	if (((uint8_t *)ptr)[1] != LIBUSB20_DT_STRING) {
+	if (((uint8_t *)ptr)[1] != LIBUSB20_DT_STRING)
 		return (LIBUSB20_ERROR_OTHER);
-	}
 	return (0);			/* success */
 }
 
@@ -933,6 +937,14 @@
 	uint8_t do_close;
 	int error;
 
+	/*
+	 * Catch invalid configuration descriptor reads early on to
+	 * avoid issues with devices that don't check for a valid USB
+	 * configuration read request.
+	 */
+	if (configIndex >= pdev->ddesc.bNumConfigurations)
+		return (NULL);
+
 	if (!pdev->is_opened) {
 		error = libusb20_dev_open(pdev, 0);
 		if (error) {
@@ -1019,6 +1031,31 @@
 	return (pdev->usb_speed);
 }
 
+int
+libusb20_dev_get_stats(struct libusb20_device *pdev, struct libusb20_device_stats *pstats)
+{
+	uint8_t do_close;
+	int error;
+
+	if (!pdev->is_opened) {
+		error = libusb20_dev_open(pdev, 0);
+		if (error == 0) {
+			do_close = 1;
+		} else {
+			do_close = 0;
+		}
+	} else {
+		do_close = 0;
+	}
+
+	error = pdev->methods->get_stats(pdev, pstats);
+
+	if (do_close)
+		(void) libusb20_dev_close(pdev);
+
+	return (error);
+}
+
 /* if this function returns an error, the device is gone */
 int
 libusb20_dev_process(struct libusb20_device *pdev)

Modified: trunk/lib/libusb/libusb20.h
===================================================================
--- trunk/lib/libusb/libusb20.h	2020-02-02 21:21:47 UTC (rev 12298)
+++ trunk/lib/libusb/libusb20.h	2020-02-02 21:27:11 UTC (rev 12299)
@@ -1,5 +1,5 @@
 /* $MidnightBSD$ */
-/* $FreeBSD: stable/10/lib/libusb/libusb20.h 250201 2013-05-03 07:44:58Z hselasky $ */
+/* $FreeBSD: stable/10/lib/libusb/libusb20.h 356399 2020-01-06 09:22:33Z hselasky $ */
 /*-
  * Copyright (c) 2008-2009 Hans Petter Selasky. All rights reserved.
  * Copyright (c) 2007-2008 Daniel Drake.  All rights reserved.
@@ -194,6 +194,12 @@
 	char	quirkname[64 - 12];
 };
 
+struct libusb20_device_stats {
+	uint64_t xfer_ok[4];		/* sorted by USB transfer type, UE_XXX */
+	uint64_t xfer_fail[4];		/* sorted by USB transfer type, UE_XXX */
+	uint64_t xfer_reserved[24];	/* reserved */
+};
+
 #define	LIBUSB20_MAX_FRAME_PRE_SCALE	(1U << 31)
 
 /* USB transfer operations */
@@ -242,6 +248,7 @@
 int	libusb20_dev_set_config_index(struct libusb20_device *pdev, uint8_t configIndex);
 int	libusb20_dev_get_debug(struct libusb20_device *pdev);
 int	libusb20_dev_get_fd(struct libusb20_device *pdev);
+int	libusb20_dev_get_stats(struct libusb20_device *pdev, struct libusb20_device_stats *pstat);
 int	libusb20_dev_kernel_driver_active(struct libusb20_device *pdev, uint8_t iface_index);
 int	libusb20_dev_open(struct libusb20_device *pdev, uint16_t transfer_max);
 int	libusb20_dev_process(struct libusb20_device *pdev);

Modified: trunk/lib/libusb/libusb20_int.h
===================================================================
--- trunk/lib/libusb/libusb20_int.h	2020-02-02 21:21:47 UTC (rev 12298)
+++ trunk/lib/libusb/libusb20_int.h	2020-02-02 21:27:11 UTC (rev 12299)
@@ -1,5 +1,5 @@
 /* $MidnightBSD$ */
-/* $FreeBSD: stable/10/lib/libusb/libusb20_int.h 302275 2016-06-29 10:58:36Z hselasky $ */
+/* $FreeBSD: stable/10/lib/libusb/libusb20_int.h 356399 2020-01-06 09:22:33Z hselasky $ */
 /*-
  * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
  *
@@ -108,10 +108,12 @@
 typedef int (libusb20_get_power_mode_t)(struct libusb20_device *pdev, uint8_t *power_mode);
 typedef int (libusb20_get_port_path_t)(struct libusb20_device *pdev, uint8_t *buf, uint8_t bufsize);
 typedef int (libusb20_get_power_usage_t)(struct libusb20_device *pdev, uint16_t *power_usage);
+typedef int (libusb20_get_stats_t)(struct libusb20_device *pdev, struct libusb20_device_stats *pstats);
 typedef int (libusb20_set_alt_index_t)(struct libusb20_device *pdev, uint8_t iface_index, uint8_t alt_index);
 typedef int (libusb20_set_config_index_t)(struct libusb20_device *pdev, uint8_t index);
 typedef int (libusb20_check_connected_t)(struct libusb20_device *pdev);
 
+
 /* USB transfer specific */
 typedef int (libusb20_tr_open_t)(struct libusb20_transfer *xfer, uint32_t MaxBufSize, uint32_t MaxFrameCount, uint8_t ep_no, uint16_t stream_id, uint8_t pre_scale);
 typedef int (libusb20_tr_close_t)(struct libusb20_transfer *xfer);
@@ -132,6 +134,7 @@
   m(n, get_power_mode) \
   m(n, get_port_path) \
   m(n, get_power_usage) \
+  m(n, get_stats) \
   m(n, set_alt_index) \
   m(n, set_config_index) \
   m(n, tr_cancel_async) \

Modified: trunk/lib/libusb/libusb20_ugen20.c
===================================================================
--- trunk/lib/libusb/libusb20_ugen20.c	2020-02-02 21:21:47 UTC (rev 12298)
+++ trunk/lib/libusb/libusb20_ugen20.c	2020-02-02 21:27:11 UTC (rev 12299)
@@ -1,5 +1,5 @@
 /* $MidnightBSD$ */
-/* $FreeBSD: stable/10/lib/libusb/libusb20_ugen20.c 310280 2016-12-19 18:26:26Z trasz $ */
+/* $FreeBSD: stable/10/lib/libusb/libusb20_ugen20.c 356399 2020-01-06 09:22:33Z hselasky $ */
 /*-
  * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
  *
@@ -80,6 +80,7 @@
 static libusb20_get_power_mode_t ugen20_get_power_mode;
 static libusb20_get_port_path_t ugen20_get_port_path;
 static libusb20_get_power_usage_t ugen20_get_power_usage;
+static libusb20_get_stats_t ugen20_get_stats;
 static libusb20_kernel_driver_active_t ugen20_kernel_driver_active;
 static libusb20_detach_kernel_driver_t ugen20_detach_kernel_driver;
 static libusb20_do_request_sync_t ugen20_do_request_sync;
@@ -678,6 +679,29 @@
 }
 
 static int
+ugen20_get_stats(struct libusb20_device *pdev, struct libusb20_device_stats *pstats)
+{
+	struct usb_device_stats st;
+
+	if (ioctl(pdev->file_ctrl, IOUSB(USB_DEVICESTATS), &st))
+		return (LIBUSB20_ERROR_OTHER);
+
+	memset(pstats, 0, sizeof(*pstats));
+
+	pstats->xfer_ok[0] = st.uds_requests_ok[0];
+	pstats->xfer_ok[1] = st.uds_requests_ok[1];
+	pstats->xfer_ok[2] = st.uds_requests_ok[2];
+	pstats->xfer_ok[3] = st.uds_requests_ok[3];
+
+	pstats->xfer_fail[0] = st.uds_requests_fail[0];
+	pstats->xfer_fail[1] = st.uds_requests_fail[1];
+	pstats->xfer_fail[2] = st.uds_requests_fail[2];
+	pstats->xfer_fail[3] = st.uds_requests_fail[3];
+
+	return (0);			/* success */
+}
+
+static int
 ugen20_kernel_driver_active(struct libusb20_device *pdev,
     uint8_t iface_index)
 {



More information about the Midnightbsd-cvs mailing list