X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Fjlink.c;h=8ce7c0d22fda8a39e24961da5706292654160164;hp=c81579ab29e9a39242f584f53c020b57aed6ecda;hb=85ed41d2100ba2f451ba8ff3d75abbeb8cf10a29;hpb=57962f4d1c2db12dffa03c7357f5d7e0d8f71fb8 diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index c81579ab29..8ce7c0d22f 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -38,6 +38,7 @@ #include #include #include +#include #include @@ -50,6 +51,7 @@ static uint8_t caps[JAYLINK_DEV_EXT_CAPS_SIZE]; static uint32_t serial_number; static bool use_serial_number; +static bool use_usb_location; static enum jaylink_usb_address usb_address; static bool use_usb_address; static enum jaylink_target_interface iface = JAYLINK_TIF_JTAG; @@ -534,6 +536,31 @@ static int jaylink_log_handler(const struct jaylink_context *ctx, return 0; } +static bool jlink_usb_location_equal(struct jaylink_device *dev) +{ + int retval; + uint8_t bus; + uint8_t *ports; + size_t num_ports; + bool equal = false; + + retval = jaylink_device_get_usb_bus_ports(dev, &bus, &ports, &num_ports); + + if (retval == JAYLINK_ERR_NOT_SUPPORTED) { + return false; + } else if (retval != JAYLINK_OK) { + LOG_WARNING("jaylink_device_get_usb_bus_ports() failed: %s.", + jaylink_strerror(retval)); + return false; + } + + equal = jtag_usb_location_equal(bus, ports, num_ports); + free(ports); + + return equal; +} + + static int jlink_init(void) { int ret; @@ -595,7 +622,9 @@ static int jlink_init(void) return ERROR_JTAG_INIT_FAILED; } - if (!use_serial_number && !use_usb_address && num_devices > 1) { + use_usb_location = (jtag_usb_get_location() != NULL); + + if (!use_serial_number && !use_usb_address && !use_usb_location && num_devices > 1) { LOG_ERROR("Multiple devices found, specify the desired device."); jaylink_free_devices(devs, true); jaylink_exit(jayctx); @@ -605,8 +634,10 @@ static int jlink_init(void) found_device = false; for (i = 0; devs[i]; i++) { + struct jaylink_device *dev = devs[i]; + if (use_serial_number) { - ret = jaylink_device_get_serial_number(devs[i], &tmp); + ret = jaylink_device_get_serial_number(dev, &tmp); if (ret == JAYLINK_ERR_NOT_AVAILABLE) { continue; @@ -621,7 +652,7 @@ static int jlink_init(void) } if (use_usb_address) { - ret = jaylink_device_get_usb_address(devs[i], &address); + ret = jaylink_device_get_usb_address(dev, &address); if (ret == JAYLINK_ERR_NOT_SUPPORTED) { continue; @@ -635,7 +666,10 @@ static int jlink_init(void) continue; } - ret = jaylink_open(devs[i], &devh); + if (use_usb_location && !jlink_usb_location_equal(dev)) + continue; + + ret = jaylink_open(dev, &devh); if (ret == JAYLINK_OK) { found_device = true; @@ -923,17 +957,17 @@ COMMAND_HANDLER(jlink_usb_command) int tmp; if (CMD_ARGC != 1) { - command_print(CMD_CTX, "Need exactly one argument for jlink usb."); + command_print(CMD, "Need exactly one argument for jlink usb."); return ERROR_COMMAND_SYNTAX_ERROR; } if (sscanf(CMD_ARGV[0], "%i", &tmp) != 1) { - command_print(CMD_CTX, "Invalid USB address: %s.", CMD_ARGV[0]); + command_print(CMD, "Invalid USB address: %s.", CMD_ARGV[0]); return ERROR_FAIL; } if (tmp < JAYLINK_USB_ADDRESS_0 || tmp > JAYLINK_USB_ADDRESS_3) { - command_print(CMD_CTX, "Invalid USB address: %s.", CMD_ARGV[0]); + command_print(CMD, "Invalid USB address: %s.", CMD_ARGV[0]); return ERROR_FAIL; } @@ -950,17 +984,17 @@ COMMAND_HANDLER(jlink_serial_command) int ret; if (CMD_ARGC != 1) { - command_print(CMD_CTX, "Need exactly one argument for jlink serial."); + command_print(CMD, "Need exactly one argument for jlink serial."); return ERROR_COMMAND_SYNTAX_ERROR; } ret = jaylink_parse_serial_number(CMD_ARGV[0], &serial_number); if (ret == JAYLINK_ERR) { - command_print(CMD_CTX, "Invalid serial number: %s.", CMD_ARGV[0]); + command_print(CMD, "Invalid serial number: %s.", CMD_ARGV[0]); return ERROR_FAIL; } else if (ret != JAYLINK_OK) { - command_print(CMD_CTX, "jaylink_parse_serial_number() failed: %s.", + command_print(CMD, "jaylink_parse_serial_number() failed: %s.", jaylink_strerror(ret)); return ERROR_FAIL; } @@ -979,20 +1013,20 @@ COMMAND_HANDLER(jlink_handle_hwstatus_command) ret = jaylink_get_hardware_status(devh, &status); if (ret != JAYLINK_OK) { - command_print(CMD_CTX, "jaylink_get_hardware_status() failed: %s.", + command_print(CMD, "jaylink_get_hardware_status() failed: %s.", jaylink_strerror(ret)); return ERROR_FAIL; } - command_print(CMD_CTX, "VTarget = %u.%03u V", + command_print(CMD, "VTarget = %u.%03u V", status.target_voltage / 1000, status.target_voltage % 1000); - command_print(CMD_CTX, "TCK = %u TDI = %u TDO = %u TMS = %u SRST = %u " + command_print(CMD, "TCK = %u TDI = %u TDO = %u TMS = %u SRST = %u " "TRST = %u", status.tck, status.tdi, status.tdo, status.tms, status.tres, status.trst); if (status.target_voltage < 1500) - command_print(CMD_CTX, "Target voltage too low. Check target power."); + command_print(CMD, "Target voltage too low. Check target power."); return ERROR_OK; } @@ -1003,7 +1037,7 @@ COMMAND_HANDLER(jlink_handle_free_memory_command) uint32_t tmp; if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_FREE_MEMORY)) { - command_print(CMD_CTX, "Retrieval of free memory is not supported by " + command_print(CMD, "Retrieval of free memory is not supported by " "the device."); return ERROR_OK; } @@ -1011,12 +1045,12 @@ COMMAND_HANDLER(jlink_handle_free_memory_command) ret = jaylink_get_free_memory(devh, &tmp); if (ret != JAYLINK_OK) { - command_print(CMD_CTX, "jaylink_get_free_memory() failed: %s.", + command_print(CMD, "jaylink_get_free_memory() failed: %s.", jaylink_strerror(ret)); return ERROR_FAIL; } - command_print(CMD_CTX, "Device has %u bytes of free memory.", tmp); + command_print(CMD, "Device has %u bytes of free memory.", tmp); return ERROR_OK; } @@ -1038,10 +1072,10 @@ COMMAND_HANDLER(jlink_handle_jlink_jtag_command) return ERROR_FAIL; } - command_print(CMD_CTX, "JTAG command version: %i", version); + command_print(CMD, "JTAG command version: %i", version); } else if (CMD_ARGC == 1) { if (sscanf(CMD_ARGV[0], "%i", &tmp) != 1) { - command_print(CMD_CTX, "Invalid argument: %s.", CMD_ARGV[0]); + command_print(CMD, "Invalid argument: %s.", CMD_ARGV[0]); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -1053,11 +1087,11 @@ COMMAND_HANDLER(jlink_handle_jlink_jtag_command) jtag_command_version = JAYLINK_JTAG_VERSION_3; break; default: - command_print(CMD_CTX, "Invalid argument: %s.", CMD_ARGV[0]); + command_print(CMD, "Invalid argument: %s.", CMD_ARGV[0]); return ERROR_COMMAND_SYNTAX_ERROR; } } else { - command_print(CMD_CTX, "Need exactly one argument for jlink jtag."); + command_print(CMD, "Need exactly one argument for jlink jtag."); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -1070,13 +1104,13 @@ COMMAND_HANDLER(jlink_handle_target_power_command) int enable; if (CMD_ARGC != 1) { - command_print(CMD_CTX, "Need exactly one argument for jlink " + command_print(CMD, "Need exactly one argument for jlink " "targetpower."); return ERROR_COMMAND_SYNTAX_ERROR; } if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SET_TARGET_POWER)) { - command_print(CMD_CTX, "Target power supply is not supported by the " + command_print(CMD, "Target power supply is not supported by the " "device."); return ERROR_OK; } @@ -1086,14 +1120,14 @@ COMMAND_HANDLER(jlink_handle_target_power_command) } else if (!strcmp(CMD_ARGV[0], "off")) { enable = false; } else { - command_print(CMD_CTX, "Invalid argument: %s.", CMD_ARGV[0]); + command_print(CMD, "Invalid argument: %s.", CMD_ARGV[0]); return ERROR_FAIL; } ret = jaylink_set_target_power(devh, enable); if (ret != JAYLINK_OK) { - command_print(CMD_CTX, "jaylink_set_target_power() failed: %s.", + command_print(CMD, "jaylink_set_target_power() failed: %s.", jaylink_strerror(ret)); return ERROR_FAIL; } @@ -1101,49 +1135,49 @@ COMMAND_HANDLER(jlink_handle_target_power_command) return ERROR_OK; } -static void show_config_usb_address(struct command_context *ctx) +static void show_config_usb_address(struct command_invocation *cmd) { if (config.usb_address != tmp_config.usb_address) - command_print(ctx, "USB address: %u [%u]", config.usb_address, + command_print(cmd, "USB address: %u [%u]", config.usb_address, tmp_config.usb_address); else - command_print(ctx, "USB address: %u", config.usb_address); + command_print(cmd, "USB address: %u", config.usb_address); } -static void show_config_ip_address(struct command_context *ctx) +static void show_config_ip_address(struct command_invocation *cmd) { if (!memcmp(config.ip_address, tmp_config.ip_address, 4)) - command_print(ctx, "IP address: %d.%d.%d.%d", + command_print(cmd, "IP address: %d.%d.%d.%d", config.ip_address[3], config.ip_address[2], config.ip_address[1], config.ip_address[0]); else - command_print(ctx, "IP address: %d.%d.%d.%d [%d.%d.%d.%d]", + command_print(cmd, "IP address: %d.%d.%d.%d [%d.%d.%d.%d]", config.ip_address[3], config.ip_address[2], config.ip_address[1], config.ip_address[0], tmp_config.ip_address[3], tmp_config.ip_address[2], tmp_config.ip_address[1], tmp_config.ip_address[0]); if (!memcmp(config.subnet_mask, tmp_config.subnet_mask, 4)) - command_print(ctx, "Subnet mask: %d.%d.%d.%d", + command_print(cmd, "Subnet mask: %d.%d.%d.%d", config.subnet_mask[3], config.subnet_mask[2], config.subnet_mask[1], config.subnet_mask[0]); else - command_print(ctx, "Subnet mask: %d.%d.%d.%d [%d.%d.%d.%d]", + command_print(cmd, "Subnet mask: %d.%d.%d.%d [%d.%d.%d.%d]", config.subnet_mask[3], config.subnet_mask[2], config.subnet_mask[1], config.subnet_mask[0], tmp_config.subnet_mask[3], tmp_config.subnet_mask[2], tmp_config.subnet_mask[1], tmp_config.subnet_mask[0]); } -static void show_config_mac_address(struct command_context *ctx) +static void show_config_mac_address(struct command_invocation *cmd) { if (!memcmp(config.mac_address, tmp_config.mac_address, 6)) - command_print(ctx, "MAC address: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x", + command_print(cmd, "MAC address: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x", config.mac_address[5], config.mac_address[4], config.mac_address[3], config.mac_address[2], config.mac_address[1], config.mac_address[0]); else - command_print(ctx, "MAC address: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x " + command_print(cmd, "MAC address: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x " "[%.02x:%.02x:%.02x:%.02x:%.02x:%.02x]", config.mac_address[5], config.mac_address[4], config.mac_address[3], config.mac_address[2], @@ -1153,7 +1187,7 @@ static void show_config_mac_address(struct command_context *ctx) tmp_config.mac_address[1], tmp_config.mac_address[0]); } -static void show_config_target_power(struct command_context *ctx) +static void show_config_target_power(struct command_invocation *cmd) { const char *target_power; const char *current_target_power; @@ -1169,24 +1203,24 @@ static void show_config_target_power(struct command_context *ctx) current_target_power = "on"; if (config.target_power != tmp_config.target_power) - command_print(ctx, "Target power supply: %s [%s]", target_power, + command_print(cmd, "Target power supply: %s [%s]", target_power, current_target_power); else - command_print(ctx, "Target power supply: %s", target_power); + command_print(cmd, "Target power supply: %s", target_power); } -static void show_config(struct command_context *ctx) +static void show_config(struct command_invocation *cmd) { - command_print(ctx, "J-Link device configuration:"); + command_print(cmd, "J-Link device configuration:"); - show_config_usb_address(ctx); + show_config_usb_address(cmd); if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_SET_TARGET_POWER)) - show_config_target_power(ctx); + show_config_target_power(cmd); if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_ETHERNET)) { - show_config_ip_address(ctx); - show_config_mac_address(ctx); + show_config_ip_address(cmd); + show_config_mac_address(cmd); } } @@ -1346,27 +1380,27 @@ COMMAND_HANDLER(jlink_handle_config_usb_address_command) uint8_t tmp; if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { - command_print(CMD_CTX, "Reading configuration is not supported by the " + command_print(CMD, "Reading configuration is not supported by the " "device."); return ERROR_OK; } if (!CMD_ARGC) { - show_config_usb_address(CMD_CTX); + show_config_usb_address(CMD); } else if (CMD_ARGC == 1) { if (sscanf(CMD_ARGV[0], "%" SCNd8, &tmp) != 1) { - command_print(CMD_CTX, "Invalid USB address: %s.", CMD_ARGV[0]); + command_print(CMD, "Invalid USB address: %s.", CMD_ARGV[0]); return ERROR_FAIL; } if (tmp > JAYLINK_USB_ADDRESS_3) { - command_print(CMD_CTX, "Invalid USB address: %u.", tmp); + command_print(CMD, "Invalid USB address: %u.", tmp); return ERROR_FAIL; } tmp_config.usb_address = tmp; } else { - command_print(CMD_CTX, "Need exactly one argument for jlink config " + command_print(CMD, "Need exactly one argument for jlink config " "usb."); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -1379,32 +1413,32 @@ COMMAND_HANDLER(jlink_handle_config_target_power_command) int enable; if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { - command_print(CMD_CTX, "Reading configuration is not supported by the " + command_print(CMD, "Reading configuration is not supported by the " "device."); return ERROR_OK; } if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SET_TARGET_POWER)) { - command_print(CMD_CTX, "Target power supply is not supported by the " + command_print(CMD, "Target power supply is not supported by the " "device."); return ERROR_OK; } if (!CMD_ARGC) { - show_config_target_power(CMD_CTX); + show_config_target_power(CMD); } else if (CMD_ARGC == 1) { if (!strcmp(CMD_ARGV[0], "on")) { enable = true; } else if (!strcmp(CMD_ARGV[0], "off")) { enable = false; } else { - command_print(CMD_CTX, "Invalid argument: %s.", CMD_ARGV[0]); + command_print(CMD, "Invalid argument: %s.", CMD_ARGV[0]); return ERROR_FAIL; } tmp_config.target_power = enable; } else { - command_print(CMD_CTX, "Need exactly one argument for jlink config " + command_print(CMD, "Need exactly one argument for jlink config " "targetpower."); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -1420,25 +1454,25 @@ COMMAND_HANDLER(jlink_handle_config_mac_address_command) const char *str; if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { - command_print(CMD_CTX, "Reading configuration is not supported by the " + command_print(CMD, "Reading configuration is not supported by the " "device."); return ERROR_OK; } if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_ETHERNET)) { - command_print(CMD_CTX, "Ethernet connectivity is not supported by the " + command_print(CMD, "Ethernet connectivity is not supported by the " "device."); return ERROR_OK; } if (!CMD_ARGC) { - show_config_mac_address(CMD_CTX); + show_config_mac_address(CMD); } else if (CMD_ARGC == 1) { str = CMD_ARGV[0]; if ((strlen(str) != 17) || (str[2] != ':' || str[5] != ':' || \ str[8] != ':' || str[11] != ':' || str[14] != ':')) { - command_print(CMD_CTX, "Invalid MAC address format."); + command_print(CMD, "Invalid MAC address format."); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -1448,18 +1482,18 @@ COMMAND_HANDLER(jlink_handle_config_mac_address_command) } if (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5])) { - command_print(CMD_CTX, "Invalid MAC address: zero address."); + command_print(CMD, "Invalid MAC address: zero address."); return ERROR_COMMAND_SYNTAX_ERROR; } if (!(0x01 & addr[0])) { - command_print(CMD_CTX, "Invalid MAC address: multicast address."); + command_print(CMD, "Invalid MAC address: multicast address."); return ERROR_COMMAND_SYNTAX_ERROR; } memcpy(tmp_config.mac_address, addr, sizeof(addr)); } else { - command_print(CMD_CTX, "Need exactly one argument for jlink config " + command_print(CMD, "Need exactly one argument for jlink config " " mac."); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -1508,19 +1542,19 @@ COMMAND_HANDLER(jlink_handle_config_ip_address_command) uint8_t subnet_bits = 24; if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { - command_print(CMD_CTX, "Reading configuration is not supported by the " + command_print(CMD, "Reading configuration is not supported by the " "device."); return ERROR_OK; } if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_ETHERNET)) { - command_print(CMD_CTX, "Ethernet connectivity is not supported by the " + command_print(CMD, "Ethernet connectivity is not supported by the " "device."); return ERROR_OK; } if (!CMD_ARGC) { - show_config_ip_address(CMD_CTX); + show_config_ip_address(CMD); } else { if (!string_to_ip(CMD_ARGV[0], ip_address, &i)) return ERROR_COMMAND_SYNTAX_ERROR; @@ -1565,19 +1599,19 @@ COMMAND_HANDLER(jlink_handle_config_write_command) int ret; if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { - command_print(CMD_CTX, "Reading configuration is not supported by the " + command_print(CMD, "Reading configuration is not supported by the " "device."); return ERROR_OK; } if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_WRITE_CONFIG)) { - command_print(CMD_CTX, "Writing configuration is not supported by the " + command_print(CMD, "Writing configuration is not supported by the " "device."); return ERROR_OK; } if (!memcmp(&config, &tmp_config, sizeof(struct device_config))) { - command_print(CMD_CTX, "Operation not performed due to no changes in " + command_print(CMD, "Operation not performed due to no changes in " "the configuration."); return ERROR_OK; } @@ -1602,7 +1636,7 @@ COMMAND_HANDLER(jlink_handle_config_write_command) } memcpy(&tmp_config, &config, sizeof(struct device_config)); - command_print(CMD_CTX, "The new device configuration applies after power " + command_print(CMD, "The new device configuration applies after power " "cycling the J-Link device."); return ERROR_OK; @@ -1611,12 +1645,12 @@ COMMAND_HANDLER(jlink_handle_config_write_command) COMMAND_HANDLER(jlink_handle_config_command) { if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { - command_print(CMD_CTX, "Device doesn't support reading configuration."); + command_print(CMD, "Device doesn't support reading configuration."); return ERROR_OK; } if (CMD_ARGC == 0) - show_config(CMD_CTX); + show_config(CMD); return ERROR_OK; } @@ -1732,7 +1766,7 @@ COMMAND_HANDLER(jlink_handle_emucom_read_command) return ERROR_FAIL; } - command_print(CMD_CTX, "%s", buf + length); + command_print(CMD, "%s", buf + length); free(buf); return ERROR_OK; @@ -1772,13 +1806,15 @@ static const struct command_registration jlink_config_subcommand_handlers[] = { .name = "reset", .handler = &jlink_handle_config_reset_command, .mode = COMMAND_EXEC, - .help = "undo configuration changes" + .help = "undo configuration changes", + .usage = "", }, { .name = "write", .handler = &jlink_handle_config_write_command, .mode = COMMAND_EXEC, - .help = "write configuration to the device" + .help = "write configuration to the device", + .usage = "", }, COMMAND_REGISTRATION_DONE }; @@ -1820,13 +1856,15 @@ static const struct command_registration jlink_subcommand_handlers[] = { .name = "freemem", .handler = &jlink_handle_free_memory_command, .mode = COMMAND_EXEC, - .help = "show free device memory" + .help = "show free device memory", + .usage = "", }, { .name = "hwstatus", .handler = &jlink_handle_hwstatus_command, .mode = COMMAND_EXEC, - .help = "show the hardware status" + .help = "show the hardware status", + .usage = "", }, { .name = "usb",