3535#include <libusb-1.0/libusb.h>
3636#endif
3737
38- #if defined(__APPLE__ ) /* snprintf is not available in pure C mode */
38+ #if defined(__APPLE__ ) || defined( __FreeBSD__ ) /* snprintf is not available in pure C mode */
3939int snprintf (char * __restrict __str , size_t __size , const char * __restrict __format , ...) __printflike (3 , 4 );
4040#endif
4141
42+ #if !defined(LIBUSB_API_VERSION ) || (LIBUSB_API_VERSION <= 0x01000103 )
43+ #define LIBUSB_DT_SUPERSPEED_HUB 0x2a
44+ #endif
45+
4246#if _POSIX_C_SOURCE >= 199309L
4347#include <time.h> /* for nanosleep */
4448#endif
@@ -314,6 +318,25 @@ static int ports2bitmap(char* const portlist)
314318}
315319
316320
321+ /*
322+ * Compatibility wrapper around libusb_get_port_numbers()
323+ */
324+
325+ static int get_port_numbers (libusb_device * dev , uint8_t * buf , uint8_t bufsize )
326+ {
327+ int pcount ;
328+ #if defined(LIBUSB_API_VERSION ) && (LIBUSB_API_VERSION >= 0x01000102 )
329+ /*
330+ * libusb_get_port_path is deprecated since libusb v1.0.16,
331+ * therefore use libusb_get_port_numbers when supported
332+ */
333+ pcount = libusb_get_port_numbers (dev , buf , bufsize );
334+ #else
335+ pcount = libusb_get_port_path (NULL , dev , buf , bufsize );
336+ #endif
337+ return pcount ;
338+ }
339+
317340/*
318341 * get USB hub properties.
319342 * most hub_info fields are filled, except for description.
@@ -364,15 +387,7 @@ static int get_hub_info(struct libusb_device *dev, struct hub_info *info)
364387 /* Convert bus and ports array into USB location string */
365388 int bus = libusb_get_bus_number (dev );
366389 snprintf (info -> location , sizeof (info -> location ), "%d" , bus );
367- #if defined(LIBUSB_API_VERSION ) && (LIBUSB_API_VERSION >= 0x01000102 )
368- /*
369- * libusb_get_port_path is deprecated since libusb v1.0.16,
370- * therefore use libusb_get_port_numbers when supported
371- */
372- int pcount = libusb_get_port_numbers (dev , port_numbers , MAX_HUB_CHAIN );
373- #else
374- int pcount = libusb_get_port_path (NULL , dev , port_numbers , MAX_HUB_CHAIN );
375- #endif
390+ int pcount = get_port_numbers (dev , port_numbers , MAX_HUB_CHAIN );
376391 int k ;
377392 for (k = 0 ; k < pcount ; k ++ ) {
378393 char s [8 ];
@@ -510,9 +525,17 @@ static int print_port_status(struct hub_info * hub, int portmask)
510525 int port_status ;
511526 struct libusb_device_handle * devh = NULL ;
512527 int rc = 0 ;
528+ int hub_bus ;
529+ int dev_bus ;
530+ unsigned char hub_pn [MAX_HUB_CHAIN ];
531+ unsigned char dev_pn [MAX_HUB_CHAIN ];
532+ int hub_plen ;
533+ int dev_plen ;
513534 struct libusb_device * dev = hub -> dev ;
514535 rc = libusb_open (dev , & devh );
515536 if (rc == 0 ) {
537+ hub_bus = libusb_get_bus_number (dev );
538+ hub_plen = get_port_numbers (dev , hub_pn , sizeof (hub_pn ));
516539 int port ;
517540 for (port = 1 ; port <= hub -> nports ; port ++ ) {
518541 if (portmask > 0 && (portmask & (1 << (port - 1 ))) == 0 ) continue ;
@@ -531,7 +554,12 @@ static int print_port_status(struct hub_info * hub, int portmask)
531554 struct libusb_device * udev ;
532555 int i = 0 ;
533556 while ((udev = usb_devs [i ++ ]) != NULL ) {
534- if (libusb_get_parent (udev ) == dev &&
557+ dev_bus = libusb_get_bus_number (udev );
558+ /* only match devices on the same bus: */
559+ if (dev_bus != hub_bus ) continue ;
560+ dev_plen = get_port_numbers (udev , dev_pn , sizeof (dev_pn ));
561+ if ((dev_plen == hub_plen + 1 ) &&
562+ (memcmp (hub_pn , dev_pn , hub_plen ) == 0 ) &&
535563 libusb_get_port_number (udev ) == port )
536564 {
537565 rc = get_device_description (udev , description , sizeof (description ));
0 commit comments