. added rm_irq_handler which un-links an irq handler from the linked
list of handlers, callable by irqctl system call . workaround for hanging keyboard bug after shutdown.. if key is pressed during or after shutdown procedure, keyboard stops working. It looks like irq 1 gets stuck high if no keyboard reading is done (e.g. because the irq is masked or tty driver has exited). Workaround is to leave irqs enabled until the last second, and call shutdown() immediately after the last driver has stopped (tty task). This way the chance of an unserviced interrupt occuring is negligible.
This commit is contained in:
@@ -24,15 +24,18 @@ register message *m_ptr; /* pointer to request message */
|
||||
int irq_vec;
|
||||
int irq_hook_id;
|
||||
int proc_nr;
|
||||
int r = OK;
|
||||
irq_hook_t *hook_ptr;
|
||||
|
||||
irq_hook_id = (unsigned) m_ptr->IRQ_HOOK_ID;
|
||||
irq_vec = (unsigned) m_ptr->IRQ_VECTOR;
|
||||
|
||||
/* See what is requested and take needed actions. */
|
||||
switch(m_ptr->IRQ_REQUEST) {
|
||||
|
||||
/* Enable or disable IRQs. This is straightforward. */
|
||||
case IRQ_ENABLE:
|
||||
case IRQ_DISABLE:
|
||||
irq_hook_id = (unsigned) m_ptr->IRQ_HOOK_ID;
|
||||
if (irq_hook_id >= NR_IRQ_HOOKS) return(EINVAL);
|
||||
if (irq_hooks[irq_hook_id].proc_nr != m_ptr->m_source) return(EPERM);
|
||||
if (m_ptr->IRQ_REQUEST == IRQ_ENABLE)
|
||||
@@ -48,8 +51,7 @@ register message *m_ptr; /* pointer to request message */
|
||||
case IRQ_SETPOLICY:
|
||||
|
||||
/* Check if IRQ line is acceptable. */
|
||||
irq_vec = (unsigned) m_ptr->IRQ_VECTOR;
|
||||
if ((unsigned) irq_vec >= NR_IRQ_VECTORS) {
|
||||
if (irq_vec < 0 || irq_vec >= NR_IRQ_VECTORS) {
|
||||
kprintf("ST: irq line %d is not acceptable!\n", irq_vec);
|
||||
return(EINVAL);
|
||||
}
|
||||
@@ -73,9 +75,22 @@ register message *m_ptr; /* pointer to request message */
|
||||
m_ptr->IRQ_HOOK_ID = irq_hook_id;
|
||||
break;
|
||||
|
||||
case IRQ_RMPOLICY:
|
||||
if(irq_hook_id < 0 || irq_hook_id >= NR_IRQ_HOOKS ||
|
||||
irq_hooks[irq_hook_id].proc_nr == NONE) {
|
||||
r = EINVAL;
|
||||
} else {
|
||||
if(m_ptr->m_source != irq_hooks[irq_hook_id].proc_nr) {
|
||||
r = EPERM;
|
||||
} else {
|
||||
r = rm_irq_handler(irq_vec, irq_hooks[irq_hook_id].id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return(EINVAL); /* invalid IRQ_REQUEST */
|
||||
r = EINVAL; /* invalid IRQ_REQUEST */
|
||||
}
|
||||
return(OK);
|
||||
return(r);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user