Skip to content

Commit

Permalink
device.hardware: adjust re-enumeration wait parameters for Windows.
Browse files Browse the repository at this point in the history
Now that libusb will support hotplug events on Windows shortly (see
libusb/libusb#1406), the hotplug wait path will get exercised.
Currently it does not wait for long enough; it takes about 5.5 s on
a representative Windows desktop machine used for testing.

This commit raises re-enumeration timeout to 10.0 s, and ensure that
the timeout is respected no matter how many hotplug events are received.
The higher fixed timeout on older libusb on Windows isn't disruptive,
and with the next libusb release will become irrelevant for most.
  • Loading branch information
whitequark committed Jun 26, 2024
1 parent 33cae38 commit 332a977
Showing 1 changed file with 14 additions and 10 deletions.
24 changes: 14 additions & 10 deletions software/glasgow/device/hardware.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,29 +161,33 @@ def hotplug_callback(usb_context, device, event):
handle.controlWrite(usb1.REQUEST_TYPE_VENDOR, REQ_RAM, REG_CPUCS, 0, [0])
handle.close()

RE_ENUMERATION_TIMEOUT = 10.0

if usb_context.hasCapability(usb1.CAP_HAS_HOTPLUG):
# Hotplug is available; process hotplug events for a while looking for the device
# that re-enumerates after firmware upload. We expect two events (one detach and
# one attach event), but allow for a bit more than that. (It is not possible to
# wait for re-enumeration without some guesswork because USB lacks geographical
# addressing.)
logger.debug(f"waiting for re-enumeration (hotplug event)")
devices_len = len(devices)
for event_count in range(5):
usb_context.handleEventsTimeout(1.0)
deadline = time.time() + RE_ENUMERATION_TIMEOUT
while deadline > time.time():
usb_context.handleEventsTimeout(0.5)
if devices_len < len(devices):
# Found it!
break
break # Found it!
else:
logger.warning("device %03d/%03d did not re-enumerate after firmware upload",
device.getBusNumber(), device.getDeviceAddress())

else:
# No hotplug capability (most likely because we're running on Windows); give
# the device a bit of time to re-enumerate. (The device disconnects from the bus
# for ~1 second, so we should wait a few times that to allow for the variable
# OS and platform delays).
logger.debug("waiting for re-enumeration")
time.sleep(5.0)
# No hotplug capability (most likely because we're running on Windows with an older
# version of libusb); give the device a bit of time to re-enumerate. The device
# disconnects from the bus for ~1 second, so we should wait a few times that
# to allow for the variable OS and platform delays. Windows seems particularly slow
# with a 5-second timeout being insufficient.
logger.debug(f"waiting for re-enumeration (fixed delay)")
time.sleep(RE_ENUMERATION_TIMEOUT)

devices.extend(list(usb_context.getDeviceIterator(skip_on_error=True)))

Expand Down

0 comments on commit 332a977

Please sign in to comment.