source: rtems/cpukit/include/rtems/irq-extension.h @ c60942ea

Last change on this file since c60942ea was c60942ea, checked in by Sebastian Huber <sebastian.huber@…>, on 07/30/20 at 08:30:15

rtems: Add rtems_interrupt_server_create()

Add rtems_interrupt_server_destroy().

Before this patch, the only way to create interrupt servers was
rtems_interrupt_server_initialize(). This function creates the default
interrupt server and in SMP configurations additional interrupt servers
for the additional processors. The interrupt server is heavily used by
libbsd. This includes the epoch based reclamation which performs time
consuming resource and memory deallocation work. This does not work well
with time critical services, for example an UART over SPI or I2C. One
approach to address this problem is to allow the application to create
custom interrupt servers with the right priority and task properties.
The interrupt server API accounted for this, however, it was not
implemented before this patch.

Close #4034.

  • Property mode set to 100644
File size: 27.9 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup rtems_interrupt_extension
5 *
6 * @brief Header file for the Interrupt Manager Extension.
7 */
8
9/*
10 * Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
11 *
12 * Copyright (C) 2008, 2020 embedded brains GmbH (http://www.embedded-brains.de)
13 *
14 * The license and distribution terms for this file may be
15 * found in the file LICENSE in this distribution or at
16 * http://www.rtems.org/license/LICENSE.
17 */
18
19#ifndef RTEMS_IRQ_EXTENSION_H
20#define RTEMS_IRQ_EXTENSION_H
21
22#include <rtems.h>
23#include <rtems/chain.h>
24
25#ifdef __cplusplus
26extern "C" {
27#endif /* __cplusplus */
28
29/**
30 * @defgroup rtems_interrupt_extension Interrupt Manager Extension
31 *
32 * @ingroup ClassicINTR
33 *
34 * In addition to the Classic API interrupt handler with a handle are
35 * supported.  You can also install multiple shared handler for one interrupt
36 * vector.
37 */
38/**@{**/
39
40/**
41 * @brief Makes the interrupt handler unique.  Prevents other handler from
42 * using the same interrupt vector.
43 */
44#define RTEMS_INTERRUPT_UNIQUE ((rtems_option) 0x00000001)
45
46/**
47 * @brief Allows that this interrupt handler may share a common interrupt
48 * vector with other handler.
49 */
50#define RTEMS_INTERRUPT_SHARED ((rtems_option) 0x00000000)
51
52/**
53 * @brief Forces that this interrupt handler replaces the first handler with
54 * the same argument.
55 */
56#define RTEMS_INTERRUPT_REPLACE ((rtems_option) 0x00000002)
57
58/**
59 * @brief Returns true if the interrupt handler unique option is set.
60 */
61#define RTEMS_INTERRUPT_IS_UNIQUE( options) \
62  ((options) & RTEMS_INTERRUPT_UNIQUE)
63
64/**
65 * @brief Returns true if the interrupt handler shared option is set.
66 */
67#define RTEMS_INTERRUPT_IS_SHARED( options) \
68  (!RTEMS_INTERRUPT_IS_UNIQUE( options))
69
70/**
71 * @brief Returns true if the interrupt handler replace option is set.
72 */
73#define RTEMS_INTERRUPT_IS_REPLACE( options) \
74  ((options) & RTEMS_INTERRUPT_REPLACE)
75
76/**
77 * @brief Interrupt handler routine type.
78 */
79typedef void (*rtems_interrupt_handler)(void *);
80
81/**
82 * @brief Installs the interrupt handler routine @a handler for the interrupt
83 * vector with number @a vector.
84 *
85 * You can set one of the mutually exclusive options
86 *
87 * - @ref RTEMS_INTERRUPT_UNIQUE
88 * - @ref RTEMS_INTERRUPT_SHARED
89 * - @ref RTEMS_INTERRUPT_REPLACE
90 *
91 * with the @a options parameter for the interrupt handler.
92 *
93 * The handler routine shall be called with argument @a arg when dispatched.
94 * The order in which the shared interrupt handlers are dispatched for one
95 * vector is BSP dependent.
96 *
97 * If the option @ref RTEMS_INTERRUPT_UNIQUE is set then it shall be ensured
98 * that this handler will be the only one for this vector.
99 *
100 * If the option @ref RTEMS_INTERRUPT_REPLACE is set then it shall be ensured
101 * that this handler will replace the first handler with the same argument for
102 * this vector if it exists, otherwise an error status shall be returned.  A
103 * second handler with the same argument for this vector shall remain
104 * unchanged.  The new handler will inherit the unique or shared option from
105 * the replaced handler.
106 *
107 * You can provide an informative description @a info.  This may be used for
108 * system debugging and status tools.  The string has to be persistent during
109 * the handler life time.
110 *
111 * This function may block.
112 *
113 * @retval RTEMS_SUCCESSFUL Successful operation.
114 * @retval RTEMS_CALLED_FROM_ISR If this function is called from interrupt
115 * context this shall be returned.
116 * @retval RTEMS_INVALID_ADDRESS If the handler address is NULL this shall be
117 * returned.
118 * @retval RTEMS_INVALID_ID If the vector number is out of range this shall be
119 * returned.
120 * @retval RTEMS_INVALID_NUMBER If an option is not applicable this shall be
121 * returned.
122 * @retval RTEMS_RESOURCE_IN_USE If the vector is already occupied with a
123 * unique handler this shall be returned.  If a unique handler should be
124 * installed and there is already a handler installed this shall be returned.
125 * @retval RTEMS_TOO_MANY If a handler with this argument is already installed
126 * for the vector this shall be returned.
127 * @retval RTEMS_UNSATISFIED If no handler exists to replace with the specified
128 * argument and vector this shall be returned.
129 * @retval RTEMS_IO_ERROR Reserved for board support package specific error
130 * conditions.
131 */
132rtems_status_code rtems_interrupt_handler_install(
133  rtems_vector_number vector,
134  const char *info,
135  rtems_option options,
136  rtems_interrupt_handler handler,
137  void *arg
138);
139
140/**
141 * @brief Removes the interrupt handler routine @a handler with argument @a arg
142 * for the interrupt vector with number @a vector.
143 *
144 * This function may block.
145 *
146 * @retval RTEMS_SUCCESSFUL Successful operation.
147 * @retval RTEMS_CALLED_FROM_ISR If this function is called from interrupt
148 * context this shall be returned.
149 * @retval RTEMS_INVALID_ADDRESS If the handler address is NULL this shall be
150 * returned.
151 * @retval RTEMS_INVALID_ID If the vector number is out of range this shall be
152 * returned.
153 * @retval RTEMS_UNSATISFIED If the handler with its argument is not installed
154 * for the vector this shall be returned.
155 * @retval RTEMS_IO_ERROR Reserved for board support package specific error
156 * conditions.
157 */
158rtems_status_code rtems_interrupt_handler_remove(
159  rtems_vector_number vector,
160  rtems_interrupt_handler handler,
161  void *arg
162);
163
164/**
165 * @brief Interrupt handler iteration routine type.
166 *
167 * @see rtems_interrupt_handler_iterate()
168 */
169typedef void (*rtems_interrupt_per_handler_routine)(
170  void *, const char *, rtems_option, rtems_interrupt_handler, void *
171);
172
173/**
174 * @brief Iterates over all installed interrupt handler of the interrupt vector
175 * with number @a vector.
176 *
177 * For each installed handler of the vector the function @a routine will be
178 * called with the supplied argument @a arg and the handler information,
179 * options, routine and argument.
180 *
181 * This function is intended for system information and diagnostics.
182 *
183 * This function may block.  Never install or remove an interrupt handler
184 * within the iteration routine.  This may result in a deadlock.
185 *
186 * @retval RTEMS_SUCCESSFUL Successful operation.
187 * @retval RTEMS_CALLED_FROM_ISR If this function is called from interrupt
188 * context this shall be returned.
189 * @retval RTEMS_INVALID_ID If the vector number is out of range this shall be
190 * returned.
191 * @retval RTEMS_IO_ERROR Reserved for board support package specific error
192 * conditions.
193 */
194rtems_status_code rtems_interrupt_handler_iterate(
195  rtems_vector_number vector,
196  rtems_interrupt_per_handler_routine routine,
197  void *arg
198);
199
200/**
201 * @brief Sets the processor affinity set of an interrupt vector.
202 *
203 * @param[in] vector The interrupt vector number.
204 * @param[in] affinity_size The storage size of the affinity set.
205 * @param[in] affinity_set The new processor affinity set for the interrupt
206 *   vector.  This pointer must not be @c NULL.
207 *
208 * @retval RTEMS_SUCCESSFUL Successful operation.
209 * @retval RTEMS_INVALID_ID The vector number is invalid.
210 * @retval RTEMS_INVALID_SIZE Invalid affinity set size.
211 * @retval RTEMS_INVALID_NUMBER Invalid processor affinity set.
212 */
213rtems_status_code rtems_interrupt_set_affinity(
214  rtems_vector_number  vector,
215  size_t               affinity_size,
216  const cpu_set_t     *affinity
217);
218
219/**
220 * @brief Gets the processor affinity set of an interrupt vector.
221 *
222 * @param[in] vector The interrupt vector number.
223 * @param[in] affinity_size The storage size of the affinity set.
224 * @param[out] affinity_set The current processor affinity set for the
225 *   interrupt vector.  This pointer must not be @c NULL.
226 *
227 * @retval RTEMS_SUCCESSFUL Successful operation.
228 * @retval RTEMS_INVALID_ID The vector number is invalid.
229 * @retval RTEMS_INVALID_SIZE Invalid affinity set size.
230 */
231rtems_status_code rtems_interrupt_get_affinity(
232  rtems_vector_number  vector,
233  size_t               affinity_size,
234  cpu_set_t           *affinity
235);
236
237/**
238 * @brief An interrupt server action.
239 *
240 * This structure must be treated as an opaque data type.  Members must not be
241 * accessed directly.
242 *
243 * @see rtems_interrupt_server_action_prepend().
244 */
245typedef struct rtems_interrupt_server_action {
246  struct rtems_interrupt_server_action *next;
247  rtems_interrupt_handler               handler;
248  void                                 *arg;
249} rtems_interrupt_server_action;
250
251/**
252 * @brief The interrupt server index of the default interrupt server.
253 */
254#define RTEMS_INTERRUPT_SERVER_DEFAULT 0
255
256/**
257 * @brief An interrupt server control.
258 *
259 * This structure must be treated as an opaque data type.  Members must not be
260 * accessed directly.
261 *
262 * @see rtems_interrupt_server_create()
263 */
264typedef struct rtems_interrupt_server_control {
265  RTEMS_INTERRUPT_LOCK_MEMBER( lock )
266  rtems_chain_control          entries;
267  rtems_id                     server;
268  unsigned long                errors;
269  uint32_t                     index;
270  rtems_chain_node             node;
271  void ( *destroy )( struct rtems_interrupt_server_control * );
272} rtems_interrupt_server_control;
273
274/**
275 * @brief An interrupt server configuration.
276 *
277 * @see rtems_interrupt_server_create()
278 */
279typedef struct {
280  /**
281   * @brief The task name of the interrupt server.
282   */
283  rtems_name name;
284
285  /**
286   * @brief The initial task priority of the interrupt server.
287   */
288  rtems_task_priority priority;
289
290  /**
291   * @brief The task storage area of the interrupt server.
292   *
293   * It shall be NULL for interrupt servers created by
294   * rtems_interrupt_server_create().
295   */
296  void *storage_area;
297
298  /**
299   * @brief The task storage size of the interrupt server.
300   *
301   * For interrupt servers created by rtems_interrupt_server_create() this is
302   * the task stack size.
303   */
304  size_t storage_size;
305
306  /**
307   * @brief The initial task modes of the interrupt server.
308   */
309  rtems_mode modes;
310
311  /**
312   * @brief The task attributes of the interrupt server.
313   */
314  rtems_attribute attributes;
315
316  /**
317   * @brief An optional handler to destroy the interrupt server control handed
318   *   over to rtems_interrupt_server_create().
319   *
320   * This handler is called in the context of the interrupt server to be
321   * deleted, see also rtems_interrupt_server_delete().
322   */
323  void ( *destroy )( rtems_interrupt_server_control * );
324} rtems_interrupt_server_config;
325
326/**
327 * @brief An interrupt server entry.
328 *
329 * This structure must be treated as an opaque data type.  Members must not be
330 * accessed directly.
331 *
332 * @see rtems_interrupt_server_entry_initialize(),
333 *   rtems_interrupt_server_action_prepend(),
334 *   rtems_interrupt_server_entry_submit(), and
335 *   rtems_interrupt_server_entry_destroy().
336 */
337typedef struct {
338  rtems_chain_node               node;
339  void                          *server;
340  rtems_vector_number            vector;
341  rtems_interrupt_server_action *actions;
342} rtems_interrupt_server_entry;
343
344/**
345 * @brief An interrupt server request.
346 *
347 * This structure must be treated as an opaque data type.  Members must not be
348 * accessed directly.
349 *
350 * @see rtems_interrupt_server_request_initialize(),
351 *   rtems_interrupt_server_request_set_vector(),
352 *   rtems_interrupt_server_request_submit(), and
353 *   rtems_interrupt_server_request_destroy().
354 */
355typedef struct {
356  rtems_interrupt_server_entry  entry;
357  rtems_interrupt_server_action action;
358} rtems_interrupt_server_request;
359
360/**
361 * @brief Initializes the interrupt server tasks.
362 *
363 * This function tries to create an interrupt server task for each processor in
364 * the system.  The tasks will have the priority @a priority, the stack size @a
365 * stack_size, the modes @a modes and the attributes @a attributes.  The count
366 * of server tasks will be returned in @a server_count.  Interrupt handlers can
367 * be installed on an interrupt server with
368 * rtems_interrupt_server_handler_install() and removed with
369 * rtems_interrupt_server_handler_remove() using a server index.  In case of an
370 * interrupt, the request will be forwarded to the interrupt server.  The
371 * handlers are executed within the interrupt server context.  If one handler
372 * blocks on something this may delay the processing of other handlers.
373 *
374 * The server count pointer @a server_count may be @a NULL.
375 *
376 * The task name of interrupt servers created by this function is
377 * rtems_build_name( 'I', 'R', 'Q', 'S' ).
378 *
379 * This function may block.
380 *
381 * @retval RTEMS_SUCCESSFUL The operation was successful.
382 *
383 * @retval RTEMS_INCORRECT_STATE The interrupt servers were already initialized.
384 *
385 * @return The function uses rtems_task_create().  If this operation is not
386 *   successful, then its status code is returned.
387 *
388 * @see rtems_interrupt_server_create() and rtems_interrupt_server_delete().
389 */
390rtems_status_code rtems_interrupt_server_initialize(
391  rtems_task_priority priority,
392  size_t stack_size,
393  rtems_mode modes,
394  rtems_attribute attributes,
395  uint32_t *server_count
396);
397
398/**
399 * @brief Creates an interrupt server.
400 *
401 * This function may block.
402 *
403 * @param[out] control is the interrupt server control.  The ownership of this
404 *   structure is transferred from the caller of this function to the interrupt
405 *   server management.
406 *
407 * @param config is the interrupt server configuration.
408 *
409 * @param[out] server_index is the pointer to a server index variable.  The
410 *   index of the built interrupt server will be stored in the referenced
411 *   variable if the operation was successful.
412 *
413 * @retval RTEMS_SUCCESSFUL The operation was successful.
414 *
415 * @return The function uses rtems_task_create().  If this operation is not
416 *   successful, then its status code is returned.
417 *
418 * @see rtems_interrupt_server_initialize() and
419 *   rtems_interrupt_server_delete().
420 */
421rtems_status_code rtems_interrupt_server_create(
422  rtems_interrupt_server_control      *control,
423  const rtems_interrupt_server_config *config,
424  uint32_t                            *server_index
425);
426
427/**
428 * @brief Destroys the interrupt server.
429 *
430 * This function may block.
431 *
432 * The interrupt server deletes itself, so after the return of the function the
433 * interrupt server may be still in the termination process depending on the
434 * task priorities of the system.
435 *
436 * @param server_index is the index of the interrupt server to destroy.  Use
437 *   ::RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server.
438 *
439 * @retval RTEMS_SUCCESSFUL The operation was successful.
440 * @retval RTEMS_INVALID_ID The interrupt server index was invalid.
441 *
442 * @see rtems_interrupt_server_create()
443 */
444rtems_status_code rtems_interrupt_server_delete( uint32_t server_index );
445
446/**
447 * @brief Installs the interrupt handler routine @a handler for the interrupt
448 * vector with number @a vector on the server @a server.
449 *
450 * The handler routine will be executed on the corresponding interrupt server
451 * task.  A server index @a server_index of @c RTEMS_INTERRUPT_SERVER_DEFAULT
452 * may be used to install the handler on the default server.
453 *
454 * This function may block.
455 *
456 * @see rtems_interrupt_handler_install().
457 *
458 * @retval RTEMS_SUCCESSFUL Successful operation.
459 * @retval RTEMS_INCORRECT_STATE The interrupt servers are not initialized.
460 * @retval RTEMS_INVALID_ID If the interrupt server index is invalid.
461 * @retval * For other errors see rtems_interrupt_handler_install().
462 */
463rtems_status_code rtems_interrupt_server_handler_install(
464  uint32_t server_index,
465  rtems_vector_number vector,
466  const char *info,
467  rtems_option options,
468  rtems_interrupt_handler handler,
469  void *arg
470);
471
472/**
473 * @brief Removes the interrupt handler routine @a handler with argument @a arg
474 * for the interrupt vector with number @a vector from the server @a server.
475 *
476 * A server index @a server_index of @c RTEMS_INTERRUPT_SERVER_DEFAULT may be
477 * used to remove the handler from the default server.
478 *
479 * This function may block.
480 *
481 * @see rtems_interrupt_handler_remove().
482 *
483 * @retval RTEMS_SUCCESSFUL Successful operation.
484 * @retval RTEMS_INCORRECT_STATE The interrupt servers are not initialized.
485 * @retval RTEMS_INVALID_ID If the interrupt server index is invalid.
486 * @retval * For other errors see rtems_interrupt_handler_remove().
487 */
488rtems_status_code rtems_interrupt_server_handler_remove(
489  uint32_t server_index,
490  rtems_vector_number vector,
491  rtems_interrupt_handler handler,
492  void *arg
493);
494
495/**
496 * @brief Iterates over all interrupt handler of the interrupt vector with
497 * number @a vector which are installed on the interrupt server specified by
498 * @a server.
499 *
500 * A server index @a server_index of @c RTEMS_INTERRUPT_SERVER_DEFAULT may be
501 * used to specify the default server.
502 *
503 * @see rtems_interrupt_handler_iterate()
504 *
505 * @retval RTEMS_SUCCESSFUL Successful operation.
506 * @retval RTEMS_INCORRECT_STATE The interrupt servers are not initialized.
507 * @retval RTEMS_INVALID_ID If the interrupt server index is invalid.
508 * @retval * For other errors see rtems_interrupt_handler_iterate().
509 */
510rtems_status_code rtems_interrupt_server_handler_iterate(
511  uint32_t server_index,
512  rtems_vector_number vector,
513  rtems_interrupt_per_handler_routine routine,
514  void *arg
515);
516
517/**
518 * @brief Moves the interrupt handlers installed on the specified source
519 * interrupt server to the destination interrupt server.
520 *
521 * This function must be called from thread context.  It may block.  Calling
522 * this function within the context of an interrupt server is undefined
523 * behaviour.
524 *
525 * @param[in] source_server_index The source interrupt server index.  Use
526 *   @c RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server.
527 * @param[in] vector The interrupt vector number.
528 * @param[in] destination_server_index The destination interrupt server index.
529 *   Use @c RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server.
530 *
531 * @retval RTEMS_SUCCESSFUL Successful operation
532 * @retval RTEMS_INCORRECT_STATE The interrupt servers are not initialized.
533 * @retval RTEMS_INVALID_ID The destination interrupt server index is invalid.
534 * @retval RTEMS_INVALID_ID The vector number is invalid.
535 * @retval RTEMS_INVALID_ID The destination interrupt server index is invalid.
536 */
537rtems_status_code rtems_interrupt_server_move(
538  uint32_t            source_server_index,
539  rtems_vector_number vector,
540  uint32_t            destination_server_index
541);
542
543/**
544 * @brief Suspends the specified interrupt server.
545 *
546 * A suspend request is sent to the specified interrupt server.  This function
547 * waits for an acknowledgment from the specified interrupt server.
548 *
549 * This function must be called from thread context.  It may block.  Calling
550 * this function within the context of an interrupt server is undefined
551 * behaviour.
552 *
553 * @param[in] server_index The interrupt server index.  Use
554 *   @c RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server.
555 *
556 * @see rtems_interrupt_server_resume().
557 *
558 * @retval RTEMS_SUCCESSFUL Successful operation
559 * @retval RTEMS_INCORRECT_STATE The interrupt servers are not initialized.
560 * @retval RTEMS_INVALID_ID If the interrupt server index is invalid.
561 */
562rtems_status_code rtems_interrupt_server_suspend( uint32_t server_index );
563
564/**
565 * @brief Resumes the specified interrupt server.
566 *
567 * This function must be called from thread context.  It may block.  Calling
568 * this function within the context of an interrupt server is undefined
569 * behaviour.
570 *
571 * @param[in] server_index The interrupt server index.  Use
572 *   @c RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server.
573 *
574 * @see rtems_interrupt_server_suspend().
575 *
576 * @retval RTEMS_SUCCESSFUL Successful operation
577 * @retval RTEMS_INCORRECT_STATE The interrupt servers are not initialized.
578 * @retval RTEMS_INVALID_ID If the interrupt server index is invalid.
579 */
580rtems_status_code rtems_interrupt_server_resume( uint32_t server_index );
581
582/**
583 * @brief Sets the processor affinity of the specified interrupt server.
584 *
585 * The scheduler is set determined by the highest numbered processor in the
586 * specified affinity set.
587 *
588 * This operation is only reliable in case the specified interrupt was
589 * suspended via rtems_interrupt_server_suspend().
590 *
591 * @param[in] server_index The interrupt server index.  Use
592 *   @c RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server.
593 * @param[in] affinity_size The storage size of the affinity set.
594 * @param[in] affinity The desired processor affinity set for the specified
595 *   interrupt server.
596 * @param[in] priority The task priority with respect to the corresponding
597 *   scheduler instance.
598 *
599 * @retval RTEMS_SUCCESSFUL Successful operation
600 * @retval RTEMS_INCORRECT_STATE The interrupt servers are not initialized.
601 * @retval RTEMS_INVALID_ID If the interrupt server index is invalid.
602 * @retval RTEMS_INVALID_SIZE Invalid affinity set size.
603 * @retval RTEMS_INVALID_NAME The affinity set contains no online processor.
604 * @retval RTEMS_INCORRECT_STATE The highest numbered online processor in the
605 *   specified affinity set is not owned by a scheduler.
606 * @retval RTEMS_INVALID_PRIORITY Invalid priority.
607 * @retval RTEMS_RESOURCE_IN_USE The interrupt server owns resources which deny
608 *   a scheduler change.
609 * @retval RTEMS_INVALID_NUMBER Invalid processor affinity set.
610 */
611rtems_status_code rtems_interrupt_server_set_affinity(
612  uint32_t            server_index,
613  size_t              affinity_size,
614  const cpu_set_t    *affinity,
615  rtems_task_priority priority
616);
617
618/**
619 * @brief Initializes the specified interrupt server entry.
620 *
621 * @param[in] server_index The interrupt server index.  Use
622 *   @c RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server.
623 * @param[in] entry The interrupt server entry to initialize.
624 *
625 * @see rtems_interrupt_server_action_prepend().
626 *
627 * @retval RTEMS_SUCCESSFUL Successful operation.
628 * @retval RTEMS_INCORRECT_STATE The interrupt servers are not initialized.
629 * @retval RTEMS_INVALID_ID If the interrupt server index is invalid.
630 */
631rtems_status_code rtems_interrupt_server_entry_initialize(
632  uint32_t                      server_index,
633  rtems_interrupt_server_entry *entry
634);
635
636/**
637 * @brief Prepends the specified interrupt server action to the list of actions
638 * of the specified interrupt server entry.
639 *
640 * No error checking is performed.
641 *
642 * @param[in] entry The interrupt server entry to prepend the interrupt server
643 *   action.  It must have been initialized via
644 *   rtems_interrupt_server_entry_initialize().
645 * @param[in] action The interrupt server action to prepend the list of actions
646 *   of the entry.
647 * @param[in] handler The interrupt handler for the action.
648 * @param[in] arg The interrupt handler argument for the action.
649 */
650void rtems_interrupt_server_action_prepend(
651  rtems_interrupt_server_entry  *entry,
652  rtems_interrupt_server_action *action,
653  rtems_interrupt_handler        handler,
654  void                          *arg
655);
656
657/**
658 * @brief Submits the specified interrupt server entry so that its interrupt
659 * server actions can be invoked by the specified interrupt server.
660 *
661 * This function may be used to do a two-step interrupt processing.  The first
662 * step is done in interrupt context which calls this function.  The second
663 * step is then done in the context of the interrupt server.
664 *
665 * This function may be called from thread or interrupt context.  It does not
666 * block.  No error checking is performed.
667 *
668 * @param[in] entry The interrupt server entry must be initialized before the
669 *   first call to this function via rtems_interrupt_server_entry_initialize()
670 *   and rtems_interrupt_server_action_prepend().  The entry and its actions
671 *   must not be modified between calls to this function.  Use
672 *   rtems_interrupt_server_entry_destroy() to destroy an entry in use.
673 */
674void rtems_interrupt_server_entry_submit(
675  rtems_interrupt_server_entry *entry
676);
677
678/**
679 * @brief Moves the interrupt server entry to the specified destination
680 * interrupt server.
681 *
682 * Calling this function concurrently with rtems_interrupt_server_entry_submit()
683 * with the same entry or while the entry is enqueued on the previous interrupt
684 * server is undefined behaviour.
685 *
686 * @param[in,out] entry The interrupt server entry.  It must have be initialized
687 *   before the call to this function.
688 * @param destination_server_index The destination interrupt server index.
689 *   Use @c RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server.
690 *
691 * @retval RTEMS_SUCCESSFUL Successful operation
692 * @retval RTEMS_INCORRECT_STATE The interrupt servers are not initialized.
693 * @retval RTEMS_INVALID_ID The destination interrupt server index is invalid.
694 */
695rtems_status_code rtems_interrupt_server_entry_move(
696  rtems_interrupt_server_entry *entry,
697  uint32_t                      destination_server_index
698);
699
700/**
701 * @brief Destroys the specified interrupt server entry.
702 *
703 * This function must be called from thread context.  It may block.  Calling
704 * this function within the context of an interrupt server is undefined
705 * behaviour.  No error checking is performed.
706 *
707 * @param[in] entry The interrupt server entry to destroy.  It must have been
708 *   initialized via rtems_interrupt_server_entry_initialize().
709 */
710void rtems_interrupt_server_entry_destroy(
711  rtems_interrupt_server_entry *entry
712);
713
714/**
715 * @brief Initializes the specified interrupt server request.
716 *
717 * @param[in] server_index The interrupt server index.  Use
718 *   @c RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server.
719 * @param[in] request The interrupt server request to initialize.
720 * @param[in] handler The interrupt handler for the request action.
721 * @param[in] arg The interrupt handler argument for the request action.
722 *
723 * @retval RTEMS_SUCCESSFUL Successful operation.
724 * @retval RTEMS_INCORRECT_STATE The interrupt servers are not initialized.
725 * @retval RTEMS_INVALID_ID If the interrupt server index is invalid.
726 *
727 * @see rtems_interrupt_server_request_set_vector().
728 */
729rtems_status_code rtems_interrupt_server_request_initialize(
730  uint32_t                        server_index,
731  rtems_interrupt_server_request *request,
732  rtems_interrupt_handler         handler,
733  void                           *arg
734);
735
736/**
737 * @brief Sets the interrupt vector in the specified interrupt server request.
738 *
739 * By default, the interrupt vector of an interrupt server request is set to a
740 * special value which is outside the range of vectors supported by the
741 * interrupt controller hardware.
742 *
743 * Calls to rtems_interrupt_server_request_submit() will disable the interrupt
744 * vector of the request.  After processing of the request by the interrupt
745 * server the interrupt vector will be enabled again.
746 *
747 * @param[in] request The initialized interrupt server request.
748 * @param[in] vector The interrupt vector number.
749 *
750 * @see rtems_interrupt_server_request_initialize().
751 */
752RTEMS_INLINE_ROUTINE void rtems_interrupt_server_request_set_vector(
753  rtems_interrupt_server_request *request,
754  rtems_vector_number             vector
755)
756{
757  request->entry.vector = vector;
758}
759
760/**
761 * @brief Submits the specified interrupt server request so that its interrupt
762 * server action can be invoked by the specified interrupt server.
763 *
764 * This function may be used to do a two-step interrupt processing.  The first
765 * step is done in interrupt context which calls this function.  The second
766 * step is then done in the context of the interrupt server.
767 *
768 * This function may be called from thread or interrupt context.  It does not
769 * block.  No error checking is performed.
770 *
771 * @param[in] request The interrupt server request must be initialized before the
772 *   first call to this function via
773 *   rtems_interrupt_server_request_initialize().  The request must not be
774 *   modified between calls to this function.  Use
775 *   rtems_interrupt_server_request_destroy() to destroy a request in use.
776 */
777RTEMS_INLINE_ROUTINE void rtems_interrupt_server_request_submit(
778  rtems_interrupt_server_request *request
779)
780{
781  rtems_interrupt_server_entry_submit( &request->entry );
782}
783
784/**
785 * @brief Destroys the specified interrupt server request.
786 *
787 * This function must be called from thread context.  It may block.  Calling
788 * this function within the context of an interrupt server is undefined
789 * behaviour.  No error checking is performed.
790 *
791 * @param[in] request The interrupt server request to destroy.  It must have
792 *   been initialized via rtems_interrupt_server_request_initialize().
793 */
794RTEMS_INLINE_ROUTINE void rtems_interrupt_server_request_destroy(
795  rtems_interrupt_server_request *request
796)
797{
798  rtems_interrupt_server_entry_destroy( &request->entry );
799}
800
801/** @} */
802
803#ifdef __cplusplus
804}
805#endif /* __cplusplus */
806
807#endif /* RTEMS_IRQ_EXTENSION_H */
Note: See TracBrowser for help on using the repository browser.