Expose a new public routine intr_event_execute_handlers() which executes
all the non-filter handlers attached to an interrupt event. This can be used by device drivers which multiplex their interrupt onto the interrupt handlers for child devices.
This commit is contained in:
parent
109ea24cc1
commit
37e9511fcb
@ -1085,16 +1085,16 @@ priv_ithread_execute_handler(struct proc *p, struct intr_handler *ih)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
ithread_execute_handlers(struct proc *p, struct intr_event *ie)
|
||||
/*
|
||||
* This is a public function for use by drivers that mux interrupt
|
||||
* handlers for child devices from their interrupt handler.
|
||||
*/
|
||||
void
|
||||
intr_event_execute_handlers(struct proc *p, struct intr_event *ie)
|
||||
{
|
||||
struct intr_handler *ih, *ihn;
|
||||
|
||||
/* Interrupt handlers should not sleep. */
|
||||
if (!(ie->ie_flags & IE_SOFT))
|
||||
THREAD_NO_SLEEPING();
|
||||
TAILQ_FOREACH_SAFE(ih, &ie->ie_handlers, ih_next, ihn) {
|
||||
|
||||
/*
|
||||
* If this handler is marked for death, remove it from
|
||||
* the list of handlers and wake up the sleeper.
|
||||
@ -1135,6 +1135,16 @@ ithread_execute_handlers(struct proc *p, struct intr_event *ie)
|
||||
if (!(ih->ih_flags & IH_MPSAFE))
|
||||
mtx_unlock(&Giant);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ithread_execute_handlers(struct proc *p, struct intr_event *ie)
|
||||
{
|
||||
|
||||
/* Interrupt handlers should not sleep. */
|
||||
if (!(ie->ie_flags & IE_SOFT))
|
||||
THREAD_NO_SLEEPING();
|
||||
intr_event_execute_handlers(p, ie);
|
||||
if (!(ie->ie_flags & IE_SOFT))
|
||||
THREAD_SLEEPING_OK();
|
||||
|
||||
|
@ -90,6 +90,16 @@ struct intr_handler {
|
||||
* The 'assign_cpu' hook is used to bind an interrupt source to a
|
||||
* specific CPU. If the interrupt cannot be bound, this function may
|
||||
* return an error.
|
||||
*
|
||||
* Note that device drivers may also use interrupt events to manage
|
||||
* multiplexing interrupt interrupt handler into handlers for child
|
||||
* devices. In that case, the above hooks are not used. The device
|
||||
* can create an event for its interrupt resource and register child
|
||||
* event handlers with that event. It can then use
|
||||
* intr_event_execute_handlers() to execute non-filter handlers.
|
||||
* Currently filter handlers are not supported by this, but that can
|
||||
* be added by splitting out the filter loop from intr_event_handle()
|
||||
* if desired.
|
||||
*/
|
||||
struct intr_event {
|
||||
TAILQ_ENTRY(intr_event) ie_list;
|
||||
@ -132,6 +142,8 @@ struct intr_event {
|
||||
#define SWI_TQ 6
|
||||
#define SWI_TQ_GIANT 6
|
||||
|
||||
struct proc;
|
||||
|
||||
extern struct intr_event *tty_intr_event;
|
||||
extern struct intr_event *clk_intr_event;
|
||||
extern void *softclock_ih;
|
||||
@ -157,6 +169,7 @@ int intr_event_create(struct intr_event **event, void *source,
|
||||
int (*assign_cpu)(void *, u_char), const char *fmt, ...)
|
||||
__printflike(9, 10);
|
||||
int intr_event_destroy(struct intr_event *ie);
|
||||
void intr_event_execute_handlers(struct proc *p, struct intr_event *ie);
|
||||
int intr_event_handle(struct intr_event *ie, struct trapframe *frame);
|
||||
int intr_event_remove_handler(void *cookie);
|
||||
int intr_getaffinity(int irq, void *mask);
|
||||
|
Loading…
Reference in New Issue
Block a user