glasgow: Device fails to enumerate when plugged in for the first time on Windows

After the first time the device (with the firmware as shipped by @1bitSquared) is enumerated on Windows 10 Version 10.0.19045 Build 19045, it fails to start:

image

When the device is in this failed state, the Glasgow CLI tool will show the following error:

>glasgow voltage
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "c:\users\maya.maya-domain\.local\bin\glasgow.exe\__main__.py", line 7, in <module>
  File "C:\Users\Maya.MAYA-DOMAIN\AppData\Local\glasgow\software\glasgow\cli.py", line 901, in main
    exit(loop.run_until_complete(_main()))
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Maya.MAYA-DOMAIN\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "C:\Users\Maya.MAYA-DOMAIN\AppData\Local\glasgow\software\glasgow\cli.py", line 493, in _main
    device = GlasgowHardwareDevice(args.serial)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Maya.MAYA-DOMAIN\AppData\Local\glasgow\software\glasgow\device\hardware.py", line 159, in __init__
    devices = self._enumerate_devices(usb_context)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Maya.MAYA-DOMAIN\AppData\Local\glasgow\software\glasgow\device\hardware.py", line 98, in _enumerate_devices
    handle = device.open()
             ^^^^^^^^^^^^^
  File "C:\Users\Maya.MAYA-DOMAIN\AppData\Local\.local\pipx\venvs\glasgow\Lib\site-packages\usb1\__init__.py", line 2055, in open
    mayRaiseUSBError(libusb1.libusb_open(self.device_p, byref(handle)))
  File "C:\Users\Maya.MAYA-DOMAIN\AppData\Local\.local\pipx\venvs\glasgow\Lib\site-packages\usb1\__init__.py", line 127, in mayRaiseUSBError
    __raiseUSBError(value)
  File "C:\Users\Maya.MAYA-DOMAIN\AppData\Local\.local\pipx\venvs\glasgow\Lib\site-packages\usb1\__init__.py", line 119, in raiseUSBError
    raise __STATUS_TO_EXCEPTION_DICT.get(value, __USBError)(value)
usb1.USBErrorNotSupported: LIBUSB_ERROR_NOT_SUPPORTED [-12]

Unplugging the device and plugging it back in resolves the issue.

When it does work, the driver stack is:

\Driver\WINUSB
\Driver\ACPI
\Driver\USBHUB3

When it does not, the driver stack is:

\Driver\ACPI
\Driver\USBHUB3

The status code is 0xc0000001 STATUS_UNSUCCESSFUL, which is unfortunately not very useful. I am not sure what causes the issue. I will be able to capture ETW traces later.

The problem can be reproduced by removing the device using the Device Manager, unplugging it, and plugging it back in.

As far as I can tell the firmware does not have the git commit hash embedded into it, so I’ve included the entire firmware: glasgow.ihex.txt.

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 15 (15 by maintainers)

Commits related to this issue

Most upvoted comments

This isn’t correct. In case of an IN request, it is necessary to wait for EP0CS & _BUSY to clear first.

My apologies; I wasn’t paying enough attention and got confused.

There is no point in waiting for EP0CS & _BUSY to clear in the beginning of the SUDAV deferred interrupt handler because it will never be set at that point:

image image

It only makes sense to wait for EP0CS & _BUSY to clear after an EP0 data transfer has been set up. In case of libfx2, this would be after a call to SETUP_EP0_BUF, SETUP_EP0_IN_DATA, or SETUP_EP0_IN_DESC.

The issue is caused by not stalling EP0 as described here:

image

In addition, it looks like this implementation of STALL_EP0() is incorrect: https://github.com/whitequark/libfx2/blob/82d154153f548b29b1be60f1c11d7a5bc102486d/firmware/library/include/fx2usb.h#L76-L77

It should be EP0CS = _HSNAK|_STALL instead:

image

No, not physical port. It was originally plugged into Port_#0004.Hub_#0002. After plugging it in Port_#0002.Hub_#0002 it works fine.

The device instance path remains the same, USB\VID_20B7&PID_9DB1\C3-20230729T201611Z, so the same device settings are used. It is only the location that is updated when it is plugged in a different port.

  • Did this happen the first ever time, and then never again after re-plugging?

Correct.

  • Does a reboot get it to occur again?

It works fine after a reboot.

(does anything / can you reproduce it?)

You can artificially make it happen the second time by uninstalling the driver using the Device Manager, unplugging the device, and plugging it back in.

Also, I am fairly certain it will happen once per physical device (i.e. VID/PID/DID/serial number combination).