Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

windows 10 only, libusb (1.0.21) appears to be holding on to old device enumeration info #295

Closed
shellriegel opened this issue Apr 28, 2017 · 6 comments
Labels

Comments

@shellriegel
Copy link

I have a custom composite USB device with usbser, winusb, usbstor interfaces.
We have a few hundred devices running for three ish years now, with billions of libusb operations. (Thanks folks!) on win7,8,10.

The unit has a feature in which I send a command to the winusb interface to reconfigure it's usb serial#.
The device soft disconnects from the USB bus, changes part of it's descriptor (the serial number), waits 500ms (or 2seconds, doesn't help the issue) and then reconnects.
Under windows 7, and the virus known as windows 8, this works fine.
Under windows 10, I get a duplicate entry of the old device in my libusb_get_device_list structure.

Below is a data dump. I have libusb debugging turned on (hence the first 3 lines)
The first line (VID 046D) is a USB flash drive that was unplugged during a PRIOR power cycle of the box. Where or why libusb is complaining about this device is a mystery to me. At the same time it may likely be a clue to the what is going on.
Using usbdview, all 3 errant devices are not present.

The second 2 lines (VID 2B2A) refer to the winusb and msc interfaces on my composite device, and the parent id of 17AD5DBB is the old parent from the previous enumeration of my device. (with the old serial number). 2B2A is a private USB VID.

Finally, the 0), 1), 2), is a simple crawl of the libusb_get_device_list with libusb_get_devicedescriptor
There should be only one VID 2B2A in this list (as there is on win7/8); there is only 1 device attached to the PC.

If I reboot, there is in fact only 1 device present, and things work. However, rebooting isn't really an option for the actual use case of the product. (but I still get the gripe about the USB flash drive)

libusb: error [init_device] device '\.\USB#VID_046D&PID_C080&MI_01#6&33F61665&0&0001' is no longer connected!
libusb: error [init_device] device '\.\USB#VID_2B2A&PID_0156&MI_02#6&17AD5DBB&1&0002' is no longer connected!
libusb: error [init_device] device '\.\USB#VID_2B2A&PID_0156&MI_03#6&17AD5DBB&1&0003' is no longer connected!

  1. VID 1B21 PID 1242 CLS 0000 PROT 00
  2. VID 1B1C PID 1B15 CLS 0000 PROT 00
  3. VID 1B1C PID 1B15 CLS 0000 PROT 00
  4. VID 046D PID C080 CLS 0000 PROT 00
  5. VID 2B2A PID 0156 CLS 00EF PROT 01
  6. VID 2B2A PID 0156 CLS 00EF PROT 01
  7. VID 8086 PID A12F CLS 0000 PROT 00

Any suggestions are welcome. I unload libusb as soon as possible after firing off the call that causes the disconnect/modification of the serial number/reconnect. I am confident that I have unloaded the libusb default context, closed libusb, and exited my program before the USB endpoint device performs the soft-disconnect.
The errant behavior happens on 3 different windows 10 Pro boxes. In all cases, the device is connected to the root hub embedded in the Intel chipset. (USB xHCI )

-Steve

@diabolo38
Copy link

diabolo38 commented Apr 29, 2017

" USB endpoint device performs the soft-disconnect." disconnect is not end point but device related and even if s/w driven it is h/w, So what you mean here ? Even by f/w what must be done is to disconnected the device Pull up /dow on, the D+/D- line to get host view a device disconnect and reconnection (force re-enumeration).
But i guess that is what you do as device is re-enumerating somehow

A similar common issue i see often is with "usb serial" device disconnect/reconnect or "f/w reset" not found by host of failing to work. It's because at reconnect time the application (terminal emulator) is stilll holding and using the first "dead" usb device instance so it can be re-created and connected to newly replug (maybe reusign the first zombi one again).
To solve this ensure all app are close (double check in program manager if the app is not still their in a kind of zombi state), then only un/re-plug device. recheck device list. No reboot is needed.
Can you try the same ?

In the past i did some re-enum test with an stm32 f/w doing usb disconnect (10ms) and changing one string https://github.com/diabolo38/STM322F4-disco/tree/reenum_test
the host app was not even closing simply closing handle calling libusb_exit / init again. I could try this again on win10 if it can help.

@shellriegel
Copy link
Author

My endpoint is an Atmel SAM3A with a high speed USB PHY. I tickle the PHY to perform a USB bus disconnect, adjust my USB descriptor, and then reboot the microcontroller after waiting 500ms.

Since the device is composite, there is a serial comm port, the winusb port, and a mass storage class.
The com port was never opened in this case, and the winusb program (using libusb) was closed before the disconnect happens. At least that is what the timestamps on the USB analyzer and the PC say :)
The MSC is a bit of a black hole. msoft has made gratuitous changes to the MSC class over the years. It used to be that if you marked a USB MSC as "non removable" it would not periodically poll the device for status. Now they poll "non removable" MSC devices every 500ms to see if it is still there.

I checked your reenum_test. On win10 if you change only the device serial number, I am confident you will find duplicate entries in your libusb_get_device_list after the reconnect.

Windows 10 introduced a cache for USB enumeration to speed up device attach. It really does speed it up. I don't believe this is a libusb issue anymore, but a win10 USB kernel issue. I will take it up with them.

@diabolo38
Copy link

I did change the f/w adding serial number string change and it is still working fine on my Win10 "home".
I do to see any duplicate
I can even see "device name" changes as device changes it.
Device manager show "Product 0 FS" or "Product 1 FS"
also device compatible h/w id or "device instance path" (my window is french) in details clearly show the 2 different serial no
USB\VID_0525&PID_A4A0\000001 for "product 0 FS"
USB\VID_0525&PID_A4A0\000002 for "product 1 FS"

00001 00002 are the 2 serial number i set device .
renum

So clearly i can't reproduce your issue on my setup , is it linked to win 10 pro ? composite device only ?
the way back end driver get installed or associated to winusb.sys ?

for info I have used Zadig to insall the driver back end (exctract only then manualy installed)
the inf file is specifying only vid/pid no serial number !
the device is not composite but single interface device.

I'll may add one interface to test on a composite device but 2nd interface wan't be associated by any "standard window driver " easily . Unless I customize a demo cdc serial /mass storage / mouse to add an extra interface :( quite some extra work ...

@shellriegel
Copy link
Author

shellriegel commented Apr 30, 2017 via email

@diabolo38
Copy link

I had to rework quite a bit ST "CDC/ACM" class desc to get window happy with serial and the extra composite interface .

bad new this is still working fine on my setup the composite dev and it's 2 function reconnects nicely w/o any duplicates (checked some > 500ms after disconnect).
com port "number" is toggling at every serial number swap what make sense as for window that is two different device.
I noticed the "serial number" doesn't appear any more in devices "path" that come much more complicated ? but serial no is correct as per usb-view.

it is getting tricky , you should post to the libusb mail list see if maintainers have extra clue.

i can share both device and host code if that can hep in your debug just let me know.
here is basically what i do

loops over
libusb_init
List/find device(s) with given vid/pid  
if have device(s) 
   open device #0 
   claim interface associated to winusb (#2 => 3rd one ) 
   Send  "vendor ctrl request"  to device #0 intf #2 , it complete on bus+host s/w before device disconnect.
   after ctrl status 10-20 lms , device disconnect from usb, re-connect after some extra time with different serial no
  release interface 
  close device 
libusb_exit
Sleep (500ms)

I use static Mingw64 libusb lib not the dll (shall not impact behavior).
PC is a CoreI5 6300HQ with intel USB 3.0 xHCI (was ok also on usb2.0 controler)

@mcuee mcuee added the windows label Sep 10, 2017
@mcuee
Copy link
Member

mcuee commented Apr 20, 2018

Close this for now. Please try the latest 1.0.22 version to see if the issue is still there or not. Will reopen if that is the case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants