Commit 5467b4f8 authored by Federico Vaga's avatar Federico Vaga

lib: do not accept index to open device

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent c9fb1743
......@@ -42,7 +42,7 @@ ZIO_ATTR_DEFINE_STD(ZIO_DEV, fd_zattr_dev_std) = {
/* Extended attributes for the device */
static struct zio_attribute fd_zattr_dev[] = {
ZIO_ATTR_EXT("version", S_IRUGO, FD_ATTR_DEV_VERSION,
FDELAY_VERSION),
FDELAY_VERSION_MAJ),
ZIO_ATTR_EXT("utc-h", _RW_, FD_ATTR_DEV_UTC_H, 0),
ZIO_ATTR_EXT("utc-l", _RW_, FD_ATTR_DEV_UTC_L, 0),
ZIO_ATTR_EXT("coarse", _RW_, FD_ATTR_DEV_COARSE, 0),
......
......@@ -17,7 +17,8 @@ enum fd_irq_resource {
FD_IRQ = 0,
};
#define FDELAY_VERSION 2 /* version of the layout of registers */
#define FDELAY_VERSION_MAJ 2 /* version of the layout of registers */
/*
* ZIO concatenates device, cset and channel extended attributes in the 32
* values that are reported in the control block. So we are limited to
......
......@@ -32,135 +32,81 @@ const char * const libfdelay_zio_version_s = "libfdelay is using zio version: "
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
static struct __fdelay_board *fd_boards;
static int fd_nboards;
/* Init the library: return the number of boards found */
int fdelay_init(void)
{
glob_t glob_dev, glob_sys;
struct __fdelay_board *b;
int i, j;
uint32_t v;
/* Look for boards in /dev: old and new pathnames: only one matches */
glob("/dev/fd-*-0-0-ctrl", 0, NULL, &glob_dev);
glob("/dev/zio/fd-*-0-0-ctrl", GLOB_APPEND, NULL, &glob_dev);
glob("/dev/zio-fd-*-0-0-ctrl", GLOB_APPEND, NULL, &glob_dev);
glob("/dev/zio/zio-fd-*-0-0-ctrl", GLOB_APPEND, NULL, &glob_dev);
/* And look in /sys as well */
glob("/sys/bus/zio/devices/fd-*", 0, NULL, &glob_sys);
glob("/sys/bus/zio/devices/zio-fd-*", GLOB_APPEND , NULL, &glob_sys);
assert(glob_dev.gl_pathc == glob_sys.gl_pathc);
/* Allocate as needed */
fd_nboards = glob_dev.gl_pathc;
if (!fd_nboards) {
fd_boards = NULL;
return 0;
}
fd_boards = calloc(glob_dev.gl_pathc, sizeof(fd_boards[0]));
if (!fd_boards) {
globfree(&glob_dev);
globfree(&glob_sys);
return -1;
}
for (i = 0, b = fd_boards; i < fd_nboards; i++, b++) {
b->sysbase = strdup(glob_sys.gl_pathv[i]);
b->devbase = strdup(glob_dev.gl_pathv[i]);
/* trim the "-0-0-ctrl" at the end */
b->devbase[strlen(b->devbase) - strlen("-0-0-ctrl")] = '\0';
/* extract dev_id */
sscanf(b->sysbase, "%*[^f]fd-%x", &b->dev_id);
for (j = 0; j < ARRAY_SIZE(b->fdc); j++) {
b->fdc[j] = -1;
}
if (fdelay_is_verbose()) {
fprintf(stderr, "%s: %04x %s %s\n", __func__,
b->dev_id, b->sysbase, b->devbase);
}
}
globfree(&glob_dev);
globfree(&glob_sys);
/* Now, if at least one board is there, check the version */
if (fd_nboards == 0)
return 0;
if (fdelay_sysfs_get(fd_boards, "version", &v) < 0)
return -1;
if (v != FDELAY_VERSION) {
fprintf(stderr, "%s: version mismatch, lib(%i) != drv(%i)\n",
__func__, FDELAY_VERSION, v);
errno = EIO;
return -1;
}
return fd_nboards;
return 0;
}
/* Free and check */
void fdelay_exit(void)
{
struct __fdelay_board *b;
int i, j, err;
for (i = 0, err = 0, b = fd_boards; i < fd_nboards; i++, b++) {
for (j = 0; j < ARRAY_SIZE(b->fdc); j++) {
if (b->fdc[j] >= 0) {
close(b->fdc[j]);
b->fdc[j] = -1;
err++;
}
}
if (err)
fprintf(stderr, "%s: device %s was still open\n",
__func__, b->devbase);
free(b->sysbase);
free(b->devbase);
}
if(fd_nboards)
free(fd_boards);
return ;
}
/* Open one specific device. -1 arguments mean "not installed" */
struct fdelay_board *fdelay_open(int index, int dev_id)
/**
* It opens one specific device. -1 arguments mean "not installed"
* @param[in] dev_id FMC device id. -1 to ignore it and use only the offset
* @return an instance token, otherwise NULL and errno is appripriately set.
* ENODEV if the device was not found. EINVAL there is a mismatch with
* the arguments
*/
#define __FMCTDC_OPEN_PATH_MAX 128
struct fdelay_board *fdelay_open(int dev_id)
{
struct __fdelay_board *b = NULL;
int i;
char path[__FMCTDC_OPEN_PATH_MAX];
struct stat sb;
uint32_t v;
int ret;
if (fdelay_is_verbose())
fprintf(stderr, "called: %s(index %i, dev_id 0x%x);\n",
__func__, index, dev_id);
if (index >= fd_nboards) {
errno = ENODEV;
return NULL;
}
if (index >= 0) {
b = fd_boards + index;
if (dev_id >= 0 && dev_id != b->dev_id) {
errno = EINVAL;
return NULL;
}
goto found;
}
if (dev_id < 0) {
errno = EINVAL;
return NULL;
}
for (i = 0, b = fd_boards; i < fd_nboards; i++, b++)
if (b->dev_id == dev_id)
goto found;
errno = ENODEV;
return NULL;
found:
/*
* We used to force post-samples to 1 here, but now
* sample-size is zero and post-samples is not used
*/
b = malloc(sizeof(*b));
if (!b)
return NULL;
/* get sysfs */
snprintf(path, sizeof(path),
"/sys/bus/zio/devices/fd-%04x", dev_id);
ret = stat(path, &sb);
if (ret < 0)
goto err_stat_s;
if (!S_ISDIR(sb.st_mode))
goto err_stat_s;
b->sysbase = strdup(path);
/* get dev */
snprintf(path, sizeof(path),
"/dev/zio/fd-%04x-0-0-ctrl", dev_id);
ret = stat(path, &sb);
if (ret < 0)
goto err_stat_d;
if (!S_ISCHR(sb.st_mode))
goto err_stat_d;
b->devbase = strndup(path, strlen(path) - strlen("-0-0-ctrl"));
ret = fdelay_sysfs_get(b, "version", &v);
if (ret)
goto err_version;
if (v != FDELAY_VERSION_MAJ) {
errno = FDELAY_ERR_VERSION_MISMATCH;
goto err_version;
}
return (void *)b;
err_version:
free(b->devbase);
err_stat_d:
free(b->sysbase);
err_stat_s:
free(b);
return NULL;
}
/* Open one specific device by logical unit number (CERN/CO-like) */
......@@ -184,22 +130,22 @@ struct fdelay_board *fdelay_open_by_lun(int lun)
errno = ENODEV;
return NULL;
}
return fdelay_open(-1, dev_id);
return fdelay_open(dev_id);
}
int fdelay_close(struct fdelay_board *userb)
{
__define_board(b, userb);
struct __fdelay_board *b = (struct __fdelay_board *)userb;
int j;
if (fdelay_is_verbose())
fprintf(stderr, "called: %s(index %li, dev_id 0x%x);\n",
__func__, b - fd_boards, b->dev_id);
for (j = 0; j < ARRAY_SIZE(b->fdc); j++) {
if (b->fdc[j] >= 0)
close(b->fdc[j]);
b->fdc[j] = -1;
}
free(b->sysbase);
free(b->devbase);
free(b);
return 0;
}
......@@ -231,6 +177,8 @@ float fdelay_read_temperature(struct fdelay_board *userb)
}
static const char *fdelay_error_string[] = {
[FDELAY_ERR_VERSION_MISMATCH - __FDELAY_ERR_MIN] =
"Incompatible version driver-library",
};
/**
......
......@@ -24,7 +24,8 @@ extern "C" {
#define __FDELAY_ERR_MIN 4096
enum fmctdc_error_numbers {
__FDELAY_ERR_MAX = __FDELAY_ERR_MIN,
FDELAY_ERR_VERSION_MISMATCH = __FDELAY_ERR_MIN,
__FDELAY_ERR_MAX,
};
/* Convenience macro for converting the physical output connector
......@@ -74,7 +75,7 @@ extern int fdelay_init(void);
extern void fdelay_exit(void);
extern const char *fdelay_strerror(int err);
extern struct fdelay_board *fdelay_open(int offset, int dev_id);
extern struct fdelay_board *fdelay_open(int dev_id);
extern struct fdelay_board *fdelay_open_by_lun(int lun);
extern int fdelay_close(struct fdelay_board *);
......
......@@ -14,7 +14,7 @@ void help(char *name)
{
fprintf(stderr, "fmc-fdelay-board-time: a tool for manipulating the FMC Fine Delay time base.\n");
fprintf(stderr, "Use: \"%s [-V] [-i <index>] [-d <dev>] <command>\"\n",
fprintf(stderr, "Use: \"%s [-V] [-d <dev>] <command>\"\n",
name);
fprintf(stderr, " where the <command> can be:\n"
" get - shows current time and White Rabbit status.\n"
......@@ -30,8 +30,8 @@ int main(int argc, char **argv)
{
struct fdelay_board *b;
struct fdelay_time t;
int nboards, i, get = 0, host = 0, wr_on = 0, wr_off = 0;
int index = -1, dev = -1;
int i, get = 0, host = 0, wr_on = 0, wr_off = 0;
int dev = -1, err;
char *s;
......@@ -42,24 +42,16 @@ int main(int argc, char **argv)
/* print versions if needed */
print_version(argc, argv);
nboards = fdelay_init();
if (nboards < 0) {
fprintf(stderr, "%s: fdelay_init(): %s\n", argv[0],
strerror(errno));
exit(1);
}
if (nboards == 0) {
fprintf(stderr, "%s: no boards found\n", argv[0]);
err = fdelay_init();
if (err) {
fprintf(stderr, "%s: library initialization failed\n", argv[0]);
exit(1);
}
if (nboards == 1)
index = 0; /* so it works with no arguments */
tools_getopt_d_i(argc, argv, &dev, &index);
tools_getopt_d_i(argc, argv, &dev);
if (index < 0 && dev < 0) {
fprintf(stderr, "%s: several boards, please pass -i or -d\n",
if (dev < 0) {
fprintf(stderr, "%s: several boards, please pass -d\n",
argv[0]);
exit(1);
}
......@@ -92,7 +84,7 @@ int main(int argc, char **argv)
t.coarse = nano * 1000 * 1000 * 1000 / 8;
}
b = fdelay_open(index, dev);
b = fdelay_open(dev);
if (!b) {
fprintf(stderr, "%s: fdelay_open(): %s\n", argv[0],
strerror(errno));
......
......@@ -15,7 +15,7 @@ char git_version[] = "git version: " GIT_VERSION;
void help(char *name)
{
fprintf(stderr, "%s: Use \"%s [-V] [-i <index>] [-d <dev>] [<opts>]\n",
fprintf(stderr, "%s: Use \"%s [-V] [-d <dev>] [<opts>]\n",
name, name);
fprintf(stderr, " options:\n"
" -c <count> default is 0 and means forever\n"
......@@ -41,8 +41,7 @@ void dump_input(struct fdelay_time *t, int np, int umode)
int main(int argc, char **argv)
{
struct fdelay_board *b;
int nboards;
int opt, index = -1, dev = -1;
int opt, err, dev = -1;
int nonblock = 0, count = 0;
int umode = TOOLS_UMODE_USER;
......@@ -54,33 +53,16 @@ int main(int argc, char **argv)
/* print versions if needed */
print_version(argc, argv);
nboards = fdelay_init();
if (nboards < 0) {
fprintf(stderr, "%s: fdelay_init(): %s\n", argv[0],
strerror(errno));
exit(1);
}
if (nboards == 0) {
fprintf(stderr, "%s: no boards found\n", argv[0]);
err = fdelay_init();
if (err) {
fprintf(stderr, "%s: library initialization failed\n", argv[0]);
exit(1);
}
if (nboards == 1)
index = 0; /* so it works with no arguments */
/* Parse our specific arguments, starting back from argv[1] */
while ((opt = getopt(argc, argv, "d:i:hc:nrf")) != -1) {
while ((opt = getopt(argc, argv, "d:hc:nrf")) != -1) {
switch (opt) {
char *rest;
case 'i':
index = strtol(optarg, &rest, 0);
if (rest && *rest) {
fprintf(stderr, "%s: Not a number \"%s\"\n",
argv[0], optarg);
exit(1);
}
break;
case 'd':
dev = strtol(optarg, &rest, 0);
if (rest && *rest) {
......@@ -117,13 +99,13 @@ int main(int argc, char **argv)
if (optind != argc)
help(argv[0]); /* too many arguments */
if (index < 0 && dev < 0) {
fprintf(stderr, "%s: several boards, please pass -i or -d\n",
if (dev < 0) {
fprintf(stderr, "%s: several boards, please pass -d\n",
argv[0]);
exit(1);
}
b = fdelay_open(index, dev);
b = fdelay_open(dev);
if (!b) {
fprintf(stderr, "%s: fdelay_open(): %s\n", argv[0],
strerror(errno));
......
......@@ -2,11 +2,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <glob.h>
#define FDELAY_INTERNAL /* hack... */
#include "fdelay-lib.h"
#include "tools-common.h"
char git_version[] = "git version: " GIT_VERSION;
......@@ -20,9 +18,8 @@ void help(char *name)
int main(int argc, char **argv)
{
int i, j;
struct __fdelay_board *b;
struct fdelay_board *ub;
glob_t g;
int err, i;
if (tools_need_help(argc, argv))
help(argv[0]);
......@@ -36,21 +33,32 @@ int main(int argc, char **argv)
exit(1);
}
i = fdelay_init();
if (i < 0) {
fprintf(stderr, "%s: fdelay_init(): %s\n", argv[0],
strerror(errno));
err = fdelay_init();
if (err) {
fprintf(stderr, "%s: library initialization failed\n",
argv[0]);
exit(1);
}
printf("%s: found %i board%s\n", argv[0], i, i ? "" : "s");
for (j = 0; j < i; j++) {
ub = fdelay_open(j, -1);
b = (typeof(b))ub;
printf(" dev_id %04x, %s, %s\n", b->dev_id, b->devbase,
b->sysbase);
err = glob("/dev/zio/fd-[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]-0-0-ctrl",
GLOB_NOSORT, NULL, &g);
if (err == GLOB_NOMATCH)
goto out_glob;
for (i = 0; i < g.gl_pathc; i++) {
uint32_t dev_id;
char dev_id_str[7]= "0x";
/* Keep only the ID */
strncpy(dev_id_str + 2,
g.gl_pathv[i] + strlen("/dev/zio/fd-"), 4);
dev_id = strtol(dev_id_str, NULL, 0);
printf(" Fine-Delay Device ID %04x\n", dev_id);
}
globfree(&g);
out_glob:
fdelay_exit();
return 0;
}
......@@ -17,7 +17,7 @@ char git_version[] = "git version: " GIT_VERSION;
void help(char *name)
{
fprintf(stderr, "%s: Use \"%s [-V] [-i <index>] [-d <dev>] [<opts>]\n",
fprintf(stderr, "%s: Use \"%s [-V] [-d <dev>] [<opts>]\n",
name, name);
fprintf(stderr, " options:\n"
" -o <output> ouput channel: 1..4 (default 1)\n"
......@@ -213,8 +213,7 @@ void parse_width(struct fdelay_pulse *p, char *s)
int main(int argc, char **argv)
{
struct fdelay_board *b;
int nboards;
int i, opt, index = -1, dev = -1, err = 0;
int i, opt, dev = -1, err = 0;
/* our parameters */
int count = 0, channel = -1;
int trigger_wait = 0, verbose = 0;
......@@ -228,35 +227,18 @@ int main(int argc, char **argv)
/* print versions if needed */
print_version(argc, argv);
nboards = fdelay_init();
if (nboards < 0) {
fprintf(stderr, "%s: fdelay_init(): %s\n", argv[0],
strerror(errno));
exit(1);
}
if (nboards == 0) {
fprintf(stderr, "%s: no boards found\n", argv[0]);
err = fdelay_init();
if (err) {
fprintf(stderr, "%s: library initialization failed\n", argv[0]);
exit(1);
}
if (nboards == 1)
index = 0; /* so it works with no arguments */
parse_default(&p);
/* Parse our specific arguments */
while ((opt = getopt(argc, argv, "d:i:ho:c:m:r:D:T:w:tp1v")) != -1) {
while ((opt = getopt(argc, argv, "d:ho:c:m:r:D:T:w:tp1v")) != -1) {
switch (opt) {
char *rest;
case 'i':
index = strtol(optarg, &rest, 0);
if (rest && *rest) {
fprintf(stderr, "%s: Not a number \"%s\"\n",
argv[0], optarg);
exit(1);
}
break;
case 'd':
dev = strtol(optarg, &rest, 0);
if (rest && *rest) {
......@@ -337,13 +319,13 @@ int main(int argc, char **argv)
if (optind != argc)
help(argv[0]); /* too many arguments */
if (index < 0 && dev < 0) {
fprintf(stderr, "%s: several boards, please pass -i or -d\n",
if (dev < 0) {
fprintf(stderr, "%s: several boards, please pass -d\n",
argv[0]);
exit(1);
}
b = fdelay_open(index, dev);
b = fdelay_open(dev);
if (!b) {
fprintf(stderr, "%s: fdelay_open(): %s\n", argv[0],
strerror(errno));
......
......@@ -14,7 +14,7 @@ void help(char *name)
{
fprintf(stderr, "fmc-fdelay-status: reports channel programming\n");
fprintf(stderr, "Use: \"%s [-V] [-i <index>] [-d <dev>] [-r]\"\n", name);
fprintf(stderr, "Use: \"%s [-V] [-d <dev>] [-r]\"\n", name);
fprintf(stderr, " -r: display raw hardware configuration");
exit(1);
}
......@@ -23,7 +23,7 @@ int main(int argc, char **argv)
{
struct fdelay_board *b;
struct fdelay_pulse p;
int nboards, ch, index = -1, dev = -1, raw = 0, opt;
int ch, err, dev = -1, raw = 0, opt;
/* Standard part of the file (repeated code) */
if (tools_need_help(argc, argv))
......@@ -32,32 +32,15 @@ int main(int argc, char **argv)
/* print versions if needed */
print_version(argc, argv);
nboards = fdelay_init();
if (nboards < 0) {
fprintf(stderr, "%s: fdelay_init(): %s\n", argv[0],
strerror(errno));
err = fdelay_init();
if (err) {
fprintf(stderr, "%s: library initialization failed\n", argv[0]);
exit(1);
}
if (nboards == 0) {
fprintf(stderr, "%s: no boards found\n", argv[0]);
exit(1);
}
if (nboards == 1)
index = 0; /* so it works with no arguments */
while ((opt = getopt(argc, argv, "i:d:rh")) != -1) {
while ((opt = getopt(argc, argv, "d:rh")) != -1) {
char *rest;
switch (opt) {
case 'i':
index = strtol(optarg, &rest, 0);
if (rest && *rest) {
fprintf(stderr, "%s: Not a number \"%s\"\n",
argv[0], optarg);
exit(1);
}
break;
case 'd':
dev = strtol(optarg, &rest, 0);
if (rest && *rest) {
......@@ -75,13 +58,13 @@ int main(int argc, char **argv)
}
}
if (index < 0 && dev < 0) {
fprintf(stderr, "%s: several boards, please pass -i or -d\n",
if (dev < 0) {
fprintf(stderr, "%s: several boards, please pass -d\n",
argv[0]);
exit(1);
}
b = fdelay_open(index, dev);
b = fdelay_open(dev);
if (!b) {
fprintf(stderr, "%s: fdelay_open(): %s\n", argv[0],
strerror(errno));
......
......@@ -12,7 +12,7 @@ char git_version[] = "git version: " GIT_VERSION;
void help(char *name)
{
fprintf(stderr, "%s: Use \"%s [-V] [-i <index>] [-d <dev>] [on|off]\n",
fprintf(stderr, "%s: Use \"%s [-V] [-d <dev>] [on|off]\n",
name, name);
exit(1);
}
......@@ -20,8 +20,9 @@ void help(char *name)
int main(int argc, char **argv)
{
struct fdelay_board *b;
int nboards, hwval, newval;
int index = -1, dev = -1;
int hwval, newval;
int dev = -1;
int err;
/* Standard part of the file (repeated code) */
......@@ -31,24 +32,16 @@ int main(int argc, char **argv)
/* print versions if needed */
print_version(argc, argv);
nboards = fdelay_init();
if (nboards < 0) {
fprintf(stderr, "%s: fdelay_init(): %s\n", argv[0],
strerror(errno));
exit(1);
}
if (nboards == 0) {
fprintf(stderr, "%s: no boards found\n", argv[0]);
err = fdelay_init();
if (err) {
fprintf(stderr, "%s: library initialization failed\n", argv[0]);
exit(1);
}
if (nboards == 1)
index = 0; /* so it works with no arguments */
tools_getopt_d_i(argc, argv, &dev, &index);
tools_getopt_d_i(argc, argv, &dev);
if (index < 0 && dev < 0) {
fprintf(stderr, "%s: several boards, please pass -i or -d\n",
if (dev < 0) {
fprintf(stderr, "%s: several boards, please pass -d\n",
argv[0]);
exit(1);
}
......@@ -65,7 +58,7 @@ int main(int argc, char **argv)
help(argv[0]);
}
/* Finally work */
b = fdelay_open(index, dev);
b = fdelay_open(dev);
if (!b) {
fprintf(stderr, "%s: fdelay_open(): %s\n", argv[0],
strerror(errno));
......@@ -73,7 +66,6 @@ int main(int argc, char **argv)
}
hwval = fdelay_get_config_tdc(b);
int err = 0;
switch(newval) {
case 1:
......
......@@ -2,8 +2,7 @@
* Simple code that is repeated over several tools
*/
extern void tools_getopt_d_i(int argc, char **argv,
int *dev, int *index);
extern void tools_getopt_d_i(int argc, char **argv, int *dev);
extern int tools_need_help(int argc, char **argv);
#define TOOLS_UMODE_USER 0
......
......@@ -21,22 +21,13 @@ void print_version(int argc, char **argv)
}
void tools_getopt_d_i(int argc, char **argv,
int *dev, int *index)
void tools_getopt_d_i(int argc, char **argv, int *dev)
{
char *rest;
int opt;
while ((opt = getopt(argc, argv, "d:i:h")) != -1) {
while ((opt = getopt(argc, argv, "d:h")) != -1) {
switch (opt) {
case 'i':
*index = strtol(optarg, &rest, 0);
if (rest && *rest) {
fprintf(stderr, "%s: Not a number \"%s\"\n",
argv[0], optarg);
exit(1);
}
break;
case 'd':
*dev = strtol(optarg, &rest, 0);
if (rest && *rest) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment