summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/shared/src/irq-server.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/shared/src/irq-server.c')
-rw-r--r--c/src/lib/libbsp/shared/src/irq-server.c148
1 files changed, 116 insertions, 32 deletions
diff --git a/c/src/lib/libbsp/shared/src/irq-server.c b/c/src/lib/libbsp/shared/src/irq-server.c
index 4f127af7ba..905c26198b 100644
--- a/c/src/lib/libbsp/shared/src/irq-server.c
+++ b/c/src/lib/libbsp/shared/src/irq-server.c
@@ -7,7 +7,7 @@
*/
/*
- * Copyright (c) 2009, 2016 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2009, 2017 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
@@ -28,24 +28,14 @@
#include <bsp/irq-generic.h>
+#define BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR (BSP_INTERRUPT_VECTOR_MAX + 1)
+
RTEMS_INTERRUPT_LOCK_DEFINE(
static,
bsp_interrupt_server_lock,
"Interrupt Server"
)
-typedef struct bsp_interrupt_server_action {
- struct bsp_interrupt_server_action *next;
- rtems_interrupt_handler handler;
- void *arg;
-} bsp_interrupt_server_action;
-
-typedef struct {
- rtems_chain_node node;
- rtems_vector_number vector;
- bsp_interrupt_server_action *actions;
-} bsp_interrupt_server_entry;
-
static rtems_id bsp_interrupt_server_id = RTEMS_ID_NONE;
static RTEMS_CHAIN_DEFINE_EMPTY(bsp_interrupt_server_chain);
@@ -64,7 +54,7 @@ static unsigned bsp_interrupt_server_errors;
static void bsp_interrupt_server_trigger(void *arg)
{
rtems_interrupt_lock_context lock_context;
- bsp_interrupt_server_entry *e = arg;
+ rtems_interrupt_server_entry *e = arg;
bsp_interrupt_vector_disable(e->vector);
@@ -82,7 +72,7 @@ static void bsp_interrupt_server_trigger(void *arg)
}
typedef struct {
- bsp_interrupt_server_entry *entry;
+ rtems_interrupt_server_entry *entry;
rtems_option *options;
} bsp_interrupt_server_iterate_entry;
@@ -102,7 +92,7 @@ static void bsp_interrupt_server_per_handler_routine(
}
}
-static bsp_interrupt_server_entry *bsp_interrupt_server_query_entry(
+static rtems_interrupt_server_entry *bsp_interrupt_server_query_entry(
rtems_vector_number vector,
rtems_option *trigger_options
)
@@ -134,8 +124,8 @@ static void bsp_interrupt_server_install_helper(void *arg)
{
bsp_interrupt_server_helper_data *hd = arg;
rtems_status_code sc;
- bsp_interrupt_server_entry *e;
- bsp_interrupt_server_action *a;
+ rtems_interrupt_server_entry *e;
+ rtems_interrupt_server_action *a;
rtems_option trigger_options;
a = calloc(1, sizeof(*a));
@@ -176,8 +166,8 @@ static void bsp_interrupt_server_install_helper(void *arg)
) {
sc = RTEMS_RESOURCE_IN_USE;
} else {
- bsp_interrupt_server_action **link = &e->actions;
- bsp_interrupt_server_action *c;
+ rtems_interrupt_server_action **link = &e->actions;
+ rtems_interrupt_server_action *c;
sc = RTEMS_SUCCESSFUL;
@@ -209,15 +199,15 @@ static void bsp_interrupt_server_remove_helper(void *arg)
{
bsp_interrupt_server_helper_data *hd = arg;
rtems_status_code sc;
- bsp_interrupt_server_entry *e;
+ rtems_interrupt_server_entry *e;
rtems_option trigger_options;
bsp_interrupt_lock();
e = bsp_interrupt_server_query_entry(hd->vector, &trigger_options);
if (e != NULL) {
- bsp_interrupt_server_action **link = &e->actions;
- bsp_interrupt_server_action *c;
+ rtems_interrupt_server_action **link = &e->actions;
+ rtems_interrupt_server_action *c;
while ((c = *link) != NULL) {
if (c->handler == hd->handler && c->arg == hd->arg) {
@@ -274,12 +264,12 @@ static rtems_status_code bsp_interrupt_server_call_helper(
.arg = arg,
.task = rtems_task_self()
};
- bsp_interrupt_server_action a = {
+ rtems_interrupt_server_action a = {
.handler = helper,
.arg = &hd
};
- bsp_interrupt_server_entry e = {
- .vector = BSP_INTERRUPT_VECTOR_MAX + 1,
+ rtems_interrupt_server_entry e = {
+ .vector = BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
.actions = &a
};
@@ -289,17 +279,17 @@ static rtems_status_code bsp_interrupt_server_call_helper(
return hd.sc;
}
-static bsp_interrupt_server_entry *bsp_interrupt_server_get_entry(void)
+static rtems_interrupt_server_entry *bsp_interrupt_server_get_entry(void)
{
rtems_interrupt_lock_context lock_context;
- bsp_interrupt_server_entry *e;
+ rtems_interrupt_server_entry *e;
rtems_chain_control *chain;
rtems_interrupt_lock_acquire(&bsp_interrupt_server_lock, &lock_context);
chain = &bsp_interrupt_server_chain;
if (!rtems_chain_is_empty(chain)) {
- e = (bsp_interrupt_server_entry *)
+ e = (rtems_interrupt_server_entry *)
rtems_chain_get_first_unprotected(chain);
rtems_chain_set_off_chain(&e->node);
} else {
@@ -315,7 +305,7 @@ static void bsp_interrupt_server_task(rtems_task_argument arg)
{
while (true) {
rtems_event_set events;
- bsp_interrupt_server_entry *e;
+ rtems_interrupt_server_entry *e;
rtems_event_system_receive(
RTEMS_EVENT_SYSTEM_SERVER,
@@ -325,11 +315,11 @@ static void bsp_interrupt_server_task(rtems_task_argument arg)
);
while ((e = bsp_interrupt_server_get_entry()) != NULL) {
- bsp_interrupt_server_action *action = e->actions;
+ rtems_interrupt_server_action *action = e->actions;
rtems_vector_number vector = e->vector;
do {
- bsp_interrupt_server_action *current = action;
+ rtems_interrupt_server_action *current = action;
action = action->next;
(*current->handler)(current->arg);
} while (action != NULL);
@@ -430,3 +420,97 @@ rtems_status_code rtems_interrupt_server_initialize(
return RTEMS_SUCCESSFUL;
}
+
+static void bsp_interrupt_server_entry_initialize(
+ rtems_interrupt_server_entry *entry
+)
+{
+ rtems_chain_set_off_chain(&entry->node);
+ entry->vector = BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR;
+ entry->actions = NULL;
+}
+
+static void bsp_interrupt_server_action_prepend(
+ rtems_interrupt_server_entry *entry,
+ rtems_interrupt_server_action *action,
+ rtems_interrupt_handler handler,
+ void *arg
+)
+{
+ action->handler = handler;
+ action->arg = arg;
+ action->next = entry->actions;
+ entry->actions = action;
+}
+
+void rtems_interrupt_server_entry_initialize(
+ rtems_interrupt_server_entry *entry
+)
+{
+ bsp_interrupt_server_entry_initialize(entry);
+}
+
+void rtems_interrupt_server_action_prepend(
+ rtems_interrupt_server_entry *entry,
+ rtems_interrupt_server_action *action,
+ rtems_interrupt_handler handler,
+ void *arg
+)
+{
+ bsp_interrupt_server_action_prepend(entry, action, handler, arg);
+}
+
+void rtems_interrupt_server_entry_submit(
+ rtems_id server,
+ rtems_interrupt_server_entry *entry
+)
+{
+ bsp_interrupt_server_trigger(entry);
+}
+
+static void bsp_interrupt_server_entry_destroy_helper(void *arg)
+{
+ bsp_interrupt_server_helper_data *hd = arg;
+
+ rtems_event_transient_send(hd->task);
+}
+
+void rtems_interrupt_server_entry_destroy(
+ rtems_id server,
+ rtems_interrupt_server_entry *entry
+)
+{
+ rtems_interrupt_lock_context lock_context;
+
+ rtems_interrupt_lock_acquire(&bsp_interrupt_server_lock, &lock_context);
+
+ if (!rtems_chain_is_node_off_chain(&entry->node)) {
+ rtems_chain_extract_unprotected(&entry->node);
+ rtems_chain_set_off_chain(&entry->node);
+ }
+
+ rtems_interrupt_lock_release(&bsp_interrupt_server_lock, &lock_context);
+
+ bsp_interrupt_server_call_helper(
+ BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
+ 0,
+ NULL,
+ NULL,
+ bsp_interrupt_server_entry_destroy_helper
+ );
+}
+
+void rtems_interrupt_server_request_initialize(
+ rtems_interrupt_server_request *request,
+ rtems_interrupt_handler handler,
+ void *arg
+)
+{
+ bsp_interrupt_server_entry_initialize(&request->entry);
+ bsp_interrupt_server_action_prepend(
+ &request->entry,
+ &request->action,
+ handler,
+ arg
+ );
+}