svn commit: r331419 - head/lib/libusb

Hans Petter Selasky hselasky at FreeBSD.org
Fri Mar 23 09:40:42 UTC 2018


Author: hselasky
Date: Fri Mar 23 09:40:41 2018
New Revision: 331419
URL: https://svnweb.freebsd.org/changeset/base/331419

Log:
  Allow the libusb20_dev_get_port_path() function to be called when the
  USB device is closed. This fixes a compatibility issue with upstream
  libusb.
  
  Found by:	romain@
  MFC after:	1 week

Modified:
  head/lib/libusb/libusb20.c
  head/lib/libusb/libusb20_int.h
  head/lib/libusb/libusb20_ugen20.c

Modified: head/lib/libusb/libusb20.c
==============================================================================
--- head/lib/libusb/libusb20.c	Fri Mar 23 05:37:18 2018	(r331418)
+++ head/lib/libusb/libusb20.c	Fri Mar 23 09:40:41 2018	(r331419)
@@ -77,7 +77,6 @@ dummy_callback(struct libusb20_transfer *xfer)
 #define	dummy_check_connected (void *)dummy_int
 #define	dummy_set_power_mode (void *)dummy_int
 #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_kernel_driver_active (void *)dummy_int
 #define	dummy_detach_kernel_driver (void *)dummy_int
@@ -745,7 +744,26 @@ libusb20_dev_get_power_mode(struct libusb20_device *pd
 int
 libusb20_dev_get_port_path(struct libusb20_device *pdev, uint8_t *buf, uint8_t bufsize)
 {
-	return (pdev->methods->get_port_path(pdev, buf, bufsize));
+
+	if (pdev->port_level == 0) {
+		/*
+		 * Fallback for backends without port path:
+		 */
+		if (bufsize < 2)
+			return (LIBUSB20_ERROR_OVERFLOW);
+		buf[0] = pdev->parent_address;
+		buf[1] = pdev->parent_port;
+		return (2);
+	}
+
+	/* check if client buffer is too small */
+	if (pdev->port_level > bufsize)
+		return (LIBUSB20_ERROR_OVERFLOW);
+
+	/* copy port number information */
+	memcpy(buf, pdev->port_path, pdev->port_level);
+
+	return (pdev->port_level);	/* success */
 }
 
 uint16_t

Modified: head/lib/libusb/libusb20_int.h
==============================================================================
--- head/lib/libusb/libusb20_int.h	Fri Mar 23 05:37:18 2018	(r331418)
+++ head/lib/libusb/libusb20_int.h	Fri Mar 23 09:40:41 2018	(r331419)
@@ -107,7 +107,6 @@ typedef int (libusb20_process_t)(struct libusb20_devic
 typedef int (libusb20_reset_device_t)(struct libusb20_device *pdev);
 typedef int (libusb20_set_power_mode_t)(struct libusb20_device *pdev, uint8_t power_mode);
 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_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);
@@ -131,7 +130,6 @@ typedef void (libusb20_tr_cancel_async_t)(struct libus
   m(n, check_connected) \
   m(n, set_power_mode) \
   m(n, get_power_mode) \
-  m(n, get_port_path) \
   m(n, get_power_usage) \
   m(n, set_alt_index) \
   m(n, set_config_index) \
@@ -237,8 +235,11 @@ struct libusb20_device {
 	uint8_t	is_opened;
 	uint8_t parent_address;
 	uint8_t parent_port;
+	uint8_t port_level;
 
 	char	usb_desc[96];
+#define	LIBUSB20_DEVICE_PORT_PATH_MAX	32
+	uint8_t	port_path[LIBUSB20_DEVICE_PORT_PATH_MAX];
 };
 
 extern const struct libusb20_backend_methods libusb20_ugen20_backend;

Modified: head/lib/libusb/libusb20_ugen20.c
==============================================================================
--- head/lib/libusb/libusb20_ugen20.c	Fri Mar 23 05:37:18 2018	(r331418)
+++ head/lib/libusb/libusb20_ugen20.c	Fri Mar 23 09:40:41 2018	(r331419)
@@ -79,7 +79,6 @@ static libusb20_reset_device_t ugen20_reset_device;
 static libusb20_check_connected_t ugen20_check_connected;
 static libusb20_set_power_mode_t ugen20_set_power_mode;
 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_kernel_driver_active_t ugen20_kernel_driver_active;
 static libusb20_detach_kernel_driver_t ugen20_detach_kernel_driver;
@@ -136,6 +135,7 @@ ugen20_enumerate(struct libusb20_device *pdev, const c
 	const char *tmp = id;
 	struct usb_device_descriptor ddesc;
 	struct usb_device_info devinfo;
+	struct usb_device_port_path udpp;
 	uint32_t plugtime;
 	char buf[64];
 	int f;
@@ -219,6 +219,13 @@ ugen20_enumerate(struct libusb20_device *pdev, const c
 	    pdev->device_address, devinfo.udi_vendor,
 	    devinfo.udi_product, pdev->bus_number);
 
+	/* get device port path, if any */
+	if (ioctl(f, IOUSB(USB_GET_DEV_PORT_PATH), &udpp) == 0 &&
+	    udpp.udp_port_level < LIBUSB20_DEVICE_PORT_PATH_MAX) {
+		memcpy(pdev->port_path, udpp.udp_port_no, udpp.udp_port_level);
+		pdev->port_level = udpp.udp_port_level;
+	}
+
 	error = 0;
 done:
 	close(f);
@@ -648,22 +655,6 @@ ugen20_get_power_mode(struct libusb20_device *pdev, ui
 	}
 	*power_mode = temp;
 	return (0);			/* success */
-}
-
-static int
-ugen20_get_port_path(struct libusb20_device *pdev, uint8_t *buf, uint8_t bufsize)
-{
-	struct usb_device_port_path udpp;
-
-	if (ioctl(pdev->file_ctrl, IOUSB(USB_GET_DEV_PORT_PATH), &udpp))
-		return (LIBUSB20_ERROR_OTHER);
-
-	if (udpp.udp_port_level > bufsize)
-		return (LIBUSB20_ERROR_OVERFLOW);
-
-	memcpy(buf, udpp.udp_port_no, udpp.udp_port_level);
-
-	return (udpp.udp_port_level);	/* success */
 }
 
 static int


More information about the svn-src-all mailing list