Fix FreeBSD issue with libusb_get_port_numbers()

Currently (as of date 20150122) an ioctl problem within the
FreeBSD kernel is preventing libusb_get_port_numbers() from working.
Hence calls to libusb_get_port_numbers() will always return 0.
This makes it impossible to establish a physical path the the usb device.

This problem has existed "forever" -
meaning that libusb_get_port_numbers() has never worked.

A fix is committed to FreeBSD "current" head  -
and will later be merged (MFC'ed) to maintenance branches.
See: https://svnweb.freebsd.org/base?view=revision&revision=277417

Additionally FreeBSD requires that devices prior to calling
libusb_get_port_numbers() have been opened with libusb_open().

The patch is "forwards-compatible".
Currently it acts specificly to libusb_get_port_numbers()
currently returning 0 on FreeBSD.
In these situations it constructs an artificial path to the device.
When FreeBSD kernels appears with proper working ioctl
supporting libusb_get_port_numbers() the code will construct
proper physical paths for newer kernels - while still generating
artificial physical paths for older defective kernels.
This commit is contained in:
Uffe Jakobsen 2015-01-22 01:11:22 +01:00 committed by Uwe Hermann
parent 7a8a1aba37
commit 19643b96e2
1 changed files with 19 additions and 0 deletions

View File

@ -276,8 +276,27 @@ SR_PRIV int usb_get_port_path(libusb_device *dev, char *path, int path_len)
uint8_t port_numbers[8]; uint8_t port_numbers[8];
int i, n, len; int i, n, len;
/*
* FreeBSD requires that devices prior to calling libusb_get_port_numbers()
* have been opened with libusb_open().
*/
#ifdef __FreeBSD__
struct libusb_device_handle *devh;
if (libusb_open(dev, &devh) != 0)
return SR_ERR;
#endif
n = libusb_get_port_numbers(dev, port_numbers, sizeof(port_numbers)); n = libusb_get_port_numbers(dev, port_numbers, sizeof(port_numbers));
#ifdef __FreeBSD__
libusb_close(devh);
#endif
/* Workaround FreeBSD libusb_get_port_numbers() returning 0. */
#ifdef __FreeBSD__
if (n == 0) {
port_numbers[0] = libusb_get_device_address(dev);
n = 1;
}
#endif
if (n < 1) if (n < 1)
return SR_ERR; return SR_ERR;