Commit 44123e81 authored by Federico Vaga's avatar Federico Vaga

lib: simplify HMQ functions

Use a dedicated token to manage the HMQ operations. This simplify the
prototypes, the logic inside the library and the management from user-space.

Now, user can use directly poll(2) without any wrapper.
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 399be71d
......@@ -17,19 +17,19 @@
static inline int wrtd_in_send_and_receive_sync(struct wrtd_desc *wrtd,
struct wrnc_msg *msg)
{
struct wrnc_hmq *hmq;
int err;
err = wrnc_hmq_open(wrtd->wrnc, WRTD_IN_TDC_CONTROL, WRNC_HMQ_INCOMING);
if (err)
return err;
hmq = wrnc_hmq_open(wrtd->wrnc, WRTD_IN_TDC_CONTROL, WRNC_HMQ_INCOMING);
if (!hmq)
return -1;
/* Send the message and get answer */
err = wrnc_slot_send_and_receive_sync(wrtd->wrnc,
WRTD_IN_TDC_CONTROL,
err = wrnc_slot_send_and_receive_sync(hmq,
WRTD_OUT_TDC_CONTROL,
msg,
WRTD_DEFAULT_TIMEOUT);
wrnc_hmq_close(wrtd->wrnc, WRTD_IN_TDC_CONTROL, WRNC_HMQ_INCOMING);
wrnc_hmq_close(hmq);
return err;
}
......
......@@ -17,19 +17,19 @@ static inline int wrtd_out_send_and_receive_sync(struct wrtd_desc *wrtd,
struct wrnc_msg *msg)
{
/* Send the message and get answer */
struct wrnc_hmq *hmq;
int err;
err = wrnc_hmq_open(wrtd->wrnc, WRTD_IN_FD_CONTROL, WRNC_HMQ_INCOMING);
if (err)
return err;
hmq = wrnc_hmq_open(wrtd->wrnc, WRTD_IN_FD_CONTROL, WRNC_HMQ_INCOMING);
if (!hmq)
return -1;
err = wrnc_slot_send_and_receive_sync(wrtd->wrnc,
WRTD_IN_FD_CONTROL,
err = wrnc_slot_send_and_receive_sync(hmq,
WRTD_OUT_FD_CONTROL,
msg,
WRTD_DEFAULT_TIMEOUT);
wrnc_hmq_close(wrtd->wrnc, WRTD_IN_FD_CONTROL, WRNC_HMQ_INCOMING);
wrnc_hmq_close(hmq);
return err;
}
......
......@@ -556,86 +556,85 @@ int wrnc_cpu_dump_application_file(struct wrnc_dev *wrnc,
* @param[in] flags HMQ flags
* @return 0 on success, -1 on error and errno is set appropriately
*/
int wrnc_hmq_open(struct wrnc_dev *wrnc, unsigned int index,
unsigned long flags)
struct wrnc_hmq *wrnc_hmq_open(struct wrnc_dev *wrnc, unsigned int index,
unsigned long flags)
{
struct wrnc_desc *wdesc = (struct wrnc_desc *)wrnc;
struct wrnc_hmq *hmq;
char path[64];
int *fd, dir = flags & WRNC_HMQ_INCOMING;
int fd, dir = flags & WRNC_HMQ_INCOMING;
if (index >= WRNC_MAX_HMQ_SLOT / 2) {
errno = EWRNC_INVAL_SLOT;
return -1;
return NULL;
}
fd = dir ? wdesc->fd_hmq_in : wdesc->fd_hmq_out;
snprintf(path, 64, "/dev/%s-hmq-%c-%02d",
wdesc->name, (dir ? 'i' : 'o'), index);
fd = open(path, (dir ? O_WRONLY : O_RDONLY));
if (fd < 0)
return NULL;
/* Do not open if it is already opened */
if (fd[index] < 0) {
snprintf(path, 64, "/dev/%s-hmq-%c-%02d",
wdesc->name, (dir ? 'i' : 'o'), index);
fd[index] = open(path, (dir ? O_WRONLY : O_RDONLY));
if (fd[index] < 0)
return -1;
hmq = malloc(sizeof(struct wrnc_hmq));
if (!hmq) {
close(fd);
return NULL;
}
return 0;
hmq->wrnc = wrnc;
hmq->index = index;
hmq->flags = flags;
hmq->fd = fd;
return (struct wrnc_hmq *)hmq;
}
/**
* It closes a HMQ slot
* @param[in] wdesc device token
* @param[in] index HMQ index
* @param[in] flags HMQ flags
* @param[in] hmq HMQ device descriptor
* @return 0 on success, -1 on error and errno is set appropriately
*/
void wrnc_hmq_close(struct wrnc_dev *wrnc, unsigned int index,
unsigned long flags)
void wrnc_hmq_close(struct wrnc_hmq *hmq)
{
struct wrnc_desc *wdesc = (struct wrnc_desc *)wrnc;
int *fd;
fd = flags & WRNC_HMQ_INCOMING ? wdesc->fd_hmq_in : wdesc->fd_hmq_out;
if (fd[index] > 0)
close(fd[index]);
if (hmq && hmq->fd > 0) {
close(hmq->fd);
free(hmq);
}
}
/**
* It sends a synchronous message. The slots are uni-directional, so you must
* specify where write the message and where the answer is expected.
* @param[in] wrnc device token
* @param[in] index_in index of the HMQ input slot
* @param[in] hmq HMQ device descriptor on the input slot
* @param[in] index_out index of the HMQ output slot
* @param[in,out] msg it contains the message to be sent; the answer will
* overwrite the message
* @param[in] timeout_ms maximum ms to wait for an answer
* @return 0 on success, -1 on error and errno is set appropriately
*/
int wrnc_slot_send_and_receive_sync(struct wrnc_dev *wrnc,
unsigned int index_in,
int wrnc_slot_send_and_receive_sync(struct wrnc_hmq *hmq,
unsigned int index_out,
struct wrnc_msg *msg,
unsigned int timeout_ms)
{
struct wrnc_desc *wdesc = (struct wrnc_desc *)wrnc;
struct wrnc_msg_sync smsg;
int err;
if (wdesc->fd_hmq_in[index_in] < 0) {
if (!hmq || hmq->fd < 0) {
errno = EWRNC_HMQ_CLOSE;
return -1;
}
/* Build the message */
smsg.index_in = index_in;
smsg.index_in = hmq->index;
smsg.index_out = index_out;
smsg.timeout_ms = timeout_ms;
memcpy(&smsg.msg, msg, sizeof(struct wrnc_msg));
/* Send the message */
err = ioctl(wdesc->fd_hmq_in[index_in], WRNC_IOCTL_MSG_SYNC, &smsg);
err = ioctl(hmq->fd, WRNC_IOCTL_MSG_SYNC, &smsg);
if (err)
return -1;
......@@ -646,46 +645,6 @@ int wrnc_slot_send_and_receive_sync(struct wrnc_dev *wrnc,
}
/**
* It is a wrapper of poll(2) for a wrnc slot device.
* @param[in] wrnc device token
* @param[in] p see poll(2), instead of the real FD use the HMQ slot index.
* This, in order to work only with slots' indexes.
* @param[in] nfds see poll(2).
* @param[in] timeout see poll(2)
* @return see poll(2)
*/
int wrnc_slot_poll(struct wrnc_dev *wrnc, struct pollfd *p, nfds_t nfds,
int timeout)
{
struct wrnc_desc *wdesc = (struct wrnc_desc *)wrnc;
struct pollfd lp[nfds];
int ret, i, index;
/* Copy requested events and retrieve fd */
for (i = 0; i < nfds; ++i) {
lp[i].events = p[i].events;
index = p[i].fd;
if (p[i].events & POLLIN) {
lp[i].fd = wdesc->fd_hmq_out[index];
}
if (p[i].events & POLLOUT) {
lp[i].fd = wdesc->fd_hmq_in[index];
}
}
ret = poll(lp, nfds, timeout);
/* Copy back the return events */
for (i = 0; i < nfds; i++)
p[i].revents = lp[i].revents;
return ret;
}
/**
* It opens a WRNC device
* @param[in] wdesc device descriptor
......@@ -853,17 +812,15 @@ int wrnc_cpu_disable(struct wrnc_dev *wrnc, unsigned int index)
/**
* It allocates and returns a message from an output message queue slot.
* The user of this function is in charge to release the memory.
* @param[in] wrnc device to use
* @param[in] index HMQ slot to read
* @param[in] hmq HMQ device descriptor
* @return a WRNC message, NULL on error and errno is set appropriately
*/
struct wrnc_msg *wrnc_slot_receive(struct wrnc_dev *wrnc, unsigned int index)
struct wrnc_msg *wrnc_slot_receive(struct wrnc_hmq *hmq)
{
struct wrnc_desc *wdesc = (struct wrnc_desc *)wrnc;
struct wrnc_msg *msg;
int n;
if (wdesc->fd_hmq_out[index] < 0) {
if (!hmq || hmq->fd < 0) {
errno = EWRNC_HMQ_CLOSE;
return NULL;
}
......@@ -873,7 +830,7 @@ struct wrnc_msg *wrnc_slot_receive(struct wrnc_dev *wrnc, unsigned int index)
return NULL;
/* Get a message from the driver */
n = read(wdesc->fd_hmq_out[index], msg, sizeof(struct wrnc_msg));
n = read(hmq->fd, msg, sizeof(struct wrnc_msg));
if (n != sizeof(struct wrnc_msg)) {
free(msg);
return NULL;
......@@ -885,17 +842,15 @@ struct wrnc_msg *wrnc_slot_receive(struct wrnc_dev *wrnc, unsigned int index)
/**
* It sends a message to an input message queue slot.
* @param[in] wrnc device to use
* @param[in] index HMQ slot to write
* @param[in] hmq HMQ device descriptor
* @param[in] msg message to send
* @return 0 on success, -1 otherwise and errno is set appropriately
*/
int wrnc_slot_send(struct wrnc_dev *wrnc, unsigned int index,
struct wrnc_msg *msg)
int wrnc_slot_send(struct wrnc_hmq *hmq, struct wrnc_msg *msg)
{
struct wrnc_desc *wdesc = (struct wrnc_desc *)wrnc;
int n;
if (wdesc->fd_hmq_in[index] < 0) {
if (!hmq || hmq->fd < 0) {
errno = EWRNC_HMQ_CLOSE;
return -1;
}
......@@ -905,7 +860,7 @@ int wrnc_slot_send(struct wrnc_dev *wrnc, unsigned int index,
return -1;
/* Get a message from the driver */
n = write(wdesc->fd_hmq_in[index], msg, sizeof(struct wrnc_msg));
n = write(hmq->fd, msg, sizeof(struct wrnc_msg));
if (n != sizeof(struct wrnc_msg))
return -1;
......@@ -913,25 +868,6 @@ int wrnc_slot_send(struct wrnc_dev *wrnc, unsigned int index,
}
/**
* It retreives the file descriptor of a slot
* @param[in] wrnc device token
* @param[in] is_input direction of the slot, 1 for input, 0 for output
* @param[in] index HMQ slot index
* @return the file descriptor number, -1 if the slot is not yet opened
*/
int wrnc_slot_fd_get(struct wrnc_dev *wrnc, unsigned int is_input,
unsigned int index)
{
struct wrnc_desc *wdesc = (struct wrnc_desc *)wrnc;
int *fd;
fd = is_input ? wdesc->fd_hmq_in : wdesc->fd_hmq_out;
return fd[index];
}
/**
* It returns the name of the device
* @param[in] wrnc device token
......
......@@ -30,6 +30,19 @@ struct wrnc_dbg {
int fd; /**< file descriptor of the debug interface */
};
/**
* HMQ slot descriptor
*/
struct wrnc_hmq {
struct wrnc_dev *wrnc; /**< where this slot belong to */
unsigned int index; /* index of the slot. Note that we have
different kind of slot and each kind start
counting from 0*/
unsigned long flags; /**< flags associated to the slot */
int fd; /**< file descriptor */
};
#define WRNC_NAME_LEN 12
#define WRNC_SYSFS_PATH_LEN 128
......@@ -112,23 +125,16 @@ extern int wrnc_cpu_disable(struct wrnc_dev *wrnc, unsigned int index);
extern int wrnc_cpu_start(struct wrnc_dev *wrnc, unsigned int index);
extern int wrnc_cpu_stop(struct wrnc_dev *wrnc, unsigned int index);
extern int wrnc_hmq_open(struct wrnc_dev *wrnc, unsigned int index,
unsigned long flags);
extern void wrnc_hmq_close(struct wrnc_dev *wrnc, unsigned int index,
unsigned long flags);
extern struct wrnc_msg *wrnc_slot_receive(struct wrnc_dev *wrnc,
unsigned int index);
extern int wrnc_slot_send(struct wrnc_dev *wrnc, unsigned int index,
struct wrnc_msg *msg);
extern int wrnc_slot_send_and_receive_sync(struct wrnc_dev *wrnc,
unsigned int index_in,
extern struct wrnc_hmq *wrnc_hmq_open(struct wrnc_dev *wrnc,
unsigned int index,
unsigned long flags);
extern void wrnc_hmq_close(struct wrnc_hmq *hmq);
extern struct wrnc_msg *wrnc_slot_receive(struct wrnc_hmq *hmq);
extern int wrnc_slot_send(struct wrnc_hmq *hmq, struct wrnc_msg *msg);
extern int wrnc_slot_send_and_receive_sync(struct wrnc_hmq *hmq,
unsigned int index_out,
struct wrnc_msg *msg,
unsigned int timeout_ms);
extern int wrnc_slot_poll(struct wrnc_dev *wrnc, struct pollfd *p, nfds_t nfds,
int timeout);
extern int wrnc_slot_fd_get(struct wrnc_dev *wrnc, unsigned int is_input,
unsigned int index);
extern int wrnc_smem_read(struct wrnc_dev *wrnc, uint32_t addr, uint32_t *data,
size_t count, enum wrnc_smem_modifier mod);
extern int wrnc_smem_write(struct wrnc_dev *wrnc, uint32_t addr, uint32_t *data,
......
......@@ -59,9 +59,9 @@ static void help()
/**
* It retreives a message from a given slots and it prints its content
* @param[in] wrnc device to use
* @param[in] slot_index index of the slot to read
* @param[in] hmq slot to read
*/
static int dump_message(struct wrnc_dev *wrnc, unsigned int slot_index)
static int dump_message(struct wrnc_dev *wrnc, struct wrnc_hmq *hmq)
{
struct wrnc_msg *wmsg;
time_t tm;
......@@ -75,8 +75,8 @@ static int dump_message(struct wrnc_dev *wrnc, unsigned int slot_index)
strftime(stime, 64,"%T", gm);
fprintf(stdout, "[%s] ", stime);
}
fprintf(stdout, "%s-hmq-i-%02d :", wrnc_name_get(wrnc), slot_index);
wmsg = wrnc_slot_receive(wrnc, slot_index);
fprintf(stdout, "%s-hmq-i-%02d :", wrnc_name_get(wrnc), hmq->index);
wmsg = wrnc_slot_receive(hmq);
if (!wmsg) {
fprintf(stdout, " error : %s\n", wrnc_strerror(errno));
return -1;
......@@ -124,6 +124,7 @@ void *dump_thread(void *arg)
struct pollfd p[MAX_SLOT], p_dbg[MAX_CPU];
struct wrnc_dbg *wdbg[MAX_CPU];
struct wrnc_dev *wrnc;
struct wrnc_hmq *hmq[th_data->n_slot];
int ret, err, i;
/* Open the device */
......@@ -135,14 +136,14 @@ void *dump_thread(void *arg)
/* Build the polling structures */
for (i = 0; i < th_data->n_slot; ++i) {
err = wrnc_hmq_open(wrnc, th_data->slot_index[i],
hmq[i] = wrnc_hmq_open(wrnc, th_data->slot_index[i],
WRNC_HMQ_OUTCOMING);
if (err) {
if (!hmq[i]) {
fprintf(stderr, "Cannot open HMQ: %s\n",
wrnc_strerror(errno));
goto out_slot;
}
p[i].fd = th_data->slot_index[i];
p[i].fd = hmq[i]->fd;
p[i].events = POLLIN | POLLERR;
}
......@@ -181,7 +182,7 @@ void *dump_thread(void *arg)
}
/* Polling slots */
ret = wrnc_slot_poll(wrnc, p, th_data->n_slot, 10000);
ret = poll(p, th_data->n_slot, 10000);
switch (ret) {
default:
/* Dump from the slot */
......@@ -189,7 +190,7 @@ void *dump_thread(void *arg)
if (!(p[i].revents & POLLIN))
continue;
err = dump_message(wrnc, p[i].fd);
err = dump_message(wrnc, hmq[i]);
if (err)
continue;
pthread_mutex_lock(&mtx);
......@@ -214,7 +215,7 @@ out_dbg:
out_slot:
/* Close all message slots */
for (i = 0; i < th_data->n_slot; ++i)
wrnc_hmq_close(wrnc, th_data->slot_index[i], WRNC_HMQ_OUTCOMING);
wrnc_hmq_close(hmq[i]);
wrnc_close(wrnc);
return NULL;
}
......
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