Commit 595fe981 authored by Federico Vaga's avatar Federico Vaga

wrtd:lib: manage logging shared mode

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 4ce4a54a
...@@ -531,6 +531,42 @@ int wrtd_in_log_level_set(struct wrtd_node *dev, unsigned int input, ...@@ -531,6 +531,42 @@ int wrtd_in_log_level_set(struct wrtd_node *dev, unsigned int input,
return wrtd_validate_acknowledge(&msg); return wrtd_validate_acknowledge(&msg);
} }
/**
* It sets the logging interface shared mode. When the logging interface
* is shared all users will receive the same messages.
* Rembember that the logging interface is not "per-channel" but "per-core".
* Even if it is possible to fake a per-channel behaviour
* for wrtd_in_log_open(); there is no way to set the shared mode for
* single channel
* @param[in] dev device token
* @param[in] shared 1 share, 0 not share
* @return 0 on success, -1 on error and errno is set appropriately
*/
int wrtd_in_log_share_set(struct wrtd_node *dev, unsigned int shared)
{
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
return wrnc_hmq_share_set(wrtd->wrnc, WRNC_HMQ_OUTCOMING,
WRTD_OUT_TDC_LOGGING, shared);
}
/**
* It gets the current shared mode status for the logging interface
* @param[in] dev device token
* @param[out] shared 1 share, 0 not share
* @return 0 on success, -1 on error and errno is set appropriately
*/
int wrtd_in_log_share_get(struct wrtd_node *dev, unsigned int *shared)
{
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
return wrnc_hmq_share_get(wrtd->wrnc, WRNC_HMQ_OUTCOMING,
WRTD_OUT_TDC_LOGGING, shared);
}
/** /**
* It opens the logging interface for the input device. You can provide a * It opens the logging interface for the input device. You can provide a
* default logging level. * default logging level.
......
...@@ -656,6 +656,41 @@ int wrtd_out_trig_enable(struct wrtd_node *dev, ...@@ -656,6 +656,41 @@ int wrtd_out_trig_enable(struct wrtd_node *dev,
} }
/**
* It sets the logging interface shared mode. When the logging interface
* is shared all users will receive the same messages.
* Rembember that the logging interface is not "per-channel" but "per-core".
* Even if it is possible to fake a per-channel behaviour
* for wrtd_in_log_open(); there is no way to set the shared mode for
* single channel
* @param[in] dev device token
* @param[in] shared 1 share, 0 not share
* @return 0 on success, -1 on error and errno is set appropriately
*/
int wrtd_out_log_share_set(struct wrtd_node *dev, unsigned int shared)
{
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
return wrnc_hmq_share_set(wrtd->wrnc, WRNC_HMQ_OUTCOMING,
WRTD_OUT_FD_LOGGING, shared);
}
/**
* It gets the current shared mode status for the logging interface
* @param[in] dev device token
* @param[out] shared 1 share, 0 not share
* @return 0 on success, -1 on error and errno is set appropriately
*/
int wrtd_out_log_share_get(struct wrtd_node *dev, unsigned int *shared)
{
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
return wrnc_hmq_share_get(wrtd->wrnc, WRNC_HMQ_OUTCOMING,
WRTD_OUT_FD_LOGGING, shared);
}
/** /**
* It opens the logging interface for the output device. You can provide a * It opens the logging interface for the output device. You can provide a
* default logging level. * default logging level.
......
...@@ -152,6 +152,8 @@ extern int wrtd_in_timebase_offset_set(struct wrtd_node *dev, ...@@ -152,6 +152,8 @@ extern int wrtd_in_timebase_offset_set(struct wrtd_node *dev,
extern int wrtd_in_counters_reset(struct wrtd_node *dev, unsigned int input); extern int wrtd_in_counters_reset(struct wrtd_node *dev, unsigned int input);
extern int wrtd_in_log_level_set(struct wrtd_node *dev, unsigned int input, extern int wrtd_in_log_level_set(struct wrtd_node *dev, unsigned int input,
uint32_t log_level); uint32_t log_level);
extern int wrtd_in_log_share_set(struct wrtd_node *dev, unsigned int shared);
extern int wrtd_in_log_share_get(struct wrtd_node *dev, unsigned int *shared);
extern struct wrnc_hmq *wrtd_in_log_open(struct wrtd_node *dev, extern struct wrnc_hmq *wrtd_in_log_open(struct wrtd_node *dev,
uint32_t lvl, uint32_t lvl,
int input); int input);
...@@ -206,6 +208,8 @@ extern int wrtd_out_pulse_width_set(struct wrtd_node *dev, unsigned int output, ...@@ -206,6 +208,8 @@ extern int wrtd_out_pulse_width_set(struct wrtd_node *dev, unsigned int output,
uint64_t pulse_width_ps); uint64_t pulse_width_ps);
extern int wrtd_out_log_level_set(struct wrtd_node *dev, unsigned int output, extern int wrtd_out_log_level_set(struct wrtd_node *dev, unsigned int output,
uint32_t log_level); uint32_t log_level);
extern int wrtd_out_log_share_set(struct wrtd_node *dev, unsigned int shared);
extern int wrtd_out_log_share_get(struct wrtd_node *dev, unsigned int *shared);
extern struct wrnc_hmq *wrtd_out_log_open(struct wrtd_node *dev, extern struct wrnc_hmq *wrtd_out_log_open(struct wrtd_node *dev,
uint32_t lvl, uint32_t lvl,
int output); int output);
......
...@@ -91,6 +91,15 @@ int main(int argc, char *argv[]) ...@@ -91,6 +91,15 @@ int main(int argc, char *argv[])
exit(1); exit(1);
} }
if (share) {
err = wrtd_in_log_share_set(wrtd, 1);
if (err)
fprintf(stderr, "Cannot set share mode: %s\n", wrtd_strerror(errno));
err = wrtd_out_log_share_set(wrtd, 1);
if (err)
fprintf(stderr, "Cannot set share mode: %s\n", wrtd_strerror(errno));
}
/* Open logging interfaces */ /* Open logging interfaces */
log[0] = wrtd_in_log_open(wrtd, WRTD_LOG_ALL, -1); log[0] = wrtd_in_log_open(wrtd, WRTD_LOG_ALL, -1);
if (!log[0]) { if (!log[0]) {
...@@ -98,11 +107,6 @@ int main(int argc, char *argv[]) ...@@ -98,11 +107,6 @@ int main(int argc, char *argv[])
wrtd_strerror(errno)); wrtd_strerror(errno));
goto out_in; goto out_in;
} }
if (share) {
err = wrnc_hmq_share_set(log[0], share);
if (err)
fprintf(stderr, "Cannot set share mode: %s\n", wrtd_strerror(errno));
}
p[0].fd = log[0]->fd; p[0].fd = log[0]->fd;
p[0].events = POLLIN; p[0].events = POLLIN;
...@@ -112,11 +116,6 @@ int main(int argc, char *argv[]) ...@@ -112,11 +116,6 @@ int main(int argc, char *argv[])
wrtd_strerror(errno)); wrtd_strerror(errno));
goto out_out; goto out_out;
} }
if (share) {
err = wrnc_hmq_share_set(log[1], share);
if (err)
fprintf(stderr, "Cannot set share mode: %s\n", wrtd_strerror(errno));
}
p[1].fd = log[1]->fd; p[1].fd = log[1]->fd;
p[1].events = POLLIN; p[1].events = POLLIN;
......
...@@ -226,6 +226,14 @@ static ssize_t wrnc_store_share(struct device *dev, ...@@ -226,6 +226,14 @@ static ssize_t wrnc_store_share(struct device *dev,
if (kstrtol(buf, 0, &val)) if (kstrtol(buf, 0, &val))
return -EINVAL; return -EINVAL;
/*
* If the status is the same, than there is nothing to do. This
* control sounds useless but it save code in user-space and it
* allows a proper error management
*/
if (val == (!!(hmq->flags & WRNC_FLAG_HMQ_SHR_USR)))
return count;
/* You cannot configure while the HMQ is in use */ /* You cannot configure while the HMQ is in use */
if (hmq->n_user > 0) if (hmq->n_user > 0)
return -EBUSY; return -EBUSY;
......
...@@ -617,17 +617,23 @@ void wrnc_hmq_close(struct wrnc_hmq *hmq) ...@@ -617,17 +617,23 @@ void wrnc_hmq_close(struct wrnc_hmq *hmq)
/** /**
* It enables/disables the message share mode. Multiple clients can read the same message * It enables/disables the message share mode. When enable, all users will read
* when they read from the same file descriptor * the same messages.
* @param[in] hmq HMQ device descriptor * @param[in] wrnc device token
* @param[in] dir slot direction, 1 CPU input, 0 CPU output
* @param[in] index slot index
* @param[in] status status to set: 1 enable, 0 disable * @param[in] status status to set: 1 enable, 0 disable
* @return 0 on success, -1 on error and errno is set appropriately * @return 0 on success, -1 on error and errno is set appropriately
*/ */
int wrnc_hmq_share_set(struct wrnc_hmq *hmq, unsigned int status) int wrnc_hmq_share_set(struct wrnc_dev *wrnc, unsigned int dir,
unsigned int index, unsigned int status)
{ {
struct wrnc_desc *wdesc = (struct wrnc_desc *)wrnc;
char path[WRNC_SYSFS_PATH_LEN]; char path[WRNC_SYSFS_PATH_LEN];
snprintf(path, WRNC_SYSFS_PATH_LEN, "%s/shared_by_users", hmq->syspath); snprintf(path, WRNC_SYSFS_PATH_LEN,
"/sys/class/wr-node-core/%s/%s-hmq-%c-%02d/shared_by_users",
wdesc->name, wdesc->name, (dir ? 'i' : 'o'), index);
return wrnc_sysfs_printf(path, "%d", status); return wrnc_sysfs_printf(path, "%d", status);
} }
...@@ -635,15 +641,21 @@ int wrnc_hmq_share_set(struct wrnc_hmq *hmq, unsigned int status) ...@@ -635,15 +641,21 @@ int wrnc_hmq_share_set(struct wrnc_hmq *hmq, unsigned int status)
/** /**
* It gets the current status of the message share mode * It gets the current status of the message share mode
* @param[in] hmq HMQ device descriptor * @param[in] wrnc device token
* @param[in] dir slot direction, 1 CPU input, 0 CPU output
* @param[in] index slot index
* @param[out] status current value * @param[out] status current value
* @return 0 on success, -1 on error and errno is set appropriately * @return 0 on success, -1 on error and errno is set appropriately
*/ */
int wrnc_hmq_share_get(struct wrnc_hmq *hmq, unsigned int *status) int wrnc_hmq_share_get(struct wrnc_dev *wrnc, unsigned int dir,
unsigned int index, unsigned int *status)
{ {
struct wrnc_desc *wdesc = (struct wrnc_desc *)wrnc;
char path[WRNC_SYSFS_PATH_LEN]; char path[WRNC_SYSFS_PATH_LEN];
snprintf(path, WRNC_SYSFS_PATH_LEN, "%s/shared_by_users", hmq->syspath); snprintf(path, WRNC_SYSFS_PATH_LEN,
"/sys/class/wr-node-core/%s/%s-hmq-%c-%02d/shared_by_users",
wdesc->name, wdesc->name, (dir ? 'i' : 'o'), index);
return wrnc_sysfs_scanf(path, "%d", status); return wrnc_sysfs_scanf(path, "%d", status);
} }
......
...@@ -119,8 +119,10 @@ extern struct wrnc_hmq *wrnc_hmq_open(struct wrnc_dev *wrnc, ...@@ -119,8 +119,10 @@ extern struct wrnc_hmq *wrnc_hmq_open(struct wrnc_dev *wrnc,
unsigned int index, unsigned int index,
unsigned long flags); unsigned long flags);
extern void wrnc_hmq_close(struct wrnc_hmq *hmq); extern void wrnc_hmq_close(struct wrnc_hmq *hmq);
extern int wrnc_hmq_share_set(struct wrnc_hmq *hmq, unsigned int status); extern int wrnc_hmq_share_set(struct wrnc_dev *wrnc, unsigned int dir,
extern int wrnc_hmq_share_get(struct wrnc_hmq *hmq, unsigned int *status); unsigned int index, unsigned int status);
extern int wrnc_hmq_share_get(struct wrnc_dev *wrnc, unsigned int dir,
unsigned int index, unsigned int *status);
extern struct wrnc_msg *wrnc_hmq_receive(struct wrnc_hmq *hmq); extern struct wrnc_msg *wrnc_hmq_receive(struct wrnc_hmq *hmq);
extern int wrnc_hmq_send(struct wrnc_hmq *hmq, struct wrnc_msg *msg); extern int wrnc_hmq_send(struct wrnc_hmq *hmq, struct wrnc_msg *msg);
extern int wrnc_hmq_send_and_receive_sync(struct wrnc_hmq *hmq, extern int wrnc_hmq_send_and_receive_sync(struct wrnc_hmq *hmq,
......
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