This is an automated email from Gerrit. "zapb <[email protected]>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9152
-- gerrit commit d40b1a5983ba8594c7f66d367186d3d627ac4932 Author: Marc Schink <[email protected]> Date: Sun Aug 17 17:09:12 2025 +0000 adapter/parport: Add device file support Allow to specify the parallel port by its device file. Deprecate port number support but keep it for backward compatibility. This is one necessary step to remove direct I/O support for the parallel port driver. While at it, consistently return ERROR_JTAG_INIT_FAILED in case of a failure in parport_init(). Change-Id: Ie68087f05ece4b32ccab9d9bdfbf7e1a779e9031 Signed-off-by: Marc Schink <[email protected]> diff --git a/doc/openocd.texi b/doc/openocd.texi index e5cd907942..4f629ab85a 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -3225,15 +3225,15 @@ The pin direction is given in the following table. @tab 2 @end multitable -@deffn {Config Command} {parport port} port_number -Configure the number of the parallel port. +@deffn {Config Command} {parport port} file +Specify the device file of the parallel port device. +The parallel port device file is usually @file{/dev/parportX} on Linux and @file{/dev/ppiX} on FreeBSD. -When using PPDEV to access the parallel port, use the number of the parallel port file @file{/dev/parport} (Linux) or @file{/dev/ppi} (FreeBSD). -The default port number is 0. +For legacy reason, the port number @var{X} can be specified instead of the device file. +@b{Note:} Using the port number is a deprecated feature and will be removed in the future. When using direct I/O, the number is the I/O port number. The default port number is 0x378 (LTP1). - @b{Note:} Direct I/O support is deprecated and will be removed in the future. @end deffn diff --git a/src/jtag/drivers/parport.c b/src/jtag/drivers/parport.c index b29562b840..89a70e9f9c 100644 --- a/src/jtag/drivers/parport.c +++ b/src/jtag/drivers/parport.c @@ -47,8 +47,7 @@ static const struct adapter_gpio_config *adapter_gpio_config; -static uint16_t parport_port; -static bool parport_write_exit_state; +static char *parport_device_file; static uint32_t parport_toggling_time_ns = 1000; static int wait_states; @@ -258,13 +257,13 @@ static int parport_init(void) if (gpio.gpio_num < 10 || gpio.gpio_num > 15 || gpio.gpio_num == 14) { LOG_ERROR("The '%s' signal pin must be 10, 11, 12, 13, or 15", adapter_gpio_get_name(gpio_index)); - return ERROR_FAIL; + goto init_fail; } } else { if (gpio.gpio_num < 2 || gpio.gpio_num > 9) { LOG_ERROR("The '%s' signal pin must be 2, 3, 4, 5, 6, 7, 8, or 9", adapter_gpio_get_name(gpio_index)); - return ERROR_FAIL; + goto init_fail; } } } @@ -292,35 +291,37 @@ static int parport_init(void) #if PARPORT_USE_PPDEV == 1 if (device_handle > 0) { LOG_ERROR("Parallel port is already open"); - return ERROR_JTAG_INIT_FAILED; + goto init_fail; } - char device_path[256]; - + if (!parport_device_file) { #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - snprintf(device_path, sizeof(device_path), "/dev/ppi%d", parport_port); + parport_device_file = strdup("/dev/ppi0"); #else - snprintf(device_path, sizeof(device_path), "/dev/parport%d", parport_port); -#endif /* __FreeBSD__, __FreeBSD_kernel__ */ + parport_device_file = strdup("/dev/parport0"); +#endif + LOG_WARNING("No parallel port specified, using %s", parport_device_file); + LOG_WARNING("DEPRECATED! The lack of a parallel port specification is deprecated and will no longer work in the future"); + } - LOG_DEBUG("Using parallel port %s", device_path); + LOG_DEBUG("Using parallel port %s", parport_device_file); - device_handle = open(device_path, O_WRONLY); + device_handle = open(parport_device_file, O_WRONLY); if (device_handle < 0) { int err = errno; - LOG_ERROR("Failed to open parallel port %s (errno = %d)", device_path, - err); + LOG_ERROR("Failed to open parallel port %s (errno = %d)", + parport_device_file, err); LOG_ERROR("Check whether the device exists and if you have the required access rights"); - return ERROR_JTAG_INIT_FAILED; + goto init_fail; } #if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) int retval = ioctl(device_handle, PPCLAIM); if (retval < 0) { - LOG_ERROR("Failed to claim parallel port %s", device_path); - return ERROR_JTAG_INIT_FAILED; + LOG_ERROR("Failed to claim parallel port %s", parport_device_file); + goto init_fail; } int value = PARPORT_MODE_COMPAT; @@ -328,7 +329,7 @@ static int parport_init(void) if (retval < 0) { LOG_ERROR("Cannot set compatible mode to device"); - return ERROR_JTAG_INIT_FAILED; + goto init_fail; } value = IEEE1284_MODE_COMPAT; @@ -336,7 +337,7 @@ static int parport_init(void) if (retval < 0) { LOG_ERROR("Cannot set compatible 1284 mode to device"); - return ERROR_JTAG_INIT_FAILED; + goto init_fail; } #endif /* not __FreeBSD__, __FreeBSD_kernel__ */ @@ -359,7 +360,7 @@ static int parport_init(void) if (ioperm(dataport, 3, 1) != 0) { #endif /* PARPORT_USE_GIVEIO */ LOG_ERROR("Missing privileges for direct I/O"); - return ERROR_JTAG_INIT_FAILED; + goto init_fail; } // Make sure parallel port is in right mode (clear tristate and interrupt). @@ -372,21 +373,27 @@ static int parport_init(void) #endif /* PARPORT_USE_PPDEV */ if (parport_reset(0, 0) != ERROR_OK) - return ERROR_FAIL; + goto init_fail; if (parport_write(0, 0, 0) != ERROR_OK) - return ERROR_FAIL; + goto init_fail; if (parport_led(true) != ERROR_OK) - return ERROR_FAIL; + goto init_fail; bitbang_interface = &parport_bitbang; return ERROR_OK; + +init_fail: + free(parport_device_file); + return ERROR_JTAG_INIT_FAILED; } static int parport_quit(void) { + free(parport_device_file); + // Deinitialize signal pin states. for (size_t i = 0; i < ARRAY_SIZE(all_signals); i++) { const enum adapter_gpio_config_index gpio_index = all_signals[i].gpio_index; @@ -421,13 +428,37 @@ COMMAND_HANDLER(parport_handle_port_command) if (CMD_ARGC != 1) return ERROR_COMMAND_SYNTAX_ERROR; - // Only if the port wasn't overwritten by command-line. - if (parport_port > 0) { - command_print(CMD, "The parallel port is already configured"); + if (parport_device_file) { + LOG_ERROR("The parallel port device file is already configured"); + return ERROR_FAIL; + } + + char *tmp; + + // We do not use the parse_xxx() or COMMAND_PARSE_xxx() functions here since + // they generate an error message if parsing fails. + char *endptr = NULL; + unsigned long port_number = strtoul(CMD_ARGV[0], &endptr, 0); + + if (*endptr == '\0' && endptr != CMD_ARGV[0]) { + LOG_WARNING("DEPRECATED! Using a port number is deprecated, use the device file instead"); + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + tmp = alloc_printf("/dev/ppi%lu", port_number); +#else + tmp = alloc_printf("/dev/parport%lu", port_number); +#endif + } else { + tmp = strdup(CMD_ARGV[0]); + } + + if (!tmp) { + LOG_ERROR("Failed to allocate memory"); return ERROR_FAIL; } - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], parport_port); + free(parport_device_file); + parport_device_file = tmp; return ERROR_OK; } @@ -489,9 +520,8 @@ static const struct command_registration parport_subcommand_handlers[] = { .name = "port", .handler = parport_handle_port_command, .mode = COMMAND_CONFIG, - .help = "Configure the address of the I/O port (e.g. 0x378) " - "or the number of the '/dev/parport' (Linux) or '/dev/ppi' (FreeBSD) device used", - .usage = "port_number", + .help = "Specify the device file of he parallel port", + .usage = "file", }, { .name = "cable", --
