Commit 2f0db9b6 authored by Alessandro Rubini's avatar Alessandro Rubini

lib: turn open/close to new prototypes

This commit makes the library consistent with the official design as
far as open and close are concerned. But buffer selection is still missing.

- open_by_lun() is not there in the low-level implementation, because
the function is expected to be library only, and is expected to fall
back to open, after finding the hardware-specific dev_if from the
administratively-set lun value.

- redundant error checking has been removed. For example, NULL names
are as bad as wild-pointer names, so the program should crash, not
receive an error and manage it. I used this policy in several places.

Other changes brought in by this:

- the board list is now static in boards.c

I'll still move something, at the end: open and close are zio-generic, not
board-specific.
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent d5df0b54
......@@ -31,10 +31,10 @@
#define FMCADC_ZIO_BRD_MASK (1LL << FMCADC_CONF_BRD_STATE_MACHINE_STATUS) | \
(1LL << FMCADC_CONF_BRD_N_CHAN)
struct fmcadc_op fa_100ms_4ch_14bit_op = {
.open = fmcadc_zio_open,
.open_by_lun = fmcadc_zio_open_by_lun,
.close = fmcadc_zio_close,
struct fmcadc_operations fa_100ms_4ch_14bit_op = {
.open = fmcadc_zio_open,
.close = fmcadc_zio_close,
.start_acquisition = fmcadc_zio_start_acquisition,
.stop_acquisition = fmcadc_zio_stop_acquisition,
.apply_config = fmcadc_zio_apply_config,
......@@ -55,83 +55,65 @@ struct fmcadc_board_type fmcadc_100ms_4ch_14bit = {
.fa_op = &fa_100ms_4ch_14bit_op,
};
/* fmcadc_open
* @name: name of the device type to open
* @dev_id: device identificator of a particular device connected to the system
/*
* The following array is the main entry point into the boards
*/
static const struct fmcadc_board_type *fmcadc_board_types[] = {
&fmcadc_100ms_4ch_14bit,
/* add new boards here */
};
static const struct fmcadc_board_type *find_board(char *name)
{
int i;
for (i = 0; i < ARRAY_SIZE(fmcadc_board_types); i++)
if (!strcmp(name, fmcadc_board_types[i]->name))
return fmcadc_board_types[i];
errno = ENODEV;
return NULL;
}
/* Open should choose the buffer type (FIXME) */
struct fmcadc_dev *fmcadc_open(char *name, unsigned int dev_id,
unsigned long buffersize,
unsigned int nbuffer,
unsigned long flags)
{
struct fmcadc_dev *dev = NULL;
int i, found = 0;
const struct fmcadc_board_type *b;
/* name cannot be NULL */
if (!name)
b = find_board(name);
if (!b)
return NULL;
/* Look in the list of supported board if the "name" board is there */
for (i = 0; i < __FMCADC_SUPPORTED_BOARDS_LAST_INDEX; ++i) {
if (!strcmp(name, fmcadc_board_types[i]->name)) {
found = 1;
break;
}
}
if (!found) {
errno = ENODEV;
return NULL; /* Not found */
}
/* The library supports this board */
if (fmcadc_board_types[i]->fa_op && fmcadc_board_types[i]->fa_op->open) {
dev = fmcadc_board_types[i]->fa_op->open(fmcadc_board_types[i],
dev_id, flags);
} else {
errno = FMCADC_ENOP;
}
return dev;
return b->fa_op->open(b, dev_id, buffersize, nbuffer, flags);
}
/*
* fmcadc_open_by_lun
* @name: name of the device type to open
* @lun: Logical Unit Number of the device
*
* TODO
*/
/* Open by lun should lookup a database */
struct fmcadc_dev *fmcadc_open_by_lun(char *name, int lun,
unsigned long buffersize,
unsigned int nbuffer,
unsigned long flags)
unsigned long buffersize,
unsigned int nbuffer,
unsigned long flags)
{
if (!name)
const struct fmcadc_board_type *b;
b = find_board(name);
if (!b)
return NULL;
/*
* FIXME: open_by_lun should lookup the database and get dev_id
* return b->fa_op->open( .... dev_id ...);
*/
errno = ENOSYS;
return NULL;
}
/*
* fmcadc_close
* @dev: the device to close
*/
int fmcadc_close(struct fmcadc_dev *dev)
{
struct fmcadc_gid *b = (void *)dev;
if (!dev) {
/* dev cannot be NULL */
errno = EINVAL;
return -1;
}
if (b->board->fa_op->close) {
return b->board->fa_op->close(dev);
} else {
errno = FMCADC_ENOP;
return -1;
}
return b->board->fa_op->close(dev);
}
......@@ -26,7 +26,6 @@
#include "fmcadc-lib.h"
#include "fmcadc-lib-int.h"
#define ZIO_DEV_PATH "/dev/zio"
#define ZIO_SYS_PATH "/sys/bus/zio/devices"
#define FMCADC_NCHAN 4
......@@ -35,48 +34,35 @@
int fmcadc_zio_stop_acquisition(struct fmcadc_dev *dev,
unsigned int flags);
struct fmcadc_dev *fmcadc_zio_open(const struct fmcadc_board_type *dev,
unsigned int dev_id,
unsigned int details)
struct fmcadc_dev *fmcadc_zio_open(const struct fmcadc_board_type *b,
unsigned int dev_id,
unsigned long totalsize,
unsigned int nbuffer,
unsigned long flags)
{
struct __fmcadc_dev_zio *fa = NULL;
struct __fmcadc_dev_zio *fa;
struct stat st;
char *syspath, *devpath, fname[128];
int udev_zio_dir = 1;
if (strlen(dev->devname) > 12) {
fprintf(stderr,
"%s: name \"%s\" is too long. ZIO's name are 12byte\n",
__func__, dev->devname);
return NULL ;
}
/* check if device exists by looking in ZIO sysfs */
asprintf(&syspath, "%s/%s-%04x", ZIO_SYS_PATH, dev->devname, dev_id);
if (stat(syspath, &st)) {
goto out_fa_stat;
}
asprintf(&syspath, "%s/%s-%04x", ZIO_SYS_PATH, b->devname, dev_id);
if (stat(syspath, &st))
goto out_fa_stat; /* ENOENT or equivalent */
/* Check where are ZIO char devices x*/
if (stat(ZIO_DEV_PATH, &st)) {
/*
* ZIO driver are not in /dev/zio, but in /dev with all other
* drivers
*/
/* ZIO char devices are in /dev/zio or just /dev (older udev) */
if (stat("/dev/zio", &st) < 0)
udev_zio_dir = 0;
}
asprintf(&devpath, "%s/%s-%04x", (udev_zio_dir ? ZIO_DEV_PATH : "/dev"),
dev->devname, dev_id);
/* Path exists, so device is there */
asprintf(&devpath, "%s/%s-%04x", (udev_zio_dir ? "/dev/zio" : "/dev"),
b->devname, dev_id);
/* Sysds path exists, so device is there, hopefully */
fa = calloc(1, sizeof(*fa));
if (!fa) {
if (!fa)
goto out_fa_alloc;
}
fa->sysbase = syspath;
fa->devbase = devpath;
fa->cset = details;
fa->cset = 0;
/* Open char devices */
sprintf(fname, "%s-0-i-ctrl", fa->devbase);
......@@ -84,9 +70,9 @@ struct fmcadc_dev *fmcadc_zio_open(const struct fmcadc_board_type *dev,
sprintf(fname, "%s-0-i-data", fa->devbase);
fa->fdd = open(fname, O_RDONLY);
if (fa->fdc < 0 || fa->fdd < 0)
goto out_fa_open;
goto out_fa_open;
fa->gid.board = dev;
fa->gid.board = b;
/* Finally, support verbose operation */
if (getenv("LIB_FMCADC_VERBOSE"))
......@@ -95,20 +81,19 @@ struct fmcadc_dev *fmcadc_zio_open(const struct fmcadc_board_type *dev,
return (void *) &fa->gid;
out_fa_open:
if (fa->fdc >= 0)
close(fa->fdc);
if (fa->fdd >= 0)
close(fa->fdd);
free(fa);
out_fa_alloc:
free(devpath);
out_fa_stat:
free(syspath);
return NULL ;
return NULL;
}
struct fmcadc_dev *fmcadc_zio_open_by_lun(char *name, int lun)
{
/* TODO implement*/
return NULL ;
}
int fmcadc_zio_close(struct fmcadc_dev *dev)
{
struct __fmcadc_dev_zio *fa = to_dev_zio(dev);
......
......@@ -8,63 +8,28 @@
/*
* offsetof and container_of come from kernel.h header file
*/
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = ((void *)ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
#define to_dev_zio(dev) (container_of(dev, struct __fmcadc_dev_zio, gid))
/* ->open takes different args than open(), so fa a fun to use tpyeof */
struct fmcadc_board_type;
struct fmcadc_dev *fmcadc_internal_open(const struct fmcadc_board_type *b,
unsigned int dev_id,
unsigned long totalsize,
unsigned int nbuffer,
unsigned long flags);
/*
* fmcadc_op: it describes the set of operation that a device library should
* support
*
* @start_acquisition start the acquisition
* @dev: device where to start acquiring
* @flags:
* @timeout: it can be used to specify how much time wait that acquisition
* is over. This value follow the select() policy: NULL to wait
* until acquisition is over; {0, 0} to return immediately
* without wait; {x, y} to wait acquisition end for a specified
* time
*
* @stop_acquisition stop the acquisition
* @dev: device where to stop acquisition
* @flags:
*
* @apply_config specific operation to apply a configuration to the device
* @dev: device to configure
* @flags:
* @conf: configuration to apply on device.
*
* @retrieve_config specific board operation to get the current configuration
* of the device
* @dev: device where retireve configuration
* @flags:
* @conf: configuration to retrieve. The mask tell which value acquire,
* then the library will acquire and set the value in the "value"
* array
*
* @request_buffer get from the device a buffer
* @dev: device where look for a buffer
* @buf: where store the buffer. The user must allocate this structure.
* @flags:
* @timeout: it can be used to specify how much time wait that a buffer is
* ready. This value follow the select() policy: NULL to wait
* until acquisition is over; {0, 0} to return immediately
* without wait; {x, y} to wait acquisition end for a specified
* time
*
* @release_buffer release the resources of a given buffer
* @dev: device that generate the buffer
* @buf: buffer to release
* The operations structure is the device-specific backend of the library
*/
struct fmcadc_op {
/* Handle board */
struct fmcadc_dev *(*open)(const struct fmcadc_board_type *dev,
unsigned int dev_id,
unsigned int details);
struct fmcadc_dev *(*open_by_lun)(char *devname, int lun);
int (*close)(struct fmcadc_dev *dev);
struct fmcadc_operations {
typeof(fmcadc_internal_open) *open;
typeof(fmcadc_close) *close;
/* Handle acquisition */
int (*start_acquisition)(struct fmcadc_dev *dev,
unsigned int flags,
......@@ -98,11 +63,11 @@ struct fmcadc_op {
* @fa_op pointer to a set of operations
*/
struct fmcadc_board_type {
char *name;
char *devname;
char *driver_type;
uint32_t capabilities[__FMCADC_CONF_TYPE_LAST_INDEX];
struct fmcadc_op *fa_op;
char *name;
char *devname;
char *driver_type;
uint32_t capabilities[__FMCADC_CONF_TYPE_LAST_INDEX];
struct fmcadc_operations *fa_op;
};
/*
......@@ -129,14 +94,14 @@ struct __fmcadc_dev_zio {
};
#define FMCADC_FLAG_VERBOSE 0x00000001
/* Open and close live in board.c, as open scans the list of boards */
struct fmcadc_dev *fmcadc_zio_open(const struct fmcadc_board_type *dev,
/* The board-specific functions are defined in fmc-adc-100m14b4cha.c */
struct fmcadc_dev *fmcadc_zio_open(const struct fmcadc_board_type *b,
unsigned int dev_id,
unsigned int details);
struct fmcadc_dev *fmcadc_zio_open_by_lun(char *name, int lun);
unsigned long totalsize,
unsigned int nbuffer,
unsigned long flags);
int fmcadc_zio_close(struct fmcadc_dev *dev);
/* The board-specific functions are defined in fmc-adc-100m14b4cha.c */
int fmcadc_zio_start_acquisition(struct fmcadc_dev *dev,
unsigned int flags, struct timeval *timeout);
int fmcadc_zio_stop_acquisition(struct fmcadc_dev *dev,
......
......@@ -26,9 +26,6 @@ enum fmcadc_supported_board {
__FMCADC_SUPPORTED_BOARDS_LAST_INDEX,
};
extern const struct fmcadc_board_type
*fmcadc_board_types[__FMCADC_SUPPORTED_BOARDS_LAST_INDEX];
/* The buffer hosts data and metadata, plus informative fields */
struct fmcadc_buffer {
void *data;
......
......@@ -21,12 +21,6 @@
#include "fmcadc-lib.h"
#include "fmcadc-lib-int.h"
const struct fmcadc_board_type
*fmcadc_board_types[__FMCADC_SUPPORTED_BOARDS_LAST_INDEX] = {
&fmcadc_100ms_4ch_14bit,
};
/* * * * * * * * * * * * * * * * * Handle Device * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * Handle Acquisition * * * * * * * * * * * * * */
......
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