From 5a629d7f767115a31985e4deaabab34a368042d7 Mon Sep 17 00:00:00 2001 From: BensenBernard Date: Tue, 16 Jun 2026 12:07:07 +0530 Subject: [PATCH] quirks: add AM261x device-specific manifest wait quirk - The AM261x ROM DFU implementation resets if the host waits for default 1 second before polling the device in the manifest state. This patch adds a device-specific quirk to set a shorter manifest wait time of 500ms for AM261x devices, preventing the USB ROM reset and allowing successful DFU operations. - Detect AM261x devices by their VID:PID(0451:6169) and apply a device-specific 500ms manifest wait through the quirks mechanism. This preserves the existing behavior for all other devices while allowing reliable firmware downloads on AM261x platforms. Signed-off-by: Bensen Bernard --- src/dfu.h | 1 + src/dfu_load.c | 2 +- src/dfu_util.c | 6 ++++++ src/quirks.c | 7 +++++++ src/quirks.h | 13 ++++++++----- 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/dfu.h b/src/dfu.h index c91c427..94b25e5 100644 --- a/src/dfu.h +++ b/src/dfu.h @@ -98,6 +98,7 @@ struct dfu_if { uint8_t altsetting; uint8_t flags; uint8_t bMaxPacketSize0; + int manifest_wait; /* Manifest state wait timeout in ms, 0 = use default */ char *alt_name; char *serial_name; libusb_device *dev; diff --git a/src/dfu_load.c b/src/dfu_load.c index d81d474..36676b8 100644 --- a/src/dfu_load.c +++ b/src/dfu_load.c @@ -197,7 +197,7 @@ get_status: case DFU_STATE_dfuMANIFEST: /* some devices (e.g. TAS1020b) need some time before we * can obtain the status */ - milli_sleep(1000); + milli_sleep(dif->manifest_wait); goto get_status; break; case DFU_STATE_dfuMANIFEST_WAIT_RST: diff --git a/src/dfu_util.c b/src/dfu_util.c index 8a26ef9..2bd6565 100644 --- a/src/dfu_util.c +++ b/src/dfu_util.c @@ -378,6 +378,12 @@ found_dfu: pdfu->altsetting = intf->bAlternateSetting; pdfu->devnum = libusb_get_device_address(dev); pdfu->busnum = libusb_get_bus_number(dev); + /* Apply device-specific manifest wait based on quirks */ + if (quirks & QUIRK_MANIFEST_WAIT_500MS) { + pdfu->manifest_wait = 500; /* 500ms to prevent USB ROM reset */ + } else { + pdfu->manifest_wait = 1000; /* default 1 second */ + } pdfu->alt_name = strdup(alt_name); if (pdfu->alt_name == NULL) errx(EX_SOFTWARE, "Out of memory"); diff --git a/src/quirks.c b/src/quirks.c index eec9ef9..220d2e6 100755 --- a/src/quirks.c +++ b/src/quirks.c @@ -72,6 +72,13 @@ uint16_t get_quirks(uint16_t vendor, uint16_t product, uint16_t bcdDevice) quirks |= QUIRK_DFUSE_LEAVE; } + /* Texas Instruments AM261x bootloader needs longer timeouts + * for large appimage transfers */ + if (vendor == VENDOR_TI && + product == PRODUCT_TI_AM261x) { + quirks |= QUIRK_MANIFEST_WAIT_500MS; + } + return (quirks); } diff --git a/src/quirks.h b/src/quirks.h index 9f0dc4f..2cfbd44 100755 --- a/src/quirks.h +++ b/src/quirks.h @@ -11,6 +11,7 @@ #define VENDOR_SIEMENS 0x0908 /* Siemens AG */ #define VENDOR_MIDIMAN 0x0763 /* Midiman */ #define VENDOR_GIGADEVICE 0x28e9 /* GigaDevice */ +#define VENDOR_TI 0x0451 /* Texas Instruments */ #define PRODUCT_FREERUNNER_FIRST 0x5117 #define PRODUCT_FREERUNNER_LAST 0x5126 @@ -22,12 +23,14 @@ #define PRODUCT_PXM50 0x02c5 /* Siemens AG, PXM 50 */ #define PRODUCT_TRANSIT 0x2806 /* M-Audio Transit (Midiman) */ #define PRODUCT_GD32 0x0189 /* GigaDevice GD32VF103 rev 1 */ +#define PRODUCT_TI_AM261x 0x6169 /* Texas Instruments AM261x */ -#define QUIRK_POLLTIMEOUT (1<<0) -#define QUIRK_FORCE_DFU11 (1<<1) -#define QUIRK_UTF8_SERIAL (1<<2) -#define QUIRK_DFUSE_LAYOUT (1<<3) -#define QUIRK_DFUSE_LEAVE (1<<4) +#define QUIRK_POLLTIMEOUT (1<<0) +#define QUIRK_FORCE_DFU11 (1<<1) +#define QUIRK_UTF8_SERIAL (1<<2) +#define QUIRK_DFUSE_LAYOUT (1<<3) +#define QUIRK_DFUSE_LEAVE (1<<4) +#define QUIRK_MANIFEST_WAIT_500MS (1<<5) /* Fallback value, works for OpenMoko */ #define DEFAULT_POLLTIMEOUT 5 -- 2.34.1