forked from Imagelibrary/rtems
Support for new rtems_interrupt_handler_iterate() function.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user