The new custom USB device we're using in production is causing us problems. The software seems to be losing the connection to the device and is unable to reconnect. The operator has to unplug and replug it, and sometimes quit the program or even reboot the computer to make it work again. Of course, since it is used in a factory environment, the immediate suspect was ESD (electrostatic discharge). But we had tested the design quite thoroughly for ESD performance. In fact, since ESD damage was one of the major problems we were having with the system that was replaced by this new device, ESD performance was high on the list of requirements. Of utmost importance was that the device would survive ESD events undamaged. It also had to be capable of transparently reconnecting to the system, in case an ESD event caused the device to get into a confused state.
At the time we were evaluating the design, I was hard at work on the device firmware, and there was hardly any PC side software written. There was only a thin API layer on top of libusb-1.0, which could be integrated into to a C/C++ program (its final target) and for which I had also generated Python bindings using SWIG on Linux. The Python bindings made for an awesome development interface to communicate with my immature firmware using the Python command line, or some small test scripts. For the ESD test, I was able to use this interface to quickly whip up a Python ESD test script, that would check if the I/O interface of the device survived the applied ESD event and would also reconnect to the device if the ESD event caused communication to be lost. Our design passed with flying colors. It would survive ESD events up to 20kV and even though it would lose connection regularly, the system would always reconnect transparently and carry on its operation.
That was on Linux. Enter Windows, and things tend to go downhill fast, as we're finding out now. After I was done with the firmware, I integrated the new system into our legacy software that is unfortunately running on Windows. There were plenty of problems with that (including some very nasty BSOD's because I was feeding it too much data at once and Windows developers don't bother to check buffer limits, even in their kernel), but eventually it seemed to work fine. Until now.
I verified that the system would not reconnect with any software call I'd throw at it. Reportedly, unplugging and replugging worked for some people, but didn't seem to work on my test system. Restarting the program didn't either. The only thing that seemed to work reliably was rebooting (I am not surprised, we are talking about Windows after all). Then I verified that the same ESD event would cause a disconnect on Linux, and it did. Only, on Linux I just needed to do an API call to reconnect and everything worked fine again. So why would the system transparently reconnect in Linux but not in Windows?
It seems the reason is that Linux is an operating system and Windows is a bad joke. The libusb Windows backend page explained the reason:
Neither WinUSB or HID can be used to send an actual reset command to an USB device. This is a limitation of the Microsoft drivers.
Beautiful. Maybe I should just dump the whole thing and rewrite everything from scratch to run on Linux? The way things have been going, I would have been done with that by now if I had chosen that option from the start, instead of wasting all this time fighting with Windows. Why do people want to use this joke of an OS? If it isn't capable of keeping either its hardware or its software under control, than what's the point? Isn't that what an OS is supposed to do?