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
|
/* When setting a policy, the caller must provide an identifier that
|
||||||
* is returned on the notification message if a interrupt occurs.
|
* is returned on the notification message if a interrupt occurs.
|
||||||
*/
|
*/
|
||||||
notify_id = (unsigned) m_ptr->IRQ_HOOK_ID;
|
notify_id = (unsigned) m_ptr->IRQ_HOOK_ID;
|
||||||
if (notify_id > CHAR_BIT * sizeof(irq_id_t) - 1) return(EINVAL);
|
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. */
|
/* Install the handler. */
|
||||||
hook_ptr->proc_nr_e = m_ptr->m_source; /* process to notify */
|
hook_ptr->proc_nr_e = m_ptr->m_source; /* process to notify */
|
||||||
hook_ptr->notify_id = notify_id; /* identifier to pass */
|
hook_ptr->notify_id = notify_id; /* identifier to pass */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user