/* The system call implemented in this file: * m_type: SYS_IRQCTL * * The parameters for this system call are: * m5_c1: IRQ_REQUEST (control operation to perform) * m5_c2: IRQ_VECTOR (irq line that must be controlled) * m5_i1: IRQ_POLICY (irq policy allows reenabling interrupts) * m5_l3: IRQ_HOOK_ID (index of irq hook assigned at kernel) * * Author: * Jorrit N. Herder */ #include "../kernel.h" #include "../system.h" /*===========================================================================* * do_irqctl * *===========================================================================*/ PUBLIC int do_irqctl(m_ptr) register message *m_ptr; /* pointer to request message */ { /* Dismember the request message. */ int irq_vec; int irq_hook_id; int proc_nr; irq_hook_t *hook_ptr; /* See what is requested and take needed actions. */ switch(m_ptr->IRQ_REQUEST) { /* Enable or disable IRQs. This is straightforward. */ case IRQ_ENABLE: { irq_hook_id = (unsigned) m_ptr->IRQ_HOOK_ID; if (irq_hook_id >= NR_IRQ_HOOKS) return(EINVAL); enable_irq(&irq_hooks[irq_hook_id]); break; } case IRQ_DISABLE: { irq_hook_id = (unsigned) m_ptr->IRQ_HOOK_ID; if (irq_hook_id >= NR_IRQ_HOOKS) return(EINVAL); disable_irq(&irq_hooks[irq_hook_id]); break; } /* Control IRQ policies. Set a policy and needed details in the IRQ table. * This policy is used by a generic function to handle hardware interrupts. */ case IRQ_SETPOLICY: { /* Check if IRQ line is acceptable. */ irq_vec = (unsigned) m_ptr->IRQ_VECTOR; if ((unsigned) irq_vec >= NR_IRQ_VECTORS) { kprintf("ST: irq line %d is not acceptable!\n", irq_vec); return(EINVAL); } /* Find a free IRQ hook for this mapping. */ hook_ptr = NULL; for (irq_hook_id=0; irq_hook_idproc_nr = m_ptr->m_source; /* process to notify */ hook_ptr->policy = m_ptr->IRQ_POLICY; /* policy for interrupts */ put_irq_handler(hook_ptr, irq_vec, generic_handler); /* Return index of the IRQ hook in use. */ m_ptr->IRQ_HOOK_ID = irq_hook_id; break; } default: return(EINVAL); /* invalid IRQ_REQUEST */ } return(OK); }