Commit 77d41f5a authored by Dimitris Lampridis's avatar Dimitris Lampridis Committed by Dimitris Lampridis

sw: rework error handling, to better align it with IVI specs

parent dd720963
This diff is collapsed.
This diff is collapsed.
......@@ -82,65 +82,74 @@ extern enum wrtd_status wrtd_return_error(struct wrtd_dev *dev,
const char *format, ...)
__attribute__((format(printf, 3, 4)));
/* Get current error message. Simpler than the official API. */
extern const char *wrtd_get_error_msg(struct wrtd_dev *dev);
/* Do the get_config action. */
enum wrtd_status wrtd_msg_get_config(struct wrtd_dev *wrtd, unsigned cpu,
struct wrtd_config_msg *res);
struct wrtd_config_msg *res,
const char *caller_func);
/* Read words from CPU space. */
enum wrtd_status wrtd_msg_readw(struct wrtd_dev *wrtd, unsigned cpu,
uint32_t addr, uint32_t count,
uint32_t *dest);
uint32_t *dest,
const char *caller_func);
/* Write words to CPU space. */
enum wrtd_status wrtd_msg_writew(struct wrtd_dev *wrtd, unsigned cpu,
uint32_t addr, uint32_t count,
const uint32_t *src);
const uint32_t *src,
const char *caller_func);
/* Check if rep_cap_id is valid (not null, length). */
enum wrtd_status wrtd_validate_id(struct wrtd_dev *wrtd,
const char *rep_cap_id);
const char *rep_cap_id,
const char *caller_func);
/* Ensure the roots have been fetched from the CPUs. */
enum wrtd_status wrtd_fill_roots(struct wrtd_dev *wrtd);
enum wrtd_status wrtd_fill_roots(struct wrtd_dev *wrtd,
const char *caller_func);
enum wrtd_status wrtd_write_root_flags(struct wrtd_dev *wrtd, unsigned cpu);
enum wrtd_status wrtd_write_root_flags(struct wrtd_dev *wrtd, unsigned cpu,
const char *caller_func);
/* Ensure the alarms have been fetched from the CPUs. */
enum wrtd_status wrtd_fill_alarms(struct wrtd_dev *wrtd);
enum wrtd_status wrtd_fill_alarms(struct wrtd_dev *wrtd,
const char *caller_func);
/* Write back alarm idx. */
enum wrtd_status wrtd_write_alarm(struct wrtd_dev *wrtd, unsigned idx);
enum wrtd_status wrtd_write_alarm(struct wrtd_dev *wrtd, unsigned idx,
const char *caller_func);
/* Find alarm index by id. */
enum wrtd_status wrtd_find_alarm(struct wrtd_dev *wrtd,
const char *rep_cap_id,
unsigned *idx);
unsigned *idx,
const char *caller_func);
/* Find rule index by id. */
enum wrtd_status wrtd_find_rule(struct wrtd_dev *wrtd,
const char *rep_cap_id,
unsigned *idx);
unsigned *idx,
const char *caller_func);
/* Internal function: allocate rules and set cpu,idx. */
enum wrtd_status wrtd_alloc_rules(struct wrtd_dev *wrtd,
struct wrtd_lib_rule **rulesp);
struct wrtd_lib_rule **rulesp,
const char *caller_func);
/* Write-back rule. */
enum wrtd_status wrtd_write_rule(struct wrtd_dev *wrtd, unsigned idx);
enum wrtd_status wrtd_write_rule(struct wrtd_dev *wrtd, unsigned idx,
const char *caller_func);
/* Ensure the rules have been fetched from the CPUs. */
enum wrtd_status wrtd_fill_rules(struct wrtd_dev *wrtd);
enum wrtd_status wrtd_fill_rules(struct wrtd_dev *wrtd,
const char *caller_func);
/* Count number of rules. */
enum wrtd_status wrtd_attr_get_rule_count(struct wrtd_dev *wrtd,
int32_t *value);
/* Reconfigure route tables and write-back rules. */
enum wrtd_status wrtd_reconfigure(struct wrtd_dev *wrtd);
enum wrtd_status wrtd_reconfigure(struct wrtd_dev *wrtd, const char *caller_func);
static inline bool wrtd_id_eq(const char *l, const char *r)
{
......@@ -157,8 +166,29 @@ static inline void wrtd_id_copy(char *dst, const char *src)
strncpy(dst, src, WRTD_ID_LEN);
}
static inline enum wrtd_status wrtd_alarm_check_disabled(struct wrtd_dev *wrtd, unsigned idx,
const char *caller_func)
{
if (wrtd->alarms[idx].alarm.enabled)
return wrtd_return_error(wrtd, WRTD_ERROR_RESOURCE_ACTIVE,
"%s/%s: Resource is enabled.",
caller_func, __func__);
return WRTD_SUCCESS;
}
static inline enum wrtd_status wrtd_rule_check_disabled(struct wrtd_dev *wrtd, unsigned idx,
const char *caller_func)
{
if (wrtd->rules[idx].rule.conf.enabled)
return wrtd_return_error(wrtd, WRTD_ERROR_RESOURCE_ACTIVE,
"%s/%s: Resource is enabled.",
caller_func, __func__);
return WRTD_SUCCESS;
}
/* Copy ID to DST of length BUF_SIZE. Check length, pad with null. */
enum wrtd_status wrtd_id_copy_buf(struct wrtd_dev *wrtd,
char *dst, int32_t buf_size, const char *id);
char *dst, int32_t buf_size, const char *id,
const char *caller_func);
#endif /* __LIBWRTD_PRIVATE__H__ */
......@@ -38,7 +38,8 @@ struct conf_map {
static enum wrtd_status wrtd_reconfigure_alloc_map(struct wrtd_dev *wrtd,
struct conf_map *map)
struct conf_map *map,
const char *caller_func)
{
enum wrtd_status status;
unsigned cpu;
......@@ -62,16 +63,16 @@ static enum wrtd_status wrtd_reconfigure_alloc_map(struct wrtd_dev *wrtd,
map->rules = malloc(map->nbr_rules * sizeof(struct rule_map));
if (map->rules == NULL)
return wrtd_return_error(wrtd, WRTD_ERROR_OUT_OF_MEMORY,
"cannot allocate map for %u rules",
map->nbr_rules);
"%s/%s: Could not allocate necessary memory.",
caller_func, __func__);
map->devs = malloc(map->nbr_devs * sizeof(struct device_map));
if (map->devs == NULL) {
free(map->rules);
map->rules = NULL;
return wrtd_return_error(wrtd, WRTD_ERROR_OUT_OF_MEMORY,
"cannot allocate map for %u devs",
map->nbr_devs);
"%s/%s: Could not allocate necessary memory.",
caller_func, __func__);
}
/* Fill rules. */
......@@ -149,20 +150,23 @@ static enum wrtd_status wrtd_find_channel(struct wrtd_dev *wrtd,
}
}
return WRTD_ERROR_RESOURCE_UNKNOWN;
return WRTD_ERROR_UNKNOWN_CHANNEL_NAME;
}
/* Assign RULE_NUM to CPU. */
static enum wrtd_status wrtd_reconfigure_place_rule(struct wrtd_dev *wrtd,
struct conf_map *map,
unsigned rule_num,
unsigned cpu)
unsigned cpu,
const char *caller_func)
{
assert(map->rules[rule_num].cpu == -1);
if (map->free_rule_slots[cpu] == 0)
return wrtd_return_error(wrtd, WRTD_ERROR_RULE_OUT_OF_RESOURCES,
"no more rule slots on cpu %u", cpu);
return wrtd_return_error
(wrtd, WRTD_ERROR_OUT_OF_RESOURCES,
"%s/%s: The device has no more resources to allocate.",
caller_func, __func__);
map->rules[rule_num].cpu = cpu;
map->free_rule_slots[cpu]--;
......@@ -174,7 +178,8 @@ static enum wrtd_status wrtd_reconfigure_place_rule(struct wrtd_dev *wrtd,
}
static enum wrtd_status wrtd_reconfigure_place(struct wrtd_dev *wrtd,
struct conf_map *map)
struct conf_map *map,
const char *caller_func)
{
enum wrtd_status status;
unsigned i;
......@@ -203,7 +208,7 @@ static enum wrtd_status wrtd_reconfigure_place(struct wrtd_dev *wrtd,
}
else {
status = wrtd_find_alarm(
wrtd, rule->conf.source_id, &ch);
wrtd, rule->conf.source_id, &ch, caller_func);
if (status == WRTD_SUCCESS) {
/* Alarm. */
cpu_affinity = wrtd->alarms[ch].cpu;
......@@ -280,7 +285,7 @@ static enum wrtd_status wrtd_reconfigure_place(struct wrtd_dev *wrtd,
/* Place rules according to input affinity. */
status = wrtd_reconfigure_place_rule
(wrtd, map, i, cpu_affinity);
(wrtd, map, i, cpu_affinity, caller_func);
WRTD_RETURN_IF_ERROR(status);
}
......@@ -299,8 +304,8 @@ static enum wrtd_status wrtd_reconfigure_place(struct wrtd_dev *wrtd,
if (slots == NULL)
return wrtd_return_error
(wrtd, WRTD_ERROR_OUT_OF_MEMORY,
"cannot allocate slots for %u rules",
nbr_cpu_rules);
"%s/%s: Could not allocate necessary memory.",
caller_func, __func__);
/* Mark all slots as unused. */
for (i = 0; i < nbr_cpu_rules; i++)
......@@ -386,7 +391,8 @@ static enum wrtd_status wrtd_reconfigure_place(struct wrtd_dev *wrtd,
static enum wrtd_status wrtd_reconfigure_write(struct wrtd_dev *wrtd,
struct conf_map *map,
struct wrtd_lib_rule *new_rules)
struct wrtd_lib_rule *new_rules,
const char *caller_func)
{
enum wrtd_status status;
struct wrtd_lib_rule *old_rules;
......@@ -416,7 +422,7 @@ static enum wrtd_status wrtd_reconfigure_write(struct wrtd_dev *wrtd,
&& (new_rules[i].rule.conf.enabled
== old_rules[i].rule.conf.enabled))
continue;
status = wrtd_write_rule(wrtd, i);
status = wrtd_write_rule(wrtd, i, caller_func);
/* FIXME: inconsistent state, free old_rules ? */
WRTD_RETURN_IF_ERROR(status);
}
......@@ -425,31 +431,31 @@ static enum wrtd_status wrtd_reconfigure_write(struct wrtd_dev *wrtd,
return WRTD_SUCCESS;
}
enum wrtd_status wrtd_reconfigure(struct wrtd_dev *wrtd)
enum wrtd_status wrtd_reconfigure(struct wrtd_dev *wrtd, const char *caller_func)
{
enum wrtd_status status;
struct conf_map map;
struct wrtd_lib_rule *new_rules;
/* Load rules and alarms. */
status = wrtd_fill_rules(wrtd);
status = wrtd_fill_rules(wrtd, caller_func);
WRTD_RETURN_IF_ERROR(status);
status = wrtd_fill_alarms(wrtd);
status = wrtd_fill_alarms(wrtd, caller_func);
WRTD_RETURN_IF_ERROR(status);
/* 1. Count number of rules. */
status = wrtd_reconfigure_alloc_map(wrtd, &map);
status = wrtd_reconfigure_alloc_map(wrtd, &map, caller_func);
WRTD_RETURN_IF_ERROR(status);
/* Place rules. */
status = wrtd_reconfigure_place(wrtd, &map);
status = wrtd_reconfigure_place(wrtd, &map, caller_func);
if (status == WRTD_SUCCESS)
status = wrtd_alloc_rules(wrtd, &new_rules);
status = wrtd_alloc_rules(wrtd, &new_rules, caller_func);
if (status == WRTD_SUCCESS)
status = wrtd_reconfigure_write(wrtd, &map, new_rules);
status = wrtd_reconfigure_write(wrtd, &map, new_rules, caller_func);
if (status != WRTD_SUCCESS)
free(new_rules);
......
......@@ -15,60 +15,67 @@ struct wrtd_dev;
/**
* @enum wrtd_status
* White Rabbit Trigger Distribution warnings and errors
* White Rabbit Trigger Distribution error codes.
* Names and values inspired by IVI 3.2 and IVI 3.15.
*/
enum wrtd_status {
/* Codes inspired by IVI 3.2 */
WRTD_SUCCESS = 0,
WRTD_ERROR_BASE = 0xBFFA3000,
WRTD_ERROR_CANNOT_RECOVER,
WRTD_ERROR_INVALID_ATTRIBUTE,
WRTD_ERROR_ATTR_NOT_WRITEABLE,
WRTD_ERROR_ATTR_NOT_READABLE,
WRTD_ERROR_INVALID_VALUE,
WRTD_ERROR_NOT_INITIALIZED,
WRTD_ERROR_MISSING_OPTION_NAME,
WRTD_ERROR_MISSING_OPTION_VALUE,
WRTD_ERROR_BAD_OPTION_NAME,
WRTD_ERROR_BAD_OPTION_VALUE,
WRTD_ERROR_OUT_OF_MEMORY,
WRTD_ERROR_OPERATION_PENDING,
WRTD_ERROR_NULL_POINTER,
WRTD_ERROR_UNEXPECTED_RESPONSE,
WRTD_ERROR_RESET_FAILED,
WRTD_ERROR_RESOURCE_UNKNOWN,
/* Resource (alar, rule) is not disabled and cannot be changed. */
WRTD_ERROR_RESOURCE_ACTIVE,
/* Require global rep cap. */
WRTD_ERROR_ATTR_INVALID_REP_CAP,
/* Feature not implemented. */
WRTD_ERROR_NOT_IMPLEMENTED,
/* Incorrect repeated capability id: too long, invalid character... */
WRTD_ERROR_BAD_REP_CAP_ID,
/* Timeout while reading log. */
WRTD_ERROR_TIMEOUT,
/* Output buffer is not long enough. */
WRTD_ERROR_BUFFER_TOO_SHORT,
WRTD_ERROR_UNKNOWN_NAME_IN_SELECTOR, // NOTE: selector == rep_cap_id
/* Codes inspired by IviLxiSync 3.15 */
WRTD_ERROR_ALARM_TIME_INVALID,
WRTD_ERROR_ALARM_EXISTS,
WRTD_ERROR_ALARM_DOES_NOT_EXIST,
WRTD_ERROR_ALARM_OUT_OF_RESOURCES,
WRTD_ERROR_RULE_EXISTS,
WRTD_ERROR_RULE_DOES_NOT_EXIST,
WRTD_ERROR_RULE_OUT_OF_RESOURCES,
WRTD_ERROR_RULE_INVALID,
WRTD_ERROR_RULE_ENABLED,
WRTD_ERROR_CANT_REMOVE_RESERVED_REP_CAP,
__WRTD_ERROR_MAX_NUMBER,
/** No error. */
WRTD_SUCCESS = 0,
/** Same as IVI_INHERENT_ERROR_BASE */
__WRTD_ERROR_BASE = 0xBFFA0000,
/** Invalid/unknown attribute. */
WRTD_ERROR_INVALID_ATTRIBUTE = __WRTD_ERROR_BASE + 0x0C,
/** Attempt to write a read-only attribute. */
WRTD_ERROR_ATTR_NOT_WRITEABLE = __WRTD_ERROR_BASE + 0x0D,
/** Attempt to read a write-only attribute. */
WRTD_ERROR_ATTR_NOT_READABLE = __WRTD_ERROR_BASE + 0x0E,
/** Invalid value provided. */
WRTD_ERROR_INVALID_VALUE = __WRTD_ERROR_BASE + 0x10,
/** Device not initialized. */
WRTD_ERROR_NOT_INITIALIZED = __WRTD_ERROR_BASE + 0x1D,
/** Unknown channel name. */
WRTD_ERROR_UNKNOWN_CHANNEL_NAME = __WRTD_ERROR_BASE + 0x20,
/** Device out of memory. */
WRTD_ERROR_OUT_OF_MEMORY = __WRTD_ERROR_BASE + 0x56,
/** Null pointer. */
WRTD_ERROR_NULL_POINTER = __WRTD_ERROR_BASE + 0x58,
/** Unexpected response. */
WRTD_ERROR_UNEXPECTED_RESPONSE = __WRTD_ERROR_BASE + 0x59,
/** Unknown resource. */
WRTD_ERROR_RESOURCE_UNKNOWN = __WRTD_ERROR_BASE + 0x60,
/** Incorrect repeated capability selector. */
WRTD_ERROR_BADLY_FORMED_SELECTOR = __WRTD_ERROR_BASE + 0x66,
/** Same as IVI_LXISYNC_ERROR_BASE */
__WRTD_LXISYNC_ERROR_BASE = 0xBFFA3000,
/** The alarm already exists. */
WRTD_ERROR_ALARM_EXISTS = __WRTD_LXISYNC_ERROR_BASE + 0x07,
/** The specified alarm has not been defined. */
WRTD_ERROR_ALARM_DOES_NOT_EXIST = __WRTD_LXISYNC_ERROR_BASE + 0x08,
/** Same as IVI_VENDOR_SPECIFIC_ERROR_BASE */
__WRTD_SPECIFIC_ERROR_BASE = 0xBFFA6000,
/** Version mismatch */
WRTD_ERROR_VERSION_MISMATCH = __WRTD_SPECIFIC_ERROR_BASE + 0x00,
/** Internal error */
WRTD_ERROR_INTERNAL = __WRTD_SPECIFIC_ERROR_BASE + 0x01,
/** Unknown event log type/reason */
WRTD_ERROR_UNKNOWN_LOG_TYPE = __WRTD_SPECIFIC_ERROR_BASE + 0x02,
/** Resource is not disabled and cannot be changed. */
WRTD_ERROR_RESOURCE_ACTIVE = __WRTD_SPECIFIC_ERROR_BASE + 0x03,
/** Attempt to access a global attribute without
using the global attribute selector */
WRTD_ERROR_ATTR_GLOBAL = __WRTD_SPECIFIC_ERROR_BASE + 0x04,
/** The device has no more resources to allocate. */
WRTD_ERROR_OUT_OF_RESOURCES = __WRTD_SPECIFIC_ERROR_BASE + 0x05,
/** The rule already exists. */
WRTD_ERROR_RULE_EXISTS = __WRTD_SPECIFIC_ERROR_BASE + 0x06,
/** The specified rule has not been defined. */
WRTD_ERROR_RULE_DOES_NOT_EXIST = __WRTD_SPECIFIC_ERROR_BASE + 0x07,
/** always last entry in this enum */
__WRTD_ERROR_MAX_NUMBER,
};
/**
......@@ -161,7 +168,7 @@ extern enum wrtd_status wrtd_close(struct wrtd_dev *dev);
extern enum wrtd_status wrtd_reset(struct wrtd_dev *dev);
extern enum wrtd_status wrtd_get_error(struct wrtd_dev *dev,
enum wrtd_status *error_code,
uint32_t buffer_size,
int32_t error_description_buffer_size,
char *error_description);
extern enum wrtd_status wrtd_error_message(struct wrtd_dev *dev,
enum wrtd_status err_code,
......
......@@ -182,7 +182,7 @@ static enum wrtd_status disp_cpu_config(struct wrtd_dev *wrtd, int cpu,
printf("\n"
"CPU #%d\n", cpu);
res = wrtd_msg_get_config(wrtd, cpu, &msg);
res = wrtd_msg_get_config(wrtd, cpu, &msg, __func__);
if (res != WRTD_SUCCESS)
return res;
printf("sync_flag: %s\n",
......@@ -194,7 +194,7 @@ static enum wrtd_status disp_cpu_config(struct wrtd_dev *wrtd, int cpu,
res = wrtd_msg_readw(wrtd, cpu, msg.root_addr,
sizeof(struct wrtd_root) / 4,
(uint32_t*)&root);
(uint32_t*)&root, __func__);
WRTD_RETURN_IF_ERROR(res);
/* Note: assume same representation, same endianness. */
......@@ -208,7 +208,7 @@ static enum wrtd_status disp_cpu_config(struct wrtd_dev *wrtd, int cpu,
(wrtd, cpu,
root.rules_addr + j * sizeof(struct wrtd_rule),
sizeof(struct wrtd_rule) / 4,
(uint32_t *)&rule);
(uint32_t *)&rule, __func__);
WRTD_RETURN_IF_ERROR(res);
printf("rule #%d\n", j);
disp_rule_conf(&rule, root.nbr_rules);
......@@ -224,7 +224,7 @@ static enum wrtd_status disp_cpu_config(struct wrtd_dev *wrtd, int cpu,
(root.alarms_addr
+ j * sizeof(struct wrtd_alarm)),
sizeof(struct wrtd_alarm) / 4,
(uint32_t *)&alarm);
(uint32_t *)&alarm, __func__);
WRTD_RETURN_IF_ERROR(res);
printf("alarm #%d\n", j);
disp_alarm(&alarm);
......@@ -326,7 +326,7 @@ static enum wrtd_status wrtd_cmd_dump_rules(struct wrtd_dev *wrtd,
enum wrtd_status status;
unsigned i;
status = wrtd_fill_rules(wrtd);
status = wrtd_fill_rules(wrtd, __func__);
WRTD_RETURN_IF_ERROR(status);
for (i = 0; i < wrtd->nbr_rules; i++) {
......@@ -347,7 +347,7 @@ static enum wrtd_status wrtd_cmd_dump_alarms(struct wrtd_dev *wrtd,
enum wrtd_status status;
unsigned i;
status = wrtd_fill_alarms(wrtd);
status = wrtd_fill_alarms(wrtd, __func__);
WRTD_RETURN_IF_ERROR(status);
for (i = 0; i < wrtd->nbr_alarms; i++) {
......
......@@ -48,8 +48,10 @@ static void print_logging (struct wrtd_dev *wrtd, int n_read)
status = wrtd_get_next_event_log_entry(
wrtd, WRTD_LOG_ENTRY_SIZE, log_entry);
if (status != WRTD_SUCCESS) {
fprintf(stderr,
"Error: %s\n", wrtd_get_error_msg(wrtd));
char error_message[256];
enum wrtd_status error_status;
wrtd_get_error (wrtd, &error_status, 256, error_message);
fprintf(stderr, "Error: %s\n", error_message);
return;
}
......@@ -94,8 +96,10 @@ int main(int argc, char *argv[])
/* Open. */
status = wrtd_init(dev_name, 0, NULL, &wrtd);
if (status != WRTD_SUCCESS) {
fprintf(stderr, "Cannot open WRTD: %s\n",
wrtd_get_error_msg(wrtd));
char error_message[256];
enum wrtd_status error_status;
wrtd_get_error (wrtd, &error_status, 256, error_message);
fprintf(stderr, "Cannot open WRTD: %s\n", error_message);
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