From 0f1fe9e438a594b2b177fa48494f5118f6726f95 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 6 Dec 2020 14:40:35 +0100 Subject: [PATCH] hosted/linux: Find BMP devices without libusb. --- src/platforms/hosted/bmp_serial.c | 144 +++++++++++++++++++++++++++++- src/platforms/hosted/platform.c | 2 +- 2 files changed, 142 insertions(+), 4 deletions(-) diff --git a/src/platforms/hosted/bmp_serial.c b/src/platforms/hosted/bmp_serial.c index 53325be..bd369fa 100644 --- a/src/platforms/hosted/bmp_serial.c +++ b/src/platforms/hosted/bmp_serial.c @@ -19,8 +19,10 @@ /* Find all known serial connected debuggers */ +#include +#include +#include #include "general.h" -#include #include "platform.h" #include "bmp_hosted.h" #include "version.h" @@ -28,13 +30,149 @@ void bmp_ident(bmp_info_t *info) { (void) info; - DEBUG_INFO("BMP hosted %s\n", FIRMWARE_VERSION); + DEBUG_INFO("BMP hosted (BMP Only) %s\n", FIRMWARE_VERSION); } void libusb_exit_function(bmp_info_t *info) {(void)info;}; + + +#ifdef __APPLE__ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info) { (void)cl_opts; (void)info; return -1; -}; +} +#elif defined(__WIN32__) || defined(__CYGWIN__) +int find_debuggers(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info) +{ + (void)cl_opts; + (void)info; + return -1; +} +#else +#define BMP_IDSTRING "usb-Black_Sphere_Technologies_Black_Magic_Probe" +#define DEVICE_BY_ID "/dev/serial/by-id/" + +/* + * Extract type, version and serial from /dev/serial/by_id + * Return 0 on success + * + * Old versions have different strings. Try to cope! + */ +static int scan_linux_id(char *name, char *type, char *version, char *serial) +{ + name += strlen(BMP_IDSTRING) + 1; + while (*name == '_') + name++; + if (!*name) { + DEBUG_WARN("Unexpected end\n"); + return -1; + } + char *p = strchr(name, '_'); + if (!p) { + DEBUG_WARN("type not found\n"); + return -1; + } + strncpy(type, name, p - name); + name = p; + while (*name != 'v') + name++; + if (!*name) { + DEBUG_WARN("Unexpected end after type\n"); + return -1; + } + p = strchr(name, '_'); + if (!p) { + DEBUG_WARN("version not found\n"); + return -1; + } + strncpy(version, name, p - name); + name = p; + while (*name == '_') + name++; + if (!*name) { + DEBUG_WARN("Unexpected end after version\n"); + return -1; + } + p = strchr(name, '-'); + if (!p) { + DEBUG_WARN("Serial not found\n"); + return -1; + } + strncpy(serial, name, p - name); + return 0; +} + +int find_debuggers(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info) +{ + char name[4096]; + if (cl_opts->opt_device) + return 1; + info->bmp_type = BMP_TYPE_BMP; + DIR *dir = opendir(DEVICE_BY_ID); + if (!dir) { + DEBUG_WARN("Could not opendir %s: %s\n", name, strerror(errno)); + return -1; + } + int found_bmps = 0; + struct dirent *dp; + int i = 0; + while ((dp = readdir(dir)) != NULL) { + if ((strstr(dp->d_name, BMP_IDSTRING)) && + (strstr(dp->d_name, "-if00"))) { + i++; + char type[256], version[256], serial[256]; + if (scan_linux_id(dp->d_name, type, version, serial)) { + DEBUG_WARN("Unexpected device name found \"%s\"\n", + dp->d_name); + } + if ((cl_opts->opt_serial && !strstr(cl_opts->opt_serial, serial)) || + (cl_opts->opt_position && cl_opts->opt_position == i)) { + /* With serial number given and partial match, we are done!*/ + strncpy(info->serial, serial, sizeof(info->serial)); + strncpy(info->manufacturer, "BMP", sizeof(info->manufacturer)); + strncpy(info->product, type, sizeof(info->product)); + strncpy(info->version, version, sizeof(info->version)); + found_bmps = 1; + break; + } else { + found_bmps++; + } + } + } + closedir(dir); + if (found_bmps < 1) { + DEBUG_WARN("No BMP probe found\n"); + return -1; + } else if (found_bmps > 1) { + DEBUG_INFO("Available Probes:\n"); + } + dir = opendir(DEVICE_BY_ID); + i = 0; + while ((dp = readdir(dir)) != NULL) { + if ((strstr(dp->d_name, BMP_IDSTRING)) && + (strstr(dp->d_name, "-if00"))) { + i++; + char type[256], version[256], serial[256]; + if (scan_linux_id(dp->d_name, type, version, serial)) { + DEBUG_WARN("Unexpected device name found \"%s\"\n", + dp->d_name); + } else if (found_bmps == 1) { + strncpy(info->serial, serial, sizeof(info->serial)); + found_bmps = 1; + strncpy(info->serial, serial, sizeof(info->serial)); + strncpy(info->manufacturer, "BMP", sizeof(info->manufacturer)); + strncpy(info->product, type, sizeof(info->product)); + strncpy(info->version, version, sizeof(info->version)); + break; + } else if (found_bmps > 1) { + DEBUG_WARN("%2d: %s, Black Sphere Technologies, Black Magic " + "Probe (%s), %s\n", i, serial, type, version); + } + } + } + closedir(dir); + return (found_bmps == 1) ? 0 : 1; +} +#endif diff --git a/src/platforms/hosted/platform.c b/src/platforms/hosted/platform.c index 42857b9..8df0dbe 100644 --- a/src/platforms/hosted/platform.c +++ b/src/platforms/hosted/platform.c @@ -46,7 +46,7 @@ jtag_proc_t jtag_proc; void gdb_ident(char *p, int count) { - snprintf(p, count, "\n for %s (%s), %s\n", info.manufacturer, info.product, + snprintf(p, count, "%s (%s), %s", info.manufacturer, info.product, info.version); }