From beeb8ec30db7c58acad68fd5a75c46e2bd2e3006 Mon Sep 17 00:00:00 2001 From: Bernhard Nortmann Date: Thu, 1 Dec 2016 10:09:23 +0100 Subject: [PATCH 1/2] fel: Add a --list option to enumerate FEL devices "./sunxi-fel --list" enumerates Allwinner USB devices that are in FEL mode. For each device detected, the SoC name/ID and - if available - the SID key will be printed to stdout. The utility then exits with status code 0 (upon success), or 1 if no devices were found. The current implementation treats the list feature as an option, to be able to handle it *before* the first attempt to call feldev_open() - which could fail (with no FEL devices connected). However, a "list" alias is available for users who expect this to be 'command' syntax, so "./sunxi-fel list" works too. Signed-off-by: Bernhard Nortmann --- fel.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/fel.c b/fel.c index 63d6745..0a8c58b 100644 --- a/fel.c +++ b/fel.c @@ -963,10 +963,35 @@ static unsigned int file_upload(feldev_handle *dev, size_t count, return i; /* return number of files that were processed */ } +static void felusb_list_devices(void) +{ + size_t devices; /* FEL device count */ + feldev_list_entry *list, *entry; + + list = list_fel_devices(&devices); + for (entry = list; entry->soc_version.soc_id; entry++) { + printf("USB device %03d:%03d Allwinner %-8s", + entry->busnum, entry->devnum, entry->soc_name); + /* output SID only if non-zero */ + if (entry->SID[0] | entry->SID[1] | entry->SID[2] | entry->SID[3]) + printf("%08x:%08x:%08x:%08x", + entry->SID[0], entry->SID[1], entry->SID[2], entry->SID[3]); + putchar('\n'); + } + free(list); + + if (verbose && devices == 0) + fprintf(stderr, "No Allwinner devices in FEL mode detected.\n"); + + feldev_done(NULL); + exit(devices > 0 ? EXIT_SUCCESS : EXIT_FAILURE); +} + int main(int argc, char **argv) { bool uboot_autostart = false; /* flag for "uboot" command = U-Boot autostart */ bool pflag_active = false; /* -p switch, causing "write" to output progress */ + bool device_list = false; /* -l switch, prints device list and exits */ feldev_handle *handle; int busnum = -1, devnum = -1; @@ -975,6 +1000,7 @@ int main(int argc, char **argv) printf("Usage: %s [options] command arguments... [command...]\n" " -v, --verbose Verbose logging\n" " -p, --progress \"write\" transfers show a progress bar\n" + " -l, --list Enumerate all (USB) FEL devices and exit\n" " -d, --dev bus:devnum Use specific USB bus and device number\n" "\n" " spl file Load and execute U-Boot SPL\n" @@ -1019,6 +1045,9 @@ int main(int argc, char **argv) verbose = true; else if (strcmp(argv[1], "--progress") == 0 || strcmp(argv[1], "-p") == 0) pflag_active = true; + else if (strcmp(argv[1], "--list") == 0 || strcmp(argv[1], "-l") == 0 + || strcmp(argv[1], "list") == 0) + device_list = true; else if (strncmp(argv[1], "--dev", 5) == 0 || strncmp(argv[1], "-d", 2) == 0) { char *dev_arg = argv[1]; dev_arg += strspn(dev_arg, "-dev="); /* skip option chars, ignore '=' */ @@ -1039,6 +1068,9 @@ int main(int argc, char **argv) argv += 1; } + if (device_list) + felusb_list_devices(); /* and exit program afterwards */ + handle = feldev_open(busnum, devnum, AW_USB_VENDOR_ID, AW_USB_PRODUCT_ID); while (argc > 1 ) { From 448fa5f74c0db5c359b72ef4770a8bb84309c947 Mon Sep 17 00:00:00 2001 From: Bernhard Nortmann Date: Mon, 21 Nov 2016 10:17:43 +0100 Subject: [PATCH 2/2] fel: Add "--sid" option to select FEL device by SID Signed-off-by: Bernhard Nortmann --- fel.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/fel.c b/fel.c index 0a8c58b..2285031 100644 --- a/fel.c +++ b/fel.c @@ -987,6 +987,24 @@ static void felusb_list_devices(void) exit(devices > 0 ? EXIT_SUCCESS : EXIT_FAILURE); } +static void select_by_sid(const char *sid_arg, int *busnum, int *devnum) +{ + char sid[36]; + feldev_list_entry *list, *entry; + + list = list_fel_devices(NULL); + for (entry = list; entry->soc_version.soc_id; entry++) { + snprintf(sid, sizeof(sid), "%08x:%08x:%08x:%08x", + entry->SID[0], entry->SID[1], entry->SID[2], entry->SID[3]); + if (strcmp(sid, sid_arg) == 0) { + *busnum = entry->busnum; + *devnum = entry->devnum; + break; + } + } + free(list); +} + int main(int argc, char **argv) { bool uboot_autostart = false; /* flag for "uboot" command = U-Boot autostart */ @@ -994,6 +1012,7 @@ int main(int argc, char **argv) bool device_list = false; /* -l switch, prints device list and exits */ feldev_handle *handle; int busnum = -1, devnum = -1; + char *sid_arg = NULL; if (argc <= 1) { puts("sunxi-fel " VERSION "\n"); @@ -1002,6 +1021,7 @@ int main(int argc, char **argv) " -p, --progress \"write\" transfers show a progress bar\n" " -l, --list Enumerate all (USB) FEL devices and exit\n" " -d, --dev bus:devnum Use specific USB bus and device number\n" + " --sid SID Select device by SID key (exact match)\n" "\n" " spl file Load and execute U-Boot SPL\n" " If file additionally contains a main U-Boot binary\n" @@ -1062,6 +1082,11 @@ int main(int argc, char **argv) exit(1); } pr_info("Selecting USB Bus %03d Device %03d\n", busnum, devnum); + } + else if (strcmp(argv[1], "--sid") == 0 && argc > 2) { + sid_arg = argv[2]; + argc -= 1; + argv += 1; } else break; /* no valid (prefix) option detected, exit loop */ argc -= 1; @@ -1070,6 +1095,16 @@ int main(int argc, char **argv) if (device_list) felusb_list_devices(); /* and exit program afterwards */ + if (sid_arg) { + /* try to set busnum and devnum according to "--sid" option */ + select_by_sid(sid_arg, &busnum, &devnum); + if (busnum <= 0 || devnum <= 0) { + fprintf(stderr, "No matching FEL device found for SID '%s'\n", + sid_arg); + exit(1); + } + pr_info("Selecting FEL device %03d:%03d by SID\n", busnum, devnum); + } handle = feldev_open(busnum, devnum, AW_USB_VENDOR_ID, AW_USB_PRODUCT_ID);