From a8d1eb7963e5811e16e8fb7e157cf3a00d888347 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Mon, 19 Sep 2011 15:41:39 +0100 Subject: [PATCH] Windows: add USB 3.0 controller support * Windows 8, NEC/Renesas, TI, Fresco Logic, Etron, VIA, ASMedia (some of which untested!) * includes workaround for NEC/Renesas USB 3.0 root hubs --- libusb/os/windows_usb.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c index f8f1fcd..a96c8c4 100644 --- a/libusb/os/windows_usb.c +++ b/libusb/os/windows_usb.c @@ -245,7 +245,7 @@ static int init_dlls(void) * Parameters: * dev_info: a pointer to a dev_info list * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed) - * guid: the GUID for which to retrieve interface details + * usb_class: the generic USB class for which to retrieve interface details * index: zero based index of the interface in the device info list * * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA @@ -253,10 +253,10 @@ static int init_dlls(void) * incremented index starting at zero) until all interfaces have been returned. */ static bool get_devinfo_data(struct libusb_context *ctx, - HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, unsigned _index) + HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, char* usb_class, unsigned _index) { if (_index <= 0) { - *dev_info = pSetupDiGetClassDevsA(NULL, "USB", NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES); + *dev_info = pSetupDiGetClassDevsA(NULL, usb_class, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES); if (*dev_info == INVALID_HANDLE_VALUE) { return false; } @@ -1183,7 +1183,8 @@ static int set_composite_interface(struct libusb_context* ctx, struct libusb_dev static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs) { struct discovered_devs *discdevs = *_discdevs; - HDEVINFO dev_info; + HDEVINFO dev_info = { 0 }; + char* usb_class[2] = {"USB", "NUSB3"}; SP_DEVINFO_DATA dev_info_data; SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL; #define MAX_ENUM_GUIDS 64 @@ -1193,6 +1194,7 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered #define GEN_PASS 2 #define DEV_PASS 3 int r = LIBUSB_SUCCESS; + int class_index = 0; unsigned int nb_guids, pass, i, j, ancestor; char path[MAX_PATH_LENGTH]; char strbuf[MAX_PATH_LENGTH]; @@ -1202,6 +1204,7 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered char* dev_id_path = NULL; unsigned long session_id; DWORD size, reg_type, port_nr, install_state; + BOOL b = FALSE; HKEY key; WCHAR guid_string_w[MAX_GUID_STRING_LENGTH]; GUID* if_guid; @@ -1283,9 +1286,14 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered } } } else { - if (!get_devinfo_data(ctx, &dev_info, &dev_info_data, i)) { - break; + // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are + // being listed under the "NUSB3" PnP Symbolic Name rather than "USB" + while ( (class_index < 2) && + (!(b = get_devinfo_data(ctx, &dev_info, &dev_info_data, usb_class[class_index], i))) ) { + class_index++; + i = 0; } + if (!b) break; } // Read the Device ID path. This is what we'll use as UID @@ -2211,7 +2219,7 @@ static int unsupported_copy_transfer_data(struct usbi_transfer *itransfer, uint3 } // These names must be uppercase -const char* hub_driver_names[] = {"USBHUB"}; +const char* hub_driver_names[] = {"USBHUB", "USBHUB3", "NUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3"}; const char* composite_driver_names[] = {"USBCCGP"}; const char* winusb_driver_names[] = {"WINUSB"}; const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = { -- 2.7.4