diff options
-rw-r--r-- | libusb/os/windows_winusb.c | 18 | ||||
-rw-r--r-- | libusb/os/windows_winusb.h | 2 | ||||
-rw-r--r-- | libusb/version_nano.h | 2 |
3 files changed, 13 insertions, 9 deletions
diff --git a/libusb/os/windows_winusb.c b/libusb/os/windows_winusb.c index 81cceef..d1d2749 100644 --- a/libusb/os/windows_winusb.c +++ b/libusb/os/windows_winusb.c @@ -864,12 +864,12 @@ static int force_hcd_device_descriptor(struct libusb_device *dev) priv->dev_descriptor.bNumConfigurations = 1; priv->active_config = 1; - if (priv->parent_dev == NULL) { + if (dev->parent_dev == NULL) { usbi_err(ctx, "program assertion failed - HCD hub has no parent"); return LIBUSB_ERROR_NO_DEVICE; } - parent_priv = _device_priv(priv->parent_dev); + parent_priv = _device_priv(dev->parent_dev); if (sscanf(parent_priv->path, "\\\\.\\PCI#VEN_%04x&DEV_%04x%*s", &vid, &pid) == 2) { priv->dev_descriptor.idVendor = (uint16_t)vid; priv->dev_descriptor.idProduct = (uint16_t)pid; @@ -1043,7 +1043,6 @@ static int init_device(struct libusb_device *dev, struct libusb_device *parent_d priv->port = port_number; dev->port_number = port_number; priv->depth = parent_priv->depth + 1; - priv->parent_dev = parent_dev; dev->parent_dev = parent_dev; // If the device address is already set, we can stop here @@ -1521,9 +1520,16 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered session_id, dev->bus_number, dev->device_address); priv = _device_priv(dev); - if (priv->parent_dev != NULL) { - if (priv->parent_dev != parent_dev) { - usbi_err(ctx, "program assertion failed - existing device should share parent"); + if ((parent_dev != NULL) && (dev->parent_dev != NULL)) { + if (dev->parent_dev != parent_dev) { + // It is possible for the actual parent device to not have existed at the + // time of enumeration, so the currently assigned parent may in fact be a + // grandparent. If the devices differ, we assume the "new" parent device + // is in fact closer to the device. + usbi_dbg("updating parent device [session %lX -> %lX]", + dev->parent_dev->session_data, parent_dev->session_data); + libusb_unref_device(dev->parent_dev); + dev->parent_dev = parent_dev; } else { // We hold a reference to parent_dev instance, but this device already // has a parent_dev reference (only one per child) diff --git a/libusb/os/windows_winusb.h b/libusb/os/windows_winusb.h index 49c1df5..a259374 100644 --- a/libusb/os/windows_winusb.h +++ b/libusb/os/windows_winusb.h @@ -201,7 +201,6 @@ struct windows_device_priv { uint8_t depth; // distance to HCD uint8_t port; // port number on the hub uint8_t active_config; - struct libusb_device *parent_dev; // access to parent is required for usermode ops struct windows_usb_api_backend const *apib; char *path; // device interface path int sub_api; // for WinUSB-like APIs @@ -231,7 +230,6 @@ static inline struct windows_device_priv *windows_device_priv_init(struct libusb p->depth = 0; p->port = 0; - p->parent_dev = NULL; p->path = NULL; p->apib = &usb_api_backend[USB_API_UNSUPPORTED]; p->sub_api = SUB_API_NOTSET; diff --git a/libusb/version_nano.h b/libusb/version_nano.h index e7cb421..59027da 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11150 +#define LIBUSB_NANO 11151 |