summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPete Batard <pete@akeo.ie>2012-09-05 22:51:19 +0100
committerPete Batard <pete@akeo.ie>2012-09-05 22:53:44 +0100
commit231547e4a5736788e8006daebec65fe8c632c56e (patch)
tree52f85acddb88ddc10a6a43ebe5f7bcd318f434c5
parent8b5ba57e568bb4c5ff03f9e55f3c37e8b36f69ae (diff)
downloadlibusb-231547e4a5736788e8006daebec65fe8c632c56e.tar.gz
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
-rw-r--r--libusb/os/windows_usb.c53
-rw-r--r--libusb/os/windows_usb.h2
-rw-r--r--libusb/version_nano.h2
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);
return LIBUSB_SUCCESS;
}
@@ -1293,8 +1290,6 @@ static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* d
{
struct windows_device_priv *priv = _device_priv(dev);
- if (priv->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