Skip to content

Commit 910e6ba

Browse files
zapb-0borneoa
authored andcommitted
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]> Reviewed-on: https://review.openocd.org/c/openocd/+/9152 Reviewed-by: Antonio Borneo <[email protected]> Tested-by: jenkins
1 parent 39ed0b0 commit 910e6ba

File tree

2 files changed

+73
-29
lines changed

2 files changed

+73
-29
lines changed

doc/openocd.texi

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3217,11 +3217,12 @@ The pin direction is given in the following table.
32173217
@tab 2
32183218
@end multitable
32193219

3220-
@deffn {Config Command} {parport port} port_number
3221-
Configure the number of the parallel port.
3220+
@deffn {Config Command} {parport port} file
3221+
Specify the device file of the parallel port device.
3222+
The parallel port device file is usually @file{/dev/parportX} on Linux and @file{/dev/ppiX} on FreeBSD.
32223223

3223-
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).
3224-
The default port number is 0.
3224+
For legacy reason, the port number @var{X} can be specified instead of the device file.
3225+
@b{Note:} Using the port number is a deprecated feature and will be removed in the future.
32253226

32263227
When using direct I/O, the number is the I/O port number.
32273228
The default port number is 0x378 (LTP1).

src/jtag/drivers/parport.c

Lines changed: 68 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,11 @@
4747

4848
static const struct adapter_gpio_config *adapter_gpio_config;
4949

50+
#if PARPORT_USE_PPDEV == 0
5051
static uint16_t parport_port;
52+
#endif
5153
static bool parport_write_exit_state;
54+
static char *parport_device_file;
5255
static uint32_t parport_toggling_time_ns = 1000;
5356
static int wait_states;
5457

@@ -258,13 +261,13 @@ static int parport_init(void)
258261
if (gpio.gpio_num < 10 || gpio.gpio_num > 15 || gpio.gpio_num == 14) {
259262
LOG_ERROR("The '%s' signal pin must be 10, 11, 12, 13, or 15",
260263
adapter_gpio_get_name(gpio_index));
261-
return ERROR_FAIL;
264+
goto init_fail;
262265
}
263266
} else {
264267
if (gpio.gpio_num < 2 || gpio.gpio_num > 9) {
265268
LOG_ERROR("The '%s' signal pin must be 2, 3, 4, 5, 6, 7, 8, or 9",
266269
adapter_gpio_get_name(gpio_index));
267-
return ERROR_FAIL;
270+
goto init_fail;
268271
}
269272
}
270273
}
@@ -292,51 +295,53 @@ static int parport_init(void)
292295
#if PARPORT_USE_PPDEV == 1
293296
if (device_handle > 0) {
294297
LOG_ERROR("Parallel port is already open");
295-
return ERROR_JTAG_INIT_FAILED;
298+
goto init_fail;
296299
}
297300

298-
char device_path[256];
299-
301+
if (!parport_device_file) {
300302
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
301-
snprintf(device_path, sizeof(device_path), "/dev/ppi%d", parport_port);
303+
parport_device_file = strdup("/dev/ppi0");
302304
#else
303-
snprintf(device_path, sizeof(device_path), "/dev/parport%d", parport_port);
304-
#endif /* __FreeBSD__, __FreeBSD_kernel__ */
305+
parport_device_file = strdup("/dev/parport0");
306+
#endif
307+
LOG_WARNING("No parallel port specified, using %s", parport_device_file);
308+
LOG_WARNING("DEPRECATED! The lack of a parallel port specification is deprecated and will no longer work in the future");
309+
}
305310

306-
LOG_DEBUG("Using parallel port %s", device_path);
311+
LOG_DEBUG("Using parallel port %s", parport_device_file);
307312

308-
device_handle = open(device_path, O_WRONLY);
313+
device_handle = open(parport_device_file, O_WRONLY);
309314

310315
if (device_handle < 0) {
311316
int err = errno;
312-
LOG_ERROR("Failed to open parallel port %s (errno = %d)", device_path,
313-
err);
317+
LOG_ERROR("Failed to open parallel port %s (errno = %d)",
318+
parport_device_file, err);
314319
LOG_ERROR("Check whether the device exists and if you have the required access rights");
315-
return ERROR_JTAG_INIT_FAILED;
320+
goto init_fail;
316321
}
317322

318323
#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
319324
int retval = ioctl(device_handle, PPCLAIM);
320325

321326
if (retval < 0) {
322-
LOG_ERROR("Failed to claim parallel port %s", device_path);
323-
return ERROR_JTAG_INIT_FAILED;
327+
LOG_ERROR("Failed to claim parallel port %s", parport_device_file);
328+
goto init_fail;
324329
}
325330

326331
int value = PARPORT_MODE_COMPAT;
327332
retval = ioctl(device_handle, PPSETMODE, &value);
328333

329334
if (retval < 0) {
330335
LOG_ERROR("Cannot set compatible mode to device");
331-
return ERROR_JTAG_INIT_FAILED;
336+
goto init_fail;
332337
}
333338

334339
value = IEEE1284_MODE_COMPAT;
335340
retval = ioctl(device_handle, PPNEGOT, &value);
336341

337342
if (retval < 0) {
338343
LOG_ERROR("Cannot set compatible 1284 mode to device");
339-
return ERROR_JTAG_INIT_FAILED;
344+
goto init_fail;
340345
}
341346
#endif /* not __FreeBSD__, __FreeBSD_kernel__ */
342347

@@ -359,7 +364,7 @@ static int parport_init(void)
359364
if (ioperm(dataport, 3, 1) != 0) {
360365
#endif /* PARPORT_USE_GIVEIO */
361366
LOG_ERROR("Missing privileges for direct I/O");
362-
return ERROR_JTAG_INIT_FAILED;
367+
goto init_fail;
363368
}
364369

365370
// Make sure parallel port is in right mode (clear tristate and interrupt).
@@ -372,21 +377,27 @@ static int parport_init(void)
372377
#endif /* PARPORT_USE_PPDEV */
373378

374379
if (parport_reset(0, 0) != ERROR_OK)
375-
return ERROR_FAIL;
380+
goto init_fail;
376381

377382
if (parport_write(0, 0, 0) != ERROR_OK)
378-
return ERROR_FAIL;
383+
goto init_fail;
379384

380385
if (parport_led(true) != ERROR_OK)
381-
return ERROR_FAIL;
386+
goto init_fail;
382387

383388
bitbang_interface = &parport_bitbang;
384389

385390
return ERROR_OK;
391+
392+
init_fail:
393+
free(parport_device_file);
394+
return ERROR_JTAG_INIT_FAILED;
386395
}
387396

388397
static int parport_quit(void)
389398
{
399+
free(parport_device_file);
400+
390401
// Deinitialize signal pin states.
391402
for (size_t i = 0; i < ARRAY_SIZE(all_signals); i++) {
392403
const enum adapter_gpio_config_index gpio_index = all_signals[i].gpio_index;
@@ -421,13 +432,46 @@ COMMAND_HANDLER(parport_handle_port_command)
421432
if (CMD_ARGC != 1)
422433
return ERROR_COMMAND_SYNTAX_ERROR;
423434

424-
// Only if the port wasn't overwritten by command-line.
435+
#if PARPORT_USE_PPDEV == 1
436+
if (parport_device_file) {
437+
LOG_ERROR("The parallel port device file is already configured");
438+
return ERROR_FAIL;
439+
}
440+
441+
char *tmp;
442+
443+
// We do not use the parse_xxx() or COMMAND_PARSE_xxx() functions here since
444+
// they generate an error message if parsing fails.
445+
char *endptr = NULL;
446+
unsigned long port_number = strtoul(CMD_ARGV[0], &endptr, 0);
447+
448+
if (*endptr == '\0' && endptr != CMD_ARGV[0]) {
449+
LOG_WARNING("DEPRECATED! Using a port number is deprecated, use the device file instead");
450+
451+
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
452+
tmp = alloc_printf("/dev/ppi%lu", port_number);
453+
#else
454+
tmp = alloc_printf("/dev/parport%lu", port_number);
455+
#endif
456+
} else {
457+
tmp = strdup(CMD_ARGV[0]);
458+
}
459+
460+
if (!tmp) {
461+
LOG_ERROR("Failed to allocate memory");
462+
return ERROR_FAIL;
463+
}
464+
465+
free(parport_device_file);
466+
parport_device_file = tmp;
467+
#else
425468
if (parport_port > 0) {
426469
command_print(CMD, "The parallel port is already configured");
427470
return ERROR_FAIL;
428471
}
429472

430473
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], parport_port);
474+
#endif
431475

432476
return ERROR_OK;
433477
}
@@ -489,9 +533,8 @@ static const struct command_registration parport_subcommand_handlers[] = {
489533
.name = "port",
490534
.handler = parport_handle_port_command,
491535
.mode = COMMAND_CONFIG,
492-
.help = "Configure the address of the I/O port (e.g. 0x378) "
493-
"or the number of the '/dev/parport' (Linux) or '/dev/ppi' (FreeBSD) device used",
494-
.usage = "port_number",
536+
.help = "Specify the device file of the parallel port",
537+
.usage = "file",
495538
},
496539
{
497540
.name = "cable",

0 commit comments

Comments
 (0)