From 63d9e840b735248d17644101996ffbefb07ab23f Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 24 Jun 2021 17:14:03 +0200 Subject: bsps/irq: Add bsp_interrupt_check_and_lock() Return RTEMS_INCORRECT_STATE instead of RTEMS_INTERNAL_ERROR in case the interrupt support is not initialized. This is similar to rtems_timer_server_fire_after() for example. Update #3269. --- bsps/include/bsp/irq-generic.h | 38 ++++++++++++++++++++-- bsps/shared/irq/irq-generic.c | 60 +++++++++++++++++++++-------------- bsps/shared/irq/irq-handler-iterate.c | 51 ++++++++--------------------- 3 files changed, 86 insertions(+), 63 deletions(-) diff --git a/bsps/include/bsp/irq-generic.h b/bsps/include/bsp/irq-generic.h index 0f9bd5765b..e9cb0b4bb9 100644 --- a/bsps/include/bsp/irq-generic.h +++ b/bsps/include/bsp/irq-generic.h @@ -428,12 +428,46 @@ bool bsp_interrupt_handler_is_empty(rtems_vector_number vector); /** @} */ -/* For internal use only */ +/** + * @brief Acquires the interrupt support lock. + * + * The interrupt support lock is a mutex. The mutex is only acquired if the + * system is the ::SYSTEM_STATE_UP state. + */ void bsp_interrupt_lock(void); -/* For internal use only */ +/** + * @brief Releases the interrupt support lock. + * + * The mutex is only released if the system is the ::SYSTEM_STATE_UP state. + */ void bsp_interrupt_unlock(void); +/** + * @brief Checks the vector and routine. When the checks were successful, the + * interrupt support lock will be obtained. + * + * @param vector is the interrupt vector number to check. + * + * @param routine is the routine to check. + * + * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. + * + * @retval ::RTEMS_INCORRECT_STATE The interrupt support was not initialized. + * + * @retval ::RTEMS_CALLED_FROM_ISR The function was called from within + * interrupt context. + * + * @retval ::RTEMS_INVALID_ADDRESS The ``routine`` parameter was NULL. + * + * @retval ::RTEMS_INVALID_ID There was no interrupt vector associated with the + * number specified by ``vector``. + */ +rtems_status_code bsp_interrupt_check_and_lock( + rtems_vector_number vector, + rtems_interrupt_handler handler +); + /** * @brief This table contains a bit map which indicates if an entry is unique * or shared. diff --git a/bsps/shared/irq/irq-generic.c b/bsps/shared/irq/irq-generic.c index a7e8c1163f..59963182ab 100644 --- a/bsps/shared/irq/irq-generic.c +++ b/bsps/shared/irq/irq-generic.c @@ -122,6 +122,32 @@ static inline bool bsp_interrupt_allocate_handler_index( #endif } +rtems_status_code bsp_interrupt_check_and_lock( + rtems_vector_number vector, + rtems_interrupt_handler handler +) +{ + if ( !bsp_interrupt_is_initialized() ) { + return RTEMS_INCORRECT_STATE; + } + + if ( handler == NULL ) { + return RTEMS_INVALID_ADDRESS; + } + + if ( !bsp_interrupt_is_valid_vector( vector ) ) { + return RTEMS_INVALID_ID; + } + + if ( rtems_interrupt_is_in_progress() ) { + return RTEMS_CALLED_FROM_ISR; + } + + bsp_interrupt_lock(); + + return RTEMS_SUCCESSFUL; +} + void bsp_interrupt_initialize(void) { rtems_status_code sc = RTEMS_SUCCESSFUL; @@ -162,25 +188,18 @@ static rtems_status_code bsp_interrupt_handler_install( void *arg ) { + rtems_status_code sc; rtems_interrupt_level level; rtems_vector_number index = 0; rtems_interrupt_entry *head = NULL; bool enable_vector = false; bool replace = RTEMS_INTERRUPT_IS_REPLACE(options); - /* Check parameters and system state */ - if (!bsp_interrupt_is_initialized()) { - return RTEMS_INTERNAL_ERROR; - } else if (!bsp_interrupt_is_valid_vector(vector)) { - return RTEMS_INVALID_ID; - } else if (handler == NULL) { - return RTEMS_INVALID_ADDRESS; - } else if (rtems_interrupt_is_in_progress()) { - return RTEMS_CALLED_FROM_ISR; - } + sc = bsp_interrupt_check_and_lock( vector, handler ); - /* Lock */ - bsp_interrupt_lock(); + if ( sc != RTEMS_SUCCESSFUL ) { + return sc; + } /* Get handler table index */ index = bsp_interrupt_handler_index(vector); @@ -325,6 +344,7 @@ static rtems_status_code bsp_interrupt_handler_remove( void *arg ) { + rtems_status_code sc; rtems_interrupt_level level; rtems_vector_number index = 0; rtems_interrupt_entry *head = NULL; @@ -332,19 +352,11 @@ static rtems_status_code bsp_interrupt_handler_remove( rtems_interrupt_entry *previous = NULL; rtems_interrupt_entry *match = NULL; - /* Check parameters and system state */ - if (!bsp_interrupt_is_initialized()) { - return RTEMS_INTERNAL_ERROR; - } else if (!bsp_interrupt_is_valid_vector(vector)) { - return RTEMS_INVALID_ID; - } else if (handler == NULL) { - return RTEMS_INVALID_ADDRESS; - } else if (rtems_interrupt_is_in_progress()) { - return RTEMS_CALLED_FROM_ISR; - } + sc = bsp_interrupt_check_and_lock( vector, handler ); - /* Lock */ - bsp_interrupt_lock(); + if ( sc != RTEMS_SUCCESSFUL ) { + return sc; + } /* Get handler table index */ index = bsp_interrupt_handler_index(vector); diff --git a/bsps/shared/irq/irq-handler-iterate.c b/bsps/shared/irq/irq-handler-iterate.c index 3c642b075e..385cb8db2d 100644 --- a/bsps/shared/irq/irq-handler-iterate.c +++ b/bsps/shared/irq/irq-handler-iterate.c @@ -36,39 +36,26 @@ #include -/** - * @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_status_code rtems_interrupt_handler_iterate( + rtems_vector_number vector, rtems_interrupt_per_handler_routine routine, - void *arg + void *arg ) { - rtems_interrupt_entry *current = NULL; - rtems_option options = 0; - rtems_vector_number index = 0; + rtems_status_code sc; + rtems_vector_number index; + rtems_option options; + rtems_interrupt_entry *current; - /* Check parameters and system state */ - if (!bsp_interrupt_is_initialized()) { - return RTEMS_INTERNAL_ERROR; - } else if (!bsp_interrupt_is_valid_vector(vector)) { - return RTEMS_INVALID_ID; - } else if (rtems_interrupt_is_in_progress()) { - return RTEMS_CALLED_FROM_ISR; - } + sc = bsp_interrupt_check_and_lock( + vector, + (rtems_interrupt_handler) routine + ); - /* Lock */ - bsp_interrupt_lock(); + if ( sc != RTEMS_SUCCESSFUL ) { + return sc; + } - /* Interate */ index = bsp_interrupt_handler_index(vector); current = &bsp_interrupt_handler_table [index]; if (!bsp_interrupt_is_empty_handler_entry(current)) { @@ -80,17 +67,7 @@ static rtems_status_code bsp_interrupt_handler_iterate( } while (current != NULL); } - /* Unlock */ bsp_interrupt_unlock(); return RTEMS_SUCCESSFUL; } - -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); -} -- cgit v1.2.3