summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Dickens <christopher.a.dickens@gmail.com>2016-09-13 22:09:50 -0700
committerNathan Hjelm <hjelmn@me.com>2016-10-01 06:59:11 -0600
commit9bf44223d4c0eabbfbf8f9e979767fe424008ec0 (patch)
tree16b527975845968eb8c087e93a553f9115120c23
parent4eca418ef50dcaf3f2fca11158410acd72e8e2e2 (diff)
downloadlibusb-9bf44223d4c0eabbfbf8f9e979767fe424008ec0.tar.gz
Windows: Fix possible false error message during device enumerationv1.0.21-rc6
During early phases of enumeration, it is possible for a device to be enumerated before its parent. When this occurs, the device assigned as the parent will actually be a grandparent. During later phases of enumeration, the parent device will in fact exist but will not match what has already been assigned to the device. This commit adds code to check for and update the parent device when this situation occurs. Closes #206 Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
-rw-r--r--libusb/os/windows_winusb.c18
-rw-r--r--libusb/os/windows_winusb.h2
-rw-r--r--libusb/version_nano.h2
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