none
USB Device wont enumerate if another device previously connected RRS feed

  • Question

  • Hello,

    We have a USB HID device (lets call it device A) and we’re developing a replacement product (device B) which is a composite USB device defining two interfaces, the first is a HID interface identical to that of device A, the second interface defines bulk endpoints which I communicate with using WinUSB.

    Both devices work fine and have had extensive testing.

    I’ve kept the Vendor & Product IDs the same on both devices, only the revision number has changed (bcdDevice field within the Device descriptor).

    Unfortunately, I’ve discovered an enumeration problem in the following scenario…

    • Device A is connected to a PC, it enumerates without problems.
    • Device A is unplugged.
    • Device B is then connected to the same PC, enumeration fails.

    In this situation Windows provides no error or PNP prompts, the only way a user knows that anything has gone wrong is by looking in Device Manager and seeing a yellow exclamation mark.

    In Device Manager, under ‘Human Interface Device’ is a listing for ‘USB Input Device’ with the yellow exclamation.

    Interestingly, if I right click this listing and select ‘Update Driver Software…’ then eventually the drivers install and the device works fine.

    I’ve logged events using USBTrace, during enumeration Windows successfully retrieves the Device and then Configuration descriptors.  Then there is URB_FUNCTION_SELECT_CONFIGURATION which fails with USBD_STATUS_INAVLID_CONFIGURATION_DESCRIPTOR (0xC0000F00).  Enumeration stops at this point.

    Unfortunately, I’m not familiar with URB functions and Windows drivers in general (which is why I use HID & WinUSB – I can use the Microsoft supplied drivers) and I’m hoping that someone here can help.

    When URB_FUNCTION_SELECT_CONFIGURATION succeeds with device B (that is, when Device A hasn’t been previously connected) then the URB header field ‘Length’ is set to 0x100, but when the function fails, the Length field is set to 0x70 which just so happens to be the same as when the function is called while enumerating Device A.  It looks as if Windows is reusing information from Device A when enumerating Device B despite the fact that the devices have different revision numbers (bcdDevice field within the Device descriptor).

    I've verified this issue in Windows Vista & 7. I've not yet tried other OS versions.

    Should this work or am I wrong to assume that I can add an Interface to a USB device without changing its Product ID?

    Device B Device & Configuration descriptors are below, Device A descriptors are virtually identical except they do not include the second interface and bcdDevice is different.

    Device Descriptor:
    bcdUSB:             0x0200
    bDeviceClass:         0x00
    bDeviceSubClass:      0x00
    bDeviceProtocol:      0x00
    bMaxPacketSize0:      0x08 (8)
    idVendor:           0x1781
    idProduct:          0x07E4
    bcdDevice:          0x0002     //Device A has bcdDevice = 0x0001
    iManufacturer:        0x01
    iProduct:             0x02
    iSerialNumber:        0x00
    bNumConfigurations:   0x01

    Configuration Descriptor:
    wTotalLength:       0x0055
    bNumInterfaces:       0x02  //Device A has
    bNumInterfaces = 0x01
    bConfigurationValue:  0x01
    iConfiguration:       0x00
    bmAttributes:         0xC0 (Bus Powered Self Powered )
    MaxPower:             0x00 (0 Ma)

    Interface Descriptor:
    bInterfaceNumber:     0x00
    bAlternateSetting:    0x00
    bNumEndpoints:        0x02
    bInterfaceClass:      0x03 (HID)
    bInterfaceSubClass:   0x00
    bInterfaceProtocol:   0x00
    iInterface:           0x04

    HID Descriptor:
    bcdHID:             0x0112
    bCountryCode:         0x00
    bNumDescriptors:      0x01
    bDescriptorType:      0x22
    wDescriptorLength:  0x0022

    Endpoint Descriptor:
    bEndpointAddress:     0x81  IN
    Transfer Type:   Interrupt
    wMaxPacketSize:     0x0040 (64)
    bInterval:            0x01

    Endpoint Descriptor:
    bEndpointAddress:     0x01  OUT
    Transfer Type:   Interrupt
    wMaxPacketSize:     0x0001 (1)
    bInterval:            0x64

    Interface Descriptor:  //New to Device B
    bInterfaceNumber:     0x01
    bAlternateSetting:    0x00
    bNumEndpoints:        0x05
    bInterfaceClass:      0xFF
    bInterfaceSubClass:   0x00
    bInterfaceProtocol:   0x00
    iInterface:           0x03

    Endpoint Descriptor:
    bEndpointAddress:     0x82  IN
    Transfer Type:        Bulk
    wMaxPacketSize:     0x0040 (64)
    bInterval:            0x00

    Endpoint Descriptor:
    bEndpointAddress:     0x83  IN
    Transfer Type:        Bulk
    wMaxPacketSize:     0x0040 (64)
    bInterval:            0x00

    Endpoint Descriptor:
    bEndpointAddress:     0x84  IN
    Transfer Type:        Bulk
    wMaxPacketSize:     0x0040 (64)
    bInterval:            0x00

    Endpoint Descriptor:
    bEndpointAddress:     0x85  IN
    Transfer Type:        Bulk
    wMaxPacketSize:     0x0040 (64)
    bInterval:            0x00

    Endpoint Descriptor:
    bEndpointAddress:     0x86  IN
    Transfer Type:        Bulk
    wMaxPacketSize:     0x0040 (64)
    bInterval:            0x00

    I'd appreciate expert advice,

    Thanks, Warwick

    Friday, October 24, 2014 1:22 PM

Answers

  • change the pid and should start working

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Friday, October 24, 2014 4:37 PM

All replies

  • change the pid and should start working

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Friday, October 24, 2014 4:37 PM
  • Hello,

    Thanks for your response.

    I appreciate that changing the Pid (or Vid) for that matter would ensure that there would be no confusion or  conflict between two devices.

    But, what I didn't make clear in my initial post, is that I want Device B to be a replacement for Device A.  Existing software that works with Device A identifies the device using the unique Vid & Pid identifiers.  Device B implements the same HID interface as Device A and if Vid & Pid remain unchanged then the existing software should also work with Device B.  New software could also take advantage of the 2nd interface exposed by Device B.

    So my question is, have I assumed incorrectly that two different devices can share the same Vid & Pid but have different revisions (different value in the bcdDevice field) and still function properly in Windows?

    Thanks,

    Warwick


    Friday, October 24, 2014 6:40 PM
  • your devices have the same identity even if the configuration is different based on the vid/pid. I don't think bcdDevice comes into play for identity.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Friday, October 24, 2014 8:32 PM
  • Thanks for your comments.  You're right, my software can be easily modified to work with either device even if their PIDs are different.  There seems little point in trying to figure out why Windows is getting confused when the PIDs are the same.  I'll assign a new PID to device B and move on.

    Kind Regards,
    Warwick
    • Proposed as answer by Pavel A Tuesday, October 28, 2014 5:35 AM
    Monday, October 27, 2014 4:31 PM