Commit c3f935f4 authored by Federico Vaga's avatar Federico Vaga

wrtd:lib: use dedicatet RT function to find trigger by id

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent c410d8b2
...@@ -53,62 +53,32 @@ static int wrtd_out_trivial_request (struct wrtd_node *dev, struct wrnc_msg *req ...@@ -53,62 +53,32 @@ static int wrtd_out_trivial_request (struct wrtd_node *dev, struct wrnc_msg *req
#define WRTD_HASH_ENTRY_CONDITIONAL 1 #define WRTD_HASH_ENTRY_CONDITIONAL 1
#define WRTD_HASH_ENTRY_EMPTY 2 #define WRTD_HASH_ENTRY_EMPTY 2
/**
* Retreives a trigger entry specified by a position in the hash table
* (bucket/index number) or by its handle (if handle parameter is not null)
* @param[in] dev device token
* @param[in] output index (0-based) of output channel
* @param[in] bucket bucket in the hash table to read
* @param[in] index specifies which entry in the selected bucket will be read
* @param[in] handle handle of the trigger to read (if null, takes bucket/index)
* @param[out] trigger retrieved trigger entry
*/
static int wrtd_out_trig_get(struct wrtd_node *dev, unsigned int output, static int __wrtd_out_trig_get(struct wrtd_desc *wrtd, uint32_t output,
unsigned int bucket, unsigned int index, struct wrnc_msg *msg,
struct wrtd_trigger_handle *handle, struct wrtd_output_trigger_state *trigger)
struct wrtd_output_trigger_state *trigger)
{ {
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev; uint32_t id = 0, seq = 0, is_conditional, entry_ok, state;
struct wrnc_msg msg = wrnc_msg_init (16); uint32_t latency_worst, latency_avg_nsamples, latency_avg_sum;
int err, is_conditional = 0, entry_ok = 0; int err;
uint32_t seq = 0, id ;
uint32_t state, latency_worst, latency_avg_sum, latency_avg_nsamples, ptr = 0;
if (output > FD_NUM_CHANNELS) {
errno = EWRTD_INVALID_CHANNEL;
return -1;
}
/* Build the message */
id = WRTD_CMD_FD_READ_HASH;
wrnc_msg_header (&msg, &id, &seq);
wrnc_msg_uint32 (&msg, &bucket);
wrnc_msg_uint32 (&msg, &index);
wrnc_msg_uint32 (&msg, &output);
if(handle)
ptr = handle->ptr_cond ? handle->ptr_cond : handle->ptr_trig;
wrnc_msg_uint32 (&msg, &ptr);
/* Send the message and get answer */ /* Send the message and get answer */
err = wrtd_out_send_and_receive_sync (wrtd, &msg); err = wrtd_out_send_and_receive_sync(wrtd, msg);
if (err) { if (err) {
errno = EWRTD_INVALID_ANSWER_STATE; errno = EWRTD_INVALID_ANSWER_STATE;
return -1; return -1;
} }
/* Deserialize and check the answer */ /* Deserialize and check the answer */
wrnc_msg_header (&msg, &id, &seq); wrnc_msg_header(msg, &id, &seq);
if (id != WRTD_REP_HASH_ENTRY) if (id != WRTD_REP_HASH_ENTRY)
{ {
errno = EWRTD_INVALID_ANSWER_STATE; errno = EWRTD_INVALID_ANSWER_STATE;
return -1; return -1;
} }
wrnc_msg_int32 (&msg, &entry_ok); wrnc_msg_uint32(msg, &entry_ok);
wrnc_msg_int32 (&msg, &is_conditional); wrnc_msg_uint32(msg, &is_conditional);
if(!entry_ok) if(!entry_ok)
return WRTD_HASH_ENTRY_EMPTY; return WRTD_HASH_ENTRY_EMPTY;
...@@ -116,47 +86,48 @@ static int wrtd_out_trig_get(struct wrtd_node *dev, unsigned int output, ...@@ -116,47 +86,48 @@ static int wrtd_out_trig_get(struct wrtd_node *dev, unsigned int output,
trigger->is_conditional = 0; trigger->is_conditional = 0;
trigger->handle.channel = output; trigger->handle.channel = output;
wrnc_msg_uint32 (&msg, (uint32_t *) &trigger->handle.ptr_trig); wrnc_msg_uint32(msg, (uint32_t *) &trigger->handle.ptr_trig);
wrnc_msg_uint32 (&msg, (uint32_t *) &trigger->handle.ptr_cond); wrnc_msg_uint32(msg, (uint32_t *) &trigger->handle.ptr_cond);
if(is_conditional) if(is_conditional)
{ {
trigger->is_conditional = 1; trigger->is_conditional = 1;
wrnc_msg_uint32 (&msg, &state); wrnc_msg_uint32(msg, &state);
wrtd_msg_trig_id (&msg, &trigger->condition); wrtd_msg_trig_id(msg, &trigger->condition);
trigger->delay_cond.ticks = 0; trigger->delay_cond.ticks = 0;
wrnc_msg_uint32 (&msg, &trigger->delay_cond.ticks); wrnc_msg_uint32(msg, &trigger->delay_cond.ticks);
wrnc_msg_uint32 (&msg, &trigger->delay_cond.frac); wrnc_msg_uint32(msg, &trigger->delay_cond.frac);
/* skip the condition latency stats for the time being */ /* skip the condition latency stats for the time being */
wrnc_msg_skip(&msg, 5); wrnc_msg_skip(msg, 5);
} }
wrnc_msg_uint32 (&msg, &state); wrnc_msg_uint32(msg, &state);
if (state & HASH_ENT_CONDITIONAL) if (state & HASH_ENT_CONDITIONAL)
return WRTD_HASH_ENTRY_CONDITIONAL; return WRTD_HASH_ENTRY_CONDITIONAL;
wrtd_msg_trig_id (&msg, &trigger->trigger); wrtd_msg_trig_id(msg, &trigger->trigger);
trigger->delay_trig.ticks = 0; trigger->delay_trig.ticks = 0;
wrnc_msg_uint32 (&msg, &trigger->delay_trig.ticks); wrnc_msg_uint32(msg, &trigger->delay_trig.ticks);
wrnc_msg_uint32 (&msg, &trigger->delay_trig.frac); wrnc_msg_uint32(msg, &trigger->delay_trig.frac);
wrnc_msg_uint32 (&msg, &latency_worst); wrnc_msg_uint32(msg, &latency_worst);
wrnc_msg_uint32 (&msg, &latency_avg_sum); wrnc_msg_uint32(msg, &latency_avg_sum);
wrnc_msg_uint32 (&msg, &latency_avg_nsamples); wrnc_msg_uint32(msg, &latency_avg_nsamples);
wrnc_msg_uint32 (&msg, &trigger->executed_pulses); wrnc_msg_uint32(msg, &trigger->executed_pulses);
wrnc_msg_uint32 (&msg, &trigger->missed_pulses); wrnc_msg_uint32(msg, &trigger->missed_pulses);
if(latency_avg_nsamples == 0) if(latency_avg_nsamples == 0)
trigger->latency_average_us = 0; trigger->latency_average_us = 0;
else else
trigger->latency_average_us = (latency_avg_sum / latency_avg_nsamples + 124) / 125; trigger->latency_average_us = (latency_avg_sum /
latency_avg_nsamples + 124) / 125;
trigger->latency_worst_us = (latency_worst + 124) / 125; trigger->latency_worst_us = (latency_worst + 124) / 125;
trigger->enabled = (state & HASH_ENT_DISABLED) ? 0 : 1; trigger->enabled = (state & HASH_ENT_DISABLED) ? 0 : 1;
if ( wrnc_msg_check_error(&msg) ) { if ( wrnc_msg_check_error(msg) ) {
errno = EWRTD_INVALID_ANSWER_STATE; errno = EWRTD_INVALID_ANSWER_STATE;
return -1; return -1;
} }
...@@ -165,6 +136,49 @@ static int wrtd_out_trig_get(struct wrtd_node *dev, unsigned int output, ...@@ -165,6 +136,49 @@ static int wrtd_out_trig_get(struct wrtd_node *dev, unsigned int output,
} }
/**
* Retreives a trigger entry specified by a position in the hash table
* (bucket/index number) or by its handle (if handle parameter is not null)
* @param[in] dev device token
* @param[in] output index (0-based) of output channel
* @param[in] bucket bucket in the hash table to read
* @param[in] index specifies which entry in the selected bucket will be read
* @param[in] handle handle of the trigger to read (if null, takes bucket/index)
* @param[out] trigger retrieved trigger entry
*/
static int wrtd_out_trig_get(struct wrtd_node *dev, unsigned int output,
unsigned int bucket, unsigned int index,
struct wrtd_trigger_handle *handle,
struct wrtd_output_trigger_state *trigger)
{
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
struct wrnc_msg msg = wrnc_msg_init (16);
uint32_t seq = 0, id ;
uint32_t ptr = 0;
if (output > FD_NUM_CHANNELS) {
errno = EWRTD_INVALID_CHANNEL;
return -1;
}
/* Build the message */
id = WRTD_CMD_FD_READ_HASH;
wrnc_msg_header (&msg, &id, &seq);
wrnc_msg_uint32 (&msg, &bucket);
wrnc_msg_uint32 (&msg, &index);
wrnc_msg_uint32 (&msg, &output);
if(handle)
ptr = handle->ptr_cond ? handle->ptr_cond : handle->ptr_trig;
wrnc_msg_uint32 (&msg, &ptr);
/* Send the message and get answer */
return __wrtd_out_trig_get(wrtd, output, &msg, trigger);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * PROTOTYPEs IMPLEMENTATION * * * * * * * * * */ /* * * * * * * * * * PROTOTYPEs IMPLEMENTATION * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
...@@ -453,9 +467,7 @@ int wrtd_out_trig_state_get_by_handle(struct wrtd_node *dev, ...@@ -453,9 +467,7 @@ int wrtd_out_trig_state_get_by_handle(struct wrtd_node *dev,
/** /**
* It returns a trigget from a given index. The index may change due to trigger * It returns a trigget from a given identifier.
* assing and un-assing. So, before use this function you have to check the
* current trigger's indexes. Note that this is not thread safe.
* Whenever is possible you should prefer wrtd_out_trig_state_get_by_handle() * Whenever is possible you should prefer wrtd_out_trig_state_get_by_handle()
* @param[in] dev device token * @param[in] dev device token
* @param[in] id identifier of the trigger to retrieve * @param[in] id identifier of the trigger to retrieve
...@@ -463,28 +475,26 @@ int wrtd_out_trig_state_get_by_handle(struct wrtd_node *dev, ...@@ -463,28 +475,26 @@ int wrtd_out_trig_state_get_by_handle(struct wrtd_node *dev,
* @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 wrtd_out_trig_state_get_by_id(struct wrtd_node *dev, int wrtd_out_trig_state_get_by_id(struct wrtd_node *dev,
struct wrtd_trig_id *id, struct wrtd_trig_id *tid,
struct wrtd_output_trigger_state *trigger) struct wrtd_output_trigger_state *trigger)
{ {
struct wrtd_output_trigger_state triggers[256]; struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
int ret, i, k; uint32_t seq = 0, id;
int ret, i;
for (k = 0; k < FD_NUM_CHANNELS; ++k) { for (i = 0; i < FD_NUM_CHANNELS; ++i) {
/* Get triggers for a given channel */ struct wrnc_msg msg = wrnc_msg_init(6);
ret = wrtd_out_trig_get_all(dev, k, triggers, 256); id = WRTD_CMD_FD_TRIG_GET_BY_ID;
if (ret < 0) { wrnc_msg_header(&msg, &id, &seq);
return -1; wrnc_msg_int32(&msg, &i);
} wrtd_msg_trig_id(&msg, tid);
/* Look for trigger ID */ ret = __wrtd_out_trig_get(wrtd, i, &msg, trigger);
for (i = 0; i < 256; ++i) { if (ret == WRTD_HASH_ENTRY_OK)
if (memcmp(id, &triggers[i].trigger, return 0;
sizeof(struct wrtd_trig_id)) == 0) {
*trigger = triggers[i];
return 0;
}
}
} }
errno = EWRTD_NOFOUND_TRIGGER; errno = EWRTD_NOFOUND_TRIGGER;
return -1; return -1;
} }
......
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