Support for new rtems_interrupt_handler_iterate() function.

This commit is contained in:
Thomas Doerfler
2008-07-24 12:44:26 +00:00
parent a39cf49f3a
commit 2e2c640ec1
4 changed files with 81 additions and 80 deletions

View File

@@ -1,3 +1,8 @@
2008-07-24 Sebastian Huber <sebastian.huber@embedded-brains.de>
* include/irq-generic.h, src/irq-generic.c, src/irq-legacy.c: Support
for new rtems_interrupt_handler_iterate() function.
2008-07-15 Joel Sherrill <joel.sherrill@oarcorp.com>
* bootcard.c: Must include bsp.h or bspopts.h or we cannot know if

View File

@@ -235,10 +235,6 @@ static inline void bsp_interrupt_handler_dispatch( rtems_vector_number vector)
/** @} */
rtems_status_code bsp_interrupt_handler_query( rtems_vector_number vector, bsp_interrupt_handler_entry *head);
rtems_status_code bsp_interrupt_handler_query_free( bsp_interrupt_handler_entry *head);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -483,24 +483,22 @@ static rtems_status_code bsp_interrupt_handler_remove( rtems_vector_number vecto
return RTEMS_SUCCESSFUL;
}
rtems_status_code rtems_interrupt_handler_install( rtems_vector_number vector, const char *info, rtems_option options, rtems_interrupt_handler handler, void *arg)
{
return bsp_interrupt_handler_install( vector, info, options, handler, arg);
}
rtems_status_code rtems_interrupt_handler_remove( rtems_vector_number vector, rtems_interrupt_handler handler, void *arg)
{
return bsp_interrupt_handler_remove( vector, handler, arg);
}
rtems_status_code bsp_interrupt_handler_query( rtems_vector_number vector, bsp_interrupt_handler_entry *head)
/**
* @brief Iterates over all installed interrupt handler of a vector.
*
* @ingroup bsp_interrupt
*
* @return In addition to the standard status codes this function returns
* RTEMS_INTERNAL_ERROR if the BSP interrupt support is not initialized.
*
* @see rtems_interrupt_handler_iterate().
*/
static rtems_status_code bsp_interrupt_handler_iterate( rtems_vector_number vector, rtems_interrupt_per_handler_routine routine, void *arg)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
bsp_interrupt_handler_entry *current_input = NULL;
bsp_interrupt_handler_entry *current_output = NULL;
/* Terminate list */
head = NULL;
bsp_interrupt_handler_entry *current = NULL;
rtems_option options = 0;
rtems_vector_number index = 0;
/* Check parameters and system state */
if (!bsp_interrupt_is_initialized()) {
@@ -517,27 +515,15 @@ rtems_status_code bsp_interrupt_handler_query( rtems_vector_number vector, bsp_i
return sc;
}
/* Fill output list */
current_input = &bsp_interrupt_handler_table [bsp_interrupt_handler_index( vector)];
if (!bsp_interrupt_is_empty_handler_entry( current_input)) {
/* Interate */
index = bsp_interrupt_handler_index( vector);
current = &bsp_interrupt_handler_table [index];
if (!bsp_interrupt_is_empty_handler_entry( current)) {
do {
bsp_interrupt_handler_entry *e = malloc( sizeof( bsp_interrupt_handler_entry));
if (e == NULL) {
bsp_interrupt_handler_query_free( head);
bsp_interrupt_unlock();
return RTEMS_NO_MEMORY;
}
*e = *current_input;
e->next = NULL;
if (head == NULL) {
head = e;
current_output = head;
} else {
current_output->next = e;
current_output = current_output->next;
}
current_input = current_input->next;
} while (current_input != NULL);
options = bsp_interrupt_is_handler_unique( index) ? RTEMS_INTERRUPT_UNIQUE : RTEMS_INTERRUPT_SHARED;
routine( arg, current->info, options, current->handler, current->arg);
current = current->next;
} while (current != NULL);
}
/* Unlock */
@@ -549,17 +535,17 @@ rtems_status_code bsp_interrupt_handler_query( rtems_vector_number vector, bsp_i
return RTEMS_SUCCESSFUL;
}
rtems_status_code bsp_interrupt_handler_query_free( bsp_interrupt_handler_entry *head)
rtems_status_code rtems_interrupt_handler_install( rtems_vector_number vector, const char *info, rtems_option options, rtems_interrupt_handler handler, void *arg)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
bsp_interrupt_handler_entry *next = NULL;
/* Free list */
while (head != NULL) {
next = head->next;
free( head);
head = next;
}
return RTEMS_SUCCESSFUL;
return bsp_interrupt_handler_install( vector, info, options, handler, arg);
}
rtems_status_code rtems_interrupt_handler_remove( rtems_vector_number vector, rtems_interrupt_handler handler, void *arg)
{
return bsp_interrupt_handler_remove( vector, handler, arg);
}
rtems_status_code rtems_interrupt_handler_iterate( rtems_vector_number vector, rtems_interrupt_per_handler_routine routine, void *arg)
{
return bsp_interrupt_handler_iterate( vector, routine, arg);
}

View File

@@ -18,6 +18,7 @@
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
*/
#include <stdbool.h>
#include <stdlib.h>
#include <rtems/irq.h>
@@ -29,12 +30,37 @@ typedef struct {
void *arg;
} bsp_interrupt_legacy_entry;
typedef struct {
rtems_irq_hdl handler;
void *handler_arg;
bsp_interrupt_legacy_entry *legacy_handler_arg;
} bsp_interrupt_legacy_iterate_entry;
static void bsp_interrupt_legacy_dispatch( rtems_vector_number vector, void *arg)
{
bsp_interrupt_legacy_entry *e = arg;
bsp_interrupt_legacy_entry *e = (bsp_interrupt_legacy_entry *) arg;
e->handler( e->arg);
}
static void bsp_interrupt_legacy_per_handler_routine(
void *arg,
const char *info,
rtems_option options,
rtems_interrupt_handler handler,
void *handler_arg
)
{
bsp_interrupt_legacy_iterate_entry *ie = (bsp_interrupt_legacy_iterate_entry *) arg;
bsp_interrupt_legacy_entry *e = NULL;
if (handler == bsp_interrupt_legacy_dispatch) {
e = (bsp_interrupt_legacy_entry *) handler_arg;
if (e->handler == ie->handler && e->arg == ie->handler_arg) {
ie->legacy_handler_arg = e;
}
}
}
/**
* @deprecated Obsolete.
*/
@@ -45,6 +71,8 @@ int BSP_get_current_rtems_irq_handler( rtems_irq_connect_data *cd)
cd->on = NULL;
cd->off = NULL;
cd->isOn = NULL;
return 1;
}
/**
@@ -74,7 +102,7 @@ int BSP_install_rtems_irq_handler( const rtems_irq_connect_data *cd)
return 0;
}
if (cd->on) {
if (cd->on != NULL) {
cd->on( cd);
}
@@ -108,7 +136,7 @@ int BSP_install_rtems_shared_irq_handler( const rtems_irq_connect_data *cd)
return 0;
}
if (cd->on) {
if (cd->on != NULL) {
cd->on( cd);
}
@@ -121,44 +149,30 @@ int BSP_install_rtems_shared_irq_handler( const rtems_irq_connect_data *cd)
int BSP_remove_rtems_irq_handler( const rtems_irq_connect_data *cd)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
bsp_interrupt_handler_entry *head = NULL;
bsp_interrupt_handler_entry *current = NULL;
bsp_interrupt_legacy_entry *e = NULL;
bsp_interrupt_legacy_iterate_entry e = {
.handler = cd->hdl,
.handler_arg = cd->handle,
.legacy_handler_arg = NULL
};
sc = bsp_interrupt_handler_query( cd->name, head);
sc = rtems_interrupt_handler_iterate( cd->name, bsp_interrupt_legacy_per_handler_routine, &e);
if (sc != RTEMS_SUCCESSFUL) {
return 0;
}
current = head;
while (current != NULL) {
if (current->handler == bsp_interrupt_legacy_dispatch) {
e = current->arg;
if (e->arg == cd->handle) {
break;
} else {
e = NULL;
}
}
current = current->next;
}
sc = bsp_interrupt_handler_query_free( head);
if (sc != RTEMS_SUCCESSFUL) {
if (e.legacy_handler_arg == NULL) {
return 0;
}
if (e == NULL) {
return 0;
}
if (cd->off) {
if (cd->off != NULL) {
cd->off( cd);
}
sc = rtems_interrupt_handler_remove( cd->name, bsp_interrupt_legacy_dispatch, e);
sc = rtems_interrupt_handler_remove( cd->name, bsp_interrupt_legacy_dispatch, e.legacy_handler_arg);
if (sc != RTEMS_SUCCESSFUL) {
return 0;
}
return 1;
}