From 332a9775a8e44386e70a1964a000e3c0ee986171 Mon Sep 17 00:00:00 2001 From: Catherine Date: Wed, 26 Jun 2024 14:17:09 +0100 Subject: [PATCH] device.hardware: adjust re-enumeration wait parameters for Windows. 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. --- software/glasgow/device/hardware.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/software/glasgow/device/hardware.py b/software/glasgow/device/hardware.py index 9424f9f2e..b9aedd1ec 100644 --- a/software/glasgow/device/hardware.py +++ b/software/glasgow/device/hardware.py @@ -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)))