Commit f8d16f0d authored by Lucas Russo's avatar Lucas Russo

dev_io: add Device IO subsytem

This was not commited as the .gitignore
file was wrong
parent 23828c6a
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h> /* getpid, getppid */
#include <unistd.h>
#include "czmq.h"
#include "dev_io.h"
#include "debug_print.h"
void print_help (char *program_name)
{
printf( "Usage: %s [options]\n"
"\t-h This help message\n"
"\t-d Daemon mode.\n"
"\t-v Verbose output\n"
"\t-t <device_type> Device type\n"
"\t-e <dev_entry> Device /dev entry\n"
"\t-b <broker_endpoint> Broker endpoint\n", program_name);
}
int main (int argc, char *argv[])
{
int verbose = 0;
int daemonize = 0;
char *dev_type = NULL;
char *dev_entry = NULL;
char *broker_endp = NULL;
char **str_p = &dev_type; /* default */
int i;
if (argc < 4) {
print_help (argv[0]);
exit (1);
}
/* FIXME: This is rather buggy! */
/* Simple handling of command-line options. This should be done
* with getopt, for instance*/
for (i = 1; i < argc; i++)
{
if (streq (argv[i], "-v")) {
verbose = 1;
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_TRACE, "[dev_io] Verbose mode set\n");
}
else if (streq (argv[i], "-d")) {
daemonize = 1;
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_TRACE, "[dev_io] Demonize mode set\n");
}
else if (streq (argv[i], "-t")) {
str_p = &dev_type;
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_TRACE, "[dev_io] Will set dev_type parameter\n");
}
else if (streq (argv[i], "-e")) {
str_p = &dev_entry;
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_TRACE, "[dev_io] Will set dev_entry parameter\n");
}
else if (streq (argv[i], "-b")) {
str_p = &broker_endp;
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_TRACE, "[dev_io] Will set broker_endp parameter\n");
}
else if (streq (argv[i], "-h")) {
print_help (argv[0]);
exit (1);
}
/* Fallout for options with parameters */
else {
*str_p = strdup (argv[i]);
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_TRACE, "[dev_io] Parameter set to \"%s\"\n", *str_p);
}
}
/* Daemonize dev_io */
if (daemonize != 0) {
int rc = daemon(0, 0);
if (rc != 0) {
perror ("[dev_io] daemon");
goto err_exit;
}
}
llio_type_e llio_type;
/* Parse command-line options */
if (streq (dev_type, "pcie")) {
llio_type = PCIE_DEV;
}
else if (streq (dev_type, "eth")) {
llio_type = ETH_DEV;
}
else {
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_FATAL, "[dev_io] Dev_type parameter is invalid\n");
goto err_exit;
}
/* We don't need it anymore */
str_p = &dev_type;
free (*str_p);
dev_type = NULL;
/* Initilialize dev_io */
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_TRACE, "[dev_io] Creating devio instance ...\n");
devio_t *devio = devio_new ("BPM0:DEVIO", dev_entry, llio_type,
broker_endp, verbose);
/* devio_t *devio = devio_new ("BPM0:DEVIO", *str_p, llio_type,
"tcp://localhost:5555", verbose); */
if (devio == NULL) {
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_FATAL, "[dev_io] devio_new error!\n");
goto err_exit;
}
/* We don't need it anymore */
str_p = &dev_entry;
free (*str_p);
dev_entry = NULL;
str_p = &broker_endp;
free (*str_p);
broker_endp = NULL;
uint32_t fmc130m_4ch_id = 0x7085ef15;
devio_err_e err;
err = devio_register_sm (devio, fmc130m_4ch_id, NULL);
if (err != DEVIO_SUCCESS) {
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_FATAL, "[dev_io] devio_register_sm error!\n");
goto err_devio;
}
err = devio_init_poller_sm (devio);
if (err != DEVIO_SUCCESS) {
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_FATAL, "[dev_io] devio_init_poller_sm error!\n");
goto err_devio;
}
while (!zctx_interrupted) {
/* Step 1: Loop though all the SDB records and intialize (boot) the
* smio modules*/
/* Step 2: Optionally, register the necessary smio modules specifying
* its ID and calling devio_register_sm */
/* Step 3: Poll all PIPE's sockets to determine if we have something to
* handle, like messages from smios */
/* Step 3.5: If we do, call devio_handle_smio () and treat its
* request as appropriate */
devio_poll_all_sm (devio);
}
err_devio:
devio_destroy (&devio);
err_exit:
free (broker_endp);
free (dev_entry);
free (dev_type);
return 0;
}
#ifndef _DEV_IO_
#define _DEV_IO_
#include "dev_io_core.h"
#endif
dev_io_DIR = hal/dev_io
# Here we call <output_name>_core_OBJS as we need to add
# more objects to this target. This is done in the hal.mk
# makefile
dev_io_core_OBJS = $(dev_io_DIR)/dev_io.o \
$(dev_io_DIR)/dev_io_core.o \
$(dev_io_DIR)/dev_io_err.o
dev_io_INCLUDE_DIRS = $(dev_io_DIR)
dev_io_OUT = dev_io
This diff is collapsed.
/*
* Copyright (C) 2014 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU LGPL, version 3 or any later version.
*/
#ifndef _DEV_IO_CORE_H_
#define _DEV_IO_CORE_H_
#include "czmq.h"
#include "mdp.h"
#include "hal_utils.h"
#include "dispatch_table.h"
#include "dev_io_err.h"
#include "ll_io.h"
/* #include "sm_io.h" */
/* #include "sm_io_thsafe_codes.h" */
/* #include "sm_io_bootstrap.h" */
/* SMIO hash key length in chars */
#define SMIO_HKEY_LEN 8
#define NODES_MAX_LEN 20
struct _smio_thsafe_server_ops_t;
struct _devio_t {
/* General information */
/*mdp_worker_t *worker;*/ /* zeroMQ Majordomo Worker */
zctx_t *ctx; /* zeroMQ Context */
void **pipes; /* Address nodes using this array of pipes */
zpoller_t *poller; /* Poller structure to multiplex threads messages */
unsigned int nnodes; /* Number of actual nodes */
char *name; /* Identification of this worker instance */
char *endpoint_broker; /* Broker location to connect to */
int verbose; /* Print activity to stdout */
/* ll_io instance for Low-Level operations*/
llio_t *llio;
/* Server part of the llio operations. This is the bridge between the
* smio client part of the llio operations and the de-facto
* llio operations */
const struct _smio_thsafe_server_ops_t *thsafe_server_ops;
/* Hash containg all the sm_io objects that
* this dev_io can handle. It is composed
* of key (10-char ID) / value (sm_io instance) */
zhash_t *sm_io_h;
/* Dispatch table containg all the sm_io thsafe operations
* that we need to handle. It is composed
* of key (4-char ID) / value (pointer to funtion) */
disp_table_t *disp_table_thsafe_ops;
};
struct _smio_thsafe_server_ops_t {
disp_table_func_fp thsafe_server_open; /* Open device */
disp_table_func_fp thsafe_server_release; /* Release device */
disp_table_func_fp thsafe_server_read_16; /* Read 16-bit data */
disp_table_func_fp thsafe_server_read_32; /* Read 32-bit data */
disp_table_func_fp thsafe_server_read_64; /* Read 64-bit data */
disp_table_func_fp thsafe_server_write_16; /* Write 16-bit data */
disp_table_func_fp thsafe_server_write_32; /* Write 32-bit data */
disp_table_func_fp thsafe_server_write_64; /* Write 64-bit data */
disp_table_func_fp thsafe_server_read_block; /* Read arbitrary block size data,
parameter size in bytes */
disp_table_func_fp thsafe_server_write_block; /* Write arbitrary block size data,
parameter size in bytes */
disp_table_func_fp thsafe_server_read_dma; /* Read arbitrary block size data via DMA,
parameter size in bytes */
disp_table_func_fp thsafe_server_write_dma; /* Write arbitrary block size data via DMA,
parameter size in bytes */
/*disp_table_func_fp_read_info_fp thsafe_server_read_info; Moved to dev_io */
/* Read device information data */
};
/* Opaque llio_th_safe_ops structure */
typedef struct _smio_thsafe_server_ops_t smio_thsafe_server_ops_t;
/* Opaque class structure */
typedef struct _devio_t devio_t;
/***************** Our methods *****************/
/* Creates a new instance of Device Information */
devio_t * devio_new (char *name, char *endpoint_dev,
llio_type_e type, char *endpoint_broker, int verbose);
/* Destroy an instance of the Device Information */
devio_err_e devio_destroy (devio_t **self_p);
/* Read specific information about the device. Typically,
* this is stored in the SDB structure inside the device */
devio_err_e devio_print_info (devio_t *self);
/* Register an specific sm_io module to this device */
devio_err_e devio_register_sm (devio_t *self, uint32_t smio_id, void *priv);
/* Register all sm_io module that this device can handle,
* according to the device information stored in the SDB */
devio_err_e devio_register_all_sm (devio_t *self);
devio_err_e devio_unregister_sm (devio_t *self, uint32_t smio_id);
devio_err_e devio_unregister_all_sm (devio_t *self);
/* Initilize poller with all of the initialized PIPE sockets */
devio_err_e devio_init_poller_sm (devio_t *self);
/* Poll all PIPE sockets */
devio_err_e devio_poll_all_sm (devio_t *self);
/* Router for all the opcodes registered for this dev_io */
/* devio_err_e devio_do_op (devio_t *self, uint32_t opcode, int nargs, ...); */
/* Router for all of the low-level operations for this dev_io */
devio_err_e devio_do_smio_op (devio_t *self, void *msg);
/********* Low-level generic methods API *********/
/* Open device */
void *smio_thsafe_server_open (void *owner, void *args);
/* Release device */
void *smio_thsafe_server_release (void *owner, void *args);
/* Read data from device */
void *smio_thsafe_server_read_16 (void *owner, void *args);
void *smio_thsafe_server_read_32 (void *owner, void *args);
void *smio_thsafe_server_read_64 (void *owner, void *args);
/* Write data to device */
void *smio_thsafe_server_write_16 (void *owner, void *args);
void *smio_thsafe_server_write_32 (void *owner, void *args);
void *smio_thsafe_server_write_64 (void *owner, void *args);
/* Read data block from device, size in bytes */
void *smio_thsafe_server_read_block (void *owner, void *args);
/* Write data block from device, size in bytes */
void *smio_thsafe_server_write_block (void *owner, void *args);
/* Read data block via DMA from device, size in bytes */
void *smio_thsafe_server_read_dma (void *owner, void *args);
/* Write data block via DMA from device, size in bytes */
void *smio_thsafe_server_write_dma (void *owner, void *args);
/* Read device information */
/* void *smio_thsafe_server_read_info (void *owner, void *args); */
#endif
/*
* Copyright (C) 2014 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU LGPL, version 3 or any later version.
*/
/* Error definitions and output stringification based on the work available
* at the libsllp project repository: https://github.com/brunoseivam/libsllp */
#include "dev_io_err.h"
static const char *devio_err [DEVIO_ERR_END] =
{
[DEVIO_SUCCESS] = "Success",
[DEVIO_ERR_ALLOC] = "Could not allocate memory",
[DEVIO_ERR_FUNC_NOT_IMPL] = "Function not implemented",
[DEVIO_ERR_NO_SMIO_OP] = "No sm_io registered for this opcode",
[DEVIO_ERR_NO_SMIO_ID] = "No sm_io registered with this ID",
[DEVIO_ERR_SMIO_DO_OP] = "Error calling specific sm_io function",
[DEVIO_ERR_NO_NODES] = "No thread nodes available",
[DEVIO_ERR_UNINIT_POLLER] = "Poller uninitilized",
[DEVIO_ERR_BAD_MSG] = "Malformed message received",
[DEVIO_ERR_TERMINATED] = "Terminated devio instance"
};
/* Convert enumeration type to string */
const char * devio_err_str (devio_err_e err)
{
return devio_err [err];
}
/*
* Copyright (C) 2014 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU LGPL, version 3 or any later version.
*/
/* Error definitions and output stringification based on the work available
* at the libsllp project repository: https://github.com/brunoseivam/libsllp */
#ifndef _DEVIO_ERR_H_
#define _DEVIO_ERR_H_
enum _devio_err_e
{
DEVIO_SUCCESS = 0, /* No error */
DEVIO_ERR_ALLOC, /* Could not allocate memory */
DEVIO_ERR_FUNC_NOT_IMPL, /* Function not implemented */
DEVIO_ERR_SMIO_DO_OP, /* Error calling sm_io specific function */
DEVIO_ERR_NO_SMIO_OP, /* No sm_io registered for the opcode argument */
DEVIO_ERR_NO_SMIO_ID, /* No sm_io registered with the id argument */
DEVIO_ERR_NO_NODES, /* No thread nodes available */
DEVIO_ERR_UNINIT_POLLER, /* Uninitliazed poller */
DEVIO_ERR_BAD_MSG, /* Malformed message received */
DEVIO_ERR_TERMINATED, /* Terminated devio instance */
DEVIO_ERR_END /* End of enum marker */
};
typedef enum _devio_err_e devio_err_e;
/* Convert enumeration type to string */
const char * devio_err_str (devio_err_e err);
#endif
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