From 231547e4a5736788e8006daebec65fe8c632c56e Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Wed, 5 Sep 2012 22:51:19 +0100 Subject: [PATCH] Windows: Fix handling of composite devices * Pass missing sub_api parameter to set_composite_interface() and composite_submit_control_transfer() * Remove api_flags attribute, that cannot apply for multiple interfaces * Also simplifies the internal ENUM_DEBUG mode * Also move polluting info logging message to debug --- libusb/os/windows_usb.c | 53 ++++++++++++++++--------------------------------- libusb/os/windows_usb.h | 2 -- libusb/version_nano.h | 2 +- 3 files changed, 18 insertions(+), 39 deletions(-) diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c index d19c732..3b751a5 100644 --- a/libusb/os/windows_usb.c +++ b/libusb/os/windows_usb.c @@ -432,7 +432,7 @@ SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details_filter(struct libusb_co // libusb0.sys is connected to this device instance. // If the the device interface guid is {F9F3FF14-AE21-48A0-8A25-8011A7A931D9} then it's a filter. safe_sprintf(filter_path, sizeof("\\\\.\\libusb0-0000"), "\\\\.\\libusb0-%04d", libusb0_symboliclink_index); - usbi_info(ctx,"assigned libusb0 symbolic link %s", filter_path); + usbi_dbg("assigned libusb0 symbolic link %s", filter_path); } else { // libusb0.sys was connected to this device instance at one time; but not anymore. } @@ -1238,8 +1238,6 @@ static int set_composite_interface(struct libusb_context* ctx, struct libusb_dev struct windows_device_priv *priv = _device_priv(dev); int interface_number; - if (priv->api_flags & USB_API_SET) - return LIBUSB_SUCCESS; if (priv->apib->id != USB_API_COMPOSITE) { usbi_err(ctx, "program assertion failed: '%s' is not composite", device_id); return LIBUSB_ERROR_NO_DEVICE; @@ -1263,15 +1261,15 @@ static int set_composite_interface(struct libusb_context* ctx, struct libusb_dev device_id, interface_number); } - // HID devices can have multiple collections (COL##) for each MI_## interface if (priv->usb_interface[interface_number].path != NULL) { - if (api != USB_API_HID) { - usbi_warn(ctx, "program assertion failed %s is not an USB HID collection", device_id); - return LIBUSB_ERROR_OTHER; + if (api == USB_API_HID) { + // HID devices can have multiple collections (COL##) for each MI_## interface + usbi_dbg("interface[%d] already set - ignoring HID collection: %s", + interface_number, device_id); + return LIBUSB_ERROR_ACCESS; } - usbi_dbg("interface[%d] already set - ignoring HID collection: %s", - interface_number, device_id); - return LIBUSB_ERROR_ACCESS; + // In other cases, just use the latest data + safe_free(priv->usb_interface[interface_number].path); } usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path); @@ -1283,7 +1281,6 @@ static int set_composite_interface(struct libusb_context* ctx, struct libusb_dev if (priv->hid == NULL) return LIBUSB_ERROR_NO_MEM; } - priv->api_flags |= USB_API_SET | (1<api_flags & USB_API_SET) - return LIBUSB_SUCCESS; if (priv->hid == NULL) { usbi_err(ctx, "program assertion failed: parent is not HID"); return LIBUSB_ERROR_NO_DEVICE; @@ -1303,11 +1298,14 @@ static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* d usbi_err(ctx, "program assertion failed: max USB interfaces reached for HID device"); return LIBUSB_ERROR_NO_DEVICE; } + if (priv->usb_interface[priv->hid->nb_interfaces].path != NULL) { + safe_free(priv->usb_interface[priv->hid->nb_interfaces].path); + } + priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path; priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID]; usbi_dbg("interface[%d] = %s", priv->hid->nb_interfaces, dev_interface_path); priv->hid->nb_interfaces++; - priv->api_flags |= USB_API_SET; return LIBUSB_SUCCESS; } @@ -1375,26 +1373,9 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) { //#define ENUM_DEBUG #ifdef ENUM_DEBUG - switch(pass) { - case HCD_PASS: - usbi_dbg("PROCESSING HCDs %s", guid_to_string(guid[pass])); - break; - case HUB_PASS: - usbi_dbg("PROCESSING HUBs %s", guid_to_string(guid[pass])); - break; - case DEV_PASS: - usbi_dbg("PROCESSING DEVs %s", guid_to_string(guid[pass])); - break; - case GEN_PASS: - usbi_dbg("PROCESSING GENs"); - break; - case HID_PASS: - usbi_dbg("PROCESSING HIDs %s", guid_to_string(guid[pass])); - break; - default: - usbi_dbg("PROCESSING EXTs %s", guid_to_string(guid[pass])); - break; - } + const char *passname[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" }; + usbi_dbg("\n#### PROCESSING %ss %s", passname[(pass<=HID_PASS)?pass:HID_PASS+1], + (pass!=GEN_PASS)?guid_to_string(guid[pass]):""); #endif for (i = 0; ; i++) { // safe loop: free up any (unprotected) dynamic resource @@ -1652,7 +1633,7 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered dev_interface_path = NULL; } else if (parent_priv->apib->id == USB_API_COMPOSITE) { usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data); - switch (set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api, SUB_API_NOTSET)) { + switch (set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api, sub_api)) { case LIBUSB_SUCCESS: dev_interface_path = NULL; break; @@ -4274,7 +4255,7 @@ static int composite_submit_control_transfer(int sub_api, struct usbi_transfer * continue; } usbi_dbg("using interface %d", i); - return priv->usb_interface[i].apib->submit_control_transfer(sub_api, itransfer); + return priv->usb_interface[i].apib->submit_control_transfer(priv->usb_interface[i].sub_api, itransfer); } } } diff --git a/libusb/os/windows_usb.h b/libusb/os/windows_usb.h index 9a493b6..8c5329b 100644 --- a/libusb/os/windows_usb.h +++ b/libusb/os/windows_usb.h @@ -238,7 +238,6 @@ struct windows_device_priv { uint8_t depth; // distance to HCD uint8_t port; // port number on the hub uint8_t active_config; - uint8_t api_flags; // HID and composite devices require additional data 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 @@ -269,7 +268,6 @@ static inline void windows_device_priv_init(libusb_device* dev) { p->parent_dev = NULL; p->path = NULL; p->apib = &usb_api_backend[USB_API_UNSUPPORTED]; - p->api_flags = 0; p->sub_api = SUB_API_NOTSET; p->hid = NULL; p->active_config = 0; diff --git a/libusb/version_nano.h b/libusb/version_nano.h index d5535f4..8b14dcf 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 10558 +#define LIBUSB_NANO 10559 -- 2.7.4