Fixed a bug in interrupt handling code when removing a handler in case of
a shared IRQ.
This commit is contained in:
parent
2ba76cfec6
commit
83d1f45578
|
@ -81,22 +81,32 @@ PUBLIC int do_irqctl(struct proc * caller, message * m_ptr)
|
|||
}
|
||||
}
|
||||
|
||||
/* Find a free IRQ hook for this mapping. */
|
||||
hook_ptr = NULL;
|
||||
for (irq_hook_id=0; irq_hook_id<NR_IRQ_HOOKS; irq_hook_id++) {
|
||||
if (irq_hooks[irq_hook_id].proc_nr_e == NONE) {
|
||||
hook_ptr = &irq_hooks[irq_hook_id]; /* free hook */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hook_ptr == NULL) return(ENOSPC);
|
||||
|
||||
/* When setting a policy, the caller must provide an identifier that
|
||||
* is returned on the notification message if a interrupt occurs.
|
||||
*/
|
||||
notify_id = (unsigned) m_ptr->IRQ_HOOK_ID;
|
||||
if (notify_id > CHAR_BIT * sizeof(irq_id_t) - 1) return(EINVAL);
|
||||
|
||||
/* Try to find an existing mapping to override. */
|
||||
hook_ptr = NULL;
|
||||
for (i=0; !hook_ptr && i<NR_IRQ_HOOKS; i++) {
|
||||
if (irq_hooks[i].proc_nr_e == m_ptr->m_source
|
||||
&& irq_hooks[i].notify_id == notify_id) {
|
||||
irq_hook_id = i;
|
||||
hook_ptr = &irq_hooks[irq_hook_id]; /* existing hook */
|
||||
rm_irq_handler(&irq_hooks[irq_hook_id]);
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is nothing to override, find a free hook for this mapping. */
|
||||
for (i=0; !hook_ptr && i<NR_IRQ_HOOKS; i++) {
|
||||
if (irq_hooks[i].proc_nr_e == NONE) {
|
||||
irq_hook_id = i;
|
||||
hook_ptr = &irq_hooks[irq_hook_id]; /* free hook */
|
||||
}
|
||||
}
|
||||
if (hook_ptr == NULL) return(ENOSPC);
|
||||
|
||||
/* Install the handler. */
|
||||
hook_ptr->proc_nr_e = m_ptr->m_source; /* process to notify */
|
||||
hook_ptr->notify_id = notify_id; /* identifier to pass */
|
||||
|
|
Loading…
Reference in a new issue