diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h --- a/lib/libusb/libusb.h +++ b/lib/libusb/libusb.h @@ -516,6 +516,7 @@ int libusb_attach_kernel_driver(libusb_device_handle * devh, int interface); int libusb_set_auto_detach_kernel_driver(libusb_device_handle *dev, int enable); int libusb_set_interface_alt_setting(libusb_device_handle * devh, int interface_number, int alternate_setting); +libusb_device *libusb_get_parent(libusb_device * dev); /* USB Descriptors */ diff --git a/lib/libusb/libusb10.h b/lib/libusb/libusb10.h --- a/lib/libusb/libusb10.h +++ b/lib/libusb/libusb10.h @@ -126,6 +126,7 @@ struct libusb_super_pollfd dev_poll; struct libusb_context *ctx; + struct libusb_device *parent_dev; TAILQ_ENTRY(libusb_device) hotplug_entry; diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c --- a/lib/libusb/libusb10.c +++ b/lib/libusb/libusb10.c @@ -309,9 +309,9 @@ libusb_get_device_list(libusb_context *ctx, libusb_device ***list) { struct libusb20_backend *usb_backend; - struct libusb20_device *pdev; + struct libusb20_device *pdev, *parent_dev; struct libusb_device *dev; - int i; + int i, j, k; ctx = GET_CONTEXT(ctx); @@ -363,6 +363,9 @@ /* set context we belong to */ dev->ctx = ctx; + /* assume we have no parent by default */ + dev->parent_dev = NULL; + /* link together the two structures */ dev->os_priv = pdev; pdev->privLuData = dev; @@ -372,6 +375,25 @@ } (*list)[i] = NULL; + /* for each device, find its parent */ + for (j = 0; j < i; j++) { + pdev = (*list)[j]->os_priv; + + for (k = 0; k < i; k++) { + if (k == j) + continue; + + parent_dev = (*list)[k]->os_priv; + + if (parent_dev->bus_number != pdev->bus_number) + continue; + if (parent_dev->device_address == pdev->parent_address) { + (*list)[j]->parent_dev = libusb_ref_device((*list)[k]); + break; + } + } + } + libusb20_be_free(usb_backend); return (i); } @@ -536,6 +558,7 @@ CTX_UNLOCK(dev->ctx); if (dev->refcnt == 0) { + libusb_unref_device(dev->parent_dev); libusb20_dev_free(dev->os_priv); free(dev); } @@ -812,6 +835,12 @@ return (err ? LIBUSB_ERROR_OTHER : 0); } +libusb_device * +libusb_get_parent(libusb_device *dev) +{ + return (dev->parent_dev); +} + static struct libusb20_transfer * libusb10_get_transfer(struct libusb20_device *pdev, uint8_t endpoint, uint8_t xfer_index)